[PATCH] media: atmel-isi: fix debug message which only show the first format
Correct the debug output message to show correct format. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index f51e41e..d5a5119 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -795,7 +795,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, xlate->host_fmt = _camera_formats[i]; xlate->code = code.code; dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code.code); + xlate->host_fmt->name, xlate->code); } break; default: -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/5] media: atmel-isi: correct yuv swap according to different sensor outputs
we need to configure the YCC_SWAP bits in ISI_CFG2 according to current sensor output and Atmel ISI output format. Current there are two cases Atmel ISI supported: 1. Atmel ISI outputs YUYV format. This case we need to setup YCC_SWAP according to sensor output format. 2. Atmel ISI output a pass-through formats, which means no swap. Just setup YCC_SWAP as default with no swap. Signed-off-by: Josh Wu <josh...@atmel.com> --- Changes in v2: - remove the duplicated variable: cfg2_yuv_swap. drivers/media/platform/soc_camera/atmel-isi.c | 39 --- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 45e304a..ce87a16 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,13 +103,37 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } +static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, + const struct soc_camera_format_xlate *xlate) +{ + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { + /* all convert to YUYV */ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_3; + case MEDIA_BUS_FMT_UYVY8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_2; + case MEDIA_BUS_FMT_YVYU8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_1; + } + } + + /* +* By default, no swap for the codec path of Atmel ISI. So codec +* output is same as sensor's output. +* For instance, if sensor's output is YUYV, then codec outputs YUYV. +* And if sensor's output is UYVY, then codec outputs UYVY. +*/ + return ISI_CFG2_YCC_SWAP_DEFAULT; +} + static void configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, u32 code) + u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2; /* According to sensor's output format to set cfg2 */ - switch (code) { + switch (xlate->code) { default: /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: @@ -117,16 +141,11 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, break; /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_UYVY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YVYU8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YUYV8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; + cfg2 = ISI_CFG2_COL_SPACE_YCbCr | + setup_cfg2_yuv_swap(isi, xlate); break; /* RGB, TODO */ } @@ -407,7 +426,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) isi_writel(isi, ISI_INTDIS, (u32)~0UL); configure_geometry(isi, icd->user_width, icd->user_height, - icd->current_fmt->code); + icd->current_fmt); spin_lock_irq(>lock); /* Clear any pending interrupt */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/5] media: atmel-isi: prepare for the support of preview path
Atmel ISI support a preview path which can output RGB data. So this patch introduces a bool variable to choose which path is enabled currently. And also we need setup corresponding path registers. By default the preview path is disabled. We only use Codec path. Signed-off-by: Josh Wu <josh...@atmel.com> --- Changes in v2: None drivers/media/platform/soc_camera/atmel-isi.c | 72 ++- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ce87a16..24501a4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -79,6 +79,7 @@ struct atmel_isi { dma_addr_t fb_descriptors_phys; struct list_head dma_desc_head; struct isi_dma_desc dma_desc[MAX_BUFFER_NUM]; + boolenable_preview_path; struct completion complete; /* ISI peripherial clock */ @@ -195,11 +196,19 @@ static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) /* start next dma frame. */ isi->active = list_entry(isi->video_buffer_list.next, struct frame_buffer, list); - isi_writel(isi, ISI_DMA_C_DSCR, - (u32)isi->active->p_dma_desc->fbd_phys); - isi_writel(isi, ISI_DMA_C_CTRL, - ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); - isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + if (!isi->enable_preview_path) { + isi_writel(isi, ISI_DMA_C_DSCR, + (u32)isi->active->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_C_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + } else { + isi_writel(isi, ISI_DMA_P_DSCR, + (u32)isi->active->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_P_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); + } } return IRQ_HANDLED; } @@ -226,7 +235,8 @@ static irqreturn_t isi_interrupt(int irq, void *dev_id) isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS); ret = IRQ_HANDLED; } else { - if (likely(pending & ISI_SR_CXFR_DONE)) + if (likely(pending & ISI_SR_CXFR_DONE) || + likely(pending & ISI_SR_PXFR_DONE)) ret = atmel_isi_handle_streaming(isi); } @@ -368,21 +378,35 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer) ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE); /* Check if already in a frame */ - if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { - dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n"); - return; - } + if (!isi->enable_preview_path) { + if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { + dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n"); + return; + } - isi_writel(isi, ISI_DMA_C_DSCR, (u32)buffer->p_dma_desc->fbd_phys); - isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); - isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + isi_writel(isi, ISI_DMA_C_DSCR, + (u32)buffer->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_C_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + } else { + isi_writel(isi, ISI_DMA_P_DSCR, + (u32)buffer->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_P_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); + } cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK; /* Enable linked list */ cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR; - /* Enable codec path and ISI */ - ctrl = ISI_CTRL_CDC | ISI_CTRL_EN; + /* Enable ISI */ + ctrl = ISI_CTRL_EN; + + if (!isi->enable_preview_path) + ctrl |= ISI_CTRL_CDC; + isi_writel(isi, ISI_CTRL, ctrl); isi_writel(isi, ISI_CFG1, cfg1); } @@ -458,15 +482,17 @@ static void stop_streaming(struct vb2_queue *vq)
[PATCH v2 4/5] media: atmel-isi: setup YCC_SWAP correctly when using preview path
The preview path only can convert UYVY format to RGB data. To make preview path work correctly, we need to set up YCC_SWAP according to sensor output and convert them to UYVY. Signed-off-by: Josh Wu <josh...@atmel.com> --- Changes in v2: - remove cfg2_yuv_swap for rgb format - correct the comment style drivers/media/platform/soc_camera/atmel-isi.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ae82068..826d04e 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -117,6 +117,20 @@ static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, case MEDIA_BUS_FMT_YVYU8_2X8: return ISI_CFG2_YCC_SWAP_MODE_1; } + } else if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_RGB565) { + /* +* Preview path is enabled, it will convert UYVY to RGB format. +* But if sensor output format is not UYVY, we need to set +* YCC_SWAP_MODE to convert it as UYVY. +*/ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_1; + case MEDIA_BUS_FMT_YUYV8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_2; + case MEDIA_BUS_FMT_YVYU8_2X8: + return ISI_CFG2_YCC_SWAP_MODE_3; + } } /* -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/5] media: atmel-isi: add code to setup correct resolution for preview path
Not like codec path, preview path can do downsampling, so we should setup a extra preview width, height for it. This patch add preview resolution setup without down sampling. So currently preview path will output same size as sensor output size. Signed-off-by: Josh Wu <josh...@atmel.com> --- Changes in v2: None drivers/media/platform/soc_camera/atmel-isi.c | 12 +++- drivers/media/platform/soc_camera/atmel-isi.h | 10 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 24501a4..ae82068 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -131,7 +131,7 @@ static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, const struct soc_camera_format_xlate *xlate) { - u32 cfg2; + u32 cfg2, psize; /* According to sensor's output format to set cfg2 */ switch (xlate->code) { @@ -159,6 +159,16 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) & ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); + + /* No down sampling, preview size equal to sensor output size */ + psize = ((width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) & + ISI_PSIZE_PREV_HSIZE_MASK; + psize |= ((height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) & + ISI_PSIZE_PREV_VSIZE_MASK; + isi_writel(isi, ISI_PSIZE, psize); + isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING); + + return; } static bool is_supported(struct soc_camera_device *icd, diff --git a/drivers/media/platform/soc_camera/atmel-isi.h b/drivers/media/platform/soc_camera/atmel-isi.h index 5acc771..0acb32a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.h +++ b/drivers/media/platform/soc_camera/atmel-isi.h @@ -79,6 +79,16 @@ #define ISI_CFG2_IM_VSIZE_MASK (0x7FF << ISI_CFG2_IM_VSIZE_OFFSET) #define ISI_CFG2_IM_HSIZE_MASK (0x7FF << ISI_CFG2_IM_HSIZE_OFFSET) +/* Bitfields in PSIZE */ +#define ISI_PSIZE_PREV_VSIZE_OFFSET0 +#define ISI_PSIZE_PREV_HSIZE_OFFSET16 +#define ISI_PSIZE_PREV_VSIZE_MASK (0x3FF << ISI_PSIZE_PREV_VSIZE_OFFSET) +#define ISI_PSIZE_PREV_HSIZE_MASK (0x3FF << ISI_PSIZE_PREV_HSIZE_OFFSET) + +/* Bitfields in PDECF */ +#define ISI_PDECF_DEC_FACTOR_MASK (0xFF << 0) +#defineISI_PDECF_NO_SAMPLING (16) + /* Bitfields in CTRL */ /* Also using in SR(ISI_V2) */ #define ISI_CTRL_EN(1 << 0) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 5/5] media: atmel-isi: support RGB565 output when sensor output YUV formats
This patch enable Atmel ISI preview path to convert the YUV to RGB format. Signed-off-by: Josh Wu <josh...@atmel.com> --- Changes in v2: - According to Guennadi's suggestion, remove the is_output_rgb() function which only used once. Also move the code into the for loop. drivers/media/platform/soc_camera/atmel-isi.c | 25 +++-- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 826d04e..8abeeeb 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -146,6 +146,10 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2, psize; + u32 fourcc = xlate->host_fmt->fourcc; + + isi->enable_preview_path = (fourcc == V4L2_PIX_FMT_RGB565 || + fourcc == V4L2_PIX_FMT_RGB32); /* According to sensor's output format to set cfg2 */ switch (xlate->code) { @@ -195,8 +199,9 @@ static bool is_supported(struct soc_camera_device *icd, case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_VYUY: + /* RGB */ + case V4L2_PIX_FMT_RGB565: return true; - /* RGB, TODO */ default: return false; } @@ -682,6 +687,14 @@ static const struct soc_mbus_pixelfmt isi_camera_formats[] = { .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample= 8, + .packing= SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, }; /* This will be corrected as we get more formats */ @@ -738,7 +751,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - int formats = 0, ret; + int formats = 0, ret, i, n; /* sensor format */ struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -772,11 +785,11 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YVYU8_2X8: - formats++; - if (xlate) { - xlate->host_fmt = _camera_formats[0]; + n = ARRAY_SIZE(isi_camera_formats); + formats += n; + for (i = 0; xlate && i < n; i++, xlate++) { + xlate->host_fmt = _camera_formats[i]; xlate->code = code.code; - xlate++; dev_dbg(icd->parent, "Providing format %s using code %d\n", isi_camera_formats[0].name, code.code); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 0/5] media: atmel-isi: enable preview path to output RGB565 format
This series will enable preview path support in atmel-isi. Which can make atmel-isi convert the YUV format (from sensor) to RGB565 format. Changes in v2: - remove the duplicated variable: cfg2_yuv_swap. - correct the comment style - According to Guennadi's suggestion, remove the is_output_rgb() function which only used once. Also move the code into the for loop. Josh Wu (5): media: atmel-isi: correct yuv swap according to different sensor outputs media: atmel-isi: prepare for the support of preview path media: atmel-isi: add code to setup correct resolution for preview path media: atmel-isi: setup YCC_SWAP correctly when using preview path media: atmel-isi: support RGB565 output when sensor output YUV formats drivers/media/platform/soc_camera/atmel-isi.c | 162 +++--- drivers/media/platform/soc_camera/atmel-isi.h | 10 ++ 2 files changed, 132 insertions(+), 40 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] v4l2-clk: add new definition: V4L2_CLK_NAME_SIZE
Make all v4l2-clk's clock name use V4L2_CLK_NAME_SIZE definition. In future, if the string increased we just need to change the V4L2_CLK_NAME_SIZE once. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/soc_camera.c | 6 +++--- drivers/media/usb/em28xx/em28xx-camera.c | 2 +- include/media/v4l2-clk.h | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 673f1d4..506a569 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1362,7 +1362,7 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd, struct soc_camera_host_desc *shd = >host_desc; struct i2c_adapter *adap; struct v4l2_subdev *subdev; - char clk_name[V4L2_SUBDEV_NAME_SIZE]; + char clk_name[V4L2_CLK_NAME_SIZE]; int ret; /* First find out how we link the main client */ @@ -1528,7 +1528,7 @@ static int scan_async_group(struct soc_camera_host *ici, struct soc_camera_async_client *sasc; struct soc_camera_device *icd; struct soc_camera_desc sdesc = {.host_desc.bus_id = ici->nr,}; - char clk_name[V4L2_SUBDEV_NAME_SIZE]; + char clk_name[V4L2_CLK_NAME_SIZE]; unsigned int i; int ret; @@ -1634,7 +1634,7 @@ static int soc_of_bind(struct soc_camera_host *ici, struct soc_camera_async_client *sasc; struct soc_of_info *info; struct i2c_client *client; - char clk_name[V4L2_SUBDEV_NAME_SIZE + 32]; + char clk_name[V4L2_CLK_NAME_SIZE]; int ret; /* allocate a new subdev and add match info to it */ diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index ed0b3a8..121cdfc 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -322,7 +322,7 @@ int em28xx_detect_sensor(struct em28xx *dev) int em28xx_init_camera(struct em28xx *dev) { - char clk_name[V4L2_SUBDEV_NAME_SIZE]; + char clk_name[V4L2_CLK_NAME_SIZE]; struct i2c_client *client = >i2c_client[dev->def_i2c_bus]; struct i2c_adapter *adap = >i2c_adap[dev->def_i2c_bus]; struct em28xx_v4l2 *v4l2 = dev->v4l2; diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 34891ea..2b94662 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -65,6 +65,8 @@ static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id, return __v4l2_clk_register_fixed(dev_id, rate, THIS_MODULE); } +#define V4L2_CLK_NAME_SIZE 64 + #define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \ "%d-%04x", adap, client) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] v4l2-clk: v4l2_clk_get() also need to find the of_fullname clock
The soc-camera host will be probed and register a v4l2_clk, but if on that moment, the i2c device is not available, then the registered v4l2_clk name is a OF string not a I2C string. So when i2c sensor probed and call v4l2_clk_get(), it only search the clock with I2C string, like "1-0030". This patch will search the clock with OF string name if fail to find the clock with I2C string name. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/v4l2-core/v4l2-clk.c | 9 + 1 file changed, 9 insertions(+) diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index 34e416a..297e10e 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) { struct v4l2_clk *clk; struct clk *ccf_clk = clk_get(dev, id); + char clk_name[V4L2_CLK_NAME_SIZE]; if (PTR_ERR(ccf_clk) == -EPROBE_DEFER) return ERR_PTR(-EPROBE_DEFER); @@ -57,6 +59,13 @@ struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) mutex_lock(_lock); clk = v4l2_clk_find(dev_name(dev)); + /* if dev_name is not found, try use the OF name to find again */ + if (PTR_ERR(clk) == -ENODEV && dev->of_node) { + v4l2_clk_name_of(clk_name, sizeof(clk_name), +of_node_full_name(dev->of_node)); + clk = v4l2_clk_find(clk_name); + } + if (!IS_ERR(clk)) atomic_inc(>use_count); mutex_unlock(_lock); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] v4l2-clk: add new macro for v4l2_clk_name_of()
This macro is used to generate a OF string for a v4l2 clock. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/soc_camera.c | 4 ++-- include/media/v4l2-clk.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index d165bff..673f1d4 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1680,8 +1680,8 @@ static int soc_of_bind(struct soc_camera_host *ici, v4l2_clk_name_i2c(clk_name, sizeof(clk_name), client->adapter->nr, client->addr); else - snprintf(clk_name, sizeof(clk_name), "of-%s", -of_node_full_name(remote)); + v4l2_clk_name_of(clk_name, sizeof(clk_name), +of_node_full_name(remote)); icd->clk = v4l2_clk_register(_camera_clk_ops, clk_name, icd); if (IS_ERR(icd->clk)) { diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 3ef6e3d..34891ea 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -68,4 +68,7 @@ static inline struct v4l2_clk *v4l2_clk_register_fixed(const char *dev_id, #define v4l2_clk_name_i2c(name, size, adap, client) snprintf(name, size, \ "%d-%04x", adap, client) +#define v4l2_clk_name_of(name, size, of_full_name) snprintf(name, size, \ + "of-%s", of_full_name) + #endif -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] soc_camera: get the clock name by using macro: v4l2_clk_name_i2c()
Since v4l2_clk_name_i2c() is defined, so just reuse it. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/soc_camera.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 9d24d44..d165bff 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1393,8 +1393,8 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd, ssdd->sd_pdata.regulators = NULL; shd->board_info->platform_data = ssdd; - snprintf(clk_name, sizeof(clk_name), "%d-%04x", -shd->i2c_adapter_id, shd->board_info->addr); + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + shd->i2c_adapter_id, shd->board_info->addr); icd->clk = v4l2_clk_register(_camera_clk_ops, clk_name, icd); if (IS_ERR(icd->clk)) { @@ -1574,8 +1574,9 @@ static int scan_async_group(struct soc_camera_host *ici, icd->sasc = sasc; icd->parent = ici->v4l2_dev.dev; - snprintf(clk_name, sizeof(clk_name), "%d-%04x", -sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address); + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + sasd->asd.match.i2c.adapter_id, + sasd->asd.match.i2c.address); icd->clk = v4l2_clk_register(_camera_clk_ops, clk_name, icd); if (IS_ERR(icd->clk)) { @@ -1676,8 +1677,8 @@ static int soc_of_bind(struct soc_camera_host *ici, client = of_find_i2c_device_by_node(remote); if (client) - snprintf(clk_name, sizeof(clk_name), "%d-%04x", -client->adapter->nr, client->addr); + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + client->adapter->nr, client->addr); else snprintf(clk_name, sizeof(clk_name), "of-%s", of_node_full_name(remote)); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/4] soc-camera: fix the bug which will fail to search the registered v4l2-clk
This patch set will fix a bug in soc-camera, which will fail to search the v4l2-clk if the i2c sensor is probed later than soc-camera host. It also add some clean up for v4l2-clk code and usage. Josh Wu (4): soc_camera: get the clock name by using macro: v4l2_clk_name_i2c() v4l2-clk: add new macro for v4l2_clk_name_of() v4l2-clk: add new definition: V4L2_CLK_NAME_SIZE v4l2-clk: v4l2_clk_get() also need to find the of_fullname clock drivers/media/platform/soc_camera/soc_camera.c | 23 --- drivers/media/usb/em28xx/em28xx-camera.c | 2 +- drivers/media/v4l2-core/v4l2-clk.c | 9 + include/media/v4l2-clk.h | 5 + 4 files changed, 27 insertions(+), 12 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] media: atmel-isi: support RGB565 output when sensor output YUV formats
Dear Guennadi, On 10/19/2015 10:03 AM, Guennadi Liakhovetski wrote: Hi Josh, On Wed, 14 Oct 2015, Josh Wu wrote: Dear Guennadi, Thanks for the review. On 10/5/2015 1:02 AM, Guennadi Liakhovetski wrote: On Tue, 22 Sep 2015, Josh Wu wrote: This patch enable Atmel ISI preview path to convert the YUV to RGB format. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 38 --- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index e87d354..e33a16a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -201,13 +201,20 @@ static bool is_supported(struct soc_camera_device *icd, case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_VYUY: + /* RGB */ + case V4L2_PIX_FMT_RGB565: return true; - /* RGB, TODO */ default: return false; } } +static bool is_output_rgb(const struct soc_mbus_pixelfmt *host_fmt) +{ + return host_fmt->fourcc == V4L2_PIX_FMT_RGB565 || + host_fmt->fourcc == V4L2_PIX_FMT_RGB32; +} + Why not just pass fourcc to this function? Or maybe just embed it in start_streaming - it won't clutter it a lot. I think pass fourcc to the function is good. Since configure_geometry() is hardware related, and the enable_preview_path is also hardware related, so I prefer initialize enable_preview_path in configure_geometry(). But you don't, you do it in start_streaming() below. Right, then I'll move it to configure_geometry() in v2.. But actually my comment was not about _where_ to do it, but whether this calculation is worth a separate function. I would just perform this calculation directly where you're calling it: static ... start_streaming(...) { ... u32 fourcc = icd->current_fmt->host_fmt->fourcc; isi->enable_preview_path = fourcc == V4L2_PIX_FMT_RGB565 || fourcc == V4L2_PIX_FMT_RGB32; I thought this "function" might be called in other place, but actually no one call it. So yes, I think there is no need to have such separated function. I'll fix it in v2. Thanks. Best Regards, Josh Wu Thanks Guennadi static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) { if (isi->active) { @@ -467,6 +474,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici->priv; int ret; +isi->enable_preview_path = is_output_rgb(icd->current_fmt->host_fmt); + pm_runtime_get_sync(ici->v4l2_dev.dev); /* Reset ISI */ @@ -688,6 +697,14 @@ static const struct soc_mbus_pixelfmt isi_camera_formats[] = { .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample= 8, + .packing= SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, }; /* This will be corrected as we get more formats */ @@ -744,7 +761,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - int formats = 0, ret; + int formats = 0, ret, i, n; /* sensor format */ struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -778,13 +795,16 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YVYU8_2X8: - formats++; - if (xlate) { - xlate->host_fmt = _camera_formats[0]; - xlate->code = code.code; - xlate++; - dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code.code); + n = ARRAY_SIZE(isi_camera_formats); + formats += n; + for (i = 0; i < n; i++) { + if (xlate) { I'd put if outside of the loop, or just do + for (i = 0; xlate && i < n; i++) { yes, that simpler one. I'll take it. Thanks. Best Regards, Josh Wu + xlate->host_fmt = _camera_formats[i]; + xlate->code =
Re: [PATCH 1/5] media: atmel-isi: correct yuv swap according to different sensor outputs
Dear Guennadi, On 10/19/2015 9:48 AM, Guennadi Liakhovetski wrote: Hi Josh, On Wed, 14 Oct 2015, Josh Wu wrote: Hi, Dear Guennadi Thanks for the review. On 10/5/2015 12:43 AM, Guennadi Liakhovetski wrote: Hi Josh, On Tue, 22 Sep 2015, Josh Wu wrote: we need to configure the YCC_SWAP bits in ISI_CFG2 according to current sensor output and Atmel ISI output format. Current there are two cases Atmel ISI supported: 1. Atmel ISI outputs YUYV format. This case we need to setup YCC_SWAP according to sensor output format. 2. Atmel ISI output a pass-through formats, which means no swap. Just setup YCC_SWAP as default with no swap. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 43 --- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 45e304a..df64294 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,13 +103,41 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } +static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, + const struct soc_camera_format_xlate *xlate) +{ This function will be called only for the four media codes from the switch-case statement below, namely for MEDIA_BUS_FMT_VYUY8_2X8 MEDIA_BUS_FMT_UYVY8_2X8 MEDIA_BUS_FMT_YVYU8_2X8 MEDIA_BUS_FMT_YUYV8_2X8 + /* By default, no swap for the codec path of Atmel ISI. So codec + * output is same as sensor's output. + * For instance, if sensor's output is YUYV, then codec outputs YUYV. + * And if sensor's output is UYVY, then codec outputs UYVY. + */ + u32 cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_DEFAULT; Then this ISI_CFG2_YCC_SWAP_DEFAULT will only hold for MEDIA_BUS_FMT_YUYV8_2X8? Why don't you just add one more case below? Don't think this initialisation is really justified. This default initial value is for all host_fmt_fourcc case. Not just for V4L2_PIX_FMT_YUYV this case. Right, yes, missed this. How about this then: if (xlate->host_fmt->fourcc != V4L2_PIX_FMT_YUYV) return ISI_CFG2_YCC_SWAP_DEFAULT; switch (xlate->code) { case MEDIA_BUS_FMT_VYUY8_2X8: return ISI_CFG2_YCC_SWAP_MODE_3; case MEDIA_BUS_FMT_UYVY8_2X8: return ISI_CFG2_YCC_SWAP_MODE_2; case MEDIA_BUS_FMT_YVYU8_2X8: return ISI_CFG2_YCC_SWAP_MODE_1; } return ISI_CFG2_YCC_SWAP_DEFAULT; Or even exactly as you have it in your patch only remove the cfg2_yuv_swap variable and do "return" directly after each "case MEDIA_..." and one more with SWAP_DEFAULT in the end. Right, that's exactly what I want to do. That looks very neat. Thanks for your advice. I'll fix it in v2. + + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { + /* all convert to YUYV */ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + } + } + + return cfg2_yuv_swap; +} + static void configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, u32 code) + u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2; /* According to sensor's output format to set cfg2 */ - switch (code) { + switch (xlate->code) { default: /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: @@ -117,16 +145,11 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, break; /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_UYVY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YVYU8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YUYV8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; + cfg2 = ISI_CFG2_COL_SPACE_YCbCr | + setup_cfg2_yuv_swap(isi, xlate); break; /* RGB, TODO */ } I would move this switch-case completely inside setup_cfg2_yuv_swap(). Just do cfg2 = setup_cfg2_yuv_swap(isi, xlate);
Re: [PATCH 1/5] media: atmel-isi: correct yuv swap according to different sensor outputs
Hi, Dear Guennadi Thanks for the review. On 10/5/2015 12:43 AM, Guennadi Liakhovetski wrote: Hi Josh, On Tue, 22 Sep 2015, Josh Wu wrote: we need to configure the YCC_SWAP bits in ISI_CFG2 according to current sensor output and Atmel ISI output format. Current there are two cases Atmel ISI supported: 1. Atmel ISI outputs YUYV format. This case we need to setup YCC_SWAP according to sensor output format. 2. Atmel ISI output a pass-through formats, which means no swap. Just setup YCC_SWAP as default with no swap. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 43 --- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 45e304a..df64294 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,13 +103,41 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } +static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, + const struct soc_camera_format_xlate *xlate) +{ This function will be called only for the four media codes from the switch-case statement below, namely for MEDIA_BUS_FMT_VYUY8_2X8 MEDIA_BUS_FMT_UYVY8_2X8 MEDIA_BUS_FMT_YVYU8_2X8 MEDIA_BUS_FMT_YUYV8_2X8 + /* By default, no swap for the codec path of Atmel ISI. So codec + * output is same as sensor's output. + * For instance, if sensor's output is YUYV, then codec outputs YUYV. + * And if sensor's output is UYVY, then codec outputs UYVY. + */ + u32 cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_DEFAULT; Then this ISI_CFG2_YCC_SWAP_DEFAULT will only hold for MEDIA_BUS_FMT_YUYV8_2X8? Why don't you just add one more case below? Don't think this initialisation is really justified. This default initial value is for all host_fmt_fourcc case. Not just for V4L2_PIX_FMT_YUYV this case. + + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { + /* all convert to YUYV */ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + } + } + + return cfg2_yuv_swap; +} + static void configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, u32 code) + u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2; /* According to sensor's output format to set cfg2 */ - switch (code) { + switch (xlate->code) { default: /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: @@ -117,16 +145,11 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, break; /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_UYVY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YVYU8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YUYV8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; + cfg2 = ISI_CFG2_COL_SPACE_YCbCr | + setup_cfg2_yuv_swap(isi, xlate); break; /* RGB, TODO */ } I would move this switch-case completely inside setup_cfg2_yuv_swap(). Just do cfg2 = setup_cfg2_yuv_swap(isi, xlate); and handle the case MEDIA_BUS_FMT_Y8_1X8: in the function too. These two switch-case statements really look redundant. Technically, you can do that. But for my point of view, the setup_cfg2_yuv_swap() only need to setup the yuv swap register field. And other cfg2 field need to be configured as well, especially in the case sensor output a RGB data. That should be implement soon. @@ -407,7 +430,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) isi_writel(isi, ISI_INTDIS, (u32)~0UL); configure_geometry(isi, icd->user_width, icd->user_height, - icd->current_fmt->code); + icd->current_fmt); spin_lock_irq(>lock); /* Clear any pending interrupt */ -- 1.9.1 Thanks Guennadi Best Regards, Josh Wu -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the bo
Re: [PATCH 4/5] media: atmel-isi: setup YCC_SWAP correctly when using preview path
Hi, Dear Guennadi On 10/5/2015 12:50 AM, Guennadi Liakhovetski wrote: On Tue, 22 Sep 2015, Josh Wu wrote: The preview path only can convert UYVY format to RGB data. To make preview path work correctly, we need to set up YCC_SWAP according to sensor output and convert them to UYVY. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index bbf6449..e87d354 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -127,6 +127,22 @@ static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; break; } + } else if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_RGB565) { + /* Preview path is enabled, it will convert UYVY to RGB format. +* But if sensor output format is not UYVY, we need to set +* YCC_SWAP_MODE to convert it as UYVY. +*/ Please, fix multiline comment style: /* * ... * ... */ oh, yes, Sure. I'll fix this. Thanks. Best Regards, Josh Wu + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + case MEDIA_BUS_FMT_YUYV8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; + } } return cfg2_yuv_swap; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 5/5] media: atmel-isi: support RGB565 output when sensor output YUV formats
Dear Guennadi, Thanks for the review. On 10/5/2015 1:02 AM, Guennadi Liakhovetski wrote: On Tue, 22 Sep 2015, Josh Wu wrote: This patch enable Atmel ISI preview path to convert the YUV to RGB format. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 38 --- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index e87d354..e33a16a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -201,13 +201,20 @@ static bool is_supported(struct soc_camera_device *icd, case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_VYUY: + /* RGB */ + case V4L2_PIX_FMT_RGB565: return true; - /* RGB, TODO */ default: return false; } } +static bool is_output_rgb(const struct soc_mbus_pixelfmt *host_fmt) +{ + return host_fmt->fourcc == V4L2_PIX_FMT_RGB565 || + host_fmt->fourcc == V4L2_PIX_FMT_RGB32; +} + Why not just pass fourcc to this function? Or maybe just embed it in start_streaming - it won't clutter it a lot. I think pass fourcc to the function is good. Since configure_geometry() is hardware related, and the enable_preview_path is also hardware related, so I prefer initialize enable_preview_path in configure_geometry(). static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) { if (isi->active) { @@ -467,6 +474,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici->priv; int ret; + isi->enable_preview_path = is_output_rgb(icd->current_fmt->host_fmt); + pm_runtime_get_sync(ici->v4l2_dev.dev); /* Reset ISI */ @@ -688,6 +697,14 @@ static const struct soc_mbus_pixelfmt isi_camera_formats[] = { .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample= 8, + .packing= SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, }; /* This will be corrected as we get more formats */ @@ -744,7 +761,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - int formats = 0, ret; + int formats = 0, ret, i, n; /* sensor format */ struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -778,13 +795,16 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YVYU8_2X8: - formats++; - if (xlate) { - xlate->host_fmt = _camera_formats[0]; - xlate->code = code.code; - xlate++; - dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code.code); + n = ARRAY_SIZE(isi_camera_formats); + formats += n; + for (i = 0; i < n; i++) { + if (xlate) { I'd put if outside of the loop, or just do + for (i = 0; xlate && i < n; i++) { yes, that simpler one. I'll take it. Thanks. Best Regards, Josh Wu + xlate->host_fmt = _camera_formats[i]; + xlate->code = code.code; + dev_dbg(icd->parent, "Providing format %s using code %d\n", + isi_camera_formats[0].name, code.code); + xlate++; + } } break; default: -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/5] media: atmel-isi: correct yuv swap according to different sensor outputs
Dear Gueannadi, On 10/5/2015 1:04 AM, Guennadi Liakhovetski wrote: Even simpler: On Sun, 4 Oct 2015, Guennadi Liakhovetski wrote: Hi Josh, On Tue, 22 Sep 2015, Josh Wu wrote: we need to configure the YCC_SWAP bits in ISI_CFG2 according to current sensor output and Atmel ISI output format. Current there are two cases Atmel ISI supported: 1. Atmel ISI outputs YUYV format. This case we need to setup YCC_SWAP according to sensor output format. 2. Atmel ISI output a pass-through formats, which means no swap. Just setup YCC_SWAP as default with no swap. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 43 --- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 45e304a..df64294 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,13 +103,41 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } +static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, + const struct soc_camera_format_xlate *xlate) +{ This function will be called only for the four media codes from the switch-case statement below, namely for MEDIA_BUS_FMT_VYUY8_2X8 MEDIA_BUS_FMT_UYVY8_2X8 MEDIA_BUS_FMT_YVYU8_2X8 MEDIA_BUS_FMT_YUYV8_2X8 + /* By default, no swap for the codec path of Atmel ISI. So codec + * output is same as sensor's output. + * For instance, if sensor's output is YUYV, then codec outputs YUYV. + * And if sensor's output is UYVY, then codec outputs UYVY. + */ + u32 cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_DEFAULT; Then this ISI_CFG2_YCC_SWAP_DEFAULT will only hold for MEDIA_BUS_FMT_YUYV8_2X8? Why don't you just add one more case below? Don't think this initialisation is really justified. + + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { + /* all convert to YUYV */ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; Why don't you just return the result value here directly? Then you don't need the variable at all yes, This sounds good. I'll take rid of the cfg2_yuv_swap variable. Thanks. Best Regards, Josh Wu + case MEDIA_BUS_FMT_UYVY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + } + } + + return cfg2_yuv_swap; +} + static void configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, u32 code) + u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2; /* According to sensor's output format to set cfg2 */ - switch (code) { + switch (xlate->code) { default: /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: @@ -117,16 +145,11 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, break; /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_UYVY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YVYU8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YUYV8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; + cfg2 = ISI_CFG2_COL_SPACE_YCbCr | + setup_cfg2_yuv_swap(isi, xlate); break; /* RGB, TODO */ } I would move this switch-case completely inside setup_cfg2_yuv_swap(). Just do cfg2 = setup_cfg2_yuv_swap(isi, xlate); and handle the case MEDIA_BUS_FMT_Y8_1X8: in the function too. These two switch-case statements really look redundant. @@ -407,7 +430,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) isi_writel(isi, ISI_INTDIS, (u32)~0UL); configure_geometry(isi, icd->user_width, icd->user_height, - icd->current_fmt->code); + icd->current_fmt); spin_lock_irq(>lock); /* Clear any pending interrupt */ -- 1.9.1 Thanks Guennadi -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/5] media: atmel-isi: support RGB565 output when sensor output YUV formats
This patch enable Atmel ISI preview path to convert the YUV to RGB format. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 38 --- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index e87d354..e33a16a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -201,13 +201,20 @@ static bool is_supported(struct soc_camera_device *icd, case V4L2_PIX_FMT_UYVY: case V4L2_PIX_FMT_YVYU: case V4L2_PIX_FMT_VYUY: + /* RGB */ + case V4L2_PIX_FMT_RGB565: return true; - /* RGB, TODO */ default: return false; } } +static bool is_output_rgb(const struct soc_mbus_pixelfmt *host_fmt) +{ + return host_fmt->fourcc == V4L2_PIX_FMT_RGB565 || + host_fmt->fourcc == V4L2_PIX_FMT_RGB32; +} + static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) { if (isi->active) { @@ -467,6 +474,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici->priv; int ret; + isi->enable_preview_path = is_output_rgb(icd->current_fmt->host_fmt); + pm_runtime_get_sync(ici->v4l2_dev.dev); /* Reset ISI */ @@ -688,6 +697,14 @@ static const struct soc_mbus_pixelfmt isi_camera_formats[] = { .order = SOC_MBUS_ORDER_LE, .layout = SOC_MBUS_LAYOUT_PACKED, }, + { + .fourcc = V4L2_PIX_FMT_RGB565, + .name = "RGB565", + .bits_per_sample= 8, + .packing= SOC_MBUS_PACKING_2X8_PADHI, + .order = SOC_MBUS_ORDER_LE, + .layout = SOC_MBUS_LAYOUT_PACKED, + }, }; /* This will be corrected as we get more formats */ @@ -744,7 +761,7 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, struct soc_camera_format_xlate *xlate) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - int formats = 0, ret; + int formats = 0, ret, i, n; /* sensor format */ struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -778,13 +795,16 @@ static int isi_camera_get_formats(struct soc_camera_device *icd, case MEDIA_BUS_FMT_VYUY8_2X8: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YVYU8_2X8: - formats++; - if (xlate) { - xlate->host_fmt = _camera_formats[0]; - xlate->code = code.code; - xlate++; - dev_dbg(icd->parent, "Providing format %s using code %d\n", - isi_camera_formats[0].name, code.code); + n = ARRAY_SIZE(isi_camera_formats); + formats += n; + for (i = 0; i < n; i++) { + if (xlate) { + xlate->host_fmt = _camera_formats[i]; + xlate->code = code.code; + dev_dbg(icd->parent, "Providing format %s using code %d\n", + isi_camera_formats[0].name, code.code); + xlate++; + } } break; default: -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/5] media: atmel-isi: correct yuv swap according to different sensor outputs
we need to configure the YCC_SWAP bits in ISI_CFG2 according to current sensor output and Atmel ISI output format. Current there are two cases Atmel ISI supported: 1. Atmel ISI outputs YUYV format. This case we need to setup YCC_SWAP according to sensor output format. 2. Atmel ISI output a pass-through formats, which means no swap. Just setup YCC_SWAP as default with no swap. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 43 --- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 45e304a..df64294 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,13 +103,41 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } +static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, + const struct soc_camera_format_xlate *xlate) +{ + /* By default, no swap for the codec path of Atmel ISI. So codec + * output is same as sensor's output. + * For instance, if sensor's output is YUYV, then codec outputs YUYV. + * And if sensor's output is UYVY, then codec outputs UYVY. + */ + u32 cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_DEFAULT; + + if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUYV) { + /* all convert to YUYV */ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; + case MEDIA_BUS_FMT_UYVY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + } + } + + return cfg2_yuv_swap; +} + static void configure_geometry(struct atmel_isi *isi, u32 width, - u32 height, u32 code) + u32 height, const struct soc_camera_format_xlate *xlate) { u32 cfg2; /* According to sensor's output format to set cfg2 */ - switch (code) { + switch (xlate->code) { default: /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: @@ -117,16 +145,11 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, break; /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_UYVY8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YVYU8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; - break; case MEDIA_BUS_FMT_YUYV8_2X8: - cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; + cfg2 = ISI_CFG2_COL_SPACE_YCbCr | + setup_cfg2_yuv_swap(isi, xlate); break; /* RGB, TODO */ } @@ -407,7 +430,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) isi_writel(isi, ISI_INTDIS, (u32)~0UL); configure_geometry(isi, icd->user_width, icd->user_height, - icd->current_fmt->code); + icd->current_fmt); spin_lock_irq(>lock); /* Clear any pending interrupt */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/5] media: atmel-isi: enable preview path to output RGB565 format
This series will enable preview path support in atmel-isi. Which can make atmel-isi convert the YUV format (from sensor) to RGB565 format. Josh Wu (5): media: atmel-isi: correct yuv swap according to different sensor outputs media: atmel-isi: prepare for the support of preview path media: atmel-isi: add code to setup correct resolution for preview path media: atmel-isi: setup YCC_SWAP correctly when using preview path media: atmel-isi: support RGB565 output when sensor output YUV formats drivers/media/platform/soc_camera/atmel-isi.c | 181 -- drivers/media/platform/soc_camera/atmel-isi.h | 10 ++ 2 files changed, 148 insertions(+), 43 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/5] media: atmel-isi: setup YCC_SWAP correctly when using preview path
The preview path only can convert UYVY format to RGB data. To make preview path work correctly, we need to set up YCC_SWAP according to sensor output and convert them to UYVY. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index bbf6449..e87d354 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -127,6 +127,22 @@ static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; break; } + } else if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_RGB565) { + /* Preview path is enabled, it will convert UYVY to RGB format. +* But if sensor output format is not UYVY, we need to set +* YCC_SWAP_MODE to convert it as UYVY. +*/ + switch (xlate->code) { + case MEDIA_BUS_FMT_VYUY8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_1; + break; + case MEDIA_BUS_FMT_YUYV8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_2; + break; + case MEDIA_BUS_FMT_YVYU8_2X8: + cfg2_yuv_swap = ISI_CFG2_YCC_SWAP_MODE_3; + break; + } } return cfg2_yuv_swap; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/5] media: atmel-isi: add code to setup correct resolution for preview path
Not like codec path, preview path can do downsampling, so we should setup a extra preview width, height for it. This patch add preview resolution setup without down sampling. So currently preview path will output same size as sensor output size. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 12 +++- drivers/media/platform/soc_camera/atmel-isi.h | 10 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index e6f4ade..bbf6449 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -135,7 +135,7 @@ static u32 setup_cfg2_yuv_swap(struct atmel_isi *isi, static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, const struct soc_camera_format_xlate *xlate) { - u32 cfg2; + u32 cfg2, psize; /* According to sensor's output format to set cfg2 */ switch (xlate->code) { @@ -163,6 +163,16 @@ static void configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) & ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); + + /* No down sampling, preview size equal to sensor output size */ + psize = ((width - 1) << ISI_PSIZE_PREV_HSIZE_OFFSET) & + ISI_PSIZE_PREV_HSIZE_MASK; + psize |= ((height - 1) << ISI_PSIZE_PREV_VSIZE_OFFSET) & + ISI_PSIZE_PREV_VSIZE_MASK; + isi_writel(isi, ISI_PSIZE, psize); + isi_writel(isi, ISI_PDECF, ISI_PDECF_NO_SAMPLING); + + return; } static bool is_supported(struct soc_camera_device *icd, diff --git a/drivers/media/platform/soc_camera/atmel-isi.h b/drivers/media/platform/soc_camera/atmel-isi.h index 5acc771..0acb32a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.h +++ b/drivers/media/platform/soc_camera/atmel-isi.h @@ -79,6 +79,16 @@ #define ISI_CFG2_IM_VSIZE_MASK (0x7FF << ISI_CFG2_IM_VSIZE_OFFSET) #define ISI_CFG2_IM_HSIZE_MASK (0x7FF << ISI_CFG2_IM_HSIZE_OFFSET) +/* Bitfields in PSIZE */ +#define ISI_PSIZE_PREV_VSIZE_OFFSET0 +#define ISI_PSIZE_PREV_HSIZE_OFFSET16 +#define ISI_PSIZE_PREV_VSIZE_MASK (0x3FF << ISI_PSIZE_PREV_VSIZE_OFFSET) +#define ISI_PSIZE_PREV_HSIZE_MASK (0x3FF << ISI_PSIZE_PREV_HSIZE_OFFSET) + +/* Bitfields in PDECF */ +#define ISI_PDECF_DEC_FACTOR_MASK (0xFF << 0) +#defineISI_PDECF_NO_SAMPLING (16) + /* Bitfields in CTRL */ /* Also using in SR(ISI_V2) */ #define ISI_CTRL_EN(1 << 0) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/5] media: atmel-isi: prepare for the support of preview path
Atmel ISI support a preview path which can output RGB data. So this patch introduces a bool variable to choose which path is enabled currently. And also we need setup corresponding path registers. By default the preview path is disabled. We only use Codec path. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 72 ++- 1 file changed, 49 insertions(+), 23 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index df64294..e6f4ade 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -79,6 +79,7 @@ struct atmel_isi { dma_addr_t fb_descriptors_phys; struct list_head dma_desc_head; struct isi_dma_desc dma_desc[MAX_BUFFER_NUM]; + boolenable_preview_path; struct completion complete; /* ISI peripherial clock */ @@ -199,11 +200,19 @@ static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) /* start next dma frame. */ isi->active = list_entry(isi->video_buffer_list.next, struct frame_buffer, list); - isi_writel(isi, ISI_DMA_C_DSCR, - (u32)isi->active->p_dma_desc->fbd_phys); - isi_writel(isi, ISI_DMA_C_CTRL, - ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); - isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + if (!isi->enable_preview_path) { + isi_writel(isi, ISI_DMA_C_DSCR, + (u32)isi->active->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_C_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + } else { + isi_writel(isi, ISI_DMA_P_DSCR, + (u32)isi->active->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_P_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); + } } return IRQ_HANDLED; } @@ -230,7 +239,8 @@ static irqreturn_t isi_interrupt(int irq, void *dev_id) isi_writel(isi, ISI_INTDIS, ISI_CTRL_DIS); ret = IRQ_HANDLED; } else { - if (likely(pending & ISI_SR_CXFR_DONE)) + if (likely(pending & ISI_SR_CXFR_DONE) || + likely(pending & ISI_SR_PXFR_DONE)) ret = atmel_isi_handle_streaming(isi); } @@ -372,21 +382,35 @@ static void start_dma(struct atmel_isi *isi, struct frame_buffer *buffer) ISI_SR_CXFR_DONE | ISI_SR_PXFR_DONE); /* Check if already in a frame */ - if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { - dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n"); - return; - } + if (!isi->enable_preview_path) { + if (isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) { + dev_err(isi->soc_host.icd->parent, "Already in frame handling.\n"); + return; + } - isi_writel(isi, ISI_DMA_C_DSCR, (u32)buffer->p_dma_desc->fbd_phys); - isi_writel(isi, ISI_DMA_C_CTRL, ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); - isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + isi_writel(isi, ISI_DMA_C_DSCR, + (u32)buffer->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_C_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_C_CH); + } else { + isi_writel(isi, ISI_DMA_P_DSCR, + (u32)buffer->p_dma_desc->fbd_phys); + isi_writel(isi, ISI_DMA_P_CTRL, + ISI_DMA_CTRL_FETCH | ISI_DMA_CTRL_DONE); + isi_writel(isi, ISI_DMA_CHER, ISI_DMA_CHSR_P_CH); + } cfg1 &= ~ISI_CFG1_FRATE_DIV_MASK; /* Enable linked list */ cfg1 |= isi->pdata.frate | ISI_CFG1_DISCR; - /* Enable codec path and ISI */ - ctrl = ISI_CTRL_CDC | ISI_CTRL_EN; + /* Enable ISI */ + ctrl = ISI_CTRL_EN; + + if (!isi->enable_preview_path) + ctrl |= ISI_CTRL_CDC; + isi_writel(isi, ISI_CTRL, ctrl); isi_writel(isi, ISI_CFG1, cfg1); } @@ -462,15 +486,17 @@ static void stop_streaming(struct vb2_queue *vq)
Re: [PATCH 0/4] atmel-isi: Remove platform data support
Hi, Guennadi On 9/20/2015 11:25 PM, Guennadi Liakhovetski wrote: Hi Laurent, Josh, It's ok not to CC me immediately if it's expected, that patches will be further forwarded (by Josh in this case) to me. And it helps, that Josh has collected all Atmel ISI patches in a git tree branch - thanks! But, please make sure, that all patches also appear in my mailbox at least once, especially if they are (even trivially) modified - like in this case, where patches 2 and 3 have been merged into 1. yes, got it. I will make sure of that in future. Thanks for the remind. Best Regards, Josh Wu Thanks Guennadi On Sat, 1 Aug 2015, Laurent Pinchart wrote: Hello, While reviewing patches for the atmel-isi I noticed a couple of small issues with the driver. Here's a patch series to fix them, the main change being the removal of platform data support now that all users have migrated to DT. The patches have been compile-tested only. Josh, would you be able to test them on hardware ? Laurent Pinchart (4): v4l: atmel-isi: Simplify error handling during DT parsing v4l: atmel-isi: Remove unused variable v4l: atmel-isi: Remove support for platform data v4l: atmel-isi: Remove unused platform data fields drivers/media/platform/soc_camera/atmel-isi.c | 40 ++-- drivers/media/platform/soc_camera/atmel-isi.h | 126 + include/media/atmel-isi.h | 131 -- 3 files changed, 136 insertions(+), 161 deletions(-) create mode 100644 drivers/media/platform/soc_camera/atmel-isi.h delete mode 100644 include/media/atmel-isi.h -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] media: soc-camera: increase the length of clk_name on soc_of_bind()
Hi, Guennadi On 8/30/2015 10:06 PM, Guennadi Liakhovetski wrote: Hi Josh, Sorry, I missed the 4.3 merge cycle, but isn't this patch a fix? Isn't it fixing soc-camera / atmel-isi on a specific platform, where the clock name is longer, than currently supported? Is this platform in the mainline and its current camera support is broken because of this? I missed your email, so sorry for the late reply. yes, it will break the detect flow if the i2c camera is loaded as module. In such a case we could still push it in for 4.3 So it is a fix, it is great if this one can still go into 4.3. Best Regards, Josh Wu Thanks Guennadi On Tue, 4 Aug 2015, Josh Wu wrote: Since in soc_of_bind() it may use the of node's full name as the clk_name, and this full name may be longer than 32 characters, take at91 i2c sensor as an example, length is 34 bytes: /ahb/apb/i2c@f8028000/camera@0x30 So this patch increase the clk_name[] array size to 64. It seems big enough so far. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/soc_camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index d708df4..fcf3e97 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1621,7 +1621,7 @@ static int soc_of_bind(struct soc_camera_host *ici, struct soc_camera_async_client *sasc; struct soc_of_info *info; struct i2c_client *client; - char clk_name[V4L2_SUBDEV_NAME_SIZE]; + char clk_name[V4L2_SUBDEV_NAME_SIZE + 32]; int ret; /* allocate a new subdev and add match info to it */ -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] media: atmel-isi: parse the DT parameters for vsync/hsync/pixclock polarity
Hi, Guennadi On 9/18/2015 5:44 PM, Guennadi Liakhovetski wrote: Hi Nicolas, Patch handling is on my todo for the coming weekend... Beside this patch, Atmel-isi still have server other patches in the patchwork for a long time. So some patch may need to rebase. Just for your convenience I create a branch here: https://github.com/JoshWu/linux-at91/commits/atmel-isi-v4.3, which collected all the Atmel-isi patches that still not merged. You can take it as a reference. Of cause, if you want I can sent out a pull request for it. thanks. Best Regards, Josh Wu Thanks Guennadi On Fri, 18 Sep 2015, Nicolas Ferre wrote: Le 04/08/2015 13:22, Laurent Pinchart a écrit : Hi Josh, Thank you for the patch. On Tuesday 04 August 2015 17:37:49 Josh Wu wrote: This patch will get the DT parameters of vsync/hsync/pixclock polarity, and pass to driver. Also add a debug information for test purpose. Signed-off-by: Josh Wu <josh...@atmel.com> Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com> Guennadi, Mauro, I don't see this patch in Linux-next and I'm not so used to http://git.linuxtv.org but didn't find it either. Well in fact it's just a lengthy version of "ping" ;-) Bye, --- Changes in v3: - add embedded sync dt property support. Changes in v2: - rewrite the debug message and add pix clock polarity setup thanks to Laurent. - update the commit log. drivers/media/platform/soc_camera/atmel-isi.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..4efc939 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd->parent, "vsync active %s, hsync active %s, sampling on pix clock %s edge\n", +common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? "low" : "high", + common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? "low" : "high", + common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING ? "falling" : "rising"); + if (isi->pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi->pdata.full_mode) @@ -1148,6 +1153,16 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, return -EINVAL; } + if (ep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi->pdata.hsync_act_low = true; + if (ep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi->pdata.vsync_act_low = true; + if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) + isi->pdata.pclk_act_falling = true; + + if (ep.bus_type == V4L2_MBUS_BT656) + isi->pdata.has_emb_sync = true; + return 0; } -- Nicolas Ferre -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/3] media: atmel-isi: move configure_geometry() to start_streaming()
As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu <josh...@atmel.com> Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com> --- Changes in v4: None Changes in v3: None Changes in v2: - Add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index a76c609..d727037 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd->user_width, icd->user_height, + icd->current_fmt->code); + if (ret < 0) + return ret; + spin_lock_irq(>lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct atmel_isi *isi = ici->priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = >fmt.pix; @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf->code != xlate->code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici->v4l2_dev.dev); - - ret = configure_geometry(isi, pix->width, pix->height, xlate->code); - - pm_runtime_put(ici->v4l2_dev.dev); - - if (ret < 0) - return ret; - pix->width = mf->width; pix->height = mf->height; pix->field = mf->field; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/3] media: atmel-isi: setup the ISI_CFG2 register directly
In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu <josh...@atmel.com> Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com> --- Changes in v4: - add a COL_SPACE_YCbCr for cfg2 Changes in v3: None Changes in v2: - add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- include/media/atmel-isi.h | 2 ++ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index f39132c..a76c609 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2 | ISI_CFG2_COL_SPACE_YCbCr; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1 | ISI_CFG2_COL_SPACE_YCbCr; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; break; /* RGB, TODO */ default: @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 &= ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) & ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) & ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); diff --git a/include/media/atmel-isi.h b/include/media/atmel-isi.h index 6008b09..e7a96b8 100644 --- a/include/media/atmel-isi.h +++ b/include/media/atmel-isi.h @@ -66,6 +66,8 @@ /* Bitfields in CFG2 */ #define ISI_CFG2_GRAYSCALE (1 << 13) +#define ISI_CFG2_COL_SPACE_YCbCr (0 << 15) +#define ISI_CFG2_COL_SPACE_RGB (1 << 15) /* Constants for YCC_SWAP(ISI_V2) */ #defineISI_CFG2_YCC_SWAP_DEFAULT (0 << 28) #defineISI_CFG2_YCC_SWAP_MODE_1(1 << 28) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/3] media: atmel-isi: add sanity check for supported formats in try/set_fmt()
After adding the format check in try_fmt()/set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu <josh...@atmel.com> --- Hi, Laurent For the similiarity between set_fmt() and try_frm() function, it need more work than I thought. So in this patch I didn't touch that part. I plan to try that later. Best Regards, Josh Wu Changes in v4: - correct the comment typo. Changes in v3: - check the whether format is supported, if no then return a default format. - misc changes according to Laurent's feedback. Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 37 +-- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index d727037..6e55d9f 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -102,17 +102,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi->regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE | ISI_CFG2_COL_SPACE_YCbCr; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3 | ISI_CFG2_COL_SPACE_YCbCr; break; @@ -126,8 +128,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT | ISI_CFG2_COL_SPACE_YCbCr; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -138,8 +138,23 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) & ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const u32 pixformat) +{ + switch (pixformat) { + /* YUV, including grey */ + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + return true; + /* RGB, TODO */ + default: + return false; + } } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -390,10 +405,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd->user_width, icd->user_height, + configure_geometry(isi, icd->user_width, icd->user_height, icd->current_fmt->code); - if (ret < 0) - return ret; spin_lock_irq(>lock); /* Clear any pending interrupt */ @@ -491,6 +504,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_mbus_framefmt *mf = int ret; + /* check with atmel-isi support format, if not support use YUYV */ + if (!is_supported(icd, pix->pixelformat)) + pix->pixelformat = V4L2_PIX_FMT_YUYV; + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); if (!xlate) { dev_warn(icd->parent, "Format %x not found\n", @@ -540,6 +557,10 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, u32 pixfmt = pix->pixelformat; int ret; + /* check with atmel-isi support format, if not support use YUYV */ + if (!is_supported(icd, pix->pixelformat)) + pix->pixelformat = V4L2_PIX_FMT_YUYV; + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (pixfmt && !xlate) { dev_warn(icd->parent, "Format %x not found\n", pixfmt); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] [media] atmel-isi: Protect PM-only functions to kill warning
Hi, Geert Uytterhoeven Thanks for the patch. On 9/6/2015 6:08 PM, Geert Uytterhoeven wrote: If CONFIG_PM=n: drivers/media/platform/soc_camera/atmel-isi.c:1044: warning: ‘atmel_isi_runtime_suspend’ defined but not used drivers/media/platform/soc_camera/atmel-isi.c:1054: warning: ‘atmel_isi_runtime_resume’ defined but not used Protect the unused functions by #ifdef CONFIG_PM to fix this. Signed-off-by: Geert Uytterhoeven <ge...@linux-m68k.org> Acked-by: Josh Wu <josh...@atmel.com> Best Regards, Josh Wu --- Resend with correct suject --- drivers/media/platform/soc_camera/atmel-isi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 90701726a06a2e5c..ccf30ccbe389233f 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1040,6 +1040,7 @@ err_alloc_ctx: return ret; } +#ifdef CONFIG_PM static int atmel_isi_runtime_suspend(struct device *dev) { struct soc_camera_host *soc_host = to_soc_camera_host(dev); @@ -1058,6 +1059,7 @@ static int atmel_isi_runtime_resume(struct device *dev) return clk_prepare_enable(isi->pclk); } +#endif /* CONFIG_PM */ static const struct dev_pm_ops atmel_isi_dev_pm_ops = { SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] media: atmel-isi: setup the ISI_CFG2 register directly
Hi, Guennadi Thanks for the review. On 8/30/2015 4:48 PM, Guennadi Liakhovetski wrote: Hi Josh, On Wed, 17 Jun 2015, Josh Wu wrote: In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Simpler doesn't necessarily mean better or more correct:) There are other fields in that register and currently the driver preserves them, with this patch you overwrite them with 0. 0 happens to be the reset value of that register. So, you should at least mention that in this patch description, just saying "simpler" doesn't convince me. Correct, I should mention that the reset value (0) of cfg2 means the YUV mode in the commit message. To use YUV mode we need to clear COL_SPACE (bit 15 of CFG2) and since the reset value is 0, so in the code, I didn't need do anything. So, at least I'd modify that, I can do that myself. But in general I'm not even sure why this patch is needed. Yes, currently those fields of that register are unused, so, we can assume they stay at their reset values. But firstly the hardware can change and at some point the reset value can change, or those other fields will get set indirectly by something. Or the driver will change at some point to support more fields of that register and then this code will have to be changed again. I understand your concern. maybe a better solution is explicitly set the COL_SPACE (bit 15) to 0 for the YUV formats. like: #define ISI_CFG2_COL_SPACE_YUV(0 << 15) case MEDIA_BUS_FMT_YVYU8_2X8: cfg2 = ISI_CFG2_COL_SPACE_YUV | ISI_CFG2_YCC_SWAP_MODE_1; break; And above modifications can be sent with RGB format support patch in future. So, I'd ask you again - do you really want this patch? yes, this patch is needed. And in future i will add the RGB format settings. If you insist - I'll take it, but I'd add the "reset value" reasoning. That would be great, thank you very much. Best Regards, Josh Wu Otherwise maybe just drop it? Thanks Guennadi Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu <josh...@atmel.com> --- drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 9070172..8bc40ca 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ default: @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 &= ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 &= ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) << ISI_CFG2_IM_HSIZE_OFFSET) & ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 &= ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) << ISI_CFG2_IM_VSIZE_OFFSET) & ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 3/3] media: atmel-isi: add sanity check for supported formats in try/set_fmt()
Hi, Laurent On 8/22/2015 2:22 AM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Friday 21 August 2015 16:08:14 Josh Wu wrote: After adding the format check in try_fmt()/set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: - check the whether format is supported, if no then return a default format. - misc changes according to Laurent's feedback. Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 37 ++-- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..84c91d3 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -102,17 +102,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi-regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; @@ -126,8 +128,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -138,8 +138,23 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const u32 pixformat) +{ + switch (pixformat) { + /* YUV, including grey */ + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + return true; + /* RGB, TODO */ + default: + return false; + } } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -390,10 +405,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd-user_width, icd-user_height, + configure_geometry(isi, icd-user_width, icd-user_height, icd-current_fmt-code); - if (ret 0) - return ret; spin_lock_irq(isi-lock); /* Clear any pending interrupt */ @@ -491,6 +504,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_mbus_framefmt *mf = format.format; int ret; + /* check with atmel-isi support format, if not support use UYVY */ + if (!is_supported(icd, pix-pixelformat)) + pix-pixelformat = V4L2_PIX_FMT_YUYV; The comment mentions UYVY and the code uses YUYV. Oops, forgotten to change the comments. I'll fix it. + xlate = soc_camera_xlate_by_fourcc(icd, pix-pixelformat); if (!xlate) { dev_warn(icd-parent, Format %x not found\n, Can this still happen ? I think this warning should not happen if user call set_fmt() with the format that get from by get_formats(). But it is a common pattern in soc_camera host code to handle this error. @@ -540,6 +557,10 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, u32 pixfmt = pix-pixelformat; int ret; + /* check with atmel-isi support format, if not support use UYVY */ + if (!is_supported(icd, pix-pixelformat)) + pix-pixelformat = V4L2_PIX_FMT_YUYV; + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (pixfmt !xlate) { dev_warn(icd-parent, Format %x not found\n, pixfmt); Same comment here. I wonder whether most of the content of isi_camera_set_fmt() and isi_camera_try_fmt() could be factorized out into a shared function. I agree. the current set_fmt() doesn't touch any hardware, so it's almost same as try_fmt(). Best Regards, Josh Wu -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/3] media: atmel-isi: setup the ISI_CFG2 register directly
In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu josh...@atmel.com Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v3: None Changes in v2: - add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index f39132c..b67da70 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ default: @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 = ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) ISI_CFG2_IM_HSIZE_OFFSET) ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 = ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/3] media: atmel-isi: add sanity check for supported formats in try/set_fmt()
After adding the format check in try_fmt()/set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: - check the whether format is supported, if no then return a default format. - misc changes according to Laurent's feedback. Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 37 +-- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..84c91d3 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -102,17 +102,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi-regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; @@ -126,8 +128,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -138,8 +138,23 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const u32 pixformat) +{ + switch (pixformat) { + /* YUV, including grey */ + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_YUYV: + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YVYU: + case V4L2_PIX_FMT_VYUY: + return true; + /* RGB, TODO */ + default: + return false; + } } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -390,10 +405,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd-user_width, icd-user_height, + configure_geometry(isi, icd-user_width, icd-user_height, icd-current_fmt-code); - if (ret 0) - return ret; spin_lock_irq(isi-lock); /* Clear any pending interrupt */ @@ -491,6 +504,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_mbus_framefmt *mf = format.format; int ret; + /* check with atmel-isi support format, if not support use UYVY */ + if (!is_supported(icd, pix-pixelformat)) + pix-pixelformat = V4L2_PIX_FMT_YUYV; + xlate = soc_camera_xlate_by_fourcc(icd, pix-pixelformat); if (!xlate) { dev_warn(icd-parent, Format %x not found\n, @@ -540,6 +557,10 @@ static int isi_camera_try_fmt(struct soc_camera_device *icd, u32 pixfmt = pix-pixelformat; int ret; + /* check with atmel-isi support format, if not support use UYVY */ + if (!is_supported(icd, pix-pixelformat)) + pix-pixelformat = V4L2_PIX_FMT_YUYV; + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (pixfmt !xlate) { dev_warn(icd-parent, Format %x not found\n, pixfmt); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/3] media: atmel-isi: move configure_geometry() to start_streaming()
As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu josh...@atmel.com Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v3: None Changes in v2: - Add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index b67da70..fe9247a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd-user_width, icd-user_height, + icd-current_fmt-code); + if (ret 0) + return ret; + spin_lock_irq(isi-lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); - struct atmel_isi *isi = ici-priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = f-fmt.pix; @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici-v4l2_dev.dev); - - ret = configure_geometry(isi, pix-width, pix-height, xlate-code); - - pm_runtime_put(ici-v4l2_dev.dev); - - if (ret 0) - return ret; - pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] media: atmel-isi: add sanity check for supported formats in set_fmt()
Hi, Laurent Could you have time to review this patch? so that I can send a pull request with your reviewed-by tags. Best Regards, Josh Wu On 8/5/2015 11:26 AM, Josh Wu wrote: After adding the format check in set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 39 +-- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index cb46aec..d0df518 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,17 +103,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi-regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; @@ -127,8 +129,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -139,8 +139,29 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const struct soc_camera_format_xlate *xlate) +{ + bool ret = true; + + switch (xlate-code) { + /* YUV, including grey */ + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + break; + /* RGB, TODO */ + default: + dev_err(icd-parent, not supported format: %d\n, + xlate-code); + ret = false; + } + + return ret; } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -391,10 +412,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd-user_width, icd-user_height, + configure_geometry(isi, icd-user_width, icd-user_height, icd-current_fmt-code); - if (ret 0) - return ret; spin_lock_irq(isi-lock); /* Clear any pending interrupt */ @@ -515,6 +534,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* check with atmel-isi support format */ + if (!is_supported(icd, xlate)) + return -EINVAL; + pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] media: atmel-isi: add sanity check for supported formats in set_fmt()
Hi, Laurent Thanks for the review. On 8/21/2015 2:30 AM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Wednesday 05 August 2015 11:26:29 Josh Wu wrote: After adding the format check in set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 39 ++-- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index cb46aec..d0df518 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,17 +103,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi-regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; @@ -127,8 +129,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -139,8 +139,29 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const struct soc_camera_format_xlate *xlate) +{ + bool ret = true; + + switch (xlate-code) { + /* YUV, including grey */ + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: I would just return true here and false below, and remove the ret variable. Ok. + break; + /* RGB, TODO */ + default: + dev_err(icd-parent, not supported format: %d\n, + xlate-code); If this can happen when userspace asks for an unsupported format I don't think you should print an error message to the kernel log. ok, I will remove this. + ret = false; + } + + return ret; } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -391,10 +412,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd-user_width, icd-user_height, + configure_geometry(isi, icd-user_width, icd-user_height, icd-current_fmt-code); - if (ret 0) - return ret; spin_lock_irq(isi-lock); /* Clear any pending interrupt */ @@ -515,6 +534,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* check with atmel-isi support format */ + if (!is_supported(icd, xlate)) + return -EINVAL; + S_FMT is supposed to pick a suitable default format when the requested format isn't supported. It shouldn't return an error. So I will move this check to beginning of S_FMT and if format not support, I will select a default format for it. Best Regards, Josh Wu pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/4] v4l: atmel-isi: Remove unused variable
Hi, Laurent On 8/1/2015 5:22 PM, Laurent Pinchart wrote: Fix a compilation warning by removing an unused local variable in the probe function. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/platform/soc_camera/atmel-isi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 9c900d9569e0..a2e50a734fa3 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -920,7 +920,6 @@ static int atmel_isi_probe(struct platform_device *pdev) struct atmel_isi *isi; struct resource *regs; int ret, i; - struct device *dev = pdev-dev; After a further check, I find this patch should be squashed with the [PATCH 3/4]. Since 'dev' is used by platform data in atmel_isi_probe() function by following code: pdata = dev-platform_data; if ((!pdata || !pdata-data_width_flags) !pdev-dev.of_node) { dev_err(pdev-dev, No config available for Atmel ISI\n); return -EINVAL; } So if you agree with it, I will squash this patch with [PATCH 3/4] Remove support for platform data in my tree. Does it sound ok for you? Best Regards, Josh Wu struct soc_camera_host *soc_host; struct isi_platform_data *pdata; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] media: soc-camera: increase the length of clk_name on soc_of_bind()
Since in soc_of_bind() it may use the of node's full name as the clk_name, and this full name may be longer than 32 characters, take at91 i2c sensor as an example, length is 34 bytes: /ahb/apb/i2c@f8028000/camera@0x30 So this patch increase the clk_name[] array size to 64. It seems big enough so far. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/soc_camera.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index d708df4..fcf3e97 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1621,7 +1621,7 @@ static int soc_of_bind(struct soc_camera_host *ici, struct soc_camera_async_client *sasc; struct soc_of_info *info; struct i2c_client *client; - char clk_name[V4L2_SUBDEV_NAME_SIZE]; + char clk_name[V4L2_SUBDEV_NAME_SIZE + 32]; int ret; /* allocate a new subdev and add match info to it */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] media: atmel-isi: parse the DT parameters for vsync/hsync polarity
Hi, Laurent On 8/1/2015 5:11 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Friday 31 July 2015 18:33:32 Josh Wu wrote: This patch will get the DT parameters of vsync/hsync polarity, and pass to the platform data. Also add a debug information for test purpose. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..a7de55c 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -811,6 +811,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd-parent, vsync is active %s, hsyc is active %s, pix clock is sampling %s\n, s/hsyc/hsync/ I'd write it as vsync active %s, hsync active %s, sampling on pix clock %s edge\n with falling and rising instead of fall and rise. Thanks, I'll correct it. + common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? fall : rise); + if (isi-pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi-pdata.full_mode) @@ -898,6 +903,11 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, goto err_probe_dt; } + if (ep.bus.parallel.flags V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi-pdata.hsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi-pdata.vsync_act_low = true; While you're at it, how about setting has_emb_sync based on ep.bus_type and pclk_act_falling from flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? I will add the pclk_act_falling handling code as well. And rebase this patch on top of your dt modifications. Best Regards Josh Wu err_probe_dt: of_node_put(np); -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] media: atmel-isi: parse the DT parameters for vsync/hsync/pixclock polarity
This patch will get the DT parameters of vsync/hsync/pixclock polarity, and pass to driver. Also add a debug information for test purpose. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - rewrite the debug message and add pix clock polarity setup thanks to Laurent. - update the commit log. drivers/media/platform/soc_camera/atmel-isi.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..d6f8def 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd-parent, vsync active %s, hsync active %s, sampling on pix clock %s\n, + common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? falling : rising); + if (isi-pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi-pdata.full_mode) @@ -1148,6 +1153,13 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, return -EINVAL; } + if (ep.bus.parallel.flags V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi-pdata.hsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi-pdata.vsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_PCLK_SAMPLE_FALLING) + isi-pdata.pclk_act_falling = true; + return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] media: atmel-isi: move configure_geometry() to start_streaming()
Hi, Laurent On 8/3/2015 9:27 PM, Laurent Pinchart wrote: Hi Josh, On Monday 03 August 2015 11:56:01 Josh Wu wrote: On 7/31/2015 10:37 PM, Laurent Pinchart wrote: On Wednesday 17 June 2015 18:39:39 Josh Wu wrote: As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8bc40ca..b01086d 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd-user_width, icd-user_height, + icd-current_fmt-code); I would also make configure_geometry a void function, as the only failure case really can't occur. I think this case can be reached if user require a RGB565 format to capture and sensor also support RGB565 format. As atmel-isi driver will provide RGB565 support via the pass-through mode (maybe we need re-consider this part). So that will cause the configure_geometry() returns an error since it found the bus format is not Y8 or YUV422. In my opinion, we should not change configure_geometry()'s return type, until we add a insanity format check before we call configure_geometry() in future. It will really confuse the user if S_FMT accepts a format but STREAMON fails due to the format being unsupported. Could that be fixed by defaulting to a known supported format in S_FMT if the requested format isn't support ? yes, it's the right way to go. You could then remove the error check in configure_geometry(). So I will send a v2 patches, which will add one more patch to add insanity check on the S_FMT and remove the error check code in configure_geometry(). And for this patch in v2, I will add your reviewed-by tag. Is that Okay for you? Best Regards, Josh Wu Apart from that, Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Thanks for the review. Best Regards, Josh Wu + if (ret 0) + return ret; + spin_lock_irq(isi-lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); - struct atmel_isi *isi = ici-priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = f-fmt.pix; @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici-v4l2_dev.dev); - - ret = configure_geometry(isi, pix-width, pix-height, xlate-code); - - pm_runtime_put(ici-v4l2_dev.dev); - - if (ret 0) - return ret; - pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] media: atmel-isi: parse the DT parameters for vsync/hsync/pixclock polarity
Hi, Laurent On 8/4/2015 4:33 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Tuesday 04 August 2015 14:47:07 Josh Wu wrote: This patch will get the DT parameters of vsync/hsync/pixclock polarity, and pass to driver. Also add a debug information for test purpose. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - rewrite the debug message and add pix clock polarity setup thanks to Laurent. - update the commit log. drivers/media/platform/soc_camera/atmel-isi.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..d6f8def 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd-parent, vsync active %s, hsync active %s, sampling on pix clock %s\n, You forgot edge right before \n :-) oops, I missed the word. + common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? falling : rising); + if (isi-pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi-pdata.full_mode) @@ -1148,6 +1153,13 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, return -EINVAL; } + if (ep.bus.parallel.flags V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi-pdata.hsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi-pdata.vsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_PCLK_SAMPLE_FALLING) + isi-pdata.pclk_act_falling = true; + How about has_emb_sync, which can be set from ep.bus_type ? yes, right. I forgot this as well. I'll generate a new version of this patch soon. Thanks for the catching. Best Regards, Josh Wu return 0; } -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3] media: atmel-isi: parse the DT parameters for vsync/hsync/pixclock polarity
This patch will get the DT parameters of vsync/hsync/pixclock polarity, and pass to driver. Also add a debug information for test purpose. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: - add embedded sync dt property support. Changes in v2: - rewrite the debug message and add pix clock polarity setup thanks to Laurent. - update the commit log. drivers/media/platform/soc_camera/atmel-isi.c | 15 +++ 1 file changed, 15 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fead841..4efc939 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -1061,6 +1061,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd-parent, vsync active %s, hsync active %s, sampling on pix clock %s edge\n, + common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? falling : rising); + if (isi-pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi-pdata.full_mode) @@ -1148,6 +1153,16 @@ static int atmel_isi_parse_dt(struct atmel_isi *isi, return -EINVAL; } + if (ep.bus.parallel.flags V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi-pdata.hsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi-pdata.vsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_PCLK_SAMPLE_FALLING) + isi-pdata.pclk_act_falling = true; + + if (ep.bus_type == V4L2_MBUS_BT656) + isi-pdata.has_emb_sync = true; + return 0; } -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] media: atmel-isi: add sanity check for supported formats in set_fmt()
After adding the format check in set_fmt(), we don't need any format check in configure_geometry(). So make configure_geometry() as void type. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - new added patch drivers/media/platform/soc_camera/atmel-isi.c | 39 +-- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index cb46aec..d0df518 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -103,17 +103,19 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) return readl(isi-regs + reg); } -static int configure_geometry(struct atmel_isi *isi, u32 width, +static void configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { u32 cfg2; /* According to sensor's output format to set cfg2 */ switch (code) { - /* YUV, including grey */ + default: + /* Grey */ case MEDIA_BUS_FMT_Y8_1X8: cfg2 = ISI_CFG2_GRAYSCALE; break; + /* YUV */ case MEDIA_BUS_FMT_VYUY8_2X8: cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; @@ -127,8 +129,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ - default: - return -EINVAL; } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); @@ -139,8 +139,29 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); +} - return 0; +static bool is_supported(struct soc_camera_device *icd, + const struct soc_camera_format_xlate *xlate) +{ + bool ret = true; + + switch (xlate-code) { + /* YUV, including grey */ + case MEDIA_BUS_FMT_Y8_1X8: + case MEDIA_BUS_FMT_VYUY8_2X8: + case MEDIA_BUS_FMT_UYVY8_2X8: + case MEDIA_BUS_FMT_YVYU8_2X8: + case MEDIA_BUS_FMT_YUYV8_2X8: + break; + /* RGB, TODO */ + default: + dev_err(icd-parent, not supported format: %d\n, + xlate-code); + ret = false; + } + + return ret; } static irqreturn_t atmel_isi_handle_streaming(struct atmel_isi *isi) @@ -391,10 +412,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); - ret = configure_geometry(isi, icd-user_width, icd-user_height, + configure_geometry(isi, icd-user_width, icd-user_height, icd-current_fmt-code); - if (ret 0) - return ret; spin_lock_irq(isi-lock); /* Clear any pending interrupt */ @@ -515,6 +534,10 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* check with atmel-isi support format */ + if (!is_supported(icd, xlate)) + return -EINVAL; + pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] media: atmel-isi: move configure_geometry() to start_streaming()
As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu josh...@atmel.com Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v2: - Add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 0fd6bc9..cb46aec 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -391,6 +391,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd-user_width, icd-user_height, + icd-current_fmt-code); + if (ret 0) + return ret; + spin_lock_irq(isi-lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -478,8 +483,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); - struct atmel_isi *isi = ici-priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = f-fmt.pix; @@ -512,16 +515,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici-v4l2_dev.dev); - - ret = configure_geometry(isi, pix-width, pix-height, xlate-code); - - pm_runtime_put(ici-v4l2_dev.dev); - - if (ret 0) - return ret; - pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/3] media: atmel-isi: setup the ISI_CFG2 register directly
In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu josh...@atmel.com Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v2: - add Laurent's reviewed-by tag. drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 274a6f7..0fd6bc9 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -106,24 +106,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ default: @@ -131,17 +132,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 = ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) ISI_CFG2_IM_HSIZE_OFFSET) ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 = ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] atmel-isi: Remove platform data support
Hi, Laurent On 8/5/2015 6:08 AM, Laurent Pinchart wrote: Hi Josh, On Monday 03 August 2015 10:56:29 Josh Wu wrote: On 8/1/2015 5:22 PM, Laurent Pinchart wrote: Hello, While reviewing patches for the atmel-isi I noticed a couple of small issues with the driver. Here's a patch series to fix them, the main change being the removal of platform data support now that all users have migrated to DT. Thanks for the patches. It's perfectly make sense. The patches have been compile-tested only. Josh, would you be able to test them on hardware ? For the whole series, here is my: Acked-by: Josh Wu josh...@atmel.com Tested-by: Josh Wu josh...@atmel.com Thank you. Do you plan to take those four patches in your tree and include them in your next pull request ? yes, I plan to take them with my other patches for atmel-isi (about the configure_geometry(), already sent for review). And I will sent a pull request to Gueannadi. Best Regards, Josh Wu Laurent Pinchart (4): v4l: atmel-isi: Simplify error handling during DT parsing v4l: atmel-isi: Remove unused variable v4l: atmel-isi: Remove support for platform data v4l: atmel-isi: Remove unused platform data fields drivers/media/platform/soc_camera/atmel-isi.c | 40 ++-- drivers/media/platform/soc_camera/atmel-isi.h | 126 include/media/atmel-isi.h | 131 3 files changed, 136 insertions(+), 161 deletions(-) create mode 100644 drivers/media/platform/soc_camera/atmel-isi.h delete mode 100644 include/media/atmel-isi.h -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] media: atmel-isi: move configure_geometry() to start_streaming()
HI, Laurent On 7/31/2015 10:37 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Wednesday 17 June 2015 18:39:39 Josh Wu wrote: As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8bc40ca..b01086d 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd-user_width, icd-user_height, + icd-current_fmt-code); I would also make configure_geometry a void function, as the only failure case really can't occur. I think this case can be reached if user require a RGB565 format to capture and sensor also support RGB565 format. As atmel-isi driver will provide RGB565 support via the pass-through mode (maybe we need re-consider this part). So that will cause the configure_geometry() returns an error since it found the bus format is not Y8 or YUV422. In my opinion, we should not change configure_geometry()'s return type, until we add a insanity format check before we call configure_geometry() in future. Apart from that, Reviewed-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Thanks for the review. Best Regards, Josh Wu + if (ret 0) + return ret; + spin_lock_irq(isi-lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); - struct atmel_isi *isi = ici-priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = f-fmt.pix; @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici-v4l2_dev.dev); - - ret = configure_geometry(isi, pix-width, pix-height, xlate-code); - - pm_runtime_put(ici-v4l2_dev.dev); - - if (ret 0) - return ret; - pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/4] atmel-isi: Remove platform data support
Hi, Laurent On 8/1/2015 5:22 PM, Laurent Pinchart wrote: Hello, While reviewing patches for the atmel-isi I noticed a couple of small issues with the driver. Here's a patch series to fix them, the main change being the removal of platform data support now that all users have migrated to DT. Thanks for the patches. It's perfectly make sense. The patches have been compile-tested only. Josh, would you be able to test them on hardware ? For the whole series, here is my: Acked-by: Josh Wu josh...@atmel.com Tested-by: Josh Wu josh...@atmel.com Best Regards, Josh Wu Laurent Pinchart (4): v4l: atmel-isi: Simplify error handling during DT parsing v4l: atmel-isi: Remove unused variable v4l: atmel-isi: Remove support for platform data v4l: atmel-isi: Remove unused platform data fields drivers/media/platform/soc_camera/atmel-isi.c | 40 ++-- drivers/media/platform/soc_camera/atmel-isi.h | 126 + include/media/atmel-isi.h | 131 -- 3 files changed, 136 insertions(+), 161 deletions(-) create mode 100644 drivers/media/platform/soc_camera/atmel-isi.h delete mode 100644 include/media/atmel-isi.h -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] media: atmel-isi: parse the DT parameters for vsync/hsync polarity
This patch will get the DT parameters of vsync/hsync polarity, and pass to the platform data. Also add a debug information for test purpose. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index fe9247a..a7de55c 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -811,6 +811,11 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING) cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; + dev_dbg(icd-parent, vsync is active %s, hsyc is active %s, pix clock is sampling %s\n, + common_flags V4L2_MBUS_VSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_HSYNC_ACTIVE_LOW ? low : high, + common_flags V4L2_MBUS_PCLK_SAMPLE_FALLING ? fall : rise); + if (isi-pdata.has_emb_sync) cfg1 |= ISI_CFG1_EMB_SYNC; if (isi-pdata.full_mode) @@ -898,6 +903,11 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, goto err_probe_dt; } + if (ep.bus.parallel.flags V4L2_MBUS_HSYNC_ACTIVE_LOW) + isi-pdata.hsync_act_low = true; + if (ep.bus.parallel.flags V4L2_MBUS_VSYNC_ACTIVE_LOW) + isi-pdata.vsync_act_low = true; + err_probe_dt: of_node_put(np); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] media: atmel-isi: setup the ISI_CFG2 register directly
Hi, list Ping..., any feedback for this series? Best Regards, Josh Wu On 6/17/2015 6:39 PM, Josh Wu wrote: In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 9070172..8bc40ca 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ default: @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 = ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) ISI_CFG2_IM_HSIZE_OFFSET) ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 = ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] media: atmel-isi: increase timeout to disable/enable isi
If ISI is working on a 1024x768 or higher resolution, it needs longer time to disable ISI. So this patch will increase timeout to 500ms. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 1482af2..354b7db 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -219,7 +219,7 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset) } timeout = wait_for_completion_timeout(isi-complete, - msecs_to_jiffies(100)); + msecs_to_jiffies(500)); if (timeout == 0) return -ETIMEDOUT; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] media: atmel-isi: move configure_geometry() to start_streaming()
As in set_fmt() function we only need to know which format is been set, we don't need to access the ISI hardware in this moment. So move the configure_geometry(), which access the ISI hardware, to start_streaming() will make code more consistent and simpler. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 17 + 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 8bc40ca..b01086d 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -390,6 +390,11 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) /* Disable all interrupts */ isi_writel(isi, ISI_INTDIS, (u32)~0UL); + ret = configure_geometry(isi, icd-user_width, icd-user_height, + icd-current_fmt-code); + if (ret 0) + return ret; + spin_lock_irq(isi-lock); /* Clear any pending interrupt */ isi_readl(isi, ISI_STATUS); @@ -477,8 +482,6 @@ static int isi_camera_init_videobuf(struct vb2_queue *q, static int isi_camera_set_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { - struct soc_camera_host *ici = to_soc_camera_host(icd-parent); - struct atmel_isi *isi = ici-priv; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = f-fmt.pix; @@ -511,16 +514,6 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; - /* Enable PM and peripheral clock before operate isi registers */ - pm_runtime_get_sync(ici-v4l2_dev.dev); - - ret = configure_geometry(isi, pix-width, pix-height, xlate-code); - - pm_runtime_put(ici-v4l2_dev.dev); - - if (ret 0) - return ret; - pix-width = mf-width; pix-height = mf-height; pix-field = mf-field; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] media: atmel-isi: setup the ISI_CFG2 register directly
In the function configure_geometry(), we will setup the ISI CFG2 according to the sensor output format. It make no sense to just read back the CFG2 register and just set part of it. So just set up this register directly makes things simpler. Currently only support YUV format from camera sensor. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 20 +++- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 9070172..8bc40ca 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -105,24 +105,25 @@ static u32 isi_readl(struct atmel_isi *isi, u32 reg) static int configure_geometry(struct atmel_isi *isi, u32 width, u32 height, u32 code) { - u32 cfg2, cr; + u32 cfg2; + /* According to sensor's output format to set cfg2 */ switch (code) { /* YUV, including grey */ case MEDIA_BUS_FMT_Y8_1X8: - cr = ISI_CFG2_GRAYSCALE; + cfg2 = ISI_CFG2_GRAYSCALE; break; case MEDIA_BUS_FMT_VYUY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_3; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_3; break; case MEDIA_BUS_FMT_UYVY8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_2; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_2; break; case MEDIA_BUS_FMT_YVYU8_2X8: - cr = ISI_CFG2_YCC_SWAP_MODE_1; + cfg2 = ISI_CFG2_YCC_SWAP_MODE_1; break; case MEDIA_BUS_FMT_YUYV8_2X8: - cr = ISI_CFG2_YCC_SWAP_DEFAULT; + cfg2 = ISI_CFG2_YCC_SWAP_DEFAULT; break; /* RGB, TODO */ default: @@ -130,17 +131,10 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, } isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - - cfg2 = isi_readl(isi, ISI_CFG2); - /* Set YCC swap mode */ - cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; - cfg2 |= cr; /* Set width */ - cfg2 = ~(ISI_CFG2_IM_HSIZE_MASK); cfg2 |= ((width - 1) ISI_CFG2_IM_HSIZE_OFFSET) ISI_CFG2_IM_HSIZE_MASK; /* Set height */ - cfg2 = ~(ISI_CFG2_IM_VSIZE_MASK); cfg2 |= ((height - 1) ISI_CFG2_IM_VSIZE_OFFSET) ISI_CFG2_IM_VSIZE_MASK; isi_writel(isi, ISI_CFG2, cfg2); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 0/3] media: atmel-isi: rework on the clock part and add runtime pm support
Hi, Guennadi Any feedback for this patch series? Best Regards, Josh Wu On 5/26/2015 5:54 PM, Josh Wu wrote: This patch series fix the peripheral clock code and enable runtime support. Also it clean up the code which is for the compatiblity of mck. Changes in v5: - add new patch to fix the condition that codec request still in work. - fix the error path in start_streaming() thanks to Laurent. Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. - totally remove clock_start()/clock_stop() as they are optional. Josh Wu (3): media: atmel-isi: disable ISI even it has codec request in stop_streaming() media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as it's not need drivers/media/platform/soc_camera/atmel-isi.c | 105 -- 1 file changed, 48 insertions(+), 57 deletions(-) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/2] media: atmel-isi: add runtime pm support
The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In atmel_isi_probe(), remove the isi disable code as in the moment ISI peripheral clock is not enable yet. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 54 +++ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2879026..194e875 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,6 +387,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -445,6 +448,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -516,7 +521,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0) return ret; @@ -736,14 +747,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -758,7 +764,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -855,9 +860,14 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -889,6 +899,7 @@ static int atmel_isi_remove(struct platform_device *pdev) sizeof(struct fbd) * MAX_BUFFER_NUM, isi-p_fb_descriptors, isi-fb_descriptors_phys); + pm_runtime_disable(pdev-dev); return 0; } @@ -1027,8 +1038,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; @@ -1049,6 +1058,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr= pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1062,6 +1074,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1074,6 +1087,30 @@ err_alloc_ctx: return ret
[PATCH v4 2/2] media: atmel-isi: remove mck back compatiable code as it's not need
The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v4: None Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - totally remove clock_start()/clock_stop() as they are optional. drivers/media/platform/soc_camera/atmel-isi.c | 46 --- 1 file changed, 46 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 194e875..65d9bc4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -35,7 +35,6 @@ #define VID_LIMIT_BYTES(16 * 1024 * 1024) #define MIN_FRAME_RATE 15 #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) -#define ISI_DEFAULT_MCLK_FREQ 2500 /* Frame buffer descriptor */ struct fbd { @@ -83,8 +82,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -741,31 +738,6 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) icd-devnum); } -/* Called with .host_lock held */ -static int isi_camera_clock_start(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Called with .host_lock held */ -static void isi_camera_clock_stop(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); -} - static unsigned int isi_camera_poll(struct file *file, poll_table *pt) { struct soc_camera_device *icd = file-private_data; @@ -875,8 +847,6 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, - .clock_start= isi_camera_clock_start, - .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, @@ -913,7 +883,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -989,21 +958,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/2] media: atmel-isi: rework on the clock part and add runtime pm support
This patch series fix the peripheral clock code and enable runtime pm support. Also it clean up the code which is for the compatiblity of mck. Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ - remove some isi disable code if peripheral clock is disabled. Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. - totally remove clock_start()/clock_stop() as they are optional. Josh Wu (2): media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as it's not need drivers/media/platform/soc_camera/atmel-isi.c | 100 -- 1 file changed, 46 insertions(+), 54 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/3] media: atmel-isi: disable ISI even it has codec request in stop_streaming()
In current code, stop_streaming() will just return if ISI is still working in the codec. But this is incorrect, we need to disable ISI even it is working on the codec. otherwise stop_streaming() will not work as we expected. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5: - add new patch to fix the condition that codec request still in work. Changes in v4: None Changes in v3: None Changes in v2: None drivers/media/platform/soc_camera/atmel-isi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2879026..2227022 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -431,11 +431,9 @@ static void stop_streaming(struct vb2_queue *vq) time_before(jiffies, timeout)) msleep(1); - if (time_after(jiffies, timeout)) { + if (time_after(jiffies, timeout)) dev_err(icd-parent, Timeout waiting for finishing codec request\n); - return; - } /* Disable interrupts */ isi_writel(isi, ISI_INTDIS, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/2] media: atmel-isi: add runtime pm support
Hi, Laurent On 5/26/2015 4:16 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Tuesday 26 May 2015 16:00:09 Josh Wu wrote: The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In atmel_isi_probe(), remove the isi disable code as in the moment ISI peripheral clock is not enable yet. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 54 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2879026..194e875 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,6 +387,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { You need to call pm_runtime_put() in the error path, otherwise an atmel_isi_wait_status() failure will keep the device enabled. Nice catch. Thanks. @@ -445,6 +448,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -516,7 +521,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); I think it would simplify the code to move the configure_geometry() call to start_streaming() as you already call pm_runtime_get_sync() there. That can be done in a separate patch though. I think it's a good idea. I would like to make this in a separate patch and not include in this series. In summary, I'll resend this patch just with the fix you mentioned in above (fix the error path in start_streaming). Is that okay for you? Best Regards, Josh Wu + if (ret 0) return ret; @@ -736,14 +747,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -758,7 +764,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -855,9 +860,14 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -889,6 +899,7 @@ static int atmel_isi_remove(struct platform_device *pdev) sizeof(struct fbd) * MAX_BUFFER_NUM, isi-p_fb_descriptors, isi-fb_descriptors_phys); + pm_runtime_disable(pdev-dev); return 0; } @@ -1027,8 +1038,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq
[PATCH v5 3/3] media: atmel-isi: remove mck back compatiable code as it's not need
The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v5: None Changes in v4: None Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - totally remove clock_start()/clock_stop() as they are optional. drivers/media/platform/soc_camera/atmel-isi.c | 46 --- 1 file changed, 46 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 0ea360a..9070172 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -35,7 +35,6 @@ #define VID_LIMIT_BYTES(16 * 1024 * 1024) #define MIN_FRAME_RATE 15 #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) -#define ISI_DEFAULT_MCLK_FREQ 2500 /* Frame buffer descriptor */ struct fbd { @@ -83,8 +82,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -740,31 +737,6 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) icd-devnum); } -/* Called with .host_lock held */ -static int isi_camera_clock_start(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Called with .host_lock held */ -static void isi_camera_clock_stop(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); -} - static unsigned int isi_camera_poll(struct file *file, poll_table *pt) { struct soc_camera_device *icd = file-private_data; @@ -874,8 +846,6 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, - .clock_start= isi_camera_clock_start, - .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, @@ -912,7 +882,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -988,21 +957,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/3] media: atmel-isi: rework on the clock part and add runtime pm support
This patch series fix the peripheral clock code and enable runtime support. Also it clean up the code which is for the compatiblity of mck. Changes in v5: - add new patch to fix the condition that codec request still in work. - fix the error path in start_streaming() thanks to Laurent. Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. - totally remove clock_start()/clock_stop() as they are optional. Josh Wu (3): media: atmel-isi: disable ISI even it has codec request in stop_streaming() media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as it's not need drivers/media/platform/soc_camera/atmel-isi.c | 105 -- 1 file changed, 48 insertions(+), 57 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/2] media: atmel-isi: add runtime pm support
On 5/26/2015 5:14 PM, Josh Wu wrote: Hi, Laurent On 5/26/2015 4:16 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Tuesday 26 May 2015 16:00:09 Josh Wu wrote: The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In atmel_isi_probe(), remove the isi disable code as in the moment ISI peripheral clock is not enable yet. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 54 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2879026..194e875 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,6 +387,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; +pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { You need to call pm_runtime_put() in the error path, otherwise an atmel_isi_wait_status() failure will keep the device enabled. Nice catch. Thanks. @@ -445,6 +448,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + +pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -516,7 +521,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; +/* Enable PM and peripheral clock before operate isi registers */ +pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + +pm_runtime_put(ici-v4l2_dev.dev); I think it would simplify the code to move the configure_geometry() call to start_streaming() as you already call pm_runtime_get_sync() there. That can be done in a separate patch though. I think it's a good idea. I would like to make this in a separate patch and not include in this series. In summary, I'll resend this patch just with the fix you mentioned in above (fix the error path in start_streaming). Is that okay for you? As I found another issue on stop_streaming(), so I sent a v5 series for this whole patch set with a new fix. Please check it. BTW: I don't include the simplify method: move configure_geometry() into start_streaming(), I perfer do that after this series is merged. Best Regards, Josh Wu Best Regards, Josh Wu + if (ret 0) return ret; @@ -736,14 +747,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; -ret = clk_prepare_enable(isi-pclk); -if (ret) -return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { -clk_disable_unprepare(isi-pclk); return ret; } } @@ -758,7 +764,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); -clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -855,9 +860,14 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; +/* Enable PM and peripheral clock before operate isi registers */ +pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); +pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -889,6 +899,7 @@ static int atmel_isi_remove(struct platform_device *pdev) sizeof(struct fbd) * MAX_BUFFER_NUM, isi-p_fb_descriptors, isi-fb_descriptors_phys); +pm_runtime_disable(pdev-dev); return 0; } @@ -1027,8 +1038,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi
[PATCH v5 2/3] media: atmel-isi: add runtime pm support
The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In atmel_isi_probe(), remove the isi disable code as in the moment ISI peripheral clock is not enable yet. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5: - fix the error path in start_streaming() thanks to Laurent. Changes in v4: - need to call pm_runtime_disable() in atmel_isi_remove(). - merged the patch which remove isi disable code in atmel_isi_probe() as isi peripherial clock is not enabled in this moment. - refine the commit log Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 55 +++ 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2227022..0ea360a 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,10 +387,13 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { dev_err(icd-parent, Reset ISI timed out\n); + pm_runtime_put(ici-v4l2_dev.dev); return ret; } /* Disable all interrupts */ @@ -443,6 +447,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -514,7 +520,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf-code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0) return ret; @@ -734,14 +746,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -756,7 +763,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -853,9 +859,14 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -887,6 +898,7 @@ static int atmel_isi_remove(struct platform_device *pdev) sizeof(struct fbd) * MAX_BUFFER_NUM, isi-p_fb_descriptors, isi-fb_descriptors_phys); + pm_runtime_disable(pdev-dev); return 0; } @@ -1025,8 +1037,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; @@ -1047,6 +1057,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr= pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1060,6 +1073,7 @@ static int atmel_isi_probe
Re: [PATCH v2 1/3] media: atmel-isi: remove the useless code which disable isi
Hi, Guennadi On 5/12/2015 4:16 AM, Guennadi Liakhovetski wrote: Hi Josh, Thanks for the patch. I'm afraid I don't quite understand why it is needed, could you maybe explain a bit more? Is it because (1) during ISI configuration the pixel clock from the sensor is (usually) anyway disabled, so, we don't have to additionally disable the ISI, without the pixel clock the ISI is anyway already disabled. or (2) disabling the ISI at those locations below breaks something, because when the ISI is disabled, the functionality, that's later used isn't available. I assume it's (1), but if that's the case, then this patch is just cosmetic, right? Right, it is (1). This patch doesn't impact the function of isi. The point is when we disable the ISI, we need make sure ISI peripheral clock and pixel clock is enabled. And also need to check the status register or irq to know whether the disable operation is successful. So best way to disable ISI is to call atmel_isi_wait_status(isi, WAIT_ISI_DISABLE). From this point, the isi_write(isi, ISI_CTRL, ISI_CTRL_DIS) in atmel_isi_probe() is not useful as ISI peripheral clock is not enable yet. but the other two in configure_geometry(), isi_camera_set_bus_param() can work and may protect the case the ISI is not in off state. The ISI is anyway disabled, so, that operation simply has no effect, but also doesn't hurt. OTOH, if some sensor keeps its master clock running all the time, then switching the ISI off as in the current version helps save some power, unless it breaks anything? So what about to keep the isi_write(isi, ISI_CTRL, ISI_CTRL_DIS) in configure_geometry() and isi_camera_set_bus_param(). Only remove it from atmel_isi_probe()? Best Regards, Josh Wu Thanks Guennadi On Thu, 9 Apr 2015, Josh Wu wrote: To program ISI control register, the pixel clock should be enabled. So without pixel clock (from sensor) enabled, disable ISI controller is not make sense. So this patch remove those code. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - this file is new added. drivers/media/platform/soc_camera/atmel-isi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c125b1d..31254b4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -131,8 +131,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, return -EINVAL; } - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - cfg2 = isi_readl(isi, ISI_CFG2); /* Set YCC swap mode */ cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; @@ -843,7 +841,6 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); return 0; @@ -1022,8 +1019,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 2/3] media: atmel-isi: add runtime pm support
On 5/6/2015 6:25 PM, Josh Wu wrote: The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 51 +++ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 31254b4..2b05f89 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -384,6 +385,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -441,6 +444,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -509,7 +514,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf.code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0) return ret; @@ -722,14 +733,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -744,7 +750,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -841,8 +846,13 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -1039,6 +1049,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr = pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1052,6 +1065,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); This function is missed in atmel_isi_remove(). I'll fix it. Best Regards, Josh Wu err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1064,6 +1078,30 @@ err_alloc_ctx: return ret; } +static int atmel_isi_runtime_suspend(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + clk_disable_unprepare(isi-pclk); + + return 0; +} +static int atmel_isi_runtime_resume(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + return clk_prepare_enable(isi-pclk); +} + +static const struct dev_pm_ops atmel_isi_dev_pm_ops = { + SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, + atmel_isi_runtime_resume, NULL) +}; + static const struct of_device_id atmel_isi_of_match[] = { { .compatible
[PATCH v3 1/3] media: atmel-isi: remove the useless code which disable isi
To program ISI control register, the pixel clock should be enabled. So without pixel clock (from sensor) enabled, disable ISI controller is not make sense. So this patch remove those code. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: None Changes in v2: - this file is new added. drivers/media/platform/soc_camera/atmel-isi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c125b1d..31254b4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -131,8 +131,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, return -EINVAL; } - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - cfg2 = isi_readl(isi, ISI_CFG2); /* Set YCC swap mode */ cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; @@ -843,7 +841,6 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); return 0; @@ -1022,8 +1019,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/3] media: atmel-isi: rework on the clock part and add runtime pm support
This patch series fix the peripheral clock code and enable runtime pm support. Also it clean up the code which is for the compatiblity of mck. Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - this file is new added. - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. - totally remove clock_start()/clock_stop() as they are optional. Josh Wu (3): media: atmel-isi: remove the useless code which disable isi media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as it's not need drivers/media/platform/soc_camera/atmel-isi.c | 102 -- 1 file changed, 45 insertions(+), 57 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/3] media: atmel-isi: add runtime pm support
The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v3: None Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 51 +++ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 31254b4..2b05f89 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -384,6 +385,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -441,6 +444,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -509,7 +514,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf.code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0) return ret; @@ -722,14 +733,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -744,7 +750,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -841,8 +846,13 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -1039,6 +1049,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr= pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1052,6 +1065,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1064,6 +1078,30 @@ err_alloc_ctx: return ret; } +static int atmel_isi_runtime_suspend(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + clk_disable_unprepare(isi-pclk); + + return 0; +} +static int atmel_isi_runtime_resume(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + return clk_prepare_enable(isi-pclk); +} + +static const struct dev_pm_ops atmel_isi_dev_pm_ops = { + SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, + atmel_isi_runtime_resume, NULL) +}; + static const struct of_device_id atmel_isi_of_match[] = { { .compatible = atmel,at91sam9g45-isi }, { } @@ -1075,6 +1113,7 @@ static struct platform_driver atmel_isi_driver = { .driver
[PATCH v3 3/3] media: atmel-isi: remove mck back compatiable code as it's not need
The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v3: - remove useless definition: ISI_DEFAULT_MCLK_FREQ Changes in v2: - totally remove clock_start()/clock_stop() as they are optional. drivers/media/platform/soc_camera/atmel-isi.c | 46 --- 1 file changed, 46 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2b05f89..d4989d1 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -35,7 +35,6 @@ #define VID_LIMIT_BYTES(16 * 1024 * 1024) #define MIN_FRAME_RATE 15 #define FRAME_INTERVAL_MILLI_SEC (1000 / MIN_FRAME_RATE) -#define ISI_DEFAULT_MCLK_FREQ 2500 /* Frame buffer descriptor */ struct fbd { @@ -83,8 +82,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -727,31 +724,6 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) icd-devnum); } -/* Called with .host_lock held */ -static int isi_camera_clock_start(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Called with .host_lock held */ -static void isi_camera_clock_stop(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); -} - static unsigned int isi_camera_poll(struct file *file, poll_table *pt) { struct soc_camera_device *icd = file-private_data; @@ -865,8 +837,6 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, - .clock_start= isi_camera_clock_start, - .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, @@ -904,7 +874,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -980,21 +949,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 3/3] media: atmel-isi: remove mck back compatiable code as it's not need
Hi, Laurent On 4/12/2015 9:08 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Thursday 09 April 2015 17:01:48 Josh Wu wrote: The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - totally remove clock_start()/clock_stop() as they are optional. drivers/media/platform/soc_camera/atmel-isi.c | 45 1 file changed, 45 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2b05f89..7bba7d9 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -83,8 +83,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -727,31 +725,6 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) icd-devnum); } -/* Called with .host_lock held */ -static int isi_camera_clock_start(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Called with .host_lock held */ -static void isi_camera_clock_stop(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); -} - static unsigned int isi_camera_poll(struct file *file, poll_table *pt) { struct soc_camera_device *icd = file-private_data; @@ -865,8 +838,6 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, - .clock_start= isi_camera_clock_start, - .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, @@ -904,7 +875,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; You can also remove the #define ISI_DEFAULT_MCLK_FREQ at the beginning of this file. I'll remove the useless definition. With this fixed, Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Thanks. Best Regards, Josh Wu isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -980,21 +950,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/3] media: atmel-isi: remove the useless code which disable isi
Hi, Laurent On 4/12/2015 9:10 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Thursday 09 April 2015 17:01:46 Josh Wu wrote: To program ISI control register, the pixel clock should be enabled. That's an awful hardware design :-( yes, But I need to live with this. So without pixel clock (from sensor) enabled, disable ISI controller is not make sense. So this patch remove those code. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - this file is new added. drivers/media/platform/soc_camera/atmel-isi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c125b1d..31254b4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -131,8 +131,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, return -EINVAL; } - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - cfg2 = isi_readl(isi, ISI_CFG2); Can the configuration registers be accessed when the pixel clock is disabled ? yes, it can be accessed. The CFG1, CFG2 are not impacted. So far as I know only the ISI_CR is impacted, we can disable/enable/reset ISI by set ISI_CR. Since ISI_CR register will work with pixel clock, so you need to poll the ISI_SR to verify your control of ISI is effective. Best Regards, Josh Wu /* Set YCC swap mode */ cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; @@ -843,7 +841,6 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); return 0; @@ -1022,8 +1019,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 3/3] media: atmel-isi: remove mck back compatiable code as it's not need
The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - totally remove clock_start()/clock_stop() as they are optional. drivers/media/platform/soc_camera/atmel-isi.c | 45 --- 1 file changed, 45 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 2b05f89..7bba7d9 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -83,8 +83,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -727,31 +725,6 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) icd-devnum); } -/* Called with .host_lock held */ -static int isi_camera_clock_start(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - - return 0; -} - -/* Called with .host_lock held */ -static void isi_camera_clock_stop(struct soc_camera_host *ici) -{ - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); -} - static unsigned int isi_camera_poll(struct file *file, poll_table *pt) { struct soc_camera_device *icd = file-private_data; @@ -865,8 +838,6 @@ static struct soc_camera_host_ops isi_soc_camera_host_ops = { .owner = THIS_MODULE, .add= isi_camera_add_device, .remove = isi_camera_remove_device, - .clock_start= isi_camera_clock_start, - .clock_stop = isi_camera_clock_stop, .set_fmt= isi_camera_set_fmt, .try_fmt= isi_camera_try_fmt, .get_formats= isi_camera_get_formats, @@ -904,7 +875,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -980,21 +950,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/3] media: atmel-isi: remove the useless code which disable isi
To program ISI control register, the pixel clock should be enabled. So without pixel clock (from sensor) enabled, disable ISI controller is not make sense. So this patch remove those code. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - this file is new added. drivers/media/platform/soc_camera/atmel-isi.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index c125b1d..31254b4 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -131,8 +131,6 @@ static int configure_geometry(struct atmel_isi *isi, u32 width, return -EINVAL; } - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - cfg2 = isi_readl(isi, ISI_CFG2); /* Set YCC swap mode */ cfg2 = ~ISI_CFG2_YCC_SWAP_MODE_MASK; @@ -843,7 +841,6 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); return 0; @@ -1022,8 +1019,6 @@ static int atmel_isi_probe(struct platform_device *pdev) if (isi-pdata.data_width_flags ISI_DATAWIDTH_10) isi-width_flags |= 1 9; - isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); - irq = platform_get_irq(pdev, 0); if (IS_ERR_VALUE(irq)) { ret = irq; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 2/3] media: atmel-isi: add runtime pm support
The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call runtime_pm_get_sync()/runtime_pm_put() when we need access ISI registers. In the meantime, as clock_start()/clock_stop() is used to control the mclk not ISI peripheral clock. So move this to start[stop]_streaming() function. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. drivers/media/platform/soc_camera/atmel-isi.c | 51 +++ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 31254b4..2b05f89 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -384,6 +385,8 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -441,6 +444,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + pm_runtime_put(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -509,7 +514,13 @@ static int isi_camera_set_fmt(struct soc_camera_device *icd, if (mf.code != xlate-code) return -EINVAL; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + ret = configure_geometry(isi, pix-width, pix-height, xlate-code); + + pm_runtime_put(ici-v4l2_dev.dev); + if (ret 0) return ret; @@ -722,14 +733,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -744,7 +750,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -841,8 +846,13 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) cfg1 |= ISI_CFG1_THMASK_BEATS_16; + /* Enable PM and peripheral clock before operate isi registers */ + pm_runtime_get_sync(ici-v4l2_dev.dev); + isi_writel(isi, ISI_CFG1, cfg1); + pm_runtime_put(ici-v4l2_dev.dev); + return 0; } @@ -1039,6 +1049,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr= pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1052,6 +1065,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1064,6 +1078,30 @@ err_alloc_ctx: return ret; } +static int atmel_isi_runtime_suspend(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + clk_disable_unprepare(isi-pclk); + + return 0; +} +static int atmel_isi_runtime_resume(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + return clk_prepare_enable(isi-pclk); +} + +static const struct dev_pm_ops atmel_isi_dev_pm_ops = { + SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, + atmel_isi_runtime_resume, NULL) +}; + static const struct of_device_id atmel_isi_of_match[] = { { .compatible = atmel,at91sam9g45-isi }, { } @@ -1075,6 +1113,7 @@ static struct platform_driver atmel_isi_driver = { .driver
[PATCH v2 0/3] media: atmel-isi: rework on the clock part and add runtime pm support
This patch series fix the peripheral clock code and enable runtime pm support. Also it clean up the code which is for the compatiblity of mck. Changes in v2: - merged v1 two patch into one. - use runtime_pm_put() instead of runtime_pm_put_sync() - enable peripheral clock before access ISI registers. - totally remove clock_start()/clock_stop() as they are optional. Josh Wu (3): media: atmel-isi: remove the useless code which disable isi media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as it's not need drivers/media/platform/soc_camera/atmel-isi.c | 101 -- 1 file changed, 45 insertions(+), 56 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] media: atmel-isi: remove mck back compatiable code as we don't need it
Hi, Laurent On 3/8/2015 8:28 AM, Laurent Pinchart wrote: On Friday 06 March 2015 21:25:36 Guennadi Liakhovetski wrote: On Fri, 6 Mar 2015, Josh Wu wrote: On 3/5/2015 6:41 PM, Laurent Pinchart wrote: On Thursday 05 March 2015 13:01:01 Josh Wu wrote: The master clock should handled by sensor itself. I like that :-) Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 32 --- 1 file changed, 32 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 4a384f1..50375ce 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -83,8 +83,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -725,26 +723,12 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) /* Called with .host_lock held */ static int isi_camera_clock_start(struct soc_camera_host *ici) { - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - return 0; Would it make sense to make the clock_start and clock_stop operations optional in the soc-camera core ? I agree. For those camera host which don't provide master clock for sensor, clock_start and clock_stop should be optional. Hi, Guennadi Do you agree with this? Yes, sure, we can do this. Would anyone like to prepare a patch? Josh, would you like to do that, or should I give it a go ? Yes, you can do that if you have time. ;-) Best Regards, Josh Wu -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] media: atmel-isi: add runtime pm support
On 3/5/2015 6:36 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Thursday 05 March 2015 13:01:00 Josh Wu wrote: The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call rumtime_pm_get/put_sync function to make pm resume/suspend. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 36 +--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index eb179e7..4a384f1 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,9 +387,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); @@ -450,7 +449,7 @@ static void stop_streaming(struct vb2_queue *vq) if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); - clk_disable_unprepare(isi-pclk); + pm_runtime_put_sync(ici-v4l2_dev.dev); Is there a reason to use pm_runtime_put_sync() and not just pm_runtime_put() ? right, for sure we can use pm_runtime_put() here. Best Regards, Josh Wu } static struct vb2_ops isi_video_qops = { @@ -1042,6 +1041,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev= pdev-dev; soc_host-nr = pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1055,6 +1057,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1067,6 +1070,30 @@ err_alloc_ctx: return ret; } +static int atmel_isi_runtime_suspend(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + clk_disable_unprepare(isi-pclk); + + return 0; +} +static int atmel_isi_runtime_resume(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + return clk_prepare_enable(isi-pclk); +} + +static const struct dev_pm_ops atmel_isi_dev_pm_ops = { + SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, + atmel_isi_runtime_resume, NULL) +}; + static const struct of_device_id atmel_isi_of_match[] = { { .compatible = atmel,at91sam9g45-isi }, { } @@ -1079,6 +1106,7 @@ static struct platform_driver atmel_isi_driver = { .name = atmel_isi, .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_isi_of_match), + .pm = atmel_isi_dev_pm_ops, }, }; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] media: atmel-isi: move the peripheral clock to start/stop_stream() function
On 3/5/2015 6:39 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Thursday 05 March 2015 13:00:59 Josh Wu wrote: As the clock_start/stop() use to control the mclk for the sensor not the ISI peripheral clock. So we move them to start/stop_stream() function. Then the driver will access registers with the peripheral clock disabled, for instance in isi_camera_set_fmt() (calling configure_geometry), isi_camera_set_bus_param() or atmel_isi_probe(). Isn't that a problem ? Or are all registers guaranteed to be accessible (and retained) when the clock is disabled ? So far, I don't see any problem yet. But I'd like to be sure of that. I'll give you the feedback after more test. Thanks for make me head up. Best Regards, Josh Wu Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 1208818..eb179e7 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -386,6 +386,10 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + ret = clk_prepare_enable(isi-pclk); + if (ret) + return ret; + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -445,6 +449,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + clk_disable_unprepare(isi-pclk); } static struct vb2_ops isi_video_qops = { @@ -723,14 +729,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -745,7 +746,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/3] media: atmel-isi: remove mck back compatiable code as we don't need it
On 3/5/2015 6:41 PM, Laurent Pinchart wrote: Hi Josh, Thank you for the patch. On Thursday 05 March 2015 13:01:01 Josh Wu wrote: The master clock should handled by sensor itself. I like that :-) Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 32 1 file changed, 32 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 4a384f1..50375ce 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -83,8 +83,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -725,26 +723,12 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) /* Called with .host_lock held */ static int isi_camera_clock_start(struct soc_camera_host *ici) { - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - return 0; Would it make sense to make the clock_start and clock_stop operations optional in the soc-camera core ? I agree. For those camera host which don't provide master clock for sensor, clock_start and clock_stop should be optional. Hi, Guennadi Do you agree with this? Best Regards, Josh Wu } /* Called with .host_lock held */ static void isi_camera_clock_stop(struct soc_camera_host *ici) { - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -894,7 +878,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -970,21 +953,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] media: atmel-isi: move the peripheral clock to start/stop_stream() function
As the clock_start/stop() use to control the mclk for the sensor not the ISI peripheral clock. So we move them to start/stop_stream() function. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 1208818..eb179e7 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -386,6 +386,10 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; + ret = clk_prepare_enable(isi-pclk); + if (ret) + return ret; + /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); if (ret 0) { @@ -445,6 +449,8 @@ static void stop_streaming(struct vb2_queue *vq) ret = atmel_isi_wait_status(isi, WAIT_ISI_DISABLE); if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); + + clk_disable_unprepare(isi-pclk); } static struct vb2_ops isi_video_qops = { @@ -723,14 +729,9 @@ static int isi_camera_clock_start(struct soc_camera_host *ici) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; - if (!IS_ERR(isi-mck)) { ret = clk_prepare_enable(isi-mck); if (ret) { - clk_disable_unprepare(isi-pclk); return ret; } } @@ -745,7 +746,6 @@ static void isi_camera_clock_stop(struct soc_camera_host *ici) if (!IS_ERR(isi-mck)) clk_disable_unprepare(isi-mck); - clk_disable_unprepare(isi-pclk); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] media: atmel-isi: add runtime pm support
The runtime pm resume/suspend will enable/disable pclk (ISI peripheral clock). And we need to call rumtime_pm_get/put_sync function to make pm resume/suspend. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 36 --- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index eb179e7..4a384f1 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -20,6 +20,7 @@ #include linux/kernel.h #include linux/module.h #include linux/platform_device.h +#include linux/pm_runtime.h #include linux/slab.h #include media/atmel-isi.h @@ -386,9 +387,7 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) struct atmel_isi *isi = ici-priv; int ret; - ret = clk_prepare_enable(isi-pclk); - if (ret) - return ret; + pm_runtime_get_sync(ici-v4l2_dev.dev); /* Reset ISI */ ret = atmel_isi_wait_status(isi, WAIT_ISI_RESET); @@ -450,7 +449,7 @@ static void stop_streaming(struct vb2_queue *vq) if (ret 0) dev_err(icd-parent, Disable ISI timed out\n); - clk_disable_unprepare(isi-pclk); + pm_runtime_put_sync(ici-v4l2_dev.dev); } static struct vb2_ops isi_video_qops = { @@ -1042,6 +1041,9 @@ static int atmel_isi_probe(struct platform_device *pdev) soc_host-v4l2_dev.dev = pdev-dev; soc_host-nr= pdev-id; + pm_suspend_ignore_children(pdev-dev, true); + pm_runtime_enable(pdev-dev); + if (isi-pdata.asd_sizes) { soc_host-asd = isi-pdata.asd; soc_host-asd_sizes = isi-pdata.asd_sizes; @@ -1055,6 +1057,7 @@ static int atmel_isi_probe(struct platform_device *pdev) return 0; err_register_soc_camera_host: + pm_runtime_disable(pdev-dev); err_req_irq: err_ioremap: vb2_dma_contig_cleanup_ctx(isi-alloc_ctx); @@ -1067,6 +1070,30 @@ err_alloc_ctx: return ret; } +static int atmel_isi_runtime_suspend(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + clk_disable_unprepare(isi-pclk); + + return 0; +} +static int atmel_isi_runtime_resume(struct device *dev) +{ + struct soc_camera_host *soc_host = to_soc_camera_host(dev); + struct atmel_isi *isi = container_of(soc_host, + struct atmel_isi, soc_host); + + return clk_prepare_enable(isi-pclk); +} + +static const struct dev_pm_ops atmel_isi_dev_pm_ops = { + SET_RUNTIME_PM_OPS(atmel_isi_runtime_suspend, + atmel_isi_runtime_resume, NULL) +}; + static const struct of_device_id atmel_isi_of_match[] = { { .compatible = atmel,at91sam9g45-isi }, { } @@ -1079,6 +1106,7 @@ static struct platform_driver atmel_isi_driver = { .name = atmel_isi, .owner = THIS_MODULE, .of_match_table = of_match_ptr(atmel_isi_of_match), + .pm = atmel_isi_dev_pm_ops, }, }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] media: atmel-isi: rework on the clock part and add runtime pm support
This patch series fix the peripheral clock code and enable runtime pm support. Aslo clean up the code which is for the compatiblity of mck. Josh Wu (3): media: atmel-isi: move the peripheral clock to start/stop_stream() function media: atmel-isi: add runtime pm support media: atmel-isi: remove mck back compatiable code as we don't need it drivers/media/platform/soc_camera/atmel-isi.c | 72 +-- 1 file changed, 34 insertions(+), 38 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] media: atmel-isi: remove mck back compatiable code as we don't need it
The master clock should handled by sensor itself. Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 32 --- 1 file changed, 32 deletions(-) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index 4a384f1..50375ce 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -83,8 +83,6 @@ struct atmel_isi { struct completion complete; /* ISI peripherial clock */ struct clk *pclk; - /* ISI_MCK, feed to camera sensor to generate pixel clock */ - struct clk *mck; unsigned intirq; struct isi_platform_datapdata; @@ -725,26 +723,12 @@ static void isi_camera_remove_device(struct soc_camera_device *icd) /* Called with .host_lock held */ static int isi_camera_clock_start(struct soc_camera_host *ici) { - struct atmel_isi *isi = ici-priv; - int ret; - - if (!IS_ERR(isi-mck)) { - ret = clk_prepare_enable(isi-mck); - if (ret) { - return ret; - } - } - return 0; } /* Called with .host_lock held */ static void isi_camera_clock_stop(struct soc_camera_host *ici) { - struct atmel_isi *isi = ici-priv; - - if (!IS_ERR(isi-mck)) - clk_disable_unprepare(isi-mck); } static unsigned int isi_camera_poll(struct file *file, poll_table *pt) @@ -894,7 +878,6 @@ static int atmel_isi_probe_dt(struct atmel_isi *isi, /* Default settings for ISI */ isi-pdata.full_mode = 1; - isi-pdata.mck_hz = ISI_DEFAULT_MCLK_FREQ; isi-pdata.frate = ISI_CFG1_FRATE_CAPTURE_ALL; np = of_graph_get_next_endpoint(np, NULL); @@ -970,21 +953,6 @@ static int atmel_isi_probe(struct platform_device *pdev) INIT_LIST_HEAD(isi-video_buffer_list); INIT_LIST_HEAD(isi-dma_desc_head); - /* ISI_MCK is the sensor master clock. It should be handled by the -* sensor driver directly, as the ISI has no use for that clock. Make -* the clock optional here while platforms transition to the correct -* model. -*/ - isi-mck = devm_clk_get(dev, isi_mck); - if (!IS_ERR(isi-mck)) { - /* Set ISI_MCK's frequency, it should be faster than pixel -* clock. -*/ - ret = clk_set_rate(isi-mck, isi-pdata.mck_hz); - if (ret 0) - return ret; - } - isi-p_fb_descriptors = dma_alloc_coherent(pdev-dev, sizeof(struct fbd) * MAX_BUFFER_NUM, isi-fb_descriptors_phys, -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 2/4] media: ov2640: add async probe function
On 3/2/2015 5:06 AM, Guennadi Liakhovetski wrote: Hi Josh, Thanks for a patch update. I think it looks good as a first step in your patch series, just a minor comment below: On Tue, 10 Feb 2015, Josh Wu wrote: In async probe, there is a case that ov2640 is probed before the host device which provided 'mclk'. To support this async probe, we will get 'mclk' at first in the probe(), if failed it will return -EPROBE_DEFER. That will let ov2640 wait for the host device probed. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5: - don't change the ov2640_s_power() code. - will get 'mclk' at the beginning of ov2640_probe(). Changes in v4: None Changes in v3: None Changes in v2: None drivers/media/i2c/soc_camera/ov2640.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 1fdce2f..057dd49 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -1068,6 +1068,10 @@ static int ov2640_probe(struct i2c_client *client, return -ENOMEM; } + priv-clk = v4l2_clk_get(client-dev, mclk); + if (IS_ERR(priv-clk)) + return -EPROBE_DEFER; + v4l2_i2c_subdev_init(priv-subdev, client, ov2640_subdev_ops); v4l2_ctrl_handler_init(priv-hdl, 2); v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, @@ -1075,24 +1079,28 @@ static int ov2640_probe(struct i2c_client *client, v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv-subdev.ctrl_handler = priv-hdl; - if (priv-hdl.error) - return priv-hdl.error; - - priv-clk = v4l2_clk_get(client-dev, mclk); - if (IS_ERR(priv-clk)) { - ret = PTR_ERR(priv-clk); - goto eclkget; + if (priv-hdl.error) { + ret = priv-hdl.error; + goto err_clk; } ret = ov2640_video_probe(client); if (ret) { - v4l2_clk_put(priv-clk); -eclkget: - v4l2_ctrl_handler_free(priv-hdl); + goto err_videoprobe; Since you add a goto here, you don't need an else after it, and the probed success message should go down, so, just make it ret = ov2640_video_probe(client); if (ret 0) goto err_videoprobe; ret = v4l2_async_register_subdev(priv-subdev); if (ret 0) goto err_videoprobe; dev_info(adapter-dev, OV2640 Probed\n); return 0; err_... Yes. This looks better. I'll update and resend this patch. This change is independent and no need to resend the whole patch series. Thanks. Best Regards, Josh Wu Thanks Guennadi } else { dev_info(adapter-dev, OV2640 Probed\n); } + ret = v4l2_async_register_subdev(priv-subdev); + if (ret 0) + goto err_videoprobe; + + return 0; + +err_videoprobe: + v4l2_ctrl_handler_free(priv-hdl); +err_clk: + v4l2_clk_put(priv-clk); return ret; } @@ -1100,6 +1108,7 @@ static int ov2640_remove(struct i2c_client *client) { struct ov2640_priv *priv = to_ov2640(client); + v4l2_async_unregister_subdev(priv-subdev); v4l2_clk_put(priv-clk); v4l2_device_unregister_subdev(priv-subdev); v4l2_ctrl_handler_free(priv-hdl); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/4][resend] media: ov2640: add async probe function
In async probe, there is a case that ov2640 is probed before the host device which provided 'mclk'. To support this async probe, we will get 'mclk' at first in the probe(), if failed it will return -EPROBE_DEFER. That will let ov2640 wait for the host device probed. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5 resend: - refine the error handling flow according to Guennadi's comment. Changes in v5: - don't change the ov2640_s_power() code. - will get 'mclk' at the beginning of ov2640_probe(). drivers/media/i2c/soc_camera/ov2640.c | 36 +-- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 1fdce2f..16adbcc 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -1068,6 +1068,10 @@ static int ov2640_probe(struct i2c_client *client, return -ENOMEM; } + priv-clk = v4l2_clk_get(client-dev, mclk); + if (IS_ERR(priv-clk)) + return -EPROBE_DEFER; + v4l2_i2c_subdev_init(priv-subdev, client, ov2640_subdev_ops); v4l2_ctrl_handler_init(priv-hdl, 2); v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, @@ -1075,24 +1079,27 @@ static int ov2640_probe(struct i2c_client *client, v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv-subdev.ctrl_handler = priv-hdl; - if (priv-hdl.error) - return priv-hdl.error; - - priv-clk = v4l2_clk_get(client-dev, mclk); - if (IS_ERR(priv-clk)) { - ret = PTR_ERR(priv-clk); - goto eclkget; + if (priv-hdl.error) { + ret = priv-hdl.error; + goto err_clk; } ret = ov2640_video_probe(client); - if (ret) { - v4l2_clk_put(priv-clk); -eclkget: - v4l2_ctrl_handler_free(priv-hdl); - } else { - dev_info(adapter-dev, OV2640 Probed\n); - } + if (ret 0) + goto err_videoprobe; + ret = v4l2_async_register_subdev(priv-subdev); + if (ret 0) + goto err_videoprobe; + + dev_info(adapter-dev, OV2640 Probed\n); + + return 0; + +err_videoprobe: + v4l2_ctrl_handler_free(priv-hdl); +err_clk: + v4l2_clk_put(priv-clk); return ret; } @@ -1100,6 +1107,7 @@ static int ov2640_remove(struct i2c_client *client) { struct ov2640_priv *priv = to_ov2640(client); + v4l2_async_unregister_subdev(priv-subdev); v4l2_clk_put(priv-clk); v4l2_device_unregister_subdev(priv-subdev); v4l2_ctrl_handler_free(priv-hdl); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v5 3/4] media: ov2640: add primary dt support
Hi, Prabhakar Lad On 2/17/2015 12:48 AM, Lad, Prabhakar wrote: Hi Josh, Thanks for the patch. On Tue, Feb 10, 2015 at 9:31 AM, Josh Wu josh...@atmel.com wrote: [Snip] - priv-clk = v4l2_clk_get(client-dev, mclk); + priv-clk = v4l2_clk_get(client-dev, xvclk); with this change don’t you need to update the board file using this driver/ the bridge driver ? I think no. First, my patch should be on top of the following two patches, which changed the *v4l2_clk_get()* behavior: [v3,1/2] V4L: remove clock name from v4l2_clk API https://patchwork.linuxtv.org/patch/28108/ [v4,2/2] V4L: add CCF support to the v4l2_clk API https://patchwork.linuxtv.org/patch/28111/ After applied above two patches, v4l2_clk_get() function is changed. The name mclk is refer to a CCF clock of the ov2640 device. If not found such a mclk CCF clock, v4l2_clk_get() will try to get the internal register clock in soc_camera.c. As the CCF dt clock is not support by ov2640 until I add DT support, that means current ov2640 driver will always not found the mclk CCF clock, and they will use internal clock. So after I changed the name mclk to xvclk, the default behavior will not change (still using internal clock registered by soc-camera.c). Best Regards, Josh Wu Regards, --Prabhakar Lad -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/4] media: ov2640: add device tree support
This patch series add device tree support for ov2640. And also add the document for the devicetree properties. v4-v5: 1. based on soc-camera v4l2-clk changes. 2. remove the master_clk related (one commit), we only have one clk. v3-v4: 1. refined the dt document. 2. Add Laurent's acked-by. v2-v3: 1. fix the gpiod_xxx api usage as we use reset pin as ACTIVE_LOW. 2. update the devicetree binding document. v1 - v2: 1. modified the dt bindings according to Laurent's suggestion. 2. add a fix patch for soc_camera. Otherwise the .reset() function won't work. Josh Wu (4): media: soc-camera: use icd-control instead of icd-pdev for reset() media: ov2640: add async probe function media: ov2640: add primary dt support media: ov2640: dt: add the device tree binding document .../devicetree/bindings/media/i2c/ov2640.txt | 46 drivers/media/i2c/soc_camera/ov2640.c | 117 ++--- drivers/media/platform/soc_camera/soc_camera.c | 8 +- 3 files changed, 152 insertions(+), 19 deletions(-) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2640.txt -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/4] media: ov2640: add async probe function
In async probe, there is a case that ov2640 is probed before the host device which provided 'mclk'. To support this async probe, we will get 'mclk' at first in the probe(), if failed it will return -EPROBE_DEFER. That will let ov2640 wait for the host device probed. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5: - don't change the ov2640_s_power() code. - will get 'mclk' at the beginning of ov2640_probe(). Changes in v4: None Changes in v3: None Changes in v2: None drivers/media/i2c/soc_camera/ov2640.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 1fdce2f..057dd49 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -1068,6 +1068,10 @@ static int ov2640_probe(struct i2c_client *client, return -ENOMEM; } + priv-clk = v4l2_clk_get(client-dev, mclk); + if (IS_ERR(priv-clk)) + return -EPROBE_DEFER; + v4l2_i2c_subdev_init(priv-subdev, client, ov2640_subdev_ops); v4l2_ctrl_handler_init(priv-hdl, 2); v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, @@ -1075,24 +1079,28 @@ static int ov2640_probe(struct i2c_client *client, v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0); priv-subdev.ctrl_handler = priv-hdl; - if (priv-hdl.error) - return priv-hdl.error; - - priv-clk = v4l2_clk_get(client-dev, mclk); - if (IS_ERR(priv-clk)) { - ret = PTR_ERR(priv-clk); - goto eclkget; + if (priv-hdl.error) { + ret = priv-hdl.error; + goto err_clk; } ret = ov2640_video_probe(client); if (ret) { - v4l2_clk_put(priv-clk); -eclkget: - v4l2_ctrl_handler_free(priv-hdl); + goto err_videoprobe; } else { dev_info(adapter-dev, OV2640 Probed\n); } + ret = v4l2_async_register_subdev(priv-subdev); + if (ret 0) + goto err_videoprobe; + + return 0; + +err_videoprobe: + v4l2_ctrl_handler_free(priv-hdl); +err_clk: + v4l2_clk_put(priv-clk); return ret; } @@ -1100,6 +1108,7 @@ static int ov2640_remove(struct i2c_client *client) { struct ov2640_priv *priv = to_ov2640(client); + v4l2_async_unregister_subdev(priv-subdev); v4l2_clk_put(priv-clk); v4l2_device_unregister_subdev(priv-subdev); v4l2_ctrl_handler_free(priv-hdl); -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 4/4] media: ov2640: dt: add the device tree binding document
Add the document for ov2640 dt. Cc: devicet...@vger.kernel.org Signed-off-by: Josh Wu josh...@atmel.com Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Acked-by: Sylwester Nawrocki s.nawro...@samsung.com --- Changes in v5: None Changes in v4: - remove aggsigned-clocks as it's general. - refine the explation. Changes in v3: - fix incorrect description. - Add assigned-clocks assigned-clock-rates. - resetb pin should be ACTIVE_LOW. Changes in v2: - change the compatible string to be consistent with verdor file. - change the clock and pins' name. - add missed pinctrl in example. .../devicetree/bindings/media/i2c/ov2640.txt | 46 ++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/ov2640.txt diff --git a/Documentation/devicetree/bindings/media/i2c/ov2640.txt b/Documentation/devicetree/bindings/media/i2c/ov2640.txt new file mode 100644 index 000..c429b5b --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/ov2640.txt @@ -0,0 +1,46 @@ +* Omnivision OV2640 CMOS sensor + +The Omnivision OV2640 sensor support multiple resolutions output, such as +CIF, SVGA, UXGA. It also can support YUV422/420, RGB565/555 or raw RGB +output format. + +Required Properties: +- compatible: should be ovti,ov2640 +- clocks: reference to the xvclk input clock. +- clock-names: should be xvclk. + +Optional Properties: +- resetb-gpios: reference to the GPIO connected to the resetb pin, if any. +- pwdn-gpios: reference to the GPIO connected to the pwdn pin, if any. + +The device node must contain one 'port' child node for its digital output +video port, in accordance with the video interface bindings defined in +Documentation/devicetree/bindings/media/video-interfaces.txt. + +Example: + + i2c1: i2c@f0018000 { + ov2640: camera@0x30 { + compatible = ovti,ov2640; + reg = 0x30; + + pinctrl-names = default; + pinctrl-0 = pinctrl_pck1 pinctrl_ov2640_pwdn pinctrl_ov2640_resetb; + + resetb-gpios = pioE 24 GPIO_ACTIVE_LOW; + pwdn-gpios = pioE 29 GPIO_ACTIVE_HIGH; + + clocks = pck1; + clock-names = xvclk; + + assigned-clocks = pck1; + assigned-clock-rates = 2500; + + port { + ov2640_0: endpoint { + remote-endpoint = isi_0; + bus-width = 8; + }; + }; + }; + }; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 3/4] media: ov2640: add primary dt support
Add device tree support for ov2640. In device tree, user needs to provide the master clock (xvclk). User can add the reset/pwdn pins if they have. Cc: devicet...@vger.kernel.org Signed-off-by: Josh Wu josh...@atmel.com Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- Changes in v5: - change the 'mclk' to 'xvclk'. As v4l2-clk will handle the CCF xvclk and v4l2 master clock internally. Changes in v4: - modify the code comment. - Add Laurent's acked by. Changes in v3: - fix gpiod usage. - refine the ov2640_probe() function. Changes in v2: - use gpiod APIs. - change the gpio pin's name according to datasheet. - reduce the delay for .reset() function. drivers/media/i2c/soc_camera/ov2640.c | 90 --- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 057dd49..c70e9e7 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -18,6 +18,8 @@ #include linux/i2c.h #include linux/slab.h #include linux/delay.h +#include linux/gpio.h +#include linux/of_gpio.h #include linux/v4l2-mediabus.h #include linux/videodev2.h @@ -283,6 +285,10 @@ struct ov2640_priv { u32 cfmt_code; struct v4l2_clk *clk; const struct ov2640_win_size*win; + + struct soc_camera_subdev_desc ssdd_dt; + struct gpio_desc *resetb_gpio; + struct gpio_desc *pwdn_gpio; }; /* @@ -1038,6 +1044,63 @@ static struct v4l2_subdev_ops ov2640_subdev_ops = { .video = ov2640_subdev_video_ops, }; +/* OF probe functions */ +static int ov2640_hw_power(struct device *dev, int on) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov2640_priv *priv = to_ov2640(client); + + dev_dbg(client-dev, %s: %s the camera\n, + __func__, on ? ENABLE : DISABLE); + + if (priv-pwdn_gpio) + gpiod_direction_output(priv-pwdn_gpio, !on); + + return 0; +} + +static int ov2640_hw_reset(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ov2640_priv *priv = to_ov2640(client); + + if (priv-resetb_gpio) { + /* Active the resetb pin to perform a reset pulse */ + gpiod_direction_output(priv-resetb_gpio, 1); + usleep_range(3000, 5000); + gpiod_direction_output(priv-resetb_gpio, 0); + } + + return 0; +} + +static int ov2640_probe_dt(struct i2c_client *client, + struct ov2640_priv *priv) +{ + /* Request the reset GPIO deasserted */ + priv-resetb_gpio = devm_gpiod_get_optional(client-dev, resetb, + GPIOD_OUT_LOW); + if (!priv-resetb_gpio) + dev_dbg(client-dev, resetb gpio is not assigned!\n); + else if (IS_ERR(priv-resetb_gpio)) + return PTR_ERR(priv-resetb_gpio); + + /* Request the power down GPIO asserted */ + priv-pwdn_gpio = devm_gpiod_get_optional(client-dev, pwdn, + GPIOD_OUT_HIGH); + if (!priv-pwdn_gpio) + dev_dbg(client-dev, pwdn gpio is not assigned!\n); + else if (IS_ERR(priv-pwdn_gpio)) + return PTR_ERR(priv-pwdn_gpio); + + /* Initialize the soc_camera_subdev_desc */ + priv-ssdd_dt.power = ov2640_hw_power; + priv-ssdd_dt.reset = ov2640_hw_reset; + client-dev.platform_data = priv-ssdd_dt; + + return 0; +} + /* * i2c_driver functions */ @@ -1049,12 +1112,6 @@ static int ov2640_probe(struct i2c_client *client, struct i2c_adapter *adapter = to_i2c_adapter(client-dev.parent); int ret; - if (!ssdd) { - dev_err(adapter-dev, - OV2640: Missing platform_data for driver\n); - return -EINVAL; - } - if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(adapter-dev, OV2640: I2C-Adapter doesn't support SMBUS\n); @@ -1068,10 +1125,22 @@ static int ov2640_probe(struct i2c_client *client, return -ENOMEM; } - priv-clk = v4l2_clk_get(client-dev, mclk); + priv-clk = v4l2_clk_get(client-dev, xvclk); if (IS_ERR(priv-clk)) return -EPROBE_DEFER; + if (!ssdd !client-dev.of_node) { + dev_err(client-dev, Missing platform_data for driver\n); + ret = -EINVAL; + goto err_clk; + } + + if (!ssdd) { + ret = ov2640_probe_dt(client, priv); + if (ret) + goto err_clk; + } + v4l2_i2c_subdev_init(priv-subdev, client, ov2640_subdev_ops); v4l2_ctrl_handler_init(priv-hdl, 2); v4l2_ctrl_new_std(priv-hdl, ov2640_ctrl_ops, @@ -1121,9 +1190,16 @@ static const struct i2c_device_id ov2640_id
[PATCH v5 1/4] media: soc-camera: use icd-control instead of icd-pdev for reset()
icd-control is the sub device dev, i.e. i2c device. icd-pdev is the soc camera device's device. To be consitent with power() function, we will call reset() with icd-control as well. Signed-off-by: Josh Wu josh...@atmel.com --- Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: None drivers/media/platform/soc_camera/soc_camera.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index f4be2a1..7e6b914 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -688,7 +688,8 @@ static int soc_camera_open(struct file *file) /* The camera could have been already on, try to reset */ if (sdesc-subdev_desc.reset) - sdesc-subdev_desc.reset(icd-pdev); + if (icd-control) + sdesc-subdev_desc.reset(icd-control); ret = soc_camera_add_device(icd); if (ret 0) { @@ -1175,7 +1176,8 @@ static void scan_add_host(struct soc_camera_host *ici) /* The camera could have been already on, try to reset */ if (ssdd-reset) - ssdd-reset(icd-pdev); + if (icd-control) + ssdd-reset(icd-control); icd-parent = ici-v4l2_dev.dev; @@ -1461,7 +1463,7 @@ static int soc_camera_async_bound(struct v4l2_async_notifier *notifier, memcpy(sdesc-subdev_desc, ssdd, sizeof(sdesc-subdev_desc)); if (ssdd-reset) - ssdd-reset(icd-pdev); + ssdd-reset(client-dev); } icd-control = client-dev; -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/2] V4L: add CCF support to the v4l2_clk API
Hi, Guennadi On 2/1/2015 7:12 PM, Guennadi Liakhovetski wrote: V4L2 clocks, e.g. used by camera sensors for their master clock, do not have to be supplied by a different V4L2 driver, they can also be supplied by an independent source. In this case the standart kernel clock API should be used to handle such clocks. This patch adds support for such cases. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de Acked-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Thanks for the patch. Tested-by: Josh Wu josh...@atmel.com Best Regards, Josh Wu --- v4: sizeof(*clk) :) drivers/media/v4l2-core/v4l2-clk.c | 48 +++--- include/media/v4l2-clk.h | 2 ++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index 3ff0b00..9f8cb20 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -9,6 +9,7 @@ */ #include linux/atomic.h +#include linux/clk.h #include linux/device.h #include linux/errno.h #include linux/list.h @@ -37,6 +38,21 @@ static struct v4l2_clk *v4l2_clk_find(const char *dev_id) struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) { struct v4l2_clk *clk; + struct clk *ccf_clk = clk_get(dev, id); + + if (PTR_ERR(ccf_clk) == -EPROBE_DEFER) + return ERR_PTR(-EPROBE_DEFER); + + if (!IS_ERR_OR_NULL(ccf_clk)) { + clk = kzalloc(sizeof(*clk), GFP_KERNEL); + if (!clk) { + clk_put(ccf_clk); + return ERR_PTR(-ENOMEM); + } + clk-clk = ccf_clk; + + return clk; + } mutex_lock(clk_lock); clk = v4l2_clk_find(dev_name(dev)); @@ -56,6 +72,12 @@ void v4l2_clk_put(struct v4l2_clk *clk) if (IS_ERR(clk)) return; + if (clk-clk) { + clk_put(clk-clk); + kfree(clk); + return; + } + mutex_lock(clk_lock); list_for_each_entry(tmp, clk_list, list) @@ -93,8 +115,12 @@ static void v4l2_clk_unlock_driver(struct v4l2_clk *clk) int v4l2_clk_enable(struct v4l2_clk *clk) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + if (clk-clk) + return clk_prepare_enable(clk-clk); + + ret = v4l2_clk_lock_driver(clk); if (ret 0) return ret; @@ -120,6 +146,9 @@ void v4l2_clk_disable(struct v4l2_clk *clk) { int enable; + if (clk-clk) + return clk_disable_unprepare(clk-clk); + mutex_lock(clk-lock); enable = --clk-enable; @@ -137,8 +166,12 @@ EXPORT_SYMBOL(v4l2_clk_disable); unsigned long v4l2_clk_get_rate(struct v4l2_clk *clk) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + + if (clk-clk) + return clk_get_rate(clk-clk); + ret = v4l2_clk_lock_driver(clk); if (ret 0) return ret; @@ -157,7 +190,16 @@ EXPORT_SYMBOL(v4l2_clk_get_rate); int v4l2_clk_set_rate(struct v4l2_clk *clk, unsigned long rate) { - int ret = v4l2_clk_lock_driver(clk); + int ret; + + if (clk-clk) { + long r = clk_round_rate(clk-clk, rate); + if (r 0) + return r; + return clk_set_rate(clk-clk, r); + } + + ret = v4l2_clk_lock_driver(clk); if (ret 0) return ret; diff --git a/include/media/v4l2-clk.h b/include/media/v4l2-clk.h index 928045f..3ef6e3d 100644 --- a/include/media/v4l2-clk.h +++ b/include/media/v4l2-clk.h @@ -22,6 +22,7 @@ struct module; struct device; +struct clk; struct v4l2_clk { struct list_head list; const struct v4l2_clk_ops *ops; @@ -29,6 +30,7 @@ struct v4l2_clk { int enable; struct mutex lock; /* Protect the enable count */ atomic_t use_count; + struct clk *clk; void *priv; }; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] media: atmel-isi: increase the burst length to improve the performance
Hi, Guennadi Ping? what about the status of this patch? Best Regards, Josh Wu On 11/25/2014 5:30 PM, Josh Wu wrote: The burst length could be BEATS_4/8/16. Before this patch, isi use default value BEATS_4. To imporve the performance we could set it to BEATS_16. Otherwise sometime it would cause the ISI overflow error. Reported-by: Bo Shen voice.s...@atmel.com Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 2 ++ include/media/atmel-isi.h | 4 2 files changed, 6 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ee5650f..fda587b 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -839,6 +839,8 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (isi-pdata.full_mode) cfg1 |= ISI_CFG1_FULL_MODE; + cfg1 |= ISI_CFG1_THMASK_BEATS_16; + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); diff --git a/include/media/atmel-isi.h b/include/media/atmel-isi.h index c2e5703..6008b09 100644 --- a/include/media/atmel-isi.h +++ b/include/media/atmel-isi.h @@ -59,6 +59,10 @@ #define ISI_CFG1_FRATE_DIV_MASK (7 8) #define ISI_CFG1_DISCR(1 11) #define ISI_CFG1_FULL_MODE(1 12) +/* Definition for THMASK(ISI_V2) */ +#defineISI_CFG1_THMASK_BEATS_4 (0 13) +#defineISI_CFG1_THMASK_BEATS_8 (1 13) +#defineISI_CFG1_THMASK_BEATS_16(2 13) /* Bitfields in CFG2 */ #define ISI_CFG2_GRAYSCALE(1 13) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/2] V4L: remove clock name from v4l2_clk API
Hi, Guennadi On 2/1/2015 7:21 AM, Guennadi Liakhovetski wrote: All uses of the v4l2_clk API so far only register one clock with a fixed name. This allows us to get rid of it, which also will make CCF and DT integration easier. Signed-off-by: Guennadi Liakhovetski g.liakhovet...@gmx.de --- Thanks for the patch. Tested-by: Josh Wu josh...@atmel.com Best Regards, Josh Wu v3: .id field removed from the struct. Since CCF clocks won't be added to the V4L2 clock list at all in patch 2 in this series, no clock ID comparison is needed in v4l2_clk_find() either. drivers/media/platform/soc_camera/soc_camera.c | 6 ++--- drivers/media/usb/em28xx/em28xx-camera.c | 2 +- drivers/media/v4l2-core/v4l2-clk.c | 33 ++ include/media/v4l2-clk.h | 8 +++ 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index f4be2a1..ce192b6 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -1380,7 +1380,7 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd, snprintf(clk_name, sizeof(clk_name), %d-%04x, shd-i2c_adapter_id, shd-board_info-addr); - icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, mclk, icd); + icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, icd); if (IS_ERR(icd-clk)) { ret = PTR_ERR(icd-clk); goto eclkreg; @@ -1561,7 +1561,7 @@ static int scan_async_group(struct soc_camera_host *ici, snprintf(clk_name, sizeof(clk_name), %d-%04x, sasd-asd.match.i2c.adapter_id, sasd-asd.match.i2c.address); - icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, mclk, icd); + icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, icd); if (IS_ERR(icd-clk)) { ret = PTR_ERR(icd-clk); goto eclkreg; @@ -1666,7 +1666,7 @@ static int soc_of_bind(struct soc_camera_host *ici, snprintf(clk_name, sizeof(clk_name), of-%s, of_node_full_name(remote)); - icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, mclk, icd); + icd-clk = v4l2_clk_register(soc_camera_clk_ops, clk_name, icd); if (IS_ERR(icd-clk)) { ret = PTR_ERR(icd-clk); goto eclkreg; diff --git a/drivers/media/usb/em28xx/em28xx-camera.c b/drivers/media/usb/em28xx/em28xx-camera.c index 7be661f..a4b22c2 100644 --- a/drivers/media/usb/em28xx/em28xx-camera.c +++ b/drivers/media/usb/em28xx/em28xx-camera.c @@ -330,7 +330,7 @@ int em28xx_init_camera(struct em28xx *dev) v4l2_clk_name_i2c(clk_name, sizeof(clk_name), i2c_adapter_id(adap), client-addr); - v4l2-clk = v4l2_clk_register_fixed(clk_name, mclk, -EINVAL); + v4l2-clk = v4l2_clk_register_fixed(clk_name, -EINVAL); if (IS_ERR(v4l2-clk)) return PTR_ERR(v4l2-clk); diff --git a/drivers/media/v4l2-core/v4l2-clk.c b/drivers/media/v4l2-core/v4l2-clk.c index e18cc04..3ff0b00 100644 --- a/drivers/media/v4l2-core/v4l2-clk.c +++ b/drivers/media/v4l2-core/v4l2-clk.c @@ -23,17 +23,13 @@ static DEFINE_MUTEX(clk_lock); static LIST_HEAD(clk_list); -static struct v4l2_clk *v4l2_clk_find(const char *dev_id, const char *id) +static struct v4l2_clk *v4l2_clk_find(const char *dev_id) { struct v4l2_clk *clk; - list_for_each_entry(clk, clk_list, list) { - if (strcmp(dev_id, clk-dev_id)) - continue; - - if (!id || !clk-id || !strcmp(clk-id, id)) + list_for_each_entry(clk, clk_list, list) + if (!strcmp(dev_id, clk-dev_id)) return clk; - } return ERR_PTR(-ENODEV); } @@ -43,7 +39,7 @@ struct v4l2_clk *v4l2_clk_get(struct device *dev, const char *id) struct v4l2_clk *clk; mutex_lock(clk_lock); - clk = v4l2_clk_find(dev_name(dev), id); + clk = v4l2_clk_find(dev_name(dev)); if (!IS_ERR(clk)) atomic_inc(clk-use_count); @@ -127,8 +123,8 @@ void v4l2_clk_disable(struct v4l2_clk *clk) mutex_lock(clk-lock); enable = --clk-enable; - if (WARN(enable 0, Unbalanced %s() on %s:%s!\n, __func__, -clk-dev_id, clk-id)) + if (WARN(enable 0, Unbalanced %s() on %s!\n, __func__, +clk-dev_id)) clk-enable++; else if (!enable clk-ops-disable) clk-ops-disable(clk); @@ -181,7 +177,7 @@ EXPORT_SYMBOL(v4l2_clk_set_rate); struct v4l2_clk *v4l2_clk_register(const struct v4l2_clk_ops *ops, const char *dev_id, - const char *id, void *priv) + void *priv) { struct v4l2_clk *clk; int ret; @@ -193,9
Re: [PATCH] media: atmel-isi: increase the burst length to improve the performance
Hi, Guennadi On 2/2/2015 6:22 PM, Guennadi Liakhovetski wrote: Hi Josh, On Mon, 2 Feb 2015, Josh Wu wrote: Hi, Guennadi Ping? what about the status of this patch? Right, got lost, sorry... Added to the queue now. Thank you. Best Regards, Josh Wu Thanks Guennadi Best Regards, Josh Wu On 11/25/2014 5:30 PM, Josh Wu wrote: The burst length could be BEATS_4/8/16. Before this patch, isi use default value BEATS_4. To imporve the performance we could set it to BEATS_16. Otherwise sometime it would cause the ISI overflow error. Reported-by: Bo Shen voice.s...@atmel.com Signed-off-by: Josh Wu josh...@atmel.com --- drivers/media/platform/soc_camera/atmel-isi.c | 2 ++ include/media/atmel-isi.h | 4 2 files changed, 6 insertions(+) diff --git a/drivers/media/platform/soc_camera/atmel-isi.c b/drivers/media/platform/soc_camera/atmel-isi.c index ee5650f..fda587b 100644 --- a/drivers/media/platform/soc_camera/atmel-isi.c +++ b/drivers/media/platform/soc_camera/atmel-isi.c @@ -839,6 +839,8 @@ static int isi_camera_set_bus_param(struct soc_camera_device *icd) if (isi-pdata.full_mode) cfg1 |= ISI_CFG1_FULL_MODE; +cfg1 |= ISI_CFG1_THMASK_BEATS_16; + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); isi_writel(isi, ISI_CFG1, cfg1); diff --git a/include/media/atmel-isi.h b/include/media/atmel-isi.h index c2e5703..6008b09 100644 --- a/include/media/atmel-isi.h +++ b/include/media/atmel-isi.h @@ -59,6 +59,10 @@ #define ISI_CFG1_FRATE_DIV_MASK (7 8) #define ISI_CFG1_DISCR (1 11) #define ISI_CFG1_FULL_MODE (1 12) +/* Definition for THMASK(ISI_V2) */ +#defineISI_CFG1_THMASK_BEATS_4 (0 13) +#defineISI_CFG1_THMASK_BEATS_8 (1 13) +#defineISI_CFG1_THMASK_BEATS_16(2 13) /* Bitfields in CFG2 */ #define ISI_CFG2_GRAYSCALE (1 13) -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] media: v4l2-image-sizes.h: add SVGA, XGA and UXGA size definitions
Hi, Guennadi On 11/28/2014 4:13 AM, Guennadi Liakhovetski wrote: Hi Josh, On Thu, 27 Nov 2014, Josh Wu wrote: Hi, Guennadi On 11/26/2014 6:23 AM, Guennadi Liakhovetski wrote: Hi Josh, On Tue, 25 Nov 2014, Josh Wu wrote: Add SVGA, UXGA and XGA size definitions to v4l2-image-sizes.h. The definitions are sorted by alphabet order. Signed-off-by: Josh Wu josh...@atmel.com Thanks for your patches. I'm ok with these two, but the second of them depends on the first one, and the first one wouldn't (normally) be going via the soc-camera tree. Mauro, how would you prefer to handle this? Should I pick up and push to you both of them or postpone #2 until the next merge window? The first patch is already merged in the media_tree. If the soc-camera tree will be merged to the media_tree, then there should have no dependency issue. Am I understanding correct? Yes, then it should be ok! Just checking the status of this patch. I don't found this patch in media's tree or soc_camera's tree. Could you take this patch in your tree? Best Regards, Josh Wu Thanks Guennadi Best Regards, Josh Wu Thanks Guennadi --- include/media/v4l2-image-sizes.h | 9 + 1 file changed, 9 insertions(+) diff --git a/include/media/v4l2-image-sizes.h b/include/media/v4l2-image-sizes.h index 10daf92..c70c917 100644 --- a/include/media/v4l2-image-sizes.h +++ b/include/media/v4l2-image-sizes.h @@ -25,10 +25,19 @@ #define QVGA_WIDTH 320 #define QVGA_HEIGHT 240 +#define SVGA_WIDTH 800 +#define SVGA_HEIGHT680 + #define SXGA_WIDTH 1280 #define SXGA_HEIGHT 1024 #define VGA_WIDTH 640 #define VGA_HEIGHT 480 +#define UXGA_WIDTH 1600 +#define UXGA_HEIGHT1200 + +#define XGA_WIDTH 1024 +#define XGA_HEIGHT 768 + #endif /* _IMAGE_SIZES_H */ -- 1.9.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] V4L: remove clock name from v4l2_clk API
On 1/12/2015 6:38 PM, Laurent Pinchart wrote: Hi Josh, On Monday 12 January 2015 17:14:33 Josh Wu wrote: On 1/9/2015 6:47 AM, Laurent Pinchart wrote: On Thursday 08 January 2015 23:37:58 Guennadi Liakhovetski wrote: On Wed, 7 Jan 2015, Josh Wu wrote: On 1/7/2015 6:17 AM, Guennadi Liakhovetski wrote: On Tue, 6 Jan 2015, Josh Wu wrote: Hi, Guennadi After look deep into this patch, I found you miss one line that should be changed as well. It's In function v4l2_clk_get(), there still has one line code called v4l2_clk_find(dev_id, id). You need to change it to v4l2_clk_find(dev_id, NULL) as well. Otherwise the code that many sensor used: v4l2_clk_get(client-dev, mclk) cannot acquired the mclk clock. After above changes, this patch works for me. I think you're right, in fact, since we now don't store CCF-based v4l2_clk wrappers on the list, this can be simplified even further, I'll update the patch. Did you only test this patch or both? I tested both patches with Atmel-isi driver. For the 2/2 patch I applied the modification Laurent suggested. Those patches works for me. The only concern is in ov2640 I still need to acquired two v4l2 clocks: xvclk that will get the xvclk CCF clock directly. mclk that make ISI driver call his clock_start()/stop() to enable/disable ISI's peripheral clock. If I only get xvclk clock, then the camera capture will be failed with a ISI timeout error. No, this doesn't look right to me. The camera sensor has only one clock input, so, it should only request one clock. Where does the clock signal to the camera come from on your system? That's correct, the sensor driver only has one clock input, so it should just request the xvclk clock. If it comes from the ISI itself, you don't need to specify the clock in the DT, since the ISI doesn't produce a clock from DT. If you do want to have your clock consumer (ov2640) and the supplier (ISI) properly described in DT, you'll have to teach the ISI to register a CCF clock source, which then will be connected to from the ov2640. If you choose not to show your clock in the DT, you can just use v4l2_clk_get(dev, xvclk) and it will be handled by v4l2_clk / soc-camera / isi-atmel. If the closk to ov2640 is supplied by a separate clock source, then you v4l2_clk_get() will connect ov2640 to it directly and soc-camera will enable and disable it on power-on / -off as required. The ISI has no way to supply a sensor clock, the clock is supplied by a separate clock source. From your above description it looks like the clock to ov2640 is supplied by a separate source, but atmel-isi's .clock_start() / .clock_stop() functions still need to be called? By looking at those functions it looks like they turn on and off clocks, supplying the ISI itself... Instead of only turning on and off clocks, provided by the ISI to a camera sensor. If my understanding is right, then this is a bug in atmel-isi and it has to be fixed. That's correct as well, the ISI driver needs to be fixed. Thanks both of you for the details. Now I got it. Indeed, I need fix this in atmel-isi driver not in ov2640 driver. So I will send a new patch for this, which should move the ISI peripheral clock enable/disable() from clock_start/stop() to isi_camera_add_device/remove_device(). Shouldn't you move it to the start_streaming() and stop_streaming() functions instead ? An even better solution would be to use runtime PM to enable/disable the ISI clock in the runtime PM resume and suspend handlers, and call pm_runtime_get_sync() and pm_runtime_put() when you need the ISI to be operational. Okay, I'll try to add the PM functions for atmel-isi in the meantime. Best Regards, Josh Wu -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html