aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 05:12:35 -0400
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-21 05:12:35 -0400
commit676ee36be04985062522804c2de04f0764212be6 (patch)
tree781df135c5a91a04decad1b7d53b5a925dc11522 /drivers/media/platform
parentb18042a673e88c9457a6d1716219c2367ca447b0 (diff)
parente183201b9e917daf2530b637b2f34f1d5afb934d (diff)
Merge branch 'patchwork' into v4l_for_linus
* patchwork: (404 commits) [media] uvcvideo: add support for VIDIOC_QUERY_EXT_CTRL [media] uvcvideo: fix cropcap v4l2-compliance failure [media] media: omap3isp: remove unused clkdev [media] coda: Add tracing support [media] coda: drop dma_sync_single_for_device in coda_bitstream_queue [media] coda: fix fill bitstream errors in nonstreaming case [media] coda: call SEQ_END when the first queue is stopped [media] coda: fail to start streaming if userspace set invalid formats [media] coda: remove duplicate error messages for buffer allocations [media] coda: move parameter buffer in together with context buffer allocation [media] coda: allocate bitstream buffer from REQBUFS, size depends on the format [media] coda: allocate per-context buffers from REQBUFS [media] coda: use strlcpy instead of snprintf [media] coda: bitstream payload is unsigned [media] coda: fix double call to debugfs_remove [media] coda: check kasprintf return value in coda_open [media] coda: bitrate can only be set in kbps steps [media] v4l2-mem2mem: no need to initialize b in v4l2_m2m_next_buf and v4l2_m2m_buf_remove [media] s5p-mfc: set allow_zero_bytesused flag for vb2_queue_init [media] coda: set allow_zero_bytesused flag for vb2_queue_init ...
Diffstat (limited to 'drivers/media/platform')
-rw-r--r--drivers/media/platform/Kconfig4
-rw-r--r--drivers/media/platform/Makefile2
-rw-r--r--drivers/media/platform/am437x/Kconfig2
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.c59
-rw-r--r--drivers/media/platform/am437x/am437x-vpfe.h3
-rw-r--r--drivers/media/platform/blackfin/bfin_capture.c348
-rw-r--r--drivers/media/platform/coda/Makefile2
-rw-r--r--drivers/media/platform/coda/coda-bit.c205
-rw-r--r--drivers/media/platform/coda/coda-common.c113
-rw-r--r--drivers/media/platform/coda/coda-jpeg.c1
-rw-r--r--drivers/media/platform/coda/coda.h18
-rw-r--r--drivers/media/platform/coda/trace.h203
-rw-r--r--drivers/media/platform/davinci/vpfe_capture.c26
-rw-r--r--drivers/media/platform/davinci/vpif_capture.c52
-rw-r--r--drivers/media/platform/davinci/vpif_capture.h2
-rw-r--r--drivers/media/platform/davinci/vpif_display.c49
-rw-r--r--drivers/media/platform/davinci/vpif_display.h2
-rw-r--r--drivers/media/platform/exynos4-is/fimc-capture.c22
-rw-r--r--drivers/media/platform/exynos4-is/fimc-isp.c28
-rw-r--r--drivers/media/platform/exynos4-is/fimc-lite.c33
-rw-r--r--drivers/media/platform/exynos4-is/mipi-csis.c16
-rw-r--r--drivers/media/platform/m2m-deinterlace.c21
-rw-r--r--drivers/media/platform/marvell-ccic/mcam-core.c48
-rw-r--r--drivers/media/platform/omap/omap_vout.c2
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.c1
-rw-r--r--drivers/media/platform/omap/omap_vout_vrfb.h4
-rw-r--r--drivers/media/platform/omap3isp/isp.c563
-rw-r--r--drivers/media/platform/omap3isp/isp.h43
-rw-r--r--drivers/media/platform/omap3isp/ispccdc.c112
-rw-r--r--drivers/media/platform/omap3isp/ispccp2.c68
-rw-r--r--drivers/media/platform/omap3isp/ispcsi2.c56
-rw-r--r--drivers/media/platform/omap3isp/ispcsiphy.c48
-rw-r--r--drivers/media/platform/omap3isp/isph3a_aewb.c1
-rw-r--r--drivers/media/platform/omap3isp/isph3a_af.c1
-rw-r--r--drivers/media/platform/omap3isp/isphist.c127
-rw-r--r--drivers/media/platform/omap3isp/isppreview.c70
-rw-r--r--drivers/media/platform/omap3isp/ispresizer.c80
-rw-r--r--drivers/media/platform/omap3isp/ispstat.c2
-rw-r--r--drivers/media/platform/omap3isp/ispstat.h5
-rw-r--r--drivers/media/platform/omap3isp/ispvideo.c20
-rw-r--r--drivers/media/platform/s3c-camif/camif-capture.c18
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c63
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h12
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c32
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h3
-rw-r--r--drivers/media/platform/s5p-mfc/s5p_mfc.c7
-rw-r--r--drivers/media/platform/s5p-tv/mixer_video.c2
-rw-r--r--drivers/media/platform/sh_vou.c30
-rw-r--r--drivers/media/platform/soc_camera/rcar_vin.c15
-rw-r--r--drivers/media/platform/soc_camera/sh_mobile_csi2.c1
-rw-r--r--drivers/media/platform/soc_camera/soc_camera.c108
-rw-r--r--drivers/media/platform/via-camera.c15
-rw-r--r--drivers/media/platform/vim2m.c23
-rw-r--r--drivers/media/platform/vivid/vivid-core.c93
-rw-r--r--drivers/media/platform/vivid/vivid-core.h8
-rw-r--r--drivers/media/platform/vivid/vivid-ctrls.c2
-rw-r--r--drivers/media/platform/vivid/vivid-kthread-cap.c125
-rw-r--r--drivers/media/platform/vivid/vivid-sdr-cap.c66
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.c1082
-rw-r--r--drivers/media/platform/vivid/vivid-tpg.h112
-rw-r--r--drivers/media/platform/vivid/vivid-vid-cap.c180
-rw-r--r--drivers/media/platform/vivid/vivid-vid-common.c378
-rw-r--r--drivers/media/platform/vivid/vivid-vid-out.c85
-rw-r--r--drivers/media/platform/vsp1/vsp1_bru.c42
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.c16
-rw-r--r--drivers/media/platform/vsp1/vsp1_entity.h4
-rw-r--r--drivers/media/platform/vsp1/vsp1_hsit.c18
-rw-r--r--drivers/media/platform/vsp1/vsp1_lif.c22
-rw-r--r--drivers/media/platform/vsp1/vsp1_lut.c22
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.c37
-rw-r--r--drivers/media/platform/vsp1/vsp1_rwpf.h12
-rw-r--r--drivers/media/platform/vsp1/vsp1_sru.c30
-rw-r--r--drivers/media/platform/vsp1/vsp1_uds.c30
-rw-r--r--drivers/media/platform/xilinx/Kconfig23
-rw-r--r--drivers/media/platform/xilinx/Makefile5
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.c766
-rw-r--r--drivers/media/platform/xilinx/xilinx-dma.h109
-rw-r--r--drivers/media/platform/xilinx/xilinx-tpg.c931
-rw-r--r--drivers/media/platform/xilinx/xilinx-vip.c323
-rw-r--r--drivers/media/platform/xilinx/xilinx-vip.h238
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.c669
-rw-r--r--drivers/media/platform/xilinx/xilinx-vipp.h49
-rw-r--r--drivers/media/platform/xilinx/xilinx-vtc.c380
-rw-r--r--drivers/media/platform/xilinx/xilinx-vtc.h42
84 files changed, 6866 insertions, 1824 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index d9b872b9285a..421f53188c6c 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -56,7 +56,7 @@ config VIDEO_VIU
56 56
57config VIDEO_TIMBERDALE 57config VIDEO_TIMBERDALE
58 tristate "Support for timberdale Video In/LogiWIN" 58 tristate "Support for timberdale Video In/LogiWIN"
59 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API 59 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && HAS_DMA
60 depends on (MFD_TIMBERDALE && TIMB_DMA) || COMPILE_TEST 60 depends on (MFD_TIMBERDALE && TIMB_DMA) || COMPILE_TEST
61 select VIDEO_ADV7180 61 select VIDEO_ADV7180
62 select VIDEOBUF_DMA_CONTIG 62 select VIDEOBUF_DMA_CONTIG
@@ -90,6 +90,7 @@ config VIDEO_OMAP3
90 select ARM_DMA_USE_IOMMU 90 select ARM_DMA_USE_IOMMU
91 select OMAP_IOMMU 91 select OMAP_IOMMU
92 select VIDEOBUF2_DMA_CONTIG 92 select VIDEOBUF2_DMA_CONTIG
93 select MFD_SYSCON
93 ---help--- 94 ---help---
94 Driver for an OMAP 3 camera controller. 95 Driver for an OMAP 3 camera controller.
95 96
@@ -117,6 +118,7 @@ source "drivers/media/platform/soc_camera/Kconfig"
117source "drivers/media/platform/exynos4-is/Kconfig" 118source "drivers/media/platform/exynos4-is/Kconfig"
118source "drivers/media/platform/s5p-tv/Kconfig" 119source "drivers/media/platform/s5p-tv/Kconfig"
119source "drivers/media/platform/am437x/Kconfig" 120source "drivers/media/platform/am437x/Kconfig"
121source "drivers/media/platform/xilinx/Kconfig"
120 122
121endif # V4L_PLATFORM_DRIVERS 123endif # V4L_PLATFORM_DRIVERS
122 124
diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile
index 3ec154742083..8f855616c237 100644
--- a/drivers/media/platform/Makefile
+++ b/drivers/media/platform/Makefile
@@ -48,4 +48,6 @@ obj-y += omap/
48 48
49obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/ 49obj-$(CONFIG_VIDEO_AM437X_VPFE) += am437x/
50 50
51obj-$(CONFIG_VIDEO_XILINX) += xilinx/
52
51ccflags-y += -I$(srctree)/drivers/media/i2c 53ccflags-y += -I$(srctree)/drivers/media/i2c
diff --git a/drivers/media/platform/am437x/Kconfig b/drivers/media/platform/am437x/Kconfig
index 7b023a76e32e..42d9c186710a 100644
--- a/drivers/media/platform/am437x/Kconfig
+++ b/drivers/media/platform/am437x/Kconfig
@@ -1,6 +1,6 @@
1config VIDEO_AM437X_VPFE 1config VIDEO_AM437X_VPFE
2 tristate "TI AM437x VPFE video capture driver" 2 tristate "TI AM437x VPFE video capture driver"
3 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API 3 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
4 depends on SOC_AM43XX || COMPILE_TEST 4 depends on SOC_AM43XX || COMPILE_TEST
5 select VIDEOBUF2_DMA_CONTIG 5 select VIDEOBUF2_DMA_CONTIG
6 help 6 help
diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c
index 56a5cb0d2152..4899924ea926 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.c
+++ b/drivers/media/platform/am437x/am437x-vpfe.c
@@ -1645,6 +1645,7 @@ static int vpfe_enum_size(struct file *file, void *priv,
1645 fse.index = fsize->index; 1645 fse.index = fsize->index;
1646 fse.pad = 0; 1646 fse.pad = 0;
1647 fse.code = mbus.code; 1647 fse.code = mbus.code;
1648 fse.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1648 ret = v4l2_subdev_call(sdinfo->sd, pad, enum_frame_size, NULL, &fse); 1649 ret = v4l2_subdev_call(sdinfo->sd, pad, enum_frame_size, NULL, &fse);
1649 if (ret) 1650 if (ret)
1650 return -EINVAL; 1651 return -EINVAL;
@@ -1700,11 +1701,16 @@ static int vpfe_get_app_input_index(struct vpfe_device *vpfe,
1700{ 1701{
1701 struct vpfe_config *cfg = vpfe->cfg; 1702 struct vpfe_config *cfg = vpfe->cfg;
1702 struct vpfe_subdev_info *sdinfo; 1703 struct vpfe_subdev_info *sdinfo;
1704 struct i2c_client *client;
1705 struct i2c_client *curr_client;
1703 int i, j = 0; 1706 int i, j = 0;
1704 1707
1708 curr_client = v4l2_get_subdevdata(vpfe->current_subdev->sd);
1705 for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { 1709 for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
1706 sdinfo = &cfg->sub_devs[i]; 1710 sdinfo = &cfg->sub_devs[i];
1707 if (!strcmp(sdinfo->name, vpfe->current_subdev->name)) { 1711 client = v4l2_get_subdevdata(sdinfo->sd);
1712 if (client->addr == curr_client->addr &&
1713 client->adapter->nr == client->adapter->nr) {
1708 if (vpfe->current_input >= 1) 1714 if (vpfe->current_input >= 1)
1709 return -1; 1715 return -1;
1710 *app_input_index = j + vpfe->current_input; 1716 *app_input_index = j + vpfe->current_input;
@@ -2296,20 +2302,10 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
2296 vpfe_dbg(1, vpfe, "vpfe_async_bound\n"); 2302 vpfe_dbg(1, vpfe, "vpfe_async_bound\n");
2297 2303
2298 for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) { 2304 for (i = 0; i < ARRAY_SIZE(vpfe->cfg->asd); i++) {
2299 sdinfo = &vpfe->cfg->sub_devs[i]; 2305 if (vpfe->cfg->asd[i]->match.of.node == asd[i].match.of.node) {
2300 2306 sdinfo = &vpfe->cfg->sub_devs[i];
2301 if (!strcmp(sdinfo->name, subdev->name)) {
2302 vpfe->sd[i] = subdev; 2307 vpfe->sd[i] = subdev;
2303 vpfe_info(vpfe, 2308 vpfe->sd[i]->grp_id = sdinfo->grp_id;
2304 "v4l2 sub device %s registered\n",
2305 subdev->name);
2306 vpfe->sd[i]->grp_id =
2307 sdinfo->grp_id;
2308 /* update tvnorms from the sub devices */
2309 for (j = 0; j < 1; j++)
2310 vpfe->video_dev->tvnorms |=
2311 sdinfo->inputs[j].std;
2312
2313 found = true; 2309 found = true;
2314 break; 2310 break;
2315 } 2311 }
@@ -2320,6 +2316,8 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
2320 return -EINVAL; 2316 return -EINVAL;
2321 } 2317 }
2322 2318
2319 vpfe->video_dev.tvnorms |= sdinfo->inputs[0].std;
2320
2323 /* setup the supported formats & indexes */ 2321 /* setup the supported formats & indexes */
2324 for (j = 0, i = 0; ; ++j) { 2322 for (j = 0, i = 0; ; ++j) {
2325 struct vpfe_fmt *fmt; 2323 struct vpfe_fmt *fmt;
@@ -2327,6 +2325,7 @@ vpfe_async_bound(struct v4l2_async_notifier *notifier,
2327 2325
2328 memset(&mbus_code, 0, sizeof(mbus_code)); 2326 memset(&mbus_code, 0, sizeof(mbus_code));
2329 mbus_code.index = j; 2327 mbus_code.index = j;
2328 mbus_code.which = V4L2_SUBDEV_FORMAT_ACTIVE;
2330 ret = v4l2_subdev_call(subdev, pad, enum_mbus_code, 2329 ret = v4l2_subdev_call(subdev, pad, enum_mbus_code,
2331 NULL, &mbus_code); 2330 NULL, &mbus_code);
2332 if (ret) 2331 if (ret)
@@ -2390,9 +2389,9 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe)
2390 2389
2391 INIT_LIST_HEAD(&vpfe->dma_queue); 2390 INIT_LIST_HEAD(&vpfe->dma_queue);
2392 2391
2393 vdev = vpfe->video_dev; 2392 vdev = &vpfe->video_dev;
2394 strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name)); 2393 strlcpy(vdev->name, VPFE_MODULE_NAME, sizeof(vdev->name));
2395 vdev->release = video_device_release; 2394 vdev->release = video_device_release_empty;
2396 vdev->fops = &vpfe_fops; 2395 vdev->fops = &vpfe_fops;
2397 vdev->ioctl_ops = &vpfe_ioctl_ops; 2396 vdev->ioctl_ops = &vpfe_ioctl_ops;
2398 vdev->v4l2_dev = &vpfe->v4l2_dev; 2397 vdev->v4l2_dev = &vpfe->v4l2_dev;
@@ -2400,7 +2399,7 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe)
2400 vdev->queue = q; 2399 vdev->queue = q;
2401 vdev->lock = &vpfe->lock; 2400 vdev->lock = &vpfe->lock;
2402 video_set_drvdata(vdev, vpfe); 2401 video_set_drvdata(vdev, vpfe);
2403 err = video_register_device(vpfe->video_dev, VFL_TYPE_GRABBER, -1); 2402 err = video_register_device(&vpfe->video_dev, VFL_TYPE_GRABBER, -1);
2404 if (err) { 2403 if (err) {
2405 vpfe_err(vpfe, 2404 vpfe_err(vpfe,
2406 "Unable to register video device.\n"); 2405 "Unable to register video device.\n");
@@ -2425,7 +2424,7 @@ static int vpfe_async_complete(struct v4l2_async_notifier *notifier)
2425static struct vpfe_config * 2424static struct vpfe_config *
2426vpfe_get_pdata(struct platform_device *pdev) 2425vpfe_get_pdata(struct platform_device *pdev)
2427{ 2426{
2428 struct device_node *endpoint = NULL, *rem = NULL; 2427 struct device_node *endpoint = NULL;
2429 struct v4l2_of_endpoint bus_cfg; 2428 struct v4l2_of_endpoint bus_cfg;
2430 struct vpfe_subdev_info *sdinfo; 2429 struct vpfe_subdev_info *sdinfo;
2431 struct vpfe_config *pdata; 2430 struct vpfe_config *pdata;
@@ -2443,6 +2442,8 @@ vpfe_get_pdata(struct platform_device *pdev)
2443 return NULL; 2442 return NULL;
2444 2443
2445 for (i = 0; ; i++) { 2444 for (i = 0; ; i++) {
2445 struct device_node *rem;
2446
2446 endpoint = of_graph_get_next_endpoint(pdev->dev.of_node, 2447 endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
2447 endpoint); 2448 endpoint);
2448 if (!endpoint) 2449 if (!endpoint)
@@ -2497,11 +2498,15 @@ vpfe_get_pdata(struct platform_device *pdev)
2497 goto done; 2498 goto done;
2498 } 2499 }
2499 2500
2500 strncpy(sdinfo->name, rem->name, sizeof(sdinfo->name));
2501
2502 pdata->asd[i] = devm_kzalloc(&pdev->dev, 2501 pdata->asd[i] = devm_kzalloc(&pdev->dev,
2503 sizeof(struct v4l2_async_subdev), 2502 sizeof(struct v4l2_async_subdev),
2504 GFP_KERNEL); 2503 GFP_KERNEL);
2504 if (!pdata->asd[i]) {
2505 of_node_put(rem);
2506 pdata = NULL;
2507 goto done;
2508 }
2509
2505 pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF; 2510 pdata->asd[i]->match_type = V4L2_ASYNC_MATCH_OF;
2506 pdata->asd[i]->match.of.node = rem; 2511 pdata->asd[i]->match.of.node = rem;
2507 of_node_put(endpoint); 2512 of_node_put(endpoint);
@@ -2513,7 +2518,6 @@ vpfe_get_pdata(struct platform_device *pdev)
2513 2518
2514done: 2519done:
2515 of_node_put(endpoint); 2520 of_node_put(endpoint);
2516 of_node_put(rem);
2517 return NULL; 2521 return NULL;
2518} 2522}
2519 2523
@@ -2561,17 +2565,11 @@ static int vpfe_probe(struct platform_device *pdev)
2561 return -EINVAL; 2565 return -EINVAL;
2562 } 2566 }
2563 2567
2564 vpfe->video_dev = video_device_alloc();
2565 if (!vpfe->video_dev) {
2566 dev_err(&pdev->dev, "Unable to allocate video device\n");
2567 return -ENOMEM;
2568 }
2569
2570 ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev); 2568 ret = v4l2_device_register(&pdev->dev, &vpfe->v4l2_dev);
2571 if (ret) { 2569 if (ret) {
2572 vpfe_err(vpfe, 2570 vpfe_err(vpfe,
2573 "Unable to register v4l2 device.\n"); 2571 "Unable to register v4l2 device.\n");
2574 goto probe_out_video_release; 2572 return ret;
2575 } 2573 }
2576 2574
2577 /* set the driver data in platform device */ 2575 /* set the driver data in platform device */
@@ -2609,9 +2607,6 @@ static int vpfe_probe(struct platform_device *pdev)
2609 2607
2610probe_out_v4l2_unregister: 2608probe_out_v4l2_unregister:
2611 v4l2_device_unregister(&vpfe->v4l2_dev); 2609 v4l2_device_unregister(&vpfe->v4l2_dev);
2612probe_out_video_release:
2613 if (!video_is_registered(vpfe->video_dev))
2614 video_device_release(vpfe->video_dev);
2615 return ret; 2610 return ret;
2616} 2611}
2617 2612
@@ -2628,7 +2623,7 @@ static int vpfe_remove(struct platform_device *pdev)
2628 2623
2629 v4l2_async_notifier_unregister(&vpfe->notifier); 2624 v4l2_async_notifier_unregister(&vpfe->notifier);
2630 v4l2_device_unregister(&vpfe->v4l2_dev); 2625 v4l2_device_unregister(&vpfe->v4l2_dev);
2631 video_unregister_device(vpfe->video_dev); 2626 video_unregister_device(&vpfe->video_dev);
2632 2627
2633 return 0; 2628 return 0;
2634} 2629}
diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h
index 0f557352313d..5bfb35649a39 100644
--- a/drivers/media/platform/am437x/am437x-vpfe.h
+++ b/drivers/media/platform/am437x/am437x-vpfe.h
@@ -83,7 +83,6 @@ struct vpfe_route {
83}; 83};
84 84
85struct vpfe_subdev_info { 85struct vpfe_subdev_info {
86 char name[32];
87 /* Sub device group id */ 86 /* Sub device group id */
88 int grp_id; 87 int grp_id;
89 /* inputs available at the sub device */ 88 /* inputs available at the sub device */
@@ -223,7 +222,7 @@ struct vpfe_ccdc {
223struct vpfe_device { 222struct vpfe_device {
224 /* V4l2 specific parameters */ 223 /* V4l2 specific parameters */
225 /* Identifies video device for this channel */ 224 /* Identifies video device for this channel */
226 struct video_device *video_dev; 225 struct video_device video_dev;
227 /* sub devices */ 226 /* sub devices */
228 struct v4l2_subdev **sd; 227 struct v4l2_subdev **sd;
229 /* vpfe cfg */ 228 /* vpfe cfg */
diff --git a/drivers/media/platform/blackfin/bfin_capture.c b/drivers/media/platform/blackfin/bfin_capture.c
index 8f6698668ecf..6a437f86dcdc 100644
--- a/drivers/media/platform/blackfin/bfin_capture.c
+++ b/drivers/media/platform/blackfin/bfin_capture.c
@@ -44,7 +44,6 @@
44#include <media/blackfin/ppi.h> 44#include <media/blackfin/ppi.h>
45 45
46#define CAPTURE_DRV_NAME "bfin_capture" 46#define CAPTURE_DRV_NAME "bfin_capture"
47#define BCAP_MIN_NUM_BUF 2
48 47
49struct bcap_format { 48struct bcap_format {
50 char *desc; 49 char *desc;
@@ -65,7 +64,7 @@ struct bcap_device {
65 /* v4l2 control handler */ 64 /* v4l2 control handler */
66 struct v4l2_ctrl_handler ctrl_handler; 65 struct v4l2_ctrl_handler ctrl_handler;
67 /* device node data */ 66 /* device node data */
68 struct video_device *video_dev; 67 struct video_device video_dev;
69 /* sub device instance */ 68 /* sub device instance */
70 struct v4l2_subdev *sd; 69 struct v4l2_subdev *sd;
71 /* capture config */ 70 /* capture config */
@@ -104,12 +103,8 @@ struct bcap_device {
104 struct completion comp; 103 struct completion comp;
105 /* prepare to stop */ 104 /* prepare to stop */
106 bool stop; 105 bool stop;
107}; 106 /* vb2 buffer sequence counter */
108 107 unsigned sequence;
109struct bcap_fh {
110 struct v4l2_fh fh;
111 /* indicates whether this file handle is doing IO */
112 bool io_allowed;
113}; 108};
114 109
115static const struct bcap_format bcap_formats[] = { 110static const struct bcap_format bcap_formats[] = {
@@ -201,90 +196,6 @@ static void bcap_free_sensor_formats(struct bcap_device *bcap_dev)
201 bcap_dev->sensor_formats = NULL; 196 bcap_dev->sensor_formats = NULL;
202} 197}
203 198
204static int bcap_open(struct file *file)
205{
206 struct bcap_device *bcap_dev = video_drvdata(file);
207 struct video_device *vfd = bcap_dev->video_dev;
208 struct bcap_fh *bcap_fh;
209
210 if (!bcap_dev->sd) {
211 v4l2_err(&bcap_dev->v4l2_dev, "No sub device registered\n");
212 return -ENODEV;
213 }
214
215 bcap_fh = kzalloc(sizeof(*bcap_fh), GFP_KERNEL);
216 if (!bcap_fh) {
217 v4l2_err(&bcap_dev->v4l2_dev,
218 "unable to allocate memory for file handle object\n");
219 return -ENOMEM;
220 }
221
222 v4l2_fh_init(&bcap_fh->fh, vfd);
223
224 /* store pointer to v4l2_fh in private_data member of file */
225 file->private_data = &bcap_fh->fh;
226 v4l2_fh_add(&bcap_fh->fh);
227 bcap_fh->io_allowed = false;
228 return 0;
229}
230
231static int bcap_release(struct file *file)
232{
233 struct bcap_device *bcap_dev = video_drvdata(file);
234 struct v4l2_fh *fh = file->private_data;
235 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
236
237 /* if this instance is doing IO */
238 if (bcap_fh->io_allowed)
239 vb2_queue_release(&bcap_dev->buffer_queue);
240
241 file->private_data = NULL;
242 v4l2_fh_del(&bcap_fh->fh);
243 v4l2_fh_exit(&bcap_fh->fh);
244 kfree(bcap_fh);
245 return 0;
246}
247
248static int bcap_mmap(struct file *file, struct vm_area_struct *vma)
249{
250 struct bcap_device *bcap_dev = video_drvdata(file);
251 int ret;
252
253 if (mutex_lock_interruptible(&bcap_dev->mutex))
254 return -ERESTARTSYS;
255 ret = vb2_mmap(&bcap_dev->buffer_queue, vma);
256 mutex_unlock(&bcap_dev->mutex);
257 return ret;
258}
259
260#ifndef CONFIG_MMU
261static unsigned long bcap_get_unmapped_area(struct file *file,
262 unsigned long addr,
263 unsigned long len,
264 unsigned long pgoff,
265 unsigned long flags)
266{
267 struct bcap_device *bcap_dev = video_drvdata(file);
268
269 return vb2_get_unmapped_area(&bcap_dev->buffer_queue,
270 addr,
271 len,
272 pgoff,
273 flags);
274}
275#endif
276
277static unsigned int bcap_poll(struct file *file, poll_table *wait)
278{
279 struct bcap_device *bcap_dev = video_drvdata(file);
280 unsigned int res;
281
282 mutex_lock(&bcap_dev->mutex);
283 res = vb2_poll(&bcap_dev->buffer_queue, file, wait);
284 mutex_unlock(&bcap_dev->mutex);
285 return res;
286}
287
288static int bcap_queue_setup(struct vb2_queue *vq, 199static int bcap_queue_setup(struct vb2_queue *vq,
289 const struct v4l2_format *fmt, 200 const struct v4l2_format *fmt,
290 unsigned int *nbuffers, unsigned int *nplanes, 201 unsigned int *nbuffers, unsigned int *nplanes,
@@ -292,37 +203,32 @@ static int bcap_queue_setup(struct vb2_queue *vq,
292{ 203{
293 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 204 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
294 205
295 if (*nbuffers < BCAP_MIN_NUM_BUF) 206 if (fmt && fmt->fmt.pix.sizeimage < bcap_dev->fmt.sizeimage)
296 *nbuffers = BCAP_MIN_NUM_BUF; 207 return -EINVAL;
208
209 if (vq->num_buffers + *nbuffers < 2)
210 *nbuffers = 2;
297 211
298 *nplanes = 1; 212 *nplanes = 1;
299 sizes[0] = bcap_dev->fmt.sizeimage; 213 sizes[0] = fmt ? fmt->fmt.pix.sizeimage : bcap_dev->fmt.sizeimage;
300 alloc_ctxs[0] = bcap_dev->alloc_ctx; 214 alloc_ctxs[0] = bcap_dev->alloc_ctx;
301 215
302 return 0; 216 return 0;
303} 217}
304 218
305static int bcap_buffer_init(struct vb2_buffer *vb)
306{
307 struct bcap_buffer *buf = to_bcap_vb(vb);
308
309 INIT_LIST_HEAD(&buf->list);
310 return 0;
311}
312
313static int bcap_buffer_prepare(struct vb2_buffer *vb) 219static int bcap_buffer_prepare(struct vb2_buffer *vb)
314{ 220{
315 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue); 221 struct bcap_device *bcap_dev = vb2_get_drv_priv(vb->vb2_queue);
316 struct bcap_buffer *buf = to_bcap_vb(vb); 222 unsigned long size = bcap_dev->fmt.sizeimage;
317 unsigned long size;
318 223
319 size = bcap_dev->fmt.sizeimage;
320 if (vb2_plane_size(vb, 0) < size) { 224 if (vb2_plane_size(vb, 0) < size) {
321 v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n", 225 v4l2_err(&bcap_dev->v4l2_dev, "buffer too small (%lu < %lu)\n",
322 vb2_plane_size(vb, 0), size); 226 vb2_plane_size(vb, 0), size);
323 return -EINVAL; 227 return -EINVAL;
324 } 228 }
325 vb2_set_plane_payload(&buf->vb, 0, size); 229 vb2_set_plane_payload(vb, 0, size);
230
231 vb->v4l2_buf.field = bcap_dev->fmt.field;
326 232
327 return 0; 233 return 0;
328} 234}
@@ -353,14 +259,16 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
353{ 259{
354 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq); 260 struct bcap_device *bcap_dev = vb2_get_drv_priv(vq);
355 struct ppi_if *ppi = bcap_dev->ppi; 261 struct ppi_if *ppi = bcap_dev->ppi;
262 struct bcap_buffer *buf, *tmp;
356 struct ppi_params params; 263 struct ppi_params params;
264 dma_addr_t addr;
357 int ret; 265 int ret;
358 266
359 /* enable streamon on the sub device */ 267 /* enable streamon on the sub device */
360 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1); 268 ret = v4l2_subdev_call(bcap_dev->sd, video, s_stream, 1);
361 if (ret && (ret != -ENOIOCTLCMD)) { 269 if (ret && (ret != -ENOIOCTLCMD)) {
362 v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n"); 270 v4l2_err(&bcap_dev->v4l2_dev, "stream on failed in subdev\n");
363 return ret; 271 goto err;
364 } 272 }
365 273
366 /* set ppi params */ 274 /* set ppi params */
@@ -399,7 +307,7 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
399 if (ret < 0) { 307 if (ret < 0) {
400 v4l2_err(&bcap_dev->v4l2_dev, 308 v4l2_err(&bcap_dev->v4l2_dev,
401 "Error in setting ppi params\n"); 309 "Error in setting ppi params\n");
402 return ret; 310 goto err;
403 } 311 }
404 312
405 /* attach ppi DMA irq handler */ 313 /* attach ppi DMA irq handler */
@@ -407,12 +315,34 @@ static int bcap_start_streaming(struct vb2_queue *vq, unsigned int count)
407 if (ret < 0) { 315 if (ret < 0) {
408 v4l2_err(&bcap_dev->v4l2_dev, 316 v4l2_err(&bcap_dev->v4l2_dev,
409 "Error in attaching interrupt handler\n"); 317 "Error in attaching interrupt handler\n");
410 return ret; 318 goto err;
411 } 319 }
412 320
321 bcap_dev->sequence = 0;
322
413 reinit_completion(&bcap_dev->comp); 323 reinit_completion(&bcap_dev->comp);
414 bcap_dev->stop = false; 324 bcap_dev->stop = false;
325
326 /* get the next frame from the dma queue */
327 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
328 struct bcap_buffer, list);
329 /* remove buffer from the dma queue */
330 list_del_init(&bcap_dev->cur_frm->list);
331 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
332 /* update DMA address */
333 ppi->ops->update_addr(ppi, (unsigned long)addr);
334 /* enable ppi */
335 ppi->ops->start(ppi);
336
415 return 0; 337 return 0;
338
339err:
340 list_for_each_entry_safe(buf, tmp, &bcap_dev->dma_queue, list) {
341 list_del(&buf->list);
342 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
343 }
344
345 return ret;
416} 346}
417 347
418static void bcap_stop_streaming(struct vb2_queue *vq) 348static void bcap_stop_streaming(struct vb2_queue *vq)
@@ -431,6 +361,9 @@ static void bcap_stop_streaming(struct vb2_queue *vq)
431 "stream off failed in subdev\n"); 361 "stream off failed in subdev\n");
432 362
433 /* release all active buffers */ 363 /* release all active buffers */
364 if (bcap_dev->cur_frm)
365 vb2_buffer_done(&bcap_dev->cur_frm->vb, VB2_BUF_STATE_ERROR);
366
434 while (!list_empty(&bcap_dev->dma_queue)) { 367 while (!list_empty(&bcap_dev->dma_queue)) {
435 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, 368 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
436 struct bcap_buffer, list); 369 struct bcap_buffer, list);
@@ -441,7 +374,6 @@ static void bcap_stop_streaming(struct vb2_queue *vq)
441 374
442static struct vb2_ops bcap_video_qops = { 375static struct vb2_ops bcap_video_qops = {
443 .queue_setup = bcap_queue_setup, 376 .queue_setup = bcap_queue_setup,
444 .buf_init = bcap_buffer_init,
445 .buf_prepare = bcap_buffer_prepare, 377 .buf_prepare = bcap_buffer_prepare,
446 .buf_cleanup = bcap_buffer_cleanup, 378 .buf_cleanup = bcap_buffer_cleanup,
447 .buf_queue = bcap_buffer_queue, 379 .buf_queue = bcap_buffer_queue,
@@ -451,57 +383,6 @@ static struct vb2_ops bcap_video_qops = {
451 .stop_streaming = bcap_stop_streaming, 383 .stop_streaming = bcap_stop_streaming,
452}; 384};
453 385
454static int bcap_reqbufs(struct file *file, void *priv,
455 struct v4l2_requestbuffers *req_buf)
456{
457 struct bcap_device *bcap_dev = video_drvdata(file);
458 struct vb2_queue *vq = &bcap_dev->buffer_queue;
459 struct v4l2_fh *fh = file->private_data;
460 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
461
462 if (vb2_is_busy(vq))
463 return -EBUSY;
464
465 bcap_fh->io_allowed = true;
466
467 return vb2_reqbufs(vq, req_buf);
468}
469
470static int bcap_querybuf(struct file *file, void *priv,
471 struct v4l2_buffer *buf)
472{
473 struct bcap_device *bcap_dev = video_drvdata(file);
474
475 return vb2_querybuf(&bcap_dev->buffer_queue, buf);
476}
477
478static int bcap_qbuf(struct file *file, void *priv,
479 struct v4l2_buffer *buf)
480{
481 struct bcap_device *bcap_dev = video_drvdata(file);
482 struct v4l2_fh *fh = file->private_data;
483 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
484
485 if (!bcap_fh->io_allowed)
486 return -EBUSY;
487
488 return vb2_qbuf(&bcap_dev->buffer_queue, buf);
489}
490
491static int bcap_dqbuf(struct file *file, void *priv,
492 struct v4l2_buffer *buf)
493{
494 struct bcap_device *bcap_dev = video_drvdata(file);
495 struct v4l2_fh *fh = file->private_data;
496 struct bcap_fh *bcap_fh = container_of(fh, struct bcap_fh, fh);
497
498 if (!bcap_fh->io_allowed)
499 return -EBUSY;
500
501 return vb2_dqbuf(&bcap_dev->buffer_queue,
502 buf, file->f_flags & O_NONBLOCK);
503}
504
505static irqreturn_t bcap_isr(int irq, void *dev_id) 386static irqreturn_t bcap_isr(int irq, void *dev_id)
506{ 387{
507 struct ppi_if *ppi = dev_id; 388 struct ppi_if *ppi = dev_id;
@@ -517,6 +398,7 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
517 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 398 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
518 ppi->err = false; 399 ppi->err = false;
519 } else { 400 } else {
401 vb->v4l2_buf.sequence = bcap_dev->sequence++;
520 vb2_buffer_done(vb, VB2_BUF_STATE_DONE); 402 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
521 } 403 }
522 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next, 404 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
@@ -543,62 +425,14 @@ static irqreturn_t bcap_isr(int irq, void *dev_id)
543 return IRQ_HANDLED; 425 return IRQ_HANDLED;
544} 426}
545 427
546static int bcap_streamon(struct file *file, void *priv,
547 enum v4l2_buf_type buf_type)
548{
549 struct bcap_device *bcap_dev = video_drvdata(file);
550 struct bcap_fh *fh = file->private_data;
551 struct ppi_if *ppi = bcap_dev->ppi;
552 dma_addr_t addr;
553 int ret;
554
555 if (!fh->io_allowed)
556 return -EBUSY;
557
558 /* call streamon to start streaming in videobuf */
559 ret = vb2_streamon(&bcap_dev->buffer_queue, buf_type);
560 if (ret)
561 return ret;
562
563 /* if dma queue is empty, return error */
564 if (list_empty(&bcap_dev->dma_queue)) {
565 v4l2_err(&bcap_dev->v4l2_dev, "dma queue is empty\n");
566 ret = -EINVAL;
567 goto err;
568 }
569
570 /* get the next frame from the dma queue */
571 bcap_dev->cur_frm = list_entry(bcap_dev->dma_queue.next,
572 struct bcap_buffer, list);
573 /* remove buffer from the dma queue */
574 list_del_init(&bcap_dev->cur_frm->list);
575 addr = vb2_dma_contig_plane_dma_addr(&bcap_dev->cur_frm->vb, 0);
576 /* update DMA address */
577 ppi->ops->update_addr(ppi, (unsigned long)addr);
578 /* enable ppi */
579 ppi->ops->start(ppi);
580
581 return 0;
582err:
583 vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
584 return ret;
585}
586
587static int bcap_streamoff(struct file *file, void *priv,
588 enum v4l2_buf_type buf_type)
589{
590 struct bcap_device *bcap_dev = video_drvdata(file);
591 struct bcap_fh *fh = file->private_data;
592
593 if (!fh->io_allowed)
594 return -EBUSY;
595
596 return vb2_streamoff(&bcap_dev->buffer_queue, buf_type);
597}
598
599static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std) 428static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std)
600{ 429{
601 struct bcap_device *bcap_dev = video_drvdata(file); 430 struct bcap_device *bcap_dev = video_drvdata(file);
431 struct v4l2_input input;
432
433 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
434 if (!(input.capabilities & V4L2_IN_CAP_STD))
435 return -ENODATA;
602 436
603 return v4l2_subdev_call(bcap_dev->sd, video, querystd, std); 437 return v4l2_subdev_call(bcap_dev->sd, video, querystd, std);
604} 438}
@@ -606,6 +440,11 @@ static int bcap_querystd(struct file *file, void *priv, v4l2_std_id *std)
606static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std) 440static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std)
607{ 441{
608 struct bcap_device *bcap_dev = video_drvdata(file); 442 struct bcap_device *bcap_dev = video_drvdata(file);
443 struct v4l2_input input;
444
445 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
446 if (!(input.capabilities & V4L2_IN_CAP_STD))
447 return -ENODATA;
609 448
610 *std = bcap_dev->std; 449 *std = bcap_dev->std;
611 return 0; 450 return 0;
@@ -614,8 +453,13 @@ static int bcap_g_std(struct file *file, void *priv, v4l2_std_id *std)
614static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std) 453static int bcap_s_std(struct file *file, void *priv, v4l2_std_id std)
615{ 454{
616 struct bcap_device *bcap_dev = video_drvdata(file); 455 struct bcap_device *bcap_dev = video_drvdata(file);
456 struct v4l2_input input;
617 int ret; 457 int ret;
618 458
459 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
460 if (!(input.capabilities & V4L2_IN_CAP_STD))
461 return -ENODATA;
462
619 if (vb2_is_busy(&bcap_dev->buffer_queue)) 463 if (vb2_is_busy(&bcap_dev->buffer_queue))
620 return -EBUSY; 464 return -EBUSY;
621 465
@@ -631,6 +475,11 @@ static int bcap_enum_dv_timings(struct file *file, void *priv,
631 struct v4l2_enum_dv_timings *timings) 475 struct v4l2_enum_dv_timings *timings)
632{ 476{
633 struct bcap_device *bcap_dev = video_drvdata(file); 477 struct bcap_device *bcap_dev = video_drvdata(file);
478 struct v4l2_input input;
479
480 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
481 if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS))
482 return -ENODATA;
634 483
635 timings->pad = 0; 484 timings->pad = 0;
636 485
@@ -642,6 +491,11 @@ static int bcap_query_dv_timings(struct file *file, void *priv,
642 struct v4l2_dv_timings *timings) 491 struct v4l2_dv_timings *timings)
643{ 492{
644 struct bcap_device *bcap_dev = video_drvdata(file); 493 struct bcap_device *bcap_dev = video_drvdata(file);
494 struct v4l2_input input;
495
496 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
497 if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS))
498 return -ENODATA;
645 499
646 return v4l2_subdev_call(bcap_dev->sd, video, 500 return v4l2_subdev_call(bcap_dev->sd, video,
647 query_dv_timings, timings); 501 query_dv_timings, timings);
@@ -651,6 +505,11 @@ static int bcap_g_dv_timings(struct file *file, void *priv,
651 struct v4l2_dv_timings *timings) 505 struct v4l2_dv_timings *timings)
652{ 506{
653 struct bcap_device *bcap_dev = video_drvdata(file); 507 struct bcap_device *bcap_dev = video_drvdata(file);
508 struct v4l2_input input;
509
510 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
511 if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS))
512 return -ENODATA;
654 513
655 *timings = bcap_dev->dv_timings; 514 *timings = bcap_dev->dv_timings;
656 return 0; 515 return 0;
@@ -660,7 +519,13 @@ static int bcap_s_dv_timings(struct file *file, void *priv,
660 struct v4l2_dv_timings *timings) 519 struct v4l2_dv_timings *timings)
661{ 520{
662 struct bcap_device *bcap_dev = video_drvdata(file); 521 struct bcap_device *bcap_dev = video_drvdata(file);
522 struct v4l2_input input;
663 int ret; 523 int ret;
524
525 input = bcap_dev->cfg->inputs[bcap_dev->cur_input];
526 if (!(input.capabilities & V4L2_IN_CAP_DV_TIMINGS))
527 return -ENODATA;
528
664 if (vb2_is_busy(&bcap_dev->buffer_queue)) 529 if (vb2_is_busy(&bcap_dev->buffer_queue))
665 return -EBUSY; 530 return -EBUSY;
666 531
@@ -881,12 +746,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = {
881 .vidioc_g_dv_timings = bcap_g_dv_timings, 746 .vidioc_g_dv_timings = bcap_g_dv_timings,
882 .vidioc_query_dv_timings = bcap_query_dv_timings, 747 .vidioc_query_dv_timings = bcap_query_dv_timings,
883 .vidioc_enum_dv_timings = bcap_enum_dv_timings, 748 .vidioc_enum_dv_timings = bcap_enum_dv_timings,
884 .vidioc_reqbufs = bcap_reqbufs, 749 .vidioc_reqbufs = vb2_ioctl_reqbufs,
885 .vidioc_querybuf = bcap_querybuf, 750 .vidioc_create_bufs = vb2_ioctl_create_bufs,
886 .vidioc_qbuf = bcap_qbuf, 751 .vidioc_querybuf = vb2_ioctl_querybuf,
887 .vidioc_dqbuf = bcap_dqbuf, 752 .vidioc_qbuf = vb2_ioctl_qbuf,
888 .vidioc_streamon = bcap_streamon, 753 .vidioc_dqbuf = vb2_ioctl_dqbuf,
889 .vidioc_streamoff = bcap_streamoff, 754 .vidioc_expbuf = vb2_ioctl_expbuf,
755 .vidioc_streamon = vb2_ioctl_streamon,
756 .vidioc_streamoff = vb2_ioctl_streamoff,
890 .vidioc_g_parm = bcap_g_parm, 757 .vidioc_g_parm = bcap_g_parm,
891 .vidioc_s_parm = bcap_s_parm, 758 .vidioc_s_parm = bcap_s_parm,
892 .vidioc_log_status = bcap_log_status, 759 .vidioc_log_status = bcap_log_status,
@@ -894,14 +761,14 @@ static const struct v4l2_ioctl_ops bcap_ioctl_ops = {
894 761
895static struct v4l2_file_operations bcap_fops = { 762static struct v4l2_file_operations bcap_fops = {
896 .owner = THIS_MODULE, 763 .owner = THIS_MODULE,
897 .open = bcap_open, 764 .open = v4l2_fh_open,
898 .release = bcap_release, 765 .release = vb2_fop_release,
899 .unlocked_ioctl = video_ioctl2, 766 .unlocked_ioctl = video_ioctl2,
900 .mmap = bcap_mmap, 767 .mmap = vb2_fop_mmap,
901#ifndef CONFIG_MMU 768#ifndef CONFIG_MMU
902 .get_unmapped_area = bcap_get_unmapped_area, 769 .get_unmapped_area = vb2_fop_get_unmapped_area,
903#endif 770#endif
904 .poll = bcap_poll 771 .poll = vb2_fop_poll
905}; 772};
906 773
907static int bcap_probe(struct platform_device *pdev) 774static int bcap_probe(struct platform_device *pdev)
@@ -942,27 +809,20 @@ static int bcap_probe(struct platform_device *pdev)
942 goto err_free_ppi; 809 goto err_free_ppi;
943 } 810 }
944 811
945 vfd = video_device_alloc(); 812 vfd = &bcap_dev->video_dev;
946 if (!vfd) {
947 ret = -ENOMEM;
948 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
949 goto err_cleanup_ctx;
950 }
951
952 /* initialize field of video device */ 813 /* initialize field of video device */
953 vfd->release = video_device_release; 814 vfd->release = video_device_release_empty;
954 vfd->fops = &bcap_fops; 815 vfd->fops = &bcap_fops;
955 vfd->ioctl_ops = &bcap_ioctl_ops; 816 vfd->ioctl_ops = &bcap_ioctl_ops;
956 vfd->tvnorms = 0; 817 vfd->tvnorms = 0;
957 vfd->v4l2_dev = &bcap_dev->v4l2_dev; 818 vfd->v4l2_dev = &bcap_dev->v4l2_dev;
958 strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name)); 819 strncpy(vfd->name, CAPTURE_DRV_NAME, sizeof(vfd->name));
959 bcap_dev->video_dev = vfd;
960 820
961 ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev); 821 ret = v4l2_device_register(&pdev->dev, &bcap_dev->v4l2_dev);
962 if (ret) { 822 if (ret) {
963 v4l2_err(pdev->dev.driver, 823 v4l2_err(pdev->dev.driver,
964 "Unable to register v4l2 device\n"); 824 "Unable to register v4l2 device\n");
965 goto err_release_vdev; 825 goto err_cleanup_ctx;
966 } 826 }
967 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n"); 827 v4l2_info(&bcap_dev->v4l2_dev, "v4l2 device registered\n");
968 828
@@ -978,13 +838,14 @@ static int bcap_probe(struct platform_device *pdev)
978 /* initialize queue */ 838 /* initialize queue */
979 q = &bcap_dev->buffer_queue; 839 q = &bcap_dev->buffer_queue;
980 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 840 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
981 q->io_modes = VB2_MMAP; 841 q->io_modes = VB2_MMAP | VB2_DMABUF;
982 q->drv_priv = bcap_dev; 842 q->drv_priv = bcap_dev;
983 q->buf_struct_size = sizeof(struct bcap_buffer); 843 q->buf_struct_size = sizeof(struct bcap_buffer);
984 q->ops = &bcap_video_qops; 844 q->ops = &bcap_video_qops;
985 q->mem_ops = &vb2_dma_contig_memops; 845 q->mem_ops = &vb2_dma_contig_memops;
986 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; 846 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
987 q->lock = &bcap_dev->mutex; 847 q->lock = &bcap_dev->mutex;
848 q->min_buffers_needed = 1;
988 849
989 ret = vb2_queue_init(q); 850 ret = vb2_queue_init(q);
990 if (ret) 851 if (ret)
@@ -997,15 +858,16 @@ static int bcap_probe(struct platform_device *pdev)
997 INIT_LIST_HEAD(&bcap_dev->dma_queue); 858 INIT_LIST_HEAD(&bcap_dev->dma_queue);
998 859
999 vfd->lock = &bcap_dev->mutex; 860 vfd->lock = &bcap_dev->mutex;
861 vfd->queue = q;
1000 862
1001 /* register video device */ 863 /* register video device */
1002 ret = video_register_device(bcap_dev->video_dev, VFL_TYPE_GRABBER, -1); 864 ret = video_register_device(&bcap_dev->video_dev, VFL_TYPE_GRABBER, -1);
1003 if (ret) { 865 if (ret) {
1004 v4l2_err(&bcap_dev->v4l2_dev, 866 v4l2_err(&bcap_dev->v4l2_dev,
1005 "Unable to register video device\n"); 867 "Unable to register video device\n");
1006 goto err_free_handler; 868 goto err_free_handler;
1007 } 869 }
1008 video_set_drvdata(bcap_dev->video_dev, bcap_dev); 870 video_set_drvdata(&bcap_dev->video_dev, bcap_dev);
1009 v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n", 871 v4l2_info(&bcap_dev->v4l2_dev, "video device registered as: %s\n",
1010 video_device_node_name(vfd)); 872 video_device_node_name(vfd));
1011 873
@@ -1083,15 +945,11 @@ static int bcap_probe(struct platform_device *pdev)
1083 } 945 }
1084 return 0; 946 return 0;
1085err_unreg_vdev: 947err_unreg_vdev:
1086 video_unregister_device(bcap_dev->video_dev); 948 video_unregister_device(&bcap_dev->video_dev);
1087 bcap_dev->video_dev = NULL;
1088err_free_handler: 949err_free_handler:
1089 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 950 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1090err_unreg_v4l2: 951err_unreg_v4l2:
1091 v4l2_device_unregister(&bcap_dev->v4l2_dev); 952 v4l2_device_unregister(&bcap_dev->v4l2_dev);
1092err_release_vdev:
1093 if (bcap_dev->video_dev)
1094 video_device_release(bcap_dev->video_dev);
1095err_cleanup_ctx: 953err_cleanup_ctx:
1096 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 954 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
1097err_free_ppi: 955err_free_ppi:
@@ -1108,7 +966,7 @@ static int bcap_remove(struct platform_device *pdev)
1108 struct bcap_device, v4l2_dev); 966 struct bcap_device, v4l2_dev);
1109 967
1110 bcap_free_sensor_formats(bcap_dev); 968 bcap_free_sensor_formats(bcap_dev);
1111 video_unregister_device(bcap_dev->video_dev); 969 video_unregister_device(&bcap_dev->video_dev);
1112 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler); 970 v4l2_ctrl_handler_free(&bcap_dev->ctrl_handler);
1113 v4l2_device_unregister(v4l2_dev); 971 v4l2_device_unregister(v4l2_dev);
1114 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx); 972 vb2_dma_contig_cleanup_ctx(bcap_dev->alloc_ctx);
diff --git a/drivers/media/platform/coda/Makefile b/drivers/media/platform/coda/Makefile
index 25ce15561695..834e504bf085 100644
--- a/drivers/media/platform/coda/Makefile
+++ b/drivers/media/platform/coda/Makefile
@@ -1,3 +1,5 @@
1ccflags-y += -I$(src)
2
1coda-objs := coda-common.o coda-bit.o coda-h264.o coda-jpeg.o 3coda-objs := coda-common.o coda-bit.o coda-h264.o coda-jpeg.o
2 4
3obj-$(CONFIG_VIDEO_CODA) += coda.o 5obj-$(CONFIG_VIDEO_CODA) += coda.o
diff --git a/drivers/media/platform/coda/coda-bit.c b/drivers/media/platform/coda/coda-bit.c
index 856b542b35b9..d0430071d2ee 100644
--- a/drivers/media/platform/coda/coda-bit.c
+++ b/drivers/media/platform/coda/coda-bit.c
@@ -15,6 +15,7 @@
15#include <linux/clk.h> 15#include <linux/clk.h>
16#include <linux/irqreturn.h> 16#include <linux/irqreturn.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/log2.h>
18#include <linux/platform_device.h> 19#include <linux/platform_device.h>
19#include <linux/reset.h> 20#include <linux/reset.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -29,13 +30,18 @@
29#include <media/videobuf2-vmalloc.h> 30#include <media/videobuf2-vmalloc.h>
30 31
31#include "coda.h" 32#include "coda.h"
33#define CREATE_TRACE_POINTS
34#include "trace.h"
32 35
36#define CODA_PARA_BUF_SIZE (10 * 1024)
33#define CODA7_PS_BUF_SIZE 0x28000 37#define CODA7_PS_BUF_SIZE 0x28000
34#define CODA9_PS_SAVE_SIZE (512 * 1024) 38#define CODA9_PS_SAVE_SIZE (512 * 1024)
35 39
36#define CODA_DEFAULT_GAMMA 4096 40#define CODA_DEFAULT_GAMMA 4096
37#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */ 41#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */
38 42
43static void coda_free_bitstream_buffer(struct coda_ctx *ctx);
44
39static inline int coda_is_initialized(struct coda_dev *dev) 45static inline int coda_is_initialized(struct coda_dev *dev)
40{ 46{
41 return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0; 47 return coda_read(dev, CODA_REG_BIT_CUR_PC) != 0;
@@ -84,15 +90,21 @@ static void coda_command_async(struct coda_ctx *ctx, int cmd)
84 coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD); 90 coda_write(dev, ctx->params.codec_mode, CODA_REG_BIT_RUN_COD_STD);
85 coda_write(dev, ctx->params.codec_mode_aux, CODA7_REG_BIT_RUN_AUX_STD); 91 coda_write(dev, ctx->params.codec_mode_aux, CODA7_REG_BIT_RUN_AUX_STD);
86 92
93 trace_coda_bit_run(ctx, cmd);
94
87 coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND); 95 coda_write(dev, cmd, CODA_REG_BIT_RUN_COMMAND);
88} 96}
89 97
90static int coda_command_sync(struct coda_ctx *ctx, int cmd) 98static int coda_command_sync(struct coda_ctx *ctx, int cmd)
91{ 99{
92 struct coda_dev *dev = ctx->dev; 100 struct coda_dev *dev = ctx->dev;
101 int ret;
93 102
94 coda_command_async(ctx, cmd); 103 coda_command_async(ctx, cmd);
95 return coda_wait_timeout(dev); 104 ret = coda_wait_timeout(dev);
105 trace_coda_bit_done(ctx);
106
107 return ret;
96} 108}
97 109
98int coda_hw_reset(struct coda_ctx *ctx) 110int coda_hw_reset(struct coda_ctx *ctx)
@@ -177,10 +189,6 @@ static int coda_bitstream_queue(struct coda_ctx *ctx,
177 if (n < src_size) 189 if (n < src_size)
178 return -ENOSPC; 190 return -ENOSPC;
179 191
180 dma_sync_single_for_device(&ctx->dev->plat_dev->dev,
181 ctx->bitstream.paddr, ctx->bitstream.size,
182 DMA_TO_DEVICE);
183
184 src_buf->v4l2_buf.sequence = ctx->qsequence++; 192 src_buf->v4l2_buf.sequence = ctx->qsequence++;
185 193
186 return 0; 194 return 0;
@@ -214,7 +222,7 @@ static bool coda_bitstream_try_queue(struct coda_ctx *ctx,
214 return true; 222 return true;
215} 223}
216 224
217void coda_fill_bitstream(struct coda_ctx *ctx) 225void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming)
218{ 226{
219 struct vb2_buffer *src_buf; 227 struct vb2_buffer *src_buf;
220 struct coda_buffer_meta *meta; 228 struct coda_buffer_meta *meta;
@@ -235,9 +243,12 @@ void coda_fill_bitstream(struct coda_ctx *ctx)
235 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG && 243 if (ctx->codec->src_fourcc == V4L2_PIX_FMT_JPEG &&
236 !coda_jpeg_check_buffer(ctx, src_buf)) { 244 !coda_jpeg_check_buffer(ctx, src_buf)) {
237 v4l2_err(&ctx->dev->v4l2_dev, 245 v4l2_err(&ctx->dev->v4l2_dev,
238 "dropping invalid JPEG frame\n"); 246 "dropping invalid JPEG frame %d\n",
247 ctx->qsequence);
239 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 248 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
240 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_ERROR); 249 v4l2_m2m_buf_done(src_buf, streaming ?
250 VB2_BUF_STATE_ERROR :
251 VB2_BUF_STATE_QUEUED);
241 continue; 252 continue;
242 } 253 }
243 254
@@ -262,6 +273,8 @@ void coda_fill_bitstream(struct coda_ctx *ctx)
262 ctx->bitstream_fifo.kfifo.mask; 273 ctx->bitstream_fifo.kfifo.mask;
263 list_add_tail(&meta->list, 274 list_add_tail(&meta->list,
264 &ctx->buffer_meta_list); 275 &ctx->buffer_meta_list);
276
277 trace_coda_bit_queue(ctx, src_buf, meta);
265 } 278 }
266 279
267 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE); 280 v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
@@ -297,6 +310,14 @@ static void coda_parabuf_write(struct coda_ctx *ctx, int index, u32 value)
297 p[index ^ 1] = value; 310 p[index ^ 1] = value;
298} 311}
299 312
313static inline int coda_alloc_context_buf(struct coda_ctx *ctx,
314 struct coda_aux_buf *buf, size_t size,
315 const char *name)
316{
317 return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry);
318}
319
320
300static void coda_free_framebuffers(struct coda_ctx *ctx) 321static void coda_free_framebuffers(struct coda_ctx *ctx)
301{ 322{
302 int i; 323 int i;
@@ -377,6 +398,7 @@ static void coda_free_context_buffers(struct coda_ctx *ctx)
377 coda_free_aux_buf(dev, &ctx->psbuf); 398 coda_free_aux_buf(dev, &ctx->psbuf);
378 if (dev->devtype->product != CODA_DX6) 399 if (dev->devtype->product != CODA_DX6)
379 coda_free_aux_buf(dev, &ctx->workbuf); 400 coda_free_aux_buf(dev, &ctx->workbuf);
401 coda_free_aux_buf(dev, &ctx->parabuf);
380} 402}
381 403
382static int coda_alloc_context_buffers(struct coda_ctx *ctx, 404static int coda_alloc_context_buffers(struct coda_ctx *ctx,
@@ -386,57 +408,42 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
386 size_t size; 408 size_t size;
387 int ret; 409 int ret;
388 410
411 if (!ctx->parabuf.vaddr) {
412 ret = coda_alloc_context_buf(ctx, &ctx->parabuf,
413 CODA_PARA_BUF_SIZE, "parabuf");
414 if (ret < 0)
415 return ret;
416 }
417
389 if (dev->devtype->product == CODA_DX6) 418 if (dev->devtype->product == CODA_DX6)
390 return 0; 419 return 0;
391 420
392 if (ctx->psbuf.vaddr) { 421 if (!ctx->slicebuf.vaddr && q_data->fourcc == V4L2_PIX_FMT_H264) {
393 v4l2_err(&dev->v4l2_dev, "psmembuf still allocated\n");
394 return -EBUSY;
395 }
396 if (ctx->slicebuf.vaddr) {
397 v4l2_err(&dev->v4l2_dev, "slicebuf still allocated\n");
398 return -EBUSY;
399 }
400 if (ctx->workbuf.vaddr) {
401 v4l2_err(&dev->v4l2_dev, "context buffer still allocated\n");
402 ret = -EBUSY;
403 return -ENOMEM;
404 }
405
406 if (q_data->fourcc == V4L2_PIX_FMT_H264) {
407 /* worst case slice size */ 422 /* worst case slice size */
408 size = (DIV_ROUND_UP(q_data->width, 16) * 423 size = (DIV_ROUND_UP(q_data->width, 16) *
409 DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512; 424 DIV_ROUND_UP(q_data->height, 16)) * 3200 / 8 + 512;
410 ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size, 425 ret = coda_alloc_context_buf(ctx, &ctx->slicebuf, size,
411 "slicebuf"); 426 "slicebuf");
412 if (ret < 0) { 427 if (ret < 0)
413 v4l2_err(&dev->v4l2_dev, 428 goto err;
414 "failed to allocate %d byte slice buffer",
415 ctx->slicebuf.size);
416 return ret;
417 }
418 } 429 }
419 430
420 if (dev->devtype->product == CODA_7541) { 431 if (!ctx->psbuf.vaddr && dev->devtype->product == CODA_7541) {
421 ret = coda_alloc_context_buf(ctx, &ctx->psbuf, 432 ret = coda_alloc_context_buf(ctx, &ctx->psbuf,
422 CODA7_PS_BUF_SIZE, "psbuf"); 433 CODA7_PS_BUF_SIZE, "psbuf");
423 if (ret < 0) { 434 if (ret < 0)
424 v4l2_err(&dev->v4l2_dev,
425 "failed to allocate psmem buffer");
426 goto err; 435 goto err;
427 }
428 } 436 }
429 437
430 size = dev->devtype->workbuf_size; 438 if (!ctx->workbuf.vaddr) {
431 if (dev->devtype->product == CODA_960 && 439 size = dev->devtype->workbuf_size;
432 q_data->fourcc == V4L2_PIX_FMT_H264) 440 if (dev->devtype->product == CODA_960 &&
433 size += CODA9_PS_SAVE_SIZE; 441 q_data->fourcc == V4L2_PIX_FMT_H264)
434 ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size, "workbuf"); 442 size += CODA9_PS_SAVE_SIZE;
435 if (ret < 0) { 443 ret = coda_alloc_context_buf(ctx, &ctx->workbuf, size,
436 v4l2_err(&dev->v4l2_dev, 444 "workbuf");
437 "failed to allocate %d byte context buffer", 445 if (ret < 0)
438 ctx->workbuf.size); 446 goto err;
439 goto err;
440 } 447 }
441 448
442 return 0; 449 return 0;
@@ -709,6 +716,27 @@ err_clk_per:
709 * Encoder context operations 716 * Encoder context operations
710 */ 717 */
711 718
719static int coda_encoder_reqbufs(struct coda_ctx *ctx,
720 struct v4l2_requestbuffers *rb)
721{
722 struct coda_q_data *q_data_src;
723 int ret;
724
725 if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
726 return 0;
727
728 if (rb->count) {
729 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
730 ret = coda_alloc_context_buffers(ctx, q_data_src);
731 if (ret < 0)
732 return ret;
733 } else {
734 coda_free_context_buffers(ctx);
735 }
736
737 return 0;
738}
739
712static int coda_start_encoding(struct coda_ctx *ctx) 740static int coda_start_encoding(struct coda_ctx *ctx)
713{ 741{
714 struct coda_dev *dev = ctx->dev; 742 struct coda_dev *dev = ctx->dev;
@@ -725,11 +753,6 @@ static int coda_start_encoding(struct coda_ctx *ctx)
725 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 753 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
726 dst_fourcc = q_data_dst->fourcc; 754 dst_fourcc = q_data_dst->fourcc;
727 755
728 /* Allocate per-instance buffers */
729 ret = coda_alloc_context_buffers(ctx, q_data_src);
730 if (ret < 0)
731 return ret;
732
733 buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 756 buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
734 bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0); 757 bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
735 bitstream_size = q_data_dst->sizeimage; 758 bitstream_size = q_data_dst->sizeimage;
@@ -1227,6 +1250,8 @@ static int coda_prepare_encode(struct coda_ctx *ctx)
1227 coda_write(dev, ctx->iram_info.axi_sram_use, 1250 coda_write(dev, ctx->iram_info.axi_sram_use,
1228 CODA7_REG_BIT_AXI_SRAM_USE); 1251 CODA7_REG_BIT_AXI_SRAM_USE);
1229 1252
1253 trace_coda_enc_pic_run(ctx, src_buf);
1254
1230 coda_command_async(ctx, CODA_COMMAND_PIC_RUN); 1255 coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
1231 1256
1232 return 0; 1257 return 0;
@@ -1241,6 +1266,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
1241 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); 1266 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1242 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1267 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1243 1268
1269 trace_coda_enc_pic_done(ctx, dst_buf);
1270
1244 /* Get results from the coda */ 1271 /* Get results from the coda */
1245 start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START); 1272 start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
1246 wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)); 1273 wr_ptr = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx));
@@ -1311,7 +1338,6 @@ static void coda_seq_end_work(struct work_struct *work)
1311 ctx->bitstream.vaddr, ctx->bitstream.size); 1338 ctx->bitstream.vaddr, ctx->bitstream.size);
1312 1339
1313 coda_free_framebuffers(ctx); 1340 coda_free_framebuffers(ctx);
1314 coda_free_context_buffers(ctx);
1315 1341
1316 mutex_unlock(&dev->coda_mutex); 1342 mutex_unlock(&dev->coda_mutex);
1317 mutex_unlock(&ctx->buffer_mutex); 1343 mutex_unlock(&ctx->buffer_mutex);
@@ -1322,11 +1348,13 @@ static void coda_bit_release(struct coda_ctx *ctx)
1322 mutex_lock(&ctx->buffer_mutex); 1348 mutex_lock(&ctx->buffer_mutex);
1323 coda_free_framebuffers(ctx); 1349 coda_free_framebuffers(ctx);
1324 coda_free_context_buffers(ctx); 1350 coda_free_context_buffers(ctx);
1351 coda_free_bitstream_buffer(ctx);
1325 mutex_unlock(&ctx->buffer_mutex); 1352 mutex_unlock(&ctx->buffer_mutex);
1326} 1353}
1327 1354
1328const struct coda_context_ops coda_bit_encode_ops = { 1355const struct coda_context_ops coda_bit_encode_ops = {
1329 .queue_init = coda_encoder_queue_init, 1356 .queue_init = coda_encoder_queue_init,
1357 .reqbufs = coda_encoder_reqbufs,
1330 .start_streaming = coda_start_encoding, 1358 .start_streaming = coda_start_encoding,
1331 .prepare_run = coda_prepare_encode, 1359 .prepare_run = coda_prepare_encode,
1332 .finish_run = coda_finish_encode, 1360 .finish_run = coda_finish_encode,
@@ -1338,6 +1366,65 @@ const struct coda_context_ops coda_bit_encode_ops = {
1338 * Decoder context operations 1366 * Decoder context operations
1339 */ 1367 */
1340 1368
1369static int coda_alloc_bitstream_buffer(struct coda_ctx *ctx,
1370 struct coda_q_data *q_data)
1371{
1372 if (ctx->bitstream.vaddr)
1373 return 0;
1374
1375 ctx->bitstream.size = roundup_pow_of_two(q_data->sizeimage * 2);
1376 ctx->bitstream.vaddr = dma_alloc_writecombine(
1377 &ctx->dev->plat_dev->dev, ctx->bitstream.size,
1378 &ctx->bitstream.paddr, GFP_KERNEL);
1379 if (!ctx->bitstream.vaddr) {
1380 v4l2_err(&ctx->dev->v4l2_dev,
1381 "failed to allocate bitstream ringbuffer");
1382 return -ENOMEM;
1383 }
1384 kfifo_init(&ctx->bitstream_fifo,
1385 ctx->bitstream.vaddr, ctx->bitstream.size);
1386
1387 return 0;
1388}
1389
1390static void coda_free_bitstream_buffer(struct coda_ctx *ctx)
1391{
1392 if (ctx->bitstream.vaddr == NULL)
1393 return;
1394
1395 dma_free_writecombine(&ctx->dev->plat_dev->dev, ctx->bitstream.size,
1396 ctx->bitstream.vaddr, ctx->bitstream.paddr);
1397 ctx->bitstream.vaddr = NULL;
1398 kfifo_init(&ctx->bitstream_fifo, NULL, 0);
1399}
1400
1401static int coda_decoder_reqbufs(struct coda_ctx *ctx,
1402 struct v4l2_requestbuffers *rb)
1403{
1404 struct coda_q_data *q_data_src;
1405 int ret;
1406
1407 if (rb->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1408 return 0;
1409
1410 if (rb->count) {
1411 q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
1412 ret = coda_alloc_context_buffers(ctx, q_data_src);
1413 if (ret < 0)
1414 return ret;
1415 ret = coda_alloc_bitstream_buffer(ctx, q_data_src);
1416 if (ret < 0) {
1417 coda_free_context_buffers(ctx);
1418 return ret;
1419 }
1420 } else {
1421 coda_free_bitstream_buffer(ctx);
1422 coda_free_context_buffers(ctx);
1423 }
1424
1425 return 0;
1426}
1427
1341static int __coda_start_decoding(struct coda_ctx *ctx) 1428static int __coda_start_decoding(struct coda_ctx *ctx)
1342{ 1429{
1343 struct coda_q_data *q_data_src, *q_data_dst; 1430 struct coda_q_data *q_data_src, *q_data_dst;
@@ -1356,11 +1443,6 @@ static int __coda_start_decoding(struct coda_ctx *ctx)
1356 src_fourcc = q_data_src->fourcc; 1443 src_fourcc = q_data_src->fourcc;
1357 dst_fourcc = q_data_dst->fourcc; 1444 dst_fourcc = q_data_dst->fourcc;
1358 1445
1359 /* Allocate per-instance buffers */
1360 ret = coda_alloc_context_buffers(ctx, q_data_src);
1361 if (ret < 0)
1362 return ret;
1363
1364 coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR); 1446 coda_write(dev, ctx->parabuf.paddr, CODA_REG_BIT_PARA_BUF_ADDR);
1365 1447
1366 /* Update coda bitstream read and write pointers from kfifo */ 1448 /* Update coda bitstream read and write pointers from kfifo */
@@ -1579,7 +1661,7 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
1579 1661
1580 /* Try to copy source buffer contents into the bitstream ringbuffer */ 1662 /* Try to copy source buffer contents into the bitstream ringbuffer */
1581 mutex_lock(&ctx->bitstream_mutex); 1663 mutex_lock(&ctx->bitstream_mutex);
1582 coda_fill_bitstream(ctx); 1664 coda_fill_bitstream(ctx, true);
1583 mutex_unlock(&ctx->bitstream_mutex); 1665 mutex_unlock(&ctx->bitstream_mutex);
1584 1666
1585 if (coda_get_bitstream_payload(ctx) < 512 && 1667 if (coda_get_bitstream_payload(ctx) < 512 &&
@@ -1675,6 +1757,8 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
1675 /* Clear decode success flag */ 1757 /* Clear decode success flag */
1676 coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS); 1758 coda_write(dev, 0, CODA_RET_DEC_PIC_SUCCESS);
1677 1759
1760 trace_coda_dec_pic_run(ctx, meta);
1761
1678 coda_command_async(ctx, CODA_COMMAND_PIC_RUN); 1762 coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
1679 1763
1680 return 0; 1764 return 0;
@@ -1704,7 +1788,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1704 * by up to 512 bytes 1788 * by up to 512 bytes
1705 */ 1789 */
1706 if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) { 1790 if (ctx->bit_stream_param & CODA_BIT_STREAM_END_FLAG) {
1707 if (coda_get_bitstream_payload(ctx) >= CODA_MAX_FRAME_SIZE - 512) 1791 if (coda_get_bitstream_payload(ctx) >= ctx->bitstream.size - 512)
1708 kfifo_init(&ctx->bitstream_fifo, 1792 kfifo_init(&ctx->bitstream_fifo,
1709 ctx->bitstream.vaddr, ctx->bitstream.size); 1793 ctx->bitstream.vaddr, ctx->bitstream.size);
1710 } 1794 }
@@ -1835,6 +1919,8 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1835 } 1919 }
1836 mutex_unlock(&ctx->bitstream_mutex); 1920 mutex_unlock(&ctx->bitstream_mutex);
1837 1921
1922 trace_coda_dec_pic_done(ctx, &ctx->frame_metas[decoded_idx]);
1923
1838 val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7; 1924 val = coda_read(dev, CODA_RET_DEC_PIC_TYPE) & 0x7;
1839 if (val == 0) 1925 if (val == 0)
1840 ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME; 1926 ctx->frame_types[decoded_idx] = V4L2_BUF_FLAG_KEYFRAME;
@@ -1874,6 +1960,8 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1874 dst_buf->v4l2_buf.timecode = meta->timecode; 1960 dst_buf->v4l2_buf.timecode = meta->timecode;
1875 dst_buf->v4l2_buf.timestamp = meta->timestamp; 1961 dst_buf->v4l2_buf.timestamp = meta->timestamp;
1876 1962
1963 trace_coda_dec_rot_done(ctx, meta, dst_buf);
1964
1877 switch (q_data_dst->fourcc) { 1965 switch (q_data_dst->fourcc) {
1878 case V4L2_PIX_FMT_YUV420: 1966 case V4L2_PIX_FMT_YUV420:
1879 case V4L2_PIX_FMT_YVU420: 1967 case V4L2_PIX_FMT_YVU420:
@@ -1906,6 +1994,7 @@ static void coda_finish_decode(struct coda_ctx *ctx)
1906 1994
1907const struct coda_context_ops coda_bit_decode_ops = { 1995const struct coda_context_ops coda_bit_decode_ops = {
1908 .queue_init = coda_decoder_queue_init, 1996 .queue_init = coda_decoder_queue_init,
1997 .reqbufs = coda_decoder_reqbufs,
1909 .start_streaming = coda_start_decoding, 1998 .start_streaming = coda_start_decoding,
1910 .prepare_run = coda_prepare_decode, 1999 .prepare_run = coda_prepare_decode,
1911 .finish_run = coda_finish_decode, 2000 .finish_run = coda_finish_decode,
@@ -1931,6 +2020,8 @@ irqreturn_t coda_irq_handler(int irq, void *data)
1931 return IRQ_HANDLED; 2020 return IRQ_HANDLED;
1932 } 2021 }
1933 2022
2023 trace_coda_bit_done(ctx);
2024
1934 if (ctx->aborting) { 2025 if (ctx->aborting) {
1935 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, 2026 v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
1936 "task has been aborted\n"); 2027 "task has been aborted\n");
diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c
index 6f32e6d6b156..8e6fe0200117 100644
--- a/drivers/media/platform/coda/coda-common.c
+++ b/drivers/media/platform/coda/coda-common.c
@@ -46,7 +46,6 @@
46#define CODADX6_MAX_INSTANCES 4 46#define CODADX6_MAX_INSTANCES 4
47#define CODA_MAX_FORMATS 4 47#define CODA_MAX_FORMATS 4
48 48
49#define CODA_PARA_BUF_SIZE (10 * 1024)
50#define CODA_ISRAM_SIZE (2048 * 2) 49#define CODA_ISRAM_SIZE (2048 * 2)
51 50
52#define MIN_W 176 51#define MIN_W 176
@@ -696,6 +695,26 @@ static int coda_s_fmt_vid_out(struct file *file, void *priv,
696 return coda_s_fmt(ctx, &f_cap); 695 return coda_s_fmt(ctx, &f_cap);
697} 696}
698 697
698static int coda_reqbufs(struct file *file, void *priv,
699 struct v4l2_requestbuffers *rb)
700{
701 struct coda_ctx *ctx = fh_to_ctx(priv);
702 int ret;
703
704 ret = v4l2_m2m_reqbufs(file, ctx->fh.m2m_ctx, rb);
705 if (ret)
706 return ret;
707
708 /*
709 * Allow to allocate instance specific per-context buffers, such as
710 * bitstream ringbuffer, slice buffer, work buffer, etc. if needed.
711 */
712 if (rb->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && ctx->ops->reqbufs)
713 return ctx->ops->reqbufs(ctx, rb);
714
715 return 0;
716}
717
699static int coda_qbuf(struct file *file, void *priv, 718static int coda_qbuf(struct file *file, void *priv,
700 struct v4l2_buffer *buf) 719 struct v4l2_buffer *buf)
701{ 720{
@@ -841,7 +860,7 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
841 .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out, 860 .vidioc_try_fmt_vid_out = coda_try_fmt_vid_out,
842 .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out, 861 .vidioc_s_fmt_vid_out = coda_s_fmt_vid_out,
843 862
844 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, 863 .vidioc_reqbufs = coda_reqbufs,
845 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, 864 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
846 865
847 .vidioc_qbuf = coda_qbuf, 866 .vidioc_qbuf = coda_qbuf,
@@ -1173,7 +1192,7 @@ static void coda_buf_queue(struct vb2_buffer *vb)
1173 mutex_lock(&ctx->bitstream_mutex); 1192 mutex_lock(&ctx->bitstream_mutex);
1174 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); 1193 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1175 if (vb2_is_streaming(vb->vb2_queue)) 1194 if (vb2_is_streaming(vb->vb2_queue))
1176 coda_fill_bitstream(ctx); 1195 coda_fill_bitstream(ctx, true);
1177 mutex_unlock(&ctx->bitstream_mutex); 1196 mutex_unlock(&ctx->bitstream_mutex);
1178 } else { 1197 } else {
1179 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb); 1198 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
@@ -1215,8 +1234,9 @@ void coda_free_aux_buf(struct coda_dev *dev,
1215 buf->vaddr, buf->paddr); 1234 buf->vaddr, buf->paddr);
1216 buf->vaddr = NULL; 1235 buf->vaddr = NULL;
1217 buf->size = 0; 1236 buf->size = 0;
1237 debugfs_remove(buf->dentry);
1238 buf->dentry = NULL;
1218 } 1239 }
1219 debugfs_remove(buf->dentry);
1220} 1240}
1221 1241
1222static int coda_start_streaming(struct vb2_queue *q, unsigned int count) 1242static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
@@ -1232,9 +1252,9 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
1232 if (q_data_src->fourcc == V4L2_PIX_FMT_H264 || 1252 if (q_data_src->fourcc == V4L2_PIX_FMT_H264 ||
1233 (q_data_src->fourcc == V4L2_PIX_FMT_JPEG && 1253 (q_data_src->fourcc == V4L2_PIX_FMT_JPEG &&
1234 ctx->dev->devtype->product == CODA_7541)) { 1254 ctx->dev->devtype->product == CODA_7541)) {
1235 /* copy the buffers that where queued before streamon */ 1255 /* copy the buffers that were queued before streamon */
1236 mutex_lock(&ctx->bitstream_mutex); 1256 mutex_lock(&ctx->bitstream_mutex);
1237 coda_fill_bitstream(ctx); 1257 coda_fill_bitstream(ctx, false);
1238 mutex_unlock(&ctx->bitstream_mutex); 1258 mutex_unlock(&ctx->bitstream_mutex);
1239 1259
1240 if (coda_get_bitstream_payload(ctx) < 512) { 1260 if (coda_get_bitstream_payload(ctx) < 512) {
@@ -1262,12 +1282,23 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
1262 if (!(ctx->streamon_out & ctx->streamon_cap)) 1282 if (!(ctx->streamon_out & ctx->streamon_cap))
1263 return 0; 1283 return 0;
1264 1284
1285 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1286 if ((q_data_src->width != q_data_dst->width &&
1287 round_up(q_data_src->width, 16) != q_data_dst->width) ||
1288 (q_data_src->height != q_data_dst->height &&
1289 round_up(q_data_src->height, 16) != q_data_dst->height)) {
1290 v4l2_err(v4l2_dev, "can't convert %dx%d to %dx%d\n",
1291 q_data_src->width, q_data_src->height,
1292 q_data_dst->width, q_data_dst->height);
1293 ret = -EINVAL;
1294 goto err;
1295 }
1296
1265 /* Allow BIT decoder device_run with no new buffers queued */ 1297 /* Allow BIT decoder device_run with no new buffers queued */
1266 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit) 1298 if (ctx->inst_type == CODA_INST_DECODER && ctx->use_bit)
1267 v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true); 1299 v4l2_m2m_set_src_buffered(ctx->fh.m2m_ctx, true);
1268 1300
1269 ctx->gopcounter = ctx->params.gop_size - 1; 1301 ctx->gopcounter = ctx->params.gop_size - 1;
1270 q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1271 1302
1272 ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc, 1303 ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
1273 q_data_dst->fourcc); 1304 q_data_dst->fourcc);
@@ -1308,6 +1339,9 @@ static void coda_stop_streaming(struct vb2_queue *q)
1308 struct coda_ctx *ctx = vb2_get_drv_priv(q); 1339 struct coda_ctx *ctx = vb2_get_drv_priv(q);
1309 struct coda_dev *dev = ctx->dev; 1340 struct coda_dev *dev = ctx->dev;
1310 struct vb2_buffer *buf; 1341 struct vb2_buffer *buf;
1342 bool stop;
1343
1344 stop = ctx->streamon_out && ctx->streamon_cap;
1311 1345
1312 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 1346 if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1313 v4l2_dbg(1, coda_debug, &dev->v4l2_dev, 1347 v4l2_dbg(1, coda_debug, &dev->v4l2_dev,
@@ -1332,7 +1366,7 @@ static void coda_stop_streaming(struct vb2_queue *q)
1332 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); 1366 v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR);
1333 } 1367 }
1334 1368
1335 if (!ctx->streamon_out && !ctx->streamon_cap) { 1369 if (stop) {
1336 struct coda_buffer_meta *meta; 1370 struct coda_buffer_meta *meta;
1337 1371
1338 if (ctx->ops->seq_end_work) { 1372 if (ctx->ops->seq_end_work) {
@@ -1457,7 +1491,7 @@ static const struct v4l2_ctrl_ops coda_ctrl_ops = {
1457static void coda_encode_ctrls(struct coda_ctx *ctx) 1491static void coda_encode_ctrls(struct coda_ctx *ctx)
1458{ 1492{
1459 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, 1493 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1460 V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1, 0); 1494 V4L2_CID_MPEG_VIDEO_BITRATE, 0, 32767000, 1000, 0);
1461 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, 1495 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
1462 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16); 1496 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 60, 1, 16);
1463 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops, 1497 v4l2_ctrl_new_std(&ctx->ctrls, &coda_ctrl_ops,
@@ -1541,6 +1575,13 @@ static int coda_queue_init(struct coda_ctx *ctx, struct vb2_queue *vq)
1541 vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); 1575 vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1542 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1576 vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1543 vq->lock = &ctx->dev->dev_mutex; 1577 vq->lock = &ctx->dev->dev_mutex;
1578 /* One way to indicate end-of-stream for coda is to set the
1579 * bytesused == 0. However by default videobuf2 handles bytesused
1580 * equal to 0 as a special case and changes its value to the size
1581 * of the buffer. Set the allow_zero_bytesused flag, so
1582 * that videobuf2 will keep the value of bytesused intact.
1583 */
1584 vq->allow_zero_bytesused = 1;
1544 1585
1545 return vb2_queue_init(vq); 1586 return vb2_queue_init(vq);
1546} 1587}
@@ -1621,6 +1662,11 @@ static int coda_open(struct file *file)
1621 set_bit(idx, &dev->instance_mask); 1662 set_bit(idx, &dev->instance_mask);
1622 1663
1623 name = kasprintf(GFP_KERNEL, "context%d", idx); 1664 name = kasprintf(GFP_KERNEL, "context%d", idx);
1665 if (!name) {
1666 ret = -ENOMEM;
1667 goto err_coda_name_init;
1668 }
1669
1624 ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root); 1670 ctx->debugfs_entry = debugfs_create_dir(name, dev->debugfs_root);
1625 kfree(name); 1671 kfree(name);
1626 1672
@@ -1682,28 +1728,6 @@ static int coda_open(struct file *file)
1682 1728
1683 ctx->fh.ctrl_handler = &ctx->ctrls; 1729 ctx->fh.ctrl_handler = &ctx->ctrls;
1684 1730
1685 if (ctx->use_bit) {
1686 ret = coda_alloc_context_buf(ctx, &ctx->parabuf,
1687 CODA_PARA_BUF_SIZE, "parabuf");
1688 if (ret < 0) {
1689 v4l2_err(&dev->v4l2_dev, "failed to allocate parabuf");
1690 goto err_dma_alloc;
1691 }
1692 }
1693 if (ctx->use_bit && ctx->inst_type == CODA_INST_DECODER) {
1694 ctx->bitstream.size = CODA_MAX_FRAME_SIZE;
1695 ctx->bitstream.vaddr = dma_alloc_writecombine(
1696 &dev->plat_dev->dev, ctx->bitstream.size,
1697 &ctx->bitstream.paddr, GFP_KERNEL);
1698 if (!ctx->bitstream.vaddr) {
1699 v4l2_err(&dev->v4l2_dev,
1700 "failed to allocate bitstream ringbuffer");
1701 ret = -ENOMEM;
1702 goto err_dma_writecombine;
1703 }
1704 }
1705 kfifo_init(&ctx->bitstream_fifo,
1706 ctx->bitstream.vaddr, ctx->bitstream.size);
1707 mutex_init(&ctx->bitstream_mutex); 1731 mutex_init(&ctx->bitstream_mutex);
1708 mutex_init(&ctx->buffer_mutex); 1732 mutex_init(&ctx->buffer_mutex);
1709 INIT_LIST_HEAD(&ctx->buffer_meta_list); 1733 INIT_LIST_HEAD(&ctx->buffer_meta_list);
@@ -1717,12 +1741,6 @@ static int coda_open(struct file *file)
1717 1741
1718 return 0; 1742 return 0;
1719 1743
1720err_dma_writecombine:
1721 if (ctx->dev->devtype->product == CODA_DX6)
1722 coda_free_aux_buf(dev, &ctx->workbuf);
1723 coda_free_aux_buf(dev, &ctx->parabuf);
1724err_dma_alloc:
1725 v4l2_ctrl_handler_free(&ctx->ctrls);
1726err_ctrls_setup: 1744err_ctrls_setup:
1727 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); 1745 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1728err_ctx_init: 1746err_ctx_init:
@@ -1735,6 +1753,7 @@ err_pm_get:
1735 v4l2_fh_del(&ctx->fh); 1753 v4l2_fh_del(&ctx->fh);
1736 v4l2_fh_exit(&ctx->fh); 1754 v4l2_fh_exit(&ctx->fh);
1737 clear_bit(ctx->idx, &dev->instance_mask); 1755 clear_bit(ctx->idx, &dev->instance_mask);
1756err_coda_name_init:
1738err_coda_max: 1757err_coda_max:
1739 kfree(ctx); 1758 kfree(ctx);
1740 return ret; 1759 return ret;
@@ -1764,14 +1783,9 @@ static int coda_release(struct file *file)
1764 list_del(&ctx->list); 1783 list_del(&ctx->list);
1765 coda_unlock(ctx); 1784 coda_unlock(ctx);
1766 1785
1767 if (ctx->bitstream.vaddr) {
1768 dma_free_writecombine(&dev->plat_dev->dev, ctx->bitstream.size,
1769 ctx->bitstream.vaddr, ctx->bitstream.paddr);
1770 }
1771 if (ctx->dev->devtype->product == CODA_DX6) 1786 if (ctx->dev->devtype->product == CODA_DX6)
1772 coda_free_aux_buf(dev, &ctx->workbuf); 1787 coda_free_aux_buf(dev, &ctx->workbuf);
1773 1788
1774 coda_free_aux_buf(dev, &ctx->parabuf);
1775 v4l2_ctrl_handler_free(&ctx->ctrls); 1789 v4l2_ctrl_handler_free(&ctx->ctrls);
1776 clk_disable_unprepare(dev->clk_ahb); 1790 clk_disable_unprepare(dev->clk_ahb);
1777 clk_disable_unprepare(dev->clk_per); 1791 clk_disable_unprepare(dev->clk_per);
@@ -1901,8 +1915,7 @@ static int coda_register_device(struct coda_dev *dev, int i)
1901 if (i >= dev->devtype->num_vdevs) 1915 if (i >= dev->devtype->num_vdevs)
1902 return -EINVAL; 1916 return -EINVAL;
1903 1917
1904 snprintf(vfd->name, sizeof(vfd->name), "%s", 1918 strlcpy(vfd->name, dev->devtype->vdevs[i]->name, sizeof(vfd->name));
1905 dev->devtype->vdevs[i]->name);
1906 vfd->fops = &coda_fops; 1919 vfd->fops = &coda_fops;
1907 vfd->ioctl_ops = &coda_ioctl_ops; 1920 vfd->ioctl_ops = &coda_ioctl_ops;
1908 vfd->release = video_device_release_empty, 1921 vfd->release = video_device_release_empty,
@@ -1933,10 +1946,8 @@ static void coda_fw_callback(const struct firmware *fw, void *context)
1933 /* allocate auxiliary per-device code buffer for the BIT processor */ 1946 /* allocate auxiliary per-device code buffer for the BIT processor */
1934 ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf", 1947 ret = coda_alloc_aux_buf(dev, &dev->codebuf, fw->size, "codebuf",
1935 dev->debugfs_root); 1948 dev->debugfs_root);
1936 if (ret < 0) { 1949 if (ret < 0)
1937 dev_err(&pdev->dev, "failed to allocate code buffer\n");
1938 goto put_pm; 1950 goto put_pm;
1939 }
1940 1951
1941 /* Copy the whole firmware image to the code buffer */ 1952 /* Copy the whole firmware image to the code buffer */
1942 memcpy(dev->codebuf.vaddr, fw->data, fw->size); 1953 memcpy(dev->codebuf.vaddr, fw->data, fw->size);
@@ -2174,20 +2185,16 @@ static int coda_probe(struct platform_device *pdev)
2174 ret = coda_alloc_aux_buf(dev, &dev->workbuf, 2185 ret = coda_alloc_aux_buf(dev, &dev->workbuf,
2175 dev->devtype->workbuf_size, "workbuf", 2186 dev->devtype->workbuf_size, "workbuf",
2176 dev->debugfs_root); 2187 dev->debugfs_root);
2177 if (ret < 0) { 2188 if (ret < 0)
2178 dev_err(&pdev->dev, "failed to allocate work buffer\n");
2179 goto err_v4l2_register; 2189 goto err_v4l2_register;
2180 }
2181 } 2190 }
2182 2191
2183 if (dev->devtype->tempbuf_size) { 2192 if (dev->devtype->tempbuf_size) {
2184 ret = coda_alloc_aux_buf(dev, &dev->tempbuf, 2193 ret = coda_alloc_aux_buf(dev, &dev->tempbuf,
2185 dev->devtype->tempbuf_size, "tempbuf", 2194 dev->devtype->tempbuf_size, "tempbuf",
2186 dev->debugfs_root); 2195 dev->debugfs_root);
2187 if (ret < 0) { 2196 if (ret < 0)
2188 dev_err(&pdev->dev, "failed to allocate temp buffer\n");
2189 goto err_v4l2_register; 2197 goto err_v4l2_register;
2190 }
2191 } 2198 }
2192 2199
2193 dev->iram.size = dev->devtype->iram_size; 2200 dev->iram.size = dev->devtype->iram_size;
diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c
index 8fa3e353f9e2..11e734bc2cbd 100644
--- a/drivers/media/platform/coda/coda-jpeg.c
+++ b/drivers/media/platform/coda/coda-jpeg.c
@@ -13,6 +13,7 @@
13#include <linux/swab.h> 13#include <linux/swab.h>
14 14
15#include "coda.h" 15#include "coda.h"
16#include "trace.h"
16 17
17#define SOI_MARKER 0xffd8 18#define SOI_MARKER 0xffd8
18#define EOI_MARKER 0xffd9 19#define EOI_MARKER 0xffd9
diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h
index 0c35cd5032ff..6a5c8f6c688e 100644
--- a/drivers/media/platform/coda/coda.h
+++ b/drivers/media/platform/coda/coda.h
@@ -12,6 +12,9 @@
12 * (at your option) any later version. 12 * (at your option) any later version.
13 */ 13 */
14 14
15#ifndef __CODA_H__
16#define __CODA_H__
17
15#include <linux/debugfs.h> 18#include <linux/debugfs.h>
16#include <linux/irqreturn.h> 19#include <linux/irqreturn.h>
17#include <linux/mutex.h> 20#include <linux/mutex.h>
@@ -26,7 +29,6 @@
26#include "coda_regs.h" 29#include "coda_regs.h"
27 30
28#define CODA_MAX_FRAMEBUFFERS 8 31#define CODA_MAX_FRAMEBUFFERS 8
29#define CODA_MAX_FRAME_SIZE 0x100000
30#define FMO_SLICE_SAVE_BUF_SIZE (32) 32#define FMO_SLICE_SAVE_BUF_SIZE (32)
31 33
32enum { 34enum {
@@ -178,6 +180,7 @@ struct coda_ctx;
178struct coda_context_ops { 180struct coda_context_ops {
179 int (*queue_init)(void *priv, struct vb2_queue *src_vq, 181 int (*queue_init)(void *priv, struct vb2_queue *src_vq,
180 struct vb2_queue *dst_vq); 182 struct vb2_queue *dst_vq);
183 int (*reqbufs)(struct coda_ctx *ctx, struct v4l2_requestbuffers *rb);
181 int (*start_streaming)(struct coda_ctx *ctx); 184 int (*start_streaming)(struct coda_ctx *ctx);
182 int (*prepare_run)(struct coda_ctx *ctx); 185 int (*prepare_run)(struct coda_ctx *ctx);
183 void (*finish_run)(struct coda_ctx *ctx); 186 void (*finish_run)(struct coda_ctx *ctx);
@@ -249,13 +252,6 @@ int coda_alloc_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf,
249 size_t size, const char *name, struct dentry *parent); 252 size_t size, const char *name, struct dentry *parent);
250void coda_free_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf); 253void coda_free_aux_buf(struct coda_dev *dev, struct coda_aux_buf *buf);
251 254
252static inline int coda_alloc_context_buf(struct coda_ctx *ctx,
253 struct coda_aux_buf *buf, size_t size,
254 const char *name)
255{
256 return coda_alloc_aux_buf(ctx->dev, buf, size, name, ctx->debugfs_entry);
257}
258
259int coda_encoder_queue_init(void *priv, struct vb2_queue *src_vq, 255int coda_encoder_queue_init(void *priv, struct vb2_queue *src_vq,
260 struct vb2_queue *dst_vq); 256 struct vb2_queue *dst_vq);
261int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq, 257int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq,
@@ -263,7 +259,7 @@ int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq,
263 259
264int coda_hw_reset(struct coda_ctx *ctx); 260int coda_hw_reset(struct coda_ctx *ctx);
265 261
266void coda_fill_bitstream(struct coda_ctx *ctx); 262void coda_fill_bitstream(struct coda_ctx *ctx, bool streaming);
267 263
268void coda_set_gdi_regs(struct coda_ctx *ctx); 264void coda_set_gdi_regs(struct coda_ctx *ctx);
269 265
@@ -284,7 +280,7 @@ const char *coda_product_name(int product);
284 280
285int coda_check_firmware(struct coda_dev *dev); 281int coda_check_firmware(struct coda_dev *dev);
286 282
287static inline int coda_get_bitstream_payload(struct coda_ctx *ctx) 283static inline unsigned int coda_get_bitstream_payload(struct coda_ctx *ctx)
288{ 284{
289 return kfifo_len(&ctx->bitstream_fifo); 285 return kfifo_len(&ctx->bitstream_fifo);
290} 286}
@@ -301,3 +297,5 @@ extern const struct coda_context_ops coda_bit_encode_ops;
301extern const struct coda_context_ops coda_bit_decode_ops; 297extern const struct coda_context_ops coda_bit_decode_ops;
302 298
303irqreturn_t coda_irq_handler(int irq, void *data); 299irqreturn_t coda_irq_handler(int irq, void *data);
300
301#endif /* __CODA_H__ */
diff --git a/drivers/media/platform/coda/trace.h b/drivers/media/platform/coda/trace.h
new file mode 100644
index 000000000000..d1d06cbd1f6a
--- /dev/null
+++ b/drivers/media/platform/coda/trace.h
@@ -0,0 +1,203 @@
1#undef TRACE_SYSTEM
2#define TRACE_SYSTEM coda
3
4#if !defined(__CODA_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ)
5#define __CODA_TRACE_H__
6
7#include <linux/tracepoint.h>
8#include <media/videobuf2-core.h>
9
10#include "coda.h"
11
12#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM)
13
14TRACE_EVENT(coda_bit_run,
15 TP_PROTO(struct coda_ctx *ctx, int cmd),
16
17 TP_ARGS(ctx, cmd),
18
19 TP_STRUCT__entry(
20 __field(int, minor)
21 __field(int, ctx)
22 __field(int, cmd)
23 ),
24
25 TP_fast_assign(
26 __entry->minor = ctx->fh.vdev->minor;
27 __entry->ctx = ctx->idx;
28 __entry->cmd = cmd;
29 ),
30
31 TP_printk("minor = %d, ctx = %d, cmd = %d",
32 __entry->minor, __entry->ctx, __entry->cmd)
33);
34
35TRACE_EVENT(coda_bit_done,
36 TP_PROTO(struct coda_ctx *ctx),
37
38 TP_ARGS(ctx),
39
40 TP_STRUCT__entry(
41 __field(int, minor)
42 __field(int, ctx)
43 ),
44
45 TP_fast_assign(
46 __entry->minor = ctx->fh.vdev->minor;
47 __entry->ctx = ctx->idx;
48 ),
49
50 TP_printk("minor = %d, ctx = %d", __entry->minor, __entry->ctx)
51);
52
53TRACE_EVENT(coda_enc_pic_run,
54 TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf),
55
56 TP_ARGS(ctx, buf),
57
58 TP_STRUCT__entry(
59 __field(int, minor)
60 __field(int, index)
61 __field(int, ctx)
62 ),
63
64 TP_fast_assign(
65 __entry->minor = ctx->fh.vdev->minor;
66 __entry->index = buf->v4l2_buf.index;
67 __entry->ctx = ctx->idx;
68 ),
69
70 TP_printk("minor = %d, index = %d, ctx = %d",
71 __entry->minor, __entry->index, __entry->ctx)
72);
73
74TRACE_EVENT(coda_enc_pic_done,
75 TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf),
76
77 TP_ARGS(ctx, buf),
78
79 TP_STRUCT__entry(
80 __field(int, minor)
81 __field(int, index)
82 __field(int, ctx)
83 ),
84
85 TP_fast_assign(
86 __entry->minor = ctx->fh.vdev->minor;
87 __entry->index = buf->v4l2_buf.index;
88 __entry->ctx = ctx->idx;
89 ),
90
91 TP_printk("minor = %d, index = %d, ctx = %d",
92 __entry->minor, __entry->index, __entry->ctx)
93);
94
95TRACE_EVENT(coda_bit_queue,
96 TP_PROTO(struct coda_ctx *ctx, struct vb2_buffer *buf,
97 struct coda_buffer_meta *meta),
98
99 TP_ARGS(ctx, buf, meta),
100
101 TP_STRUCT__entry(
102 __field(int, minor)
103 __field(int, index)
104 __field(int, start)
105 __field(int, end)
106 __field(int, ctx)
107 ),
108
109 TP_fast_assign(
110 __entry->minor = ctx->fh.vdev->minor;
111 __entry->index = buf->v4l2_buf.index;
112 __entry->start = meta->start;
113 __entry->end = meta->end;
114 __entry->ctx = ctx->idx;
115 ),
116
117 TP_printk("minor = %d, index = %d, start = 0x%x, end = 0x%x, ctx = %d",
118 __entry->minor, __entry->index, __entry->start, __entry->end,
119 __entry->ctx)
120);
121
122TRACE_EVENT(coda_dec_pic_run,
123 TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta),
124
125 TP_ARGS(ctx, meta),
126
127 TP_STRUCT__entry(
128 __field(int, minor)
129 __field(int, start)
130 __field(int, end)
131 __field(int, ctx)
132 ),
133
134 TP_fast_assign(
135 __entry->minor = ctx->fh.vdev->minor;
136 __entry->start = meta ? meta->start : 0;
137 __entry->end = meta ? meta->end : 0;
138 __entry->ctx = ctx->idx;
139 ),
140
141 TP_printk("minor = %d, start = 0x%x, end = 0x%x, ctx = %d",
142 __entry->minor, __entry->start, __entry->end, __entry->ctx)
143);
144
145TRACE_EVENT(coda_dec_pic_done,
146 TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta),
147
148 TP_ARGS(ctx, meta),
149
150 TP_STRUCT__entry(
151 __field(int, minor)
152 __field(int, start)
153 __field(int, end)
154 __field(int, ctx)
155 ),
156
157 TP_fast_assign(
158 __entry->minor = ctx->fh.vdev->minor;
159 __entry->start = meta->start;
160 __entry->end = meta->end;
161 __entry->ctx = ctx->idx;
162 ),
163
164 TP_printk("minor = %d, start = 0x%x, end = 0x%x, ctx = %d",
165 __entry->minor, __entry->start, __entry->end, __entry->ctx)
166);
167
168TRACE_EVENT(coda_dec_rot_done,
169 TP_PROTO(struct coda_ctx *ctx, struct coda_buffer_meta *meta,
170 struct vb2_buffer *buf),
171
172 TP_ARGS(ctx, meta, buf),
173
174 TP_STRUCT__entry(
175 __field(int, minor)
176 __field(int, start)
177 __field(int, end)
178 __field(int, index)
179 __field(int, ctx)
180 ),
181
182 TP_fast_assign(
183 __entry->minor = ctx->fh.vdev->minor;
184 __entry->start = meta->start;
185 __entry->end = meta->end;
186 __entry->index = buf->v4l2_buf.index;
187 __entry->ctx = ctx->idx;
188 ),
189
190 TP_printk("minor = %d, start = 0x%x, end = 0x%x, index = %d, ctx = %d",
191 __entry->minor, __entry->start, __entry->end, __entry->index,
192 __entry->ctx)
193);
194
195#endif /* __CODA_TRACE_H__ */
196
197#undef TRACE_INCLUDE_PATH
198#define TRACE_INCLUDE_PATH .
199#undef TRACE_INCLUDE_FILE
200#define TRACE_INCLUDE_FILE trace
201
202/* This part must be outside protection */
203#include <trace/define_trace.h>
diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index b41bf7e822c8..ccfcf3f528d3 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
@@ -1871,16 +1871,9 @@ static int vpfe_probe(struct platform_device *pdev)
1871 goto probe_free_ccdc_cfg_mem; 1871 goto probe_free_ccdc_cfg_mem;
1872 } 1872 }
1873 1873
1874 /* Allocate memory for video device */ 1874 vfd = &vpfe_dev->video_dev;
1875 vfd = video_device_alloc();
1876 if (NULL == vfd) {
1877 ret = -ENOMEM;
1878 v4l2_err(pdev->dev.driver, "Unable to alloc video device\n");
1879 goto probe_out_release_irq;
1880 }
1881
1882 /* Initialize field of video device */ 1875 /* Initialize field of video device */
1883 vfd->release = video_device_release; 1876 vfd->release = video_device_release_empty;
1884 vfd->fops = &vpfe_fops; 1877 vfd->fops = &vpfe_fops;
1885 vfd->ioctl_ops = &vpfe_ioctl_ops; 1878 vfd->ioctl_ops = &vpfe_ioctl_ops;
1886 vfd->tvnorms = 0; 1879 vfd->tvnorms = 0;
@@ -1891,14 +1884,12 @@ static int vpfe_probe(struct platform_device *pdev)
1891 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff, 1884 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
1892 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff, 1885 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
1893 (VPFE_CAPTURE_VERSION_CODE) & 0xff); 1886 (VPFE_CAPTURE_VERSION_CODE) & 0xff);
1894 /* Set video_dev to the video device */
1895 vpfe_dev->video_dev = vfd;
1896 1887
1897 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev); 1888 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
1898 if (ret) { 1889 if (ret) {
1899 v4l2_err(pdev->dev.driver, 1890 v4l2_err(pdev->dev.driver,
1900 "Unable to register v4l2 device.\n"); 1891 "Unable to register v4l2 device.\n");
1901 goto probe_out_video_release; 1892 goto probe_out_release_irq;
1902 } 1893 }
1903 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n"); 1894 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
1904 spin_lock_init(&vpfe_dev->irqlock); 1895 spin_lock_init(&vpfe_dev->irqlock);
@@ -1914,7 +1905,7 @@ static int vpfe_probe(struct platform_device *pdev)
1914 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, 1905 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1915 "video_dev=%p\n", &vpfe_dev->video_dev); 1906 "video_dev=%p\n", &vpfe_dev->video_dev);
1916 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1907 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1917 ret = video_register_device(vpfe_dev->video_dev, 1908 ret = video_register_device(&vpfe_dev->video_dev,
1918 VFL_TYPE_GRABBER, -1); 1909 VFL_TYPE_GRABBER, -1);
1919 1910
1920 if (ret) { 1911 if (ret) {
@@ -1927,7 +1918,7 @@ static int vpfe_probe(struct platform_device *pdev)
1927 /* set the driver data in platform device */ 1918 /* set the driver data in platform device */
1928 platform_set_drvdata(pdev, vpfe_dev); 1919 platform_set_drvdata(pdev, vpfe_dev);
1929 /* set driver private data */ 1920 /* set driver private data */
1930 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev); 1921 video_set_drvdata(&vpfe_dev->video_dev, vpfe_dev);
1931 i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id); 1922 i2c_adap = i2c_get_adapter(vpfe_cfg->i2c_adapter_id);
1932 num_subdevs = vpfe_cfg->num_subdevs; 1923 num_subdevs = vpfe_cfg->num_subdevs;
1933 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs, 1924 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
@@ -1979,12 +1970,9 @@ static int vpfe_probe(struct platform_device *pdev)
1979probe_sd_out: 1970probe_sd_out:
1980 kfree(vpfe_dev->sd); 1971 kfree(vpfe_dev->sd);
1981probe_out_video_unregister: 1972probe_out_video_unregister:
1982 video_unregister_device(vpfe_dev->video_dev); 1973 video_unregister_device(&vpfe_dev->video_dev);
1983probe_out_v4l2_unregister: 1974probe_out_v4l2_unregister:
1984 v4l2_device_unregister(&vpfe_dev->v4l2_dev); 1975 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
1985probe_out_video_release:
1986 if (!video_is_registered(vpfe_dev->video_dev))
1987 video_device_release(vpfe_dev->video_dev);
1988probe_out_release_irq: 1976probe_out_release_irq:
1989 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 1977 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
1990probe_free_ccdc_cfg_mem: 1978probe_free_ccdc_cfg_mem:
@@ -2007,7 +1995,7 @@ static int vpfe_remove(struct platform_device *pdev)
2007 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev); 1995 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2008 kfree(vpfe_dev->sd); 1996 kfree(vpfe_dev->sd);
2009 v4l2_device_unregister(&vpfe_dev->v4l2_dev); 1997 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2010 video_unregister_device(vpfe_dev->video_dev); 1998 video_unregister_device(&vpfe_dev->video_dev);
2011 kfree(vpfe_dev); 1999 kfree(vpfe_dev);
2012 kfree(ccdc_cfg); 2000 kfree(ccdc_cfg);
2013 return 0; 2001 return 0;
diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
index fa0a51521772..a5f548138b91 100644
--- a/drivers/media/platform/davinci/vpif_capture.c
+++ b/drivers/media/platform/davinci/vpif_capture.c
@@ -712,7 +712,7 @@ static int vpif_set_input(
712 ch->vpifparams.iface = chan_cfg->vpif_if; 712 ch->vpifparams.iface = chan_cfg->vpif_if;
713 713
714 /* update tvnorms from the sub device input info */ 714 /* update tvnorms from the sub device input info */
715 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std; 715 ch->video_dev.tvnorms = chan_cfg->inputs[index].input.std;
716 return 0; 716 return 0;
717} 717}
718 718
@@ -1337,7 +1337,7 @@ static int vpif_probe_complete(void)
1337 struct video_device *vdev; 1337 struct video_device *vdev;
1338 struct channel_obj *ch; 1338 struct channel_obj *ch;
1339 struct vb2_queue *q; 1339 struct vb2_queue *q;
1340 int i, j, err, k; 1340 int j, err, k;
1341 1341
1342 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { 1342 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
1343 ch = vpif_obj.dev[j]; 1343 ch = vpif_obj.dev[j];
@@ -1384,16 +1384,16 @@ static int vpif_probe_complete(void)
1384 INIT_LIST_HEAD(&common->dma_queue); 1384 INIT_LIST_HEAD(&common->dma_queue);
1385 1385
1386 /* Initialize the video_device structure */ 1386 /* Initialize the video_device structure */
1387 vdev = ch->video_dev; 1387 vdev = &ch->video_dev;
1388 strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); 1388 strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
1389 vdev->release = video_device_release; 1389 vdev->release = video_device_release_empty;
1390 vdev->fops = &vpif_fops; 1390 vdev->fops = &vpif_fops;
1391 vdev->ioctl_ops = &vpif_ioctl_ops; 1391 vdev->ioctl_ops = &vpif_ioctl_ops;
1392 vdev->v4l2_dev = &vpif_obj.v4l2_dev; 1392 vdev->v4l2_dev = &vpif_obj.v4l2_dev;
1393 vdev->vfl_dir = VFL_DIR_RX; 1393 vdev->vfl_dir = VFL_DIR_RX;
1394 vdev->queue = q; 1394 vdev->queue = q;
1395 vdev->lock = &common->lock; 1395 vdev->lock = &common->lock;
1396 video_set_drvdata(ch->video_dev, ch); 1396 video_set_drvdata(&ch->video_dev, ch);
1397 err = video_register_device(vdev, 1397 err = video_register_device(vdev,
1398 VFL_TYPE_GRABBER, (j ? 1 : 0)); 1398 VFL_TYPE_GRABBER, (j ? 1 : 0));
1399 if (err) 1399 if (err)
@@ -1410,14 +1410,9 @@ probe_out:
1410 common = &ch->common[k]; 1410 common = &ch->common[k];
1411 vb2_dma_contig_cleanup_ctx(common->alloc_ctx); 1411 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1412 /* Unregister video device */ 1412 /* Unregister video device */
1413 video_unregister_device(ch->video_dev); 1413 video_unregister_device(&ch->video_dev);
1414 } 1414 }
1415 kfree(vpif_obj.sd); 1415 kfree(vpif_obj.sd);
1416 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1417 ch = vpif_obj.dev[i];
1418 /* Note: does nothing if ch->video_dev == NULL */
1419 video_device_release(ch->video_dev);
1420 }
1421 v4l2_device_unregister(&vpif_obj.v4l2_dev); 1416 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1422 1417
1423 return err; 1418 return err;
@@ -1438,13 +1433,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
1438static __init int vpif_probe(struct platform_device *pdev) 1433static __init int vpif_probe(struct platform_device *pdev)
1439{ 1434{
1440 struct vpif_subdev_info *subdevdata; 1435 struct vpif_subdev_info *subdevdata;
1441 int i, j, err;
1442 int res_idx = 0;
1443 struct i2c_adapter *i2c_adap; 1436 struct i2c_adapter *i2c_adap;
1444 struct channel_obj *ch;
1445 struct video_device *vfd;
1446 struct resource *res; 1437 struct resource *res;
1447 int subdev_count; 1438 int subdev_count;
1439 int res_idx = 0;
1440 int i, err;
1448 1441
1449 vpif_dev = &pdev->dev; 1442 vpif_dev = &pdev->dev;
1450 1443
@@ -1472,24 +1465,6 @@ static __init int vpif_probe(struct platform_device *pdev)
1472 res_idx++; 1465 res_idx++;
1473 } 1466 }
1474 1467
1475 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1476 /* Get the pointer to the channel object */
1477 ch = vpif_obj.dev[i];
1478 /* Allocate memory for video device */
1479 vfd = video_device_alloc();
1480 if (NULL == vfd) {
1481 for (j = 0; j < i; j++) {
1482 ch = vpif_obj.dev[j];
1483 video_device_release(ch->video_dev);
1484 }
1485 err = -ENOMEM;
1486 goto vpif_unregister;
1487 }
1488
1489 /* Set video_dev to the video device */
1490 ch->video_dev = vfd;
1491 }
1492
1493 vpif_obj.config = pdev->dev.platform_data; 1468 vpif_obj.config = pdev->dev.platform_data;
1494 1469
1495 subdev_count = vpif_obj.config->subdev_count; 1470 subdev_count = vpif_obj.config->subdev_count;
@@ -1498,7 +1473,7 @@ static __init int vpif_probe(struct platform_device *pdev)
1498 if (vpif_obj.sd == NULL) { 1473 if (vpif_obj.sd == NULL) {
1499 vpif_err("unable to allocate memory for subdevice pointers\n"); 1474 vpif_err("unable to allocate memory for subdevice pointers\n");
1500 err = -ENOMEM; 1475 err = -ENOMEM;
1501 goto vpif_sd_error; 1476 goto vpif_unregister;
1502 } 1477 }
1503 1478
1504 if (!vpif_obj.config->asd_sizes) { 1479 if (!vpif_obj.config->asd_sizes) {
@@ -1541,13 +1516,6 @@ static __init int vpif_probe(struct platform_device *pdev)
1541probe_subdev_out: 1516probe_subdev_out:
1542 /* free sub devices memory */ 1517 /* free sub devices memory */
1543 kfree(vpif_obj.sd); 1518 kfree(vpif_obj.sd);
1544
1545vpif_sd_error:
1546 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1547 ch = vpif_obj.dev[i];
1548 /* Note: does nothing if ch->video_dev == NULL */
1549 video_device_release(ch->video_dev);
1550 }
1551vpif_unregister: 1519vpif_unregister:
1552 v4l2_device_unregister(&vpif_obj.v4l2_dev); 1520 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1553 1521
@@ -1576,7 +1544,7 @@ static int vpif_remove(struct platform_device *device)
1576 common = &ch->common[VPIF_VIDEO_INDEX]; 1544 common = &ch->common[VPIF_VIDEO_INDEX];
1577 vb2_dma_contig_cleanup_ctx(common->alloc_ctx); 1545 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1578 /* Unregister video device */ 1546 /* Unregister video device */
1579 video_unregister_device(ch->video_dev); 1547 video_unregister_device(&ch->video_dev);
1580 kfree(vpif_obj.dev[i]); 1548 kfree(vpif_obj.dev[i]);
1581 } 1549 }
1582 return 0; 1550 return 0;
diff --git a/drivers/media/platform/davinci/vpif_capture.h b/drivers/media/platform/davinci/vpif_capture.h
index f65d28d38e66..8b8a663f6b22 100644
--- a/drivers/media/platform/davinci/vpif_capture.h
+++ b/drivers/media/platform/davinci/vpif_capture.h
@@ -92,7 +92,7 @@ struct common_obj {
92 92
93struct channel_obj { 93struct channel_obj {
94 /* Identifies video device for this channel */ 94 /* Identifies video device for this channel */
95 struct video_device *video_dev; 95 struct video_device video_dev;
96 /* Indicates id of the field which is being displayed */ 96 /* Indicates id of the field which is being displayed */
97 u32 field_id; 97 u32 field_id;
98 /* flag to indicate whether decoder is initialized */ 98 /* flag to indicate whether decoder is initialized */
diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c
index 839c24de1fd8..682e5d578bf7 100644
--- a/drivers/media/platform/davinci/vpif_display.c
+++ b/drivers/media/platform/davinci/vpif_display.c
@@ -829,7 +829,7 @@ static int vpif_set_output(struct vpif_display_config *vpif_cfg,
829 ch->sd = sd; 829 ch->sd = sd;
830 if (chan_cfg->outputs != NULL) 830 if (chan_cfg->outputs != NULL)
831 /* update tvnorms from the sub device output info */ 831 /* update tvnorms from the sub device output info */
832 ch->video_dev->tvnorms = chan_cfg->outputs[index].output.std; 832 ch->video_dev.tvnorms = chan_cfg->outputs[index].output.std;
833 return 0; 833 return 0;
834} 834}
835 835
@@ -1204,16 +1204,16 @@ static int vpif_probe_complete(void)
1204 ch, &ch->video_dev); 1204 ch, &ch->video_dev);
1205 1205
1206 /* Initialize the video_device structure */ 1206 /* Initialize the video_device structure */
1207 vdev = ch->video_dev; 1207 vdev = &ch->video_dev;
1208 strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name)); 1208 strlcpy(vdev->name, VPIF_DRIVER_NAME, sizeof(vdev->name));
1209 vdev->release = video_device_release; 1209 vdev->release = video_device_release_empty;
1210 vdev->fops = &vpif_fops; 1210 vdev->fops = &vpif_fops;
1211 vdev->ioctl_ops = &vpif_ioctl_ops; 1211 vdev->ioctl_ops = &vpif_ioctl_ops;
1212 vdev->v4l2_dev = &vpif_obj.v4l2_dev; 1212 vdev->v4l2_dev = &vpif_obj.v4l2_dev;
1213 vdev->vfl_dir = VFL_DIR_TX; 1213 vdev->vfl_dir = VFL_DIR_TX;
1214 vdev->queue = q; 1214 vdev->queue = q;
1215 vdev->lock = &common->lock; 1215 vdev->lock = &common->lock;
1216 video_set_drvdata(ch->video_dev, ch); 1216 video_set_drvdata(&ch->video_dev, ch);
1217 err = video_register_device(vdev, VFL_TYPE_GRABBER, 1217 err = video_register_device(vdev, VFL_TYPE_GRABBER,
1218 (j ? 3 : 2)); 1218 (j ? 3 : 2));
1219 if (err < 0) 1219 if (err < 0)
@@ -1227,9 +1227,7 @@ probe_out:
1227 ch = vpif_obj.dev[k]; 1227 ch = vpif_obj.dev[k];
1228 common = &ch->common[k]; 1228 common = &ch->common[k];
1229 vb2_dma_contig_cleanup_ctx(common->alloc_ctx); 1229 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1230 video_unregister_device(ch->video_dev); 1230 video_unregister_device(&ch->video_dev);
1231 video_device_release(ch->video_dev);
1232 ch->video_dev = NULL;
1233 } 1231 }
1234 return err; 1232 return err;
1235} 1233}
@@ -1246,13 +1244,11 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
1246static __init int vpif_probe(struct platform_device *pdev) 1244static __init int vpif_probe(struct platform_device *pdev)
1247{ 1245{
1248 struct vpif_subdev_info *subdevdata; 1246 struct vpif_subdev_info *subdevdata;
1249 int i, j = 0, err = 0;
1250 int res_idx = 0;
1251 struct i2c_adapter *i2c_adap; 1247 struct i2c_adapter *i2c_adap;
1252 struct channel_obj *ch;
1253 struct video_device *vfd;
1254 struct resource *res; 1248 struct resource *res;
1255 int subdev_count; 1249 int subdev_count;
1250 int res_idx = 0;
1251 int i, err;
1256 1252
1257 vpif_dev = &pdev->dev; 1253 vpif_dev = &pdev->dev;
1258 err = initialize_vpif(); 1254 err = initialize_vpif();
@@ -1281,25 +1277,6 @@ static __init int vpif_probe(struct platform_device *pdev)
1281 res_idx++; 1277 res_idx++;
1282 } 1278 }
1283 1279
1284 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1285 /* Get the pointer to the channel object */
1286 ch = vpif_obj.dev[i];
1287
1288 /* Allocate memory for video device */
1289 vfd = video_device_alloc();
1290 if (vfd == NULL) {
1291 for (j = 0; j < i; j++) {
1292 ch = vpif_obj.dev[j];
1293 video_device_release(ch->video_dev);
1294 }
1295 err = -ENOMEM;
1296 goto vpif_unregister;
1297 }
1298
1299 /* Set video_dev to the video device */
1300 ch->video_dev = vfd;
1301 }
1302
1303 vpif_obj.config = pdev->dev.platform_data; 1280 vpif_obj.config = pdev->dev.platform_data;
1304 subdev_count = vpif_obj.config->subdev_count; 1281 subdev_count = vpif_obj.config->subdev_count;
1305 subdevdata = vpif_obj.config->subdevinfo; 1282 subdevdata = vpif_obj.config->subdevinfo;
@@ -1308,7 +1285,7 @@ static __init int vpif_probe(struct platform_device *pdev)
1308 if (vpif_obj.sd == NULL) { 1285 if (vpif_obj.sd == NULL) {
1309 vpif_err("unable to allocate memory for subdevice pointers\n"); 1286 vpif_err("unable to allocate memory for subdevice pointers\n");
1310 err = -ENOMEM; 1287 err = -ENOMEM;
1311 goto vpif_sd_error; 1288 goto vpif_unregister;
1312 } 1289 }
1313 1290
1314 if (!vpif_obj.config->asd_sizes) { 1291 if (!vpif_obj.config->asd_sizes) {
@@ -1348,12 +1325,6 @@ static __init int vpif_probe(struct platform_device *pdev)
1348 1325
1349probe_subdev_out: 1326probe_subdev_out:
1350 kfree(vpif_obj.sd); 1327 kfree(vpif_obj.sd);
1351vpif_sd_error:
1352 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1353 ch = vpif_obj.dev[i];
1354 /* Note: does nothing if ch->video_dev == NULL */
1355 video_device_release(ch->video_dev);
1356 }
1357vpif_unregister: 1328vpif_unregister:
1358 v4l2_device_unregister(&vpif_obj.v4l2_dev); 1329 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1359 1330
@@ -1379,9 +1350,7 @@ static int vpif_remove(struct platform_device *device)
1379 common = &ch->common[VPIF_VIDEO_INDEX]; 1350 common = &ch->common[VPIF_VIDEO_INDEX];
1380 vb2_dma_contig_cleanup_ctx(common->alloc_ctx); 1351 vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
1381 /* Unregister video device */ 1352 /* Unregister video device */
1382 video_unregister_device(ch->video_dev); 1353 video_unregister_device(&ch->video_dev);
1383
1384 ch->video_dev = NULL;
1385 kfree(vpif_obj.dev[i]); 1354 kfree(vpif_obj.dev[i]);
1386 } 1355 }
1387 1356
diff --git a/drivers/media/platform/davinci/vpif_display.h b/drivers/media/platform/davinci/vpif_display.h
index 7b21a7607674..849e0e385f18 100644
--- a/drivers/media/platform/davinci/vpif_display.h
+++ b/drivers/media/platform/davinci/vpif_display.h
@@ -100,7 +100,7 @@ struct common_obj {
100 100
101struct channel_obj { 101struct channel_obj {
102 /* V4l2 specific parameters */ 102 /* V4l2 specific parameters */
103 struct video_device *video_dev; /* Identifies video device for 103 struct video_device video_dev; /* Identifies video device for
104 * this channel */ 104 * this channel */
105 u32 field_id; /* Indicates id of the field 105 u32 field_id; /* Indicates id of the field
106 * which is being displayed */ 106 * which is being displayed */
diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c
index 8a2fd8c33d42..cfebf292e15a 100644
--- a/drivers/media/platform/exynos4-is/fimc-capture.c
+++ b/drivers/media/platform/exynos4-is/fimc-capture.c
@@ -1482,7 +1482,7 @@ void fimc_sensor_notify(struct v4l2_subdev *sd, unsigned int notification,
1482} 1482}
1483 1483
1484static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd, 1484static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1485 struct v4l2_subdev_fh *fh, 1485 struct v4l2_subdev_pad_config *cfg,
1486 struct v4l2_subdev_mbus_code_enum *code) 1486 struct v4l2_subdev_mbus_code_enum *code)
1487{ 1487{
1488 struct fimc_fmt *fmt; 1488 struct fimc_fmt *fmt;
@@ -1495,7 +1495,7 @@ static int fimc_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1495} 1495}
1496 1496
1497static int fimc_subdev_get_fmt(struct v4l2_subdev *sd, 1497static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
1498 struct v4l2_subdev_fh *fh, 1498 struct v4l2_subdev_pad_config *cfg,
1499 struct v4l2_subdev_format *fmt) 1499 struct v4l2_subdev_format *fmt)
1500{ 1500{
1501 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1501 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
@@ -1504,7 +1504,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
1504 struct v4l2_mbus_framefmt *mf; 1504 struct v4l2_mbus_framefmt *mf;
1505 1505
1506 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1506 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1507 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1507 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1508 fmt->format = *mf; 1508 fmt->format = *mf;
1509 return 0; 1509 return 0;
1510 } 1510 }
@@ -1536,7 +1536,7 @@ static int fimc_subdev_get_fmt(struct v4l2_subdev *sd,
1536} 1536}
1537 1537
1538static int fimc_subdev_set_fmt(struct v4l2_subdev *sd, 1538static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1539 struct v4l2_subdev_fh *fh, 1539 struct v4l2_subdev_pad_config *cfg,
1540 struct v4l2_subdev_format *fmt) 1540 struct v4l2_subdev_format *fmt)
1541{ 1541{
1542 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1542 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
@@ -1559,7 +1559,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1559 mf->colorspace = V4L2_COLORSPACE_JPEG; 1559 mf->colorspace = V4L2_COLORSPACE_JPEG;
1560 1560
1561 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1561 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1562 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1562 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1563 *mf = fmt->format; 1563 *mf = fmt->format;
1564 return 0; 1564 return 0;
1565 } 1565 }
@@ -1602,7 +1602,7 @@ static int fimc_subdev_set_fmt(struct v4l2_subdev *sd,
1602} 1602}
1603 1603
1604static int fimc_subdev_get_selection(struct v4l2_subdev *sd, 1604static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1605 struct v4l2_subdev_fh *fh, 1605 struct v4l2_subdev_pad_config *cfg,
1606 struct v4l2_subdev_selection *sel) 1606 struct v4l2_subdev_selection *sel)
1607{ 1607{
1608 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1608 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
@@ -1628,10 +1628,10 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1628 return 0; 1628 return 0;
1629 1629
1630 case V4L2_SEL_TGT_CROP: 1630 case V4L2_SEL_TGT_CROP:
1631 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); 1631 try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
1632 break; 1632 break;
1633 case V4L2_SEL_TGT_COMPOSE: 1633 case V4L2_SEL_TGT_COMPOSE:
1634 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); 1634 try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad);
1635 f = &ctx->d_frame; 1635 f = &ctx->d_frame;
1636 break; 1636 break;
1637 default: 1637 default:
@@ -1657,7 +1657,7 @@ static int fimc_subdev_get_selection(struct v4l2_subdev *sd,
1657} 1657}
1658 1658
1659static int fimc_subdev_set_selection(struct v4l2_subdev *sd, 1659static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
1660 struct v4l2_subdev_fh *fh, 1660 struct v4l2_subdev_pad_config *cfg,
1661 struct v4l2_subdev_selection *sel) 1661 struct v4l2_subdev_selection *sel)
1662{ 1662{
1663 struct fimc_dev *fimc = v4l2_get_subdevdata(sd); 1663 struct fimc_dev *fimc = v4l2_get_subdevdata(sd);
@@ -1675,10 +1675,10 @@ static int fimc_subdev_set_selection(struct v4l2_subdev *sd,
1675 1675
1676 switch (sel->target) { 1676 switch (sel->target) {
1677 case V4L2_SEL_TGT_CROP: 1677 case V4L2_SEL_TGT_CROP:
1678 try_sel = v4l2_subdev_get_try_crop(fh, sel->pad); 1678 try_sel = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
1679 break; 1679 break;
1680 case V4L2_SEL_TGT_COMPOSE: 1680 case V4L2_SEL_TGT_COMPOSE:
1681 try_sel = v4l2_subdev_get_try_compose(fh, sel->pad); 1681 try_sel = v4l2_subdev_get_try_compose(sd, cfg, sel->pad);
1682 f = &ctx->d_frame; 1682 f = &ctx->d_frame;
1683 break; 1683 break;
1684 default: 1684 default:
diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c
index 60c744915549..5d78f5716f3b 100644
--- a/drivers/media/platform/exynos4-is/fimc-isp.c
+++ b/drivers/media/platform/exynos4-is/fimc-isp.c
@@ -112,7 +112,7 @@ static const struct media_entity_operations fimc_is_subdev_media_ops = {
112}; 112};
113 113
114static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd, 114static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd,
115 struct v4l2_subdev_fh *fh, 115 struct v4l2_subdev_pad_config *cfg,
116 struct v4l2_subdev_mbus_code_enum *code) 116 struct v4l2_subdev_mbus_code_enum *code)
117{ 117{
118 const struct fimc_fmt *fmt; 118 const struct fimc_fmt *fmt;
@@ -125,14 +125,14 @@ static int fimc_is_subdev_enum_mbus_code(struct v4l2_subdev *sd,
125} 125}
126 126
127static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd, 127static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
128 struct v4l2_subdev_fh *fh, 128 struct v4l2_subdev_pad_config *cfg,
129 struct v4l2_subdev_format *fmt) 129 struct v4l2_subdev_format *fmt)
130{ 130{
131 struct fimc_isp *isp = v4l2_get_subdevdata(sd); 131 struct fimc_isp *isp = v4l2_get_subdevdata(sd);
132 struct v4l2_mbus_framefmt *mf = &fmt->format; 132 struct v4l2_mbus_framefmt *mf = &fmt->format;
133 133
134 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 134 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
135 *mf = *v4l2_subdev_get_try_format(fh, fmt->pad); 135 *mf = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
136 return 0; 136 return 0;
137 } 137 }
138 138
@@ -162,7 +162,7 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
162} 162}
163 163
164static void __isp_subdev_try_format(struct fimc_isp *isp, 164static void __isp_subdev_try_format(struct fimc_isp *isp,
165 struct v4l2_subdev_fh *fh, 165 struct v4l2_subdev_pad_config *cfg,
166 struct v4l2_subdev_format *fmt) 166 struct v4l2_subdev_format *fmt)
167{ 167{
168 struct v4l2_mbus_framefmt *mf = &fmt->format; 168 struct v4l2_mbus_framefmt *mf = &fmt->format;
@@ -178,7 +178,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp,
178 mf->code = MEDIA_BUS_FMT_SGRBG10_1X10; 178 mf->code = MEDIA_BUS_FMT_SGRBG10_1X10;
179 } else { 179 } else {
180 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) 180 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
181 format = v4l2_subdev_get_try_format(fh, 181 format = v4l2_subdev_get_try_format(&isp->subdev, cfg,
182 FIMC_ISP_SD_PAD_SINK); 182 FIMC_ISP_SD_PAD_SINK);
183 else 183 else
184 format = &isp->sink_fmt; 184 format = &isp->sink_fmt;
@@ -197,7 +197,7 @@ static void __isp_subdev_try_format(struct fimc_isp *isp,
197} 197}
198 198
199static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd, 199static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
200 struct v4l2_subdev_fh *fh, 200 struct v4l2_subdev_pad_config *cfg,
201 struct v4l2_subdev_format *fmt) 201 struct v4l2_subdev_format *fmt)
202{ 202{
203 struct fimc_isp *isp = v4l2_get_subdevdata(sd); 203 struct fimc_isp *isp = v4l2_get_subdevdata(sd);
@@ -209,10 +209,10 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
209 __func__, fmt->pad, mf->code, mf->width, mf->height); 209 __func__, fmt->pad, mf->code, mf->width, mf->height);
210 210
211 mutex_lock(&isp->subdev_lock); 211 mutex_lock(&isp->subdev_lock);
212 __isp_subdev_try_format(isp, fh, fmt); 212 __isp_subdev_try_format(isp, cfg, fmt);
213 213
214 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 214 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
215 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 215 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
216 *mf = fmt->format; 216 *mf = fmt->format;
217 217
218 /* Propagate format to the source pads */ 218 /* Propagate format to the source pads */
@@ -223,8 +223,8 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
223 for (pad = FIMC_ISP_SD_PAD_SRC_FIFO; 223 for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
224 pad < FIMC_ISP_SD_PADS_NUM; pad++) { 224 pad < FIMC_ISP_SD_PADS_NUM; pad++) {
225 format.pad = pad; 225 format.pad = pad;
226 __isp_subdev_try_format(isp, fh, &format); 226 __isp_subdev_try_format(isp, cfg, &format);
227 mf = v4l2_subdev_get_try_format(fh, pad); 227 mf = v4l2_subdev_get_try_format(sd, cfg, pad);
228 *mf = format.format; 228 *mf = format.format;
229 } 229 }
230 } 230 }
@@ -236,7 +236,7 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
236 isp->sink_fmt = *mf; 236 isp->sink_fmt = *mf;
237 237
238 format.pad = FIMC_ISP_SD_PAD_SRC_DMA; 238 format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
239 __isp_subdev_try_format(isp, fh, &format); 239 __isp_subdev_try_format(isp, cfg, &format);
240 240
241 isp->src_fmt = format.format; 241 isp->src_fmt = format.format;
242 __is_set_frame_size(is, &isp->src_fmt); 242 __is_set_frame_size(is, &isp->src_fmt);
@@ -369,7 +369,7 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
369 struct v4l2_mbus_framefmt fmt; 369 struct v4l2_mbus_framefmt fmt;
370 struct v4l2_mbus_framefmt *format; 370 struct v4l2_mbus_framefmt *format;
371 371
372 format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SINK); 372 format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SINK);
373 373
374 fmt.colorspace = V4L2_COLORSPACE_SRGB; 374 fmt.colorspace = V4L2_COLORSPACE_SRGB;
375 fmt.code = fimc_isp_formats[0].mbus_code; 375 fmt.code = fimc_isp_formats[0].mbus_code;
@@ -378,12 +378,12 @@ static int fimc_isp_subdev_open(struct v4l2_subdev *sd,
378 fmt.field = V4L2_FIELD_NONE; 378 fmt.field = V4L2_FIELD_NONE;
379 *format = fmt; 379 *format = fmt;
380 380
381 format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SRC_FIFO); 381 format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_FIFO);
382 fmt.width = DEFAULT_PREVIEW_STILL_WIDTH; 382 fmt.width = DEFAULT_PREVIEW_STILL_WIDTH;
383 fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT; 383 fmt.height = DEFAULT_PREVIEW_STILL_HEIGHT;
384 *format = fmt; 384 *format = fmt;
385 385
386 format = v4l2_subdev_get_try_format(fh, FIMC_ISP_SD_PAD_SRC_DMA); 386 format = v4l2_subdev_get_try_format(sd, fh->pad, FIMC_ISP_SD_PAD_SRC_DMA);
387 *format = fmt; 387 *format = fmt;
388 388
389 return 0; 389 return 0;
diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c
index 2510f189e242..ca6261a86a5f 100644
--- a/drivers/media/platform/exynos4-is/fimc-lite.c
+++ b/drivers/media/platform/exynos4-is/fimc-lite.c
@@ -568,7 +568,7 @@ static const struct v4l2_file_operations fimc_lite_fops = {
568 */ 568 */
569 569
570static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc, 570static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
571 struct v4l2_subdev_fh *fh, 571 struct v4l2_subdev_pad_config *cfg,
572 struct v4l2_subdev_format *format) 572 struct v4l2_subdev_format *format)
573{ 573{
574 struct flite_drvdata *dd = fimc->dd; 574 struct flite_drvdata *dd = fimc->dd;
@@ -592,13 +592,13 @@ static const struct fimc_fmt *fimc_lite_subdev_try_fmt(struct fimc_lite *fimc,
592 struct v4l2_rect *rect; 592 struct v4l2_rect *rect;
593 593
594 if (format->which == V4L2_SUBDEV_FORMAT_TRY) { 594 if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
595 sink_fmt = v4l2_subdev_get_try_format(fh, 595 sink_fmt = v4l2_subdev_get_try_format(&fimc->subdev, cfg,
596 FLITE_SD_PAD_SINK); 596 FLITE_SD_PAD_SINK);
597 597
598 mf->code = sink_fmt->code; 598 mf->code = sink_fmt->code;
599 mf->colorspace = sink_fmt->colorspace; 599 mf->colorspace = sink_fmt->colorspace;
600 600
601 rect = v4l2_subdev_get_try_crop(fh, 601 rect = v4l2_subdev_get_try_crop(&fimc->subdev, cfg,
602 FLITE_SD_PAD_SINK); 602 FLITE_SD_PAD_SINK);
603 } else { 603 } else {
604 mf->code = sink->fmt->mbus_code; 604 mf->code = sink->fmt->mbus_code;
@@ -1047,7 +1047,7 @@ static const struct media_entity_operations fimc_lite_subdev_media_ops = {
1047}; 1047};
1048 1048
1049static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd, 1049static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1050 struct v4l2_subdev_fh *fh, 1050 struct v4l2_subdev_pad_config *cfg,
1051 struct v4l2_subdev_mbus_code_enum *code) 1051 struct v4l2_subdev_mbus_code_enum *code)
1052{ 1052{
1053 const struct fimc_fmt *fmt; 1053 const struct fimc_fmt *fmt;
@@ -1060,16 +1060,17 @@ static int fimc_lite_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1060} 1060}
1061 1061
1062static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt( 1062static struct v4l2_mbus_framefmt *__fimc_lite_subdev_get_try_fmt(
1063 struct v4l2_subdev_fh *fh, unsigned int pad) 1063 struct v4l2_subdev *sd,
1064 struct v4l2_subdev_pad_config *cfg, unsigned int pad)
1064{ 1065{
1065 if (pad != FLITE_SD_PAD_SINK) 1066 if (pad != FLITE_SD_PAD_SINK)
1066 pad = FLITE_SD_PAD_SOURCE_DMA; 1067 pad = FLITE_SD_PAD_SOURCE_DMA;
1067 1068
1068 return v4l2_subdev_get_try_format(fh, pad); 1069 return v4l2_subdev_get_try_format(sd, cfg, pad);
1069} 1070}
1070 1071
1071static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd, 1072static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1072 struct v4l2_subdev_fh *fh, 1073 struct v4l2_subdev_pad_config *cfg,
1073 struct v4l2_subdev_format *fmt) 1074 struct v4l2_subdev_format *fmt)
1074{ 1075{
1075 struct fimc_lite *fimc = v4l2_get_subdevdata(sd); 1076 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
@@ -1077,7 +1078,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1077 struct flite_frame *f = &fimc->inp_frame; 1078 struct flite_frame *f = &fimc->inp_frame;
1078 1079
1079 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1080 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1080 mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad); 1081 mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad);
1081 fmt->format = *mf; 1082 fmt->format = *mf;
1082 return 0; 1083 return 0;
1083 } 1084 }
@@ -1100,7 +1101,7 @@ static int fimc_lite_subdev_get_fmt(struct v4l2_subdev *sd,
1100} 1101}
1101 1102
1102static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd, 1103static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1103 struct v4l2_subdev_fh *fh, 1104 struct v4l2_subdev_pad_config *cfg,
1104 struct v4l2_subdev_format *fmt) 1105 struct v4l2_subdev_format *fmt)
1105{ 1106{
1106 struct fimc_lite *fimc = v4l2_get_subdevdata(sd); 1107 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
@@ -1122,17 +1123,17 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1122 return -EBUSY; 1123 return -EBUSY;
1123 } 1124 }
1124 1125
1125 ffmt = fimc_lite_subdev_try_fmt(fimc, fh, fmt); 1126 ffmt = fimc_lite_subdev_try_fmt(fimc, cfg, fmt);
1126 1127
1127 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1128 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1128 struct v4l2_mbus_framefmt *src_fmt; 1129 struct v4l2_mbus_framefmt *src_fmt;
1129 1130
1130 mf = __fimc_lite_subdev_get_try_fmt(fh, fmt->pad); 1131 mf = __fimc_lite_subdev_get_try_fmt(sd, cfg, fmt->pad);
1131 *mf = fmt->format; 1132 *mf = fmt->format;
1132 1133
1133 if (fmt->pad == FLITE_SD_PAD_SINK) { 1134 if (fmt->pad == FLITE_SD_PAD_SINK) {
1134 unsigned int pad = FLITE_SD_PAD_SOURCE_DMA; 1135 unsigned int pad = FLITE_SD_PAD_SOURCE_DMA;
1135 src_fmt = __fimc_lite_subdev_get_try_fmt(fh, pad); 1136 src_fmt = __fimc_lite_subdev_get_try_fmt(sd, cfg, pad);
1136 *src_fmt = *mf; 1137 *src_fmt = *mf;
1137 } 1138 }
1138 1139
@@ -1160,7 +1161,7 @@ static int fimc_lite_subdev_set_fmt(struct v4l2_subdev *sd,
1160} 1161}
1161 1162
1162static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd, 1163static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1163 struct v4l2_subdev_fh *fh, 1164 struct v4l2_subdev_pad_config *cfg,
1164 struct v4l2_subdev_selection *sel) 1165 struct v4l2_subdev_selection *sel)
1165{ 1166{
1166 struct fimc_lite *fimc = v4l2_get_subdevdata(sd); 1167 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
@@ -1172,7 +1173,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1172 return -EINVAL; 1173 return -EINVAL;
1173 1174
1174 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { 1175 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1175 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad); 1176 sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
1176 return 0; 1177 return 0;
1177 } 1178 }
1178 1179
@@ -1195,7 +1196,7 @@ static int fimc_lite_subdev_get_selection(struct v4l2_subdev *sd,
1195} 1196}
1196 1197
1197static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd, 1198static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1198 struct v4l2_subdev_fh *fh, 1199 struct v4l2_subdev_pad_config *cfg,
1199 struct v4l2_subdev_selection *sel) 1200 struct v4l2_subdev_selection *sel)
1200{ 1201{
1201 struct fimc_lite *fimc = v4l2_get_subdevdata(sd); 1202 struct fimc_lite *fimc = v4l2_get_subdevdata(sd);
@@ -1209,7 +1210,7 @@ static int fimc_lite_subdev_set_selection(struct v4l2_subdev *sd,
1209 fimc_lite_try_crop(fimc, &sel->r); 1210 fimc_lite_try_crop(fimc, &sel->r);
1210 1211
1211 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { 1212 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1212 *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r; 1213 *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r;
1213 } else { 1214 } else {
1214 unsigned long flags; 1215 unsigned long flags;
1215 spin_lock_irqsave(&fimc->slock, flags); 1216 spin_lock_irqsave(&fimc->slock, flags);
diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c
index 2504aa89a6f4..d74e1bec3d86 100644
--- a/drivers/media/platform/exynos4-is/mipi-csis.c
+++ b/drivers/media/platform/exynos4-is/mipi-csis.c
@@ -540,7 +540,7 @@ unlock:
540} 540}
541 541
542static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd, 542static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
543 struct v4l2_subdev_fh *fh, 543 struct v4l2_subdev_pad_config *cfg,
544 struct v4l2_subdev_mbus_code_enum *code) 544 struct v4l2_subdev_mbus_code_enum *code)
545{ 545{
546 if (code->index >= ARRAY_SIZE(s5pcsis_formats)) 546 if (code->index >= ARRAY_SIZE(s5pcsis_formats))
@@ -568,23 +568,23 @@ static struct csis_pix_format const *s5pcsis_try_format(
568} 568}
569 569
570static struct v4l2_mbus_framefmt *__s5pcsis_get_format( 570static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
571 struct csis_state *state, struct v4l2_subdev_fh *fh, 571 struct csis_state *state, struct v4l2_subdev_pad_config *cfg,
572 enum v4l2_subdev_format_whence which) 572 enum v4l2_subdev_format_whence which)
573{ 573{
574 if (which == V4L2_SUBDEV_FORMAT_TRY) 574 if (which == V4L2_SUBDEV_FORMAT_TRY)
575 return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL; 575 return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL;
576 576
577 return &state->format; 577 return &state->format;
578} 578}
579 579
580static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 580static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
581 struct v4l2_subdev_format *fmt) 581 struct v4l2_subdev_format *fmt)
582{ 582{
583 struct csis_state *state = sd_to_csis_state(sd); 583 struct csis_state *state = sd_to_csis_state(sd);
584 struct csis_pix_format const *csis_fmt; 584 struct csis_pix_format const *csis_fmt;
585 struct v4l2_mbus_framefmt *mf; 585 struct v4l2_mbus_framefmt *mf;
586 586
587 mf = __s5pcsis_get_format(state, fh, fmt->which); 587 mf = __s5pcsis_get_format(state, cfg, fmt->which);
588 588
589 if (fmt->pad == CSIS_PAD_SOURCE) { 589 if (fmt->pad == CSIS_PAD_SOURCE) {
590 if (mf) { 590 if (mf) {
@@ -605,13 +605,13 @@ static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
605 return 0; 605 return 0;
606} 606}
607 607
608static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 608static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
609 struct v4l2_subdev_format *fmt) 609 struct v4l2_subdev_format *fmt)
610{ 610{
611 struct csis_state *state = sd_to_csis_state(sd); 611 struct csis_state *state = sd_to_csis_state(sd);
612 struct v4l2_mbus_framefmt *mf; 612 struct v4l2_mbus_framefmt *mf;
613 613
614 mf = __s5pcsis_get_format(state, fh, fmt->which); 614 mf = __s5pcsis_get_format(state, cfg, fmt->which);
615 if (!mf) 615 if (!mf)
616 return -EINVAL; 616 return -EINVAL;
617 617
@@ -651,7 +651,7 @@ static int s5pcsis_log_status(struct v4l2_subdev *sd)
651 651
652static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) 652static int s5pcsis_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
653{ 653{
654 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0); 654 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(sd, fh->pad, 0);
655 655
656 format->colorspace = V4L2_COLORSPACE_JPEG; 656 format->colorspace = V4L2_COLORSPACE_JPEG;
657 format->code = s5pcsis_formats[0].code; 657 format->code = s5pcsis_formats[0].code;
diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c
index b70c1aecca37..92d954973ccf 100644
--- a/drivers/media/platform/m2m-deinterlace.c
+++ b/drivers/media/platform/m2m-deinterlace.c
@@ -127,7 +127,7 @@ static struct deinterlace_fmt *find_format(struct v4l2_format *f)
127 127
128struct deinterlace_dev { 128struct deinterlace_dev {
129 struct v4l2_device v4l2_dev; 129 struct v4l2_device v4l2_dev;
130 struct video_device *vfd; 130 struct video_device vfd;
131 131
132 atomic_t busy; 132 atomic_t busy;
133 struct mutex dev_mutex; 133 struct mutex dev_mutex;
@@ -983,7 +983,7 @@ static struct video_device deinterlace_videodev = {
983 .fops = &deinterlace_fops, 983 .fops = &deinterlace_fops,
984 .ioctl_ops = &deinterlace_ioctl_ops, 984 .ioctl_ops = &deinterlace_ioctl_ops,
985 .minor = -1, 985 .minor = -1,
986 .release = video_device_release, 986 .release = video_device_release_empty,
987 .vfl_dir = VFL_DIR_M2M, 987 .vfl_dir = VFL_DIR_M2M,
988}; 988};
989 989
@@ -1026,13 +1026,7 @@ static int deinterlace_probe(struct platform_device *pdev)
1026 atomic_set(&pcdev->busy, 0); 1026 atomic_set(&pcdev->busy, 0);
1027 mutex_init(&pcdev->dev_mutex); 1027 mutex_init(&pcdev->dev_mutex);
1028 1028
1029 vfd = video_device_alloc(); 1029 vfd = &pcdev->vfd;
1030 if (!vfd) {
1031 v4l2_err(&pcdev->v4l2_dev, "Failed to allocate video device\n");
1032 ret = -ENOMEM;
1033 goto unreg_dev;
1034 }
1035
1036 *vfd = deinterlace_videodev; 1030 *vfd = deinterlace_videodev;
1037 vfd->lock = &pcdev->dev_mutex; 1031 vfd->lock = &pcdev->dev_mutex;
1038 vfd->v4l2_dev = &pcdev->v4l2_dev; 1032 vfd->v4l2_dev = &pcdev->v4l2_dev;
@@ -1040,12 +1034,11 @@ static int deinterlace_probe(struct platform_device *pdev)
1040 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 1034 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1041 if (ret) { 1035 if (ret) {
1042 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n"); 1036 v4l2_err(&pcdev->v4l2_dev, "Failed to register video device\n");
1043 goto rel_vdev; 1037 goto unreg_dev;
1044 } 1038 }
1045 1039
1046 video_set_drvdata(vfd, pcdev); 1040 video_set_drvdata(vfd, pcdev);
1047 snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name); 1041 snprintf(vfd->name, sizeof(vfd->name), "%s", deinterlace_videodev.name);
1048 pcdev->vfd = vfd;
1049 v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME 1042 v4l2_info(&pcdev->v4l2_dev, MEM2MEM_TEST_MODULE_NAME
1050 " Device registered as /dev/video%d\n", vfd->num); 1043 " Device registered as /dev/video%d\n", vfd->num);
1051 1044
@@ -1069,11 +1062,9 @@ static int deinterlace_probe(struct platform_device *pdev)
1069 1062
1070 v4l2_m2m_release(pcdev->m2m_dev); 1063 v4l2_m2m_release(pcdev->m2m_dev);
1071err_m2m: 1064err_m2m:
1072 video_unregister_device(pcdev->vfd); 1065 video_unregister_device(&pcdev->vfd);
1073err_ctx: 1066err_ctx:
1074 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 1067 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1075rel_vdev:
1076 video_device_release(vfd);
1077unreg_dev: 1068unreg_dev:
1078 v4l2_device_unregister(&pcdev->v4l2_dev); 1069 v4l2_device_unregister(&pcdev->v4l2_dev);
1079rel_dma: 1070rel_dma:
@@ -1088,7 +1079,7 @@ static int deinterlace_remove(struct platform_device *pdev)
1088 1079
1089 v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME); 1080 v4l2_info(&pcdev->v4l2_dev, "Removing " MEM2MEM_TEST_MODULE_NAME);
1090 v4l2_m2m_release(pcdev->m2m_dev); 1081 v4l2_m2m_release(pcdev->m2m_dev);
1091 video_unregister_device(pcdev->vfd); 1082 video_unregister_device(&pcdev->vfd);
1092 v4l2_device_unregister(&pcdev->v4l2_dev); 1083 v4l2_device_unregister(&pcdev->v4l2_dev);
1093 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx); 1084 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
1094 dma_release_channel(pcdev->dma_chan); 1085 dma_release_channel(pcdev->dma_chan);
diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c
index dd5b1415f974..9c64b5d01c6a 100644
--- a/drivers/media/platform/marvell-ccic/mcam-core.c
+++ b/drivers/media/platform/marvell-ccic/mcam-core.c
@@ -1568,24 +1568,64 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
1568 struct v4l2_frmsizeenum *sizes) 1568 struct v4l2_frmsizeenum *sizes)
1569{ 1569{
1570 struct mcam_camera *cam = priv; 1570 struct mcam_camera *cam = priv;
1571 struct mcam_format_struct *f;
1572 struct v4l2_subdev_frame_size_enum fse = {
1573 .index = sizes->index,
1574 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1575 };
1571 int ret; 1576 int ret;
1572 1577
1578 f = mcam_find_format(sizes->pixel_format);
1579 if (f->pixelformat != sizes->pixel_format)
1580 return -EINVAL;
1581 fse.code = f->mbus_code;
1573 mutex_lock(&cam->s_mutex); 1582 mutex_lock(&cam->s_mutex);
1574 ret = sensor_call(cam, video, enum_framesizes, sizes); 1583 ret = sensor_call(cam, pad, enum_frame_size, NULL, &fse);
1575 mutex_unlock(&cam->s_mutex); 1584 mutex_unlock(&cam->s_mutex);
1576 return ret; 1585 if (ret)
1586 return ret;
1587 if (fse.min_width == fse.max_width &&
1588 fse.min_height == fse.max_height) {
1589 sizes->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1590 sizes->discrete.width = fse.min_width;
1591 sizes->discrete.height = fse.min_height;
1592 return 0;
1593 }
1594 sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
1595 sizes->stepwise.min_width = fse.min_width;
1596 sizes->stepwise.max_width = fse.max_width;
1597 sizes->stepwise.min_height = fse.min_height;
1598 sizes->stepwise.max_height = fse.max_height;
1599 sizes->stepwise.step_width = 1;
1600 sizes->stepwise.step_height = 1;
1601 return 0;
1577} 1602}
1578 1603
1579static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv, 1604static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
1580 struct v4l2_frmivalenum *interval) 1605 struct v4l2_frmivalenum *interval)
1581{ 1606{
1582 struct mcam_camera *cam = priv; 1607 struct mcam_camera *cam = priv;
1608 struct mcam_format_struct *f;
1609 struct v4l2_subdev_frame_interval_enum fie = {
1610 .index = interval->index,
1611 .width = interval->width,
1612 .height = interval->height,
1613 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1614 };
1583 int ret; 1615 int ret;
1584 1616
1617 f = mcam_find_format(interval->pixel_format);
1618 if (f->pixelformat != interval->pixel_format)
1619 return -EINVAL;
1620 fie.code = f->mbus_code;
1585 mutex_lock(&cam->s_mutex); 1621 mutex_lock(&cam->s_mutex);
1586 ret = sensor_call(cam, video, enum_frameintervals, interval); 1622 ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie);
1587 mutex_unlock(&cam->s_mutex); 1623 mutex_unlock(&cam->s_mutex);
1588 return ret; 1624 if (ret)
1625 return ret;
1626 interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1627 interval->discrete = fie.interval;
1628 return 0;
1589} 1629}
1590 1630
1591#ifdef CONFIG_VIDEO_ADV_DEBUG 1631#ifdef CONFIG_VIDEO_ADV_DEBUG
diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
index ba2d8f973d58..17b189a81ec5 100644
--- a/drivers/media/platform/omap/omap_vout.c
+++ b/drivers/media/platform/omap/omap_vout.c
@@ -1978,7 +1978,7 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev,
1978 vout->cropped_offset = 0; 1978 vout->cropped_offset = 0;
1979 1979
1980 if (ovid->rotation_type == VOUT_ROT_VRFB) { 1980 if (ovid->rotation_type == VOUT_ROT_VRFB) {
1981 int static_vrfb_allocation = (vid_num == 0) ? 1981 bool static_vrfb_allocation = (vid_num == 0) ?
1982 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; 1982 vid1_static_vrfb_alloc : vid2_static_vrfb_alloc;
1983 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num, 1983 ret = omap_vout_setup_vrfb_bufs(pdev, vid_num,
1984 static_vrfb_allocation); 1984 static_vrfb_allocation);
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c
index aa39306afc73..c6e252760c62 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.c
+++ b/drivers/media/platform/omap/omap_vout_vrfb.c
@@ -21,6 +21,7 @@
21 21
22#include "omap_voutdef.h" 22#include "omap_voutdef.h"
23#include "omap_voutlib.h" 23#include "omap_voutlib.h"
24#include "omap_vout_vrfb.h"
24 25
25#define OMAP_DMA_NO_DEVICE 0 26#define OMAP_DMA_NO_DEVICE 0
26 27
diff --git a/drivers/media/platform/omap/omap_vout_vrfb.h b/drivers/media/platform/omap/omap_vout_vrfb.h
index 4c2314839b48..c976975024df 100644
--- a/drivers/media/platform/omap/omap_vout_vrfb.h
+++ b/drivers/media/platform/omap/omap_vout_vrfb.h
@@ -15,7 +15,7 @@
15#ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB 15#ifdef CONFIG_VIDEO_OMAP2_VOUT_VRFB
16void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout); 16void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout);
17int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, 17int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
18 u32 static_vrfb_allocation); 18 bool static_vrfb_allocation);
19void omap_vout_release_vrfb(struct omap_vout_device *vout); 19void omap_vout_release_vrfb(struct omap_vout_device *vout);
20int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, 20int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
21 unsigned int *count, unsigned int startindex); 21 unsigned int *count, unsigned int startindex);
@@ -25,7 +25,7 @@ void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout);
25#else 25#else
26static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }; 26static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { };
27static inline int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, 27static inline int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
28 u32 static_vrfb_allocation) 28 bool static_vrfb_allocation)
29 { return 0; }; 29 { return 0; };
30static inline void omap_vout_release_vrfb(struct omap_vout_device *vout) { }; 30static inline void omap_vout_release_vrfb(struct omap_vout_device *vout) { };
31static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, 31static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c
index deca80903c3a..18d0a871747f 100644
--- a/drivers/media/platform/omap3isp/isp.c
+++ b/drivers/media/platform/omap3isp/isp.c
@@ -51,6 +51,7 @@
51#include <linux/dma-mapping.h> 51#include <linux/dma-mapping.h>
52#include <linux/i2c.h> 52#include <linux/i2c.h>
53#include <linux/interrupt.h> 53#include <linux/interrupt.h>
54#include <linux/mfd/syscon.h>
54#include <linux/module.h> 55#include <linux/module.h>
55#include <linux/omap-iommu.h> 56#include <linux/omap-iommu.h>
56#include <linux/platform_device.h> 57#include <linux/platform_device.h>
@@ -63,6 +64,7 @@
63 64
64#include <media/v4l2-common.h> 65#include <media/v4l2-common.h>
65#include <media/v4l2-device.h> 66#include <media/v4l2-device.h>
67#include <media/v4l2-of.h>
66 68
67#include "isp.h" 69#include "isp.h"
68#include "ispreg.h" 70#include "ispreg.h"
@@ -85,35 +87,45 @@ static void isp_restore_ctx(struct isp_device *isp);
85static const struct isp_res_mapping isp_res_maps[] = { 87static const struct isp_res_mapping isp_res_maps[] = {
86 { 88 {
87 .isp_rev = ISP_REVISION_2_0, 89 .isp_rev = ISP_REVISION_2_0,
88 .map = 1 << OMAP3_ISP_IOMEM_MAIN | 90 .offset = {
89 1 << OMAP3_ISP_IOMEM_CCP2 | 91 /* first MMIO area */
90 1 << OMAP3_ISP_IOMEM_CCDC | 92 0x0000, /* base, len 0x0070 */
91 1 << OMAP3_ISP_IOMEM_HIST | 93 0x0400, /* ccp2, len 0x01f0 */
92 1 << OMAP3_ISP_IOMEM_H3A | 94 0x0600, /* ccdc, len 0x00a8 */
93 1 << OMAP3_ISP_IOMEM_PREV | 95 0x0a00, /* hist, len 0x0048 */
94 1 << OMAP3_ISP_IOMEM_RESZ | 96 0x0c00, /* h3a, len 0x0060 */
95 1 << OMAP3_ISP_IOMEM_SBL | 97 0x0e00, /* preview, len 0x00a0 */
96 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | 98 0x1000, /* resizer, len 0x00ac */
97 1 << OMAP3_ISP_IOMEM_CSIPHY2 | 99 0x1200, /* sbl, len 0x00fc */
98 1 << OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 100 /* second MMIO area */
101 0x0000, /* csi2a, len 0x0170 */
102 0x0170, /* csiphy2, len 0x000c */
103 },
104 .syscon_offset = 0xdc,
105 .phy_type = ISP_PHY_TYPE_3430,
99 }, 106 },
100 { 107 {
101 .isp_rev = ISP_REVISION_15_0, 108 .isp_rev = ISP_REVISION_15_0,
102 .map = 1 << OMAP3_ISP_IOMEM_MAIN | 109 .offset = {
103 1 << OMAP3_ISP_IOMEM_CCP2 | 110 /* first MMIO area */
104 1 << OMAP3_ISP_IOMEM_CCDC | 111 0x0000, /* base, len 0x0070 */
105 1 << OMAP3_ISP_IOMEM_HIST | 112 0x0400, /* ccp2, len 0x01f0 */
106 1 << OMAP3_ISP_IOMEM_H3A | 113 0x0600, /* ccdc, len 0x00a8 */
107 1 << OMAP3_ISP_IOMEM_PREV | 114 0x0a00, /* hist, len 0x0048 */
108 1 << OMAP3_ISP_IOMEM_RESZ | 115 0x0c00, /* h3a, len 0x0060 */
109 1 << OMAP3_ISP_IOMEM_SBL | 116 0x0e00, /* preview, len 0x00a0 */
110 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | 117 0x1000, /* resizer, len 0x00ac */
111 1 << OMAP3_ISP_IOMEM_CSIPHY2 | 118 0x1200, /* sbl, len 0x00fc */
112 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 | 119 /* second MMIO area */
113 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 | 120 0x0000, /* csi2a, len 0x0170 (1st area) */
114 1 << OMAP3_ISP_IOMEM_CSIPHY1 | 121 0x0170, /* csiphy2, len 0x000c */
115 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2 | 122 0x01c0, /* csi2a, len 0x0040 (2nd area) */
116 1 << OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 123 0x0400, /* csi2c, len 0x0170 (1st area) */
124 0x0570, /* csiphy1, len 0x000c */
125 0x05c0, /* csi2c, len 0x0040 (2nd area) */
126 },
127 .syscon_offset = 0x2f0,
128 .phy_type = ISP_PHY_TYPE_3630,
117 }, 129 },
118}; 130};
119 131
@@ -279,9 +291,20 @@ static const struct clk_init_data isp_xclk_init_data = {
279 .num_parents = 1, 291 .num_parents = 1,
280}; 292};
281 293
294static struct clk *isp_xclk_src_get(struct of_phandle_args *clkspec, void *data)
295{
296 unsigned int idx = clkspec->args[0];
297 struct isp_device *isp = data;
298
299 if (idx >= ARRAY_SIZE(isp->xclks))
300 return ERR_PTR(-ENOENT);
301
302 return isp->xclks[idx].clk;
303}
304
282static int isp_xclk_init(struct isp_device *isp) 305static int isp_xclk_init(struct isp_device *isp)
283{ 306{
284 struct isp_platform_data *pdata = isp->pdata; 307 struct device_node *np = isp->dev->of_node;
285 struct clk_init_data init; 308 struct clk_init_data init;
286 unsigned int i; 309 unsigned int i;
287 310
@@ -311,37 +334,27 @@ static int isp_xclk_init(struct isp_device *isp)
311 xclk->clk = clk_register(NULL, &xclk->hw); 334 xclk->clk = clk_register(NULL, &xclk->hw);
312 if (IS_ERR(xclk->clk)) 335 if (IS_ERR(xclk->clk))
313 return PTR_ERR(xclk->clk); 336 return PTR_ERR(xclk->clk);
314
315 if (pdata->xclks[i].con_id == NULL &&
316 pdata->xclks[i].dev_id == NULL)
317 continue;
318
319 xclk->lookup = kzalloc(sizeof(*xclk->lookup), GFP_KERNEL);
320 if (xclk->lookup == NULL)
321 return -ENOMEM;
322
323 xclk->lookup->con_id = pdata->xclks[i].con_id;
324 xclk->lookup->dev_id = pdata->xclks[i].dev_id;
325 xclk->lookup->clk = xclk->clk;
326
327 clkdev_add(xclk->lookup);
328 } 337 }
329 338
339 if (np)
340 of_clk_add_provider(np, isp_xclk_src_get, isp);
341
330 return 0; 342 return 0;
331} 343}
332 344
333static void isp_xclk_cleanup(struct isp_device *isp) 345static void isp_xclk_cleanup(struct isp_device *isp)
334{ 346{
347 struct device_node *np = isp->dev->of_node;
335 unsigned int i; 348 unsigned int i;
336 349
350 if (np)
351 of_clk_del_provider(np);
352
337 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) { 353 for (i = 0; i < ARRAY_SIZE(isp->xclks); ++i) {
338 struct isp_xclk *xclk = &isp->xclks[i]; 354 struct isp_xclk *xclk = &isp->xclks[i];
339 355
340 if (!IS_ERR(xclk->clk)) 356 if (!IS_ERR(xclk->clk))
341 clk_unregister(xclk->clk); 357 clk_unregister(xclk->clk);
342
343 if (xclk->lookup)
344 clkdev_drop(xclk->lookup);
345 } 358 }
346} 359}
347 360
@@ -422,7 +435,7 @@ static void isp_core_init(struct isp_device *isp, int idle)
422 */ 435 */
423void omap3isp_configure_bridge(struct isp_device *isp, 436void omap3isp_configure_bridge(struct isp_device *isp,
424 enum ccdc_input_entity input, 437 enum ccdc_input_entity input,
425 const struct isp_parallel_platform_data *pdata, 438 const struct isp_parallel_cfg *parcfg,
426 unsigned int shift, unsigned int bridge) 439 unsigned int shift, unsigned int bridge)
427{ 440{
428 u32 ispctrl_val; 441 u32 ispctrl_val;
@@ -437,8 +450,8 @@ void omap3isp_configure_bridge(struct isp_device *isp,
437 switch (input) { 450 switch (input) {
438 case CCDC_INPUT_PARALLEL: 451 case CCDC_INPUT_PARALLEL:
439 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; 452 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
440 ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; 453 ispctrl_val |= parcfg->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
441 shift += pdata->data_lane_shift * 2; 454 shift += parcfg->data_lane_shift * 2;
442 break; 455 break;
443 456
444 case CCDC_INPUT_CSI2A: 457 case CCDC_INPUT_CSI2A:
@@ -1784,58 +1797,121 @@ static void isp_unregister_entities(struct isp_device *isp)
1784} 1797}
1785 1798
1786/* 1799/*
1787 * isp_register_subdev_group - Register a group of subdevices 1800 * isp_register_subdev - Register a sub-device
1788 * @isp: OMAP3 ISP device 1801 * @isp: OMAP3 ISP device
1789 * @board_info: I2C subdevs board information array 1802 * @isp_subdev: platform data related to a sub-device
1790 * 1803 *
1791 * Register all I2C subdevices in the board_info array. The array must be 1804 * Register an I2C sub-device which has not been registered by other
1792 * terminated by a NULL entry, and the first entry must be the sensor. 1805 * means (such as the Device Tree).
1793 * 1806 *
1794 * Return a pointer to the sensor media entity if it has been successfully 1807 * Return a pointer to the sub-device if it has been successfully
1795 * registered, or NULL otherwise. 1808 * registered, or NULL otherwise.
1796 */ 1809 */
1797static struct v4l2_subdev * 1810static struct v4l2_subdev *
1798isp_register_subdev_group(struct isp_device *isp, 1811isp_register_subdev(struct isp_device *isp,
1799 struct isp_subdev_i2c_board_info *board_info) 1812 struct isp_platform_subdev *isp_subdev)
1800{ 1813{
1801 struct v4l2_subdev *sensor = NULL; 1814 struct i2c_adapter *adapter;
1802 unsigned int first; 1815 struct v4l2_subdev *sd;
1803 1816
1804 if (board_info->board_info == NULL) 1817 if (isp_subdev->board_info == NULL)
1805 return NULL; 1818 return NULL;
1806 1819
1807 for (first = 1; board_info->board_info; ++board_info, first = 0) { 1820 adapter = i2c_get_adapter(isp_subdev->i2c_adapter_id);
1808 struct v4l2_subdev *subdev; 1821 if (adapter == NULL) {
1809 struct i2c_adapter *adapter; 1822 dev_err(isp->dev,
1823 "%s: Unable to get I2C adapter %d for device %s\n",
1824 __func__, isp_subdev->i2c_adapter_id,
1825 isp_subdev->board_info->type);
1826 return NULL;
1827 }
1810 1828
1811 adapter = i2c_get_adapter(board_info->i2c_adapter_id); 1829 sd = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
1812 if (adapter == NULL) { 1830 isp_subdev->board_info, NULL);
1813 dev_err(isp->dev, "%s: Unable to get I2C adapter %d for " 1831 if (sd == NULL) {
1814 "device %s\n", __func__, 1832 dev_err(isp->dev, "%s: Unable to register subdev %s\n",
1815 board_info->i2c_adapter_id, 1833 __func__, isp_subdev->board_info->type);
1816 board_info->board_info->type); 1834 return NULL;
1817 continue; 1835 }
1818 }
1819 1836
1820 subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, 1837 return sd;
1821 board_info->board_info, NULL); 1838}
1822 if (subdev == NULL) { 1839
1823 dev_err(isp->dev, "%s: Unable to register subdev %s\n", 1840static int isp_link_entity(
1824 __func__, board_info->board_info->type); 1841 struct isp_device *isp, struct media_entity *entity,
1825 continue; 1842 enum isp_interface_type interface)
1826 } 1843{
1844 struct media_entity *input;
1845 unsigned int flags;
1846 unsigned int pad;
1847 unsigned int i;
1848
1849 /* Connect the sensor to the correct interface module.
1850 * Parallel sensors are connected directly to the CCDC, while
1851 * serial sensors are connected to the CSI2a, CCP2b or CSI2c
1852 * receiver through CSIPHY1 or CSIPHY2.
1853 */
1854 switch (interface) {
1855 case ISP_INTERFACE_PARALLEL:
1856 input = &isp->isp_ccdc.subdev.entity;
1857 pad = CCDC_PAD_SINK;
1858 flags = 0;
1859 break;
1860
1861 case ISP_INTERFACE_CSI2A_PHY2:
1862 input = &isp->isp_csi2a.subdev.entity;
1863 pad = CSI2_PAD_SINK;
1864 flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
1865 break;
1866
1867 case ISP_INTERFACE_CCP2B_PHY1:
1868 case ISP_INTERFACE_CCP2B_PHY2:
1869 input = &isp->isp_ccp2.subdev.entity;
1870 pad = CCP2_PAD_SINK;
1871 flags = 0;
1872 break;
1873
1874 case ISP_INTERFACE_CSI2C_PHY1:
1875 input = &isp->isp_csi2c.subdev.entity;
1876 pad = CSI2_PAD_SINK;
1877 flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED;
1878 break;
1827 1879
1828 if (first) 1880 default:
1829 sensor = subdev; 1881 dev_err(isp->dev, "%s: invalid interface type %u\n", __func__,
1882 interface);
1883 return -EINVAL;
1884 }
1885
1886 /*
1887 * Not all interfaces are available on all revisions of the
1888 * ISP. The sub-devices of those interfaces aren't initialised
1889 * in such a case. Check this by ensuring the num_pads is
1890 * non-zero.
1891 */
1892 if (!input->num_pads) {
1893 dev_err(isp->dev, "%s: invalid input %u\n", entity->name,
1894 interface);
1895 return -EINVAL;
1896 }
1897
1898 for (i = 0; i < entity->num_pads; i++) {
1899 if (entity->pads[i].flags & MEDIA_PAD_FL_SOURCE)
1900 break;
1901 }
1902 if (i == entity->num_pads) {
1903 dev_err(isp->dev, "%s: no source pad in external entity\n",
1904 __func__);
1905 return -EINVAL;
1830 } 1906 }
1831 1907
1832 return sensor; 1908 return media_entity_create_link(entity, i, input, pad, flags);
1833} 1909}
1834 1910
1835static int isp_register_entities(struct isp_device *isp) 1911static int isp_register_entities(struct isp_device *isp)
1836{ 1912{
1837 struct isp_platform_data *pdata = isp->pdata; 1913 struct isp_platform_data *pdata = isp->pdata;
1838 struct isp_v4l2_subdevs_group *subdevs; 1914 struct isp_platform_subdev *isp_subdev;
1839 int ret; 1915 int ret;
1840 1916
1841 isp->media_dev.dev = isp->dev; 1917 isp->media_dev.dev = isp->dev;
@@ -1892,74 +1968,31 @@ static int isp_register_entities(struct isp_device *isp)
1892 if (ret < 0) 1968 if (ret < 0)
1893 goto done; 1969 goto done;
1894 1970
1971 /*
1972 * Device Tree --- the external sub-devices will be registered
1973 * later. The same goes for the sub-device node registration.
1974 */
1975 if (isp->dev->of_node)
1976 return 0;
1977
1895 /* Register external entities */ 1978 /* Register external entities */
1896 for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { 1979 for (isp_subdev = pdata ? pdata->subdevs : NULL;
1897 struct v4l2_subdev *sensor; 1980 isp_subdev && isp_subdev->board_info; isp_subdev++) {
1898 struct media_entity *input; 1981 struct v4l2_subdev *sd;
1899 unsigned int flags;
1900 unsigned int pad;
1901 unsigned int i;
1902
1903 sensor = isp_register_subdev_group(isp, subdevs->subdevs);
1904 if (sensor == NULL)
1905 continue;
1906 1982
1907 sensor->host_priv = subdevs; 1983 sd = isp_register_subdev(isp, isp_subdev);
1908 1984
1909 /* Connect the sensor to the correct interface module. Parallel 1985 /*
1910 * sensors are connected directly to the CCDC, while serial 1986 * No bus information --- this is either a flash or a
1911 * sensors are connected to the CSI2a, CCP2b or CSI2c receiver 1987 * lens subdev.
1912 * through CSIPHY1 or CSIPHY2.
1913 */ 1988 */
1914 switch (subdevs->interface) { 1989 if (!sd || !isp_subdev->bus)
1915 case ISP_INTERFACE_PARALLEL: 1990 continue;
1916 input = &isp->isp_ccdc.subdev.entity;
1917 pad = CCDC_PAD_SINK;
1918 flags = 0;
1919 break;
1920
1921 case ISP_INTERFACE_CSI2A_PHY2:
1922 input = &isp->isp_csi2a.subdev.entity;
1923 pad = CSI2_PAD_SINK;
1924 flags = MEDIA_LNK_FL_IMMUTABLE
1925 | MEDIA_LNK_FL_ENABLED;
1926 break;
1927
1928 case ISP_INTERFACE_CCP2B_PHY1:
1929 case ISP_INTERFACE_CCP2B_PHY2:
1930 input = &isp->isp_ccp2.subdev.entity;
1931 pad = CCP2_PAD_SINK;
1932 flags = 0;
1933 break;
1934
1935 case ISP_INTERFACE_CSI2C_PHY1:
1936 input = &isp->isp_csi2c.subdev.entity;
1937 pad = CSI2_PAD_SINK;
1938 flags = MEDIA_LNK_FL_IMMUTABLE
1939 | MEDIA_LNK_FL_ENABLED;
1940 break;
1941
1942 default:
1943 dev_err(isp->dev, "%s: invalid interface type %u\n",
1944 __func__, subdevs->interface);
1945 ret = -EINVAL;
1946 goto done;
1947 }
1948 1991
1949 for (i = 0; i < sensor->entity.num_pads; i++) { 1992 sd->host_priv = isp_subdev->bus;
1950 if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
1951 break;
1952 }
1953 if (i == sensor->entity.num_pads) {
1954 dev_err(isp->dev,
1955 "%s: no source pad in external entity\n",
1956 __func__);
1957 ret = -EINVAL;
1958 goto done;
1959 }
1960 1993
1961 ret = media_entity_create_link(&sensor->entity, i, input, pad, 1994 ret = isp_link_entity(isp, &sd->entity,
1962 flags); 1995 isp_subdev->bus->interface);
1963 if (ret < 0) 1996 if (ret < 0)
1964 goto done; 1997 goto done;
1965 } 1998 }
@@ -1967,8 +2000,10 @@ static int isp_register_entities(struct isp_device *isp)
1967 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); 2000 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
1968 2001
1969done: 2002done:
1970 if (ret < 0) 2003 if (ret < 0) {
1971 isp_unregister_entities(isp); 2004 isp_unregister_entities(isp);
2005 v4l2_async_notifier_unregister(&isp->notifier);
2006 }
1972 2007
1973 return ret; 2008 return ret;
1974} 2009}
@@ -2183,6 +2218,7 @@ static int isp_remove(struct platform_device *pdev)
2183{ 2218{
2184 struct isp_device *isp = platform_get_drvdata(pdev); 2219 struct isp_device *isp = platform_get_drvdata(pdev);
2185 2220
2221 v4l2_async_notifier_unregister(&isp->notifier);
2186 isp_unregister_entities(isp); 2222 isp_unregister_entities(isp);
2187 isp_cleanup_modules(isp); 2223 isp_cleanup_modules(isp);
2188 isp_xclk_cleanup(isp); 2224 isp_xclk_cleanup(isp);
@@ -2194,26 +2230,156 @@ static int isp_remove(struct platform_device *pdev)
2194 return 0; 2230 return 0;
2195} 2231}
2196 2232
2197static int isp_map_mem_resource(struct platform_device *pdev, 2233enum isp_of_phy {
2198 struct isp_device *isp, 2234 ISP_OF_PHY_PARALLEL = 0,
2199 enum isp_mem_resources res) 2235 ISP_OF_PHY_CSIPHY1,
2236 ISP_OF_PHY_CSIPHY2,
2237};
2238
2239static int isp_of_parse_node(struct device *dev, struct device_node *node,
2240 struct isp_async_subdev *isd)
2200{ 2241{
2201 struct resource *mem; 2242 struct isp_bus_cfg *buscfg = &isd->bus;
2243 struct v4l2_of_endpoint vep;
2244 unsigned int i;
2202 2245
2203 /* request the mem region for the camera registers */ 2246 v4l2_of_parse_endpoint(node, &vep);
2247
2248 dev_dbg(dev, "parsing endpoint %s, interface %u\n", node->full_name,
2249 vep.base.port);
2250
2251 switch (vep.base.port) {
2252 case ISP_OF_PHY_PARALLEL:
2253 buscfg->interface = ISP_INTERFACE_PARALLEL;
2254 buscfg->bus.parallel.data_lane_shift =
2255 vep.bus.parallel.data_shift;
2256 buscfg->bus.parallel.clk_pol =
2257 !!(vep.bus.parallel.flags
2258 & V4L2_MBUS_PCLK_SAMPLE_FALLING);
2259 buscfg->bus.parallel.hs_pol =
2260 !!(vep.bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW);
2261 buscfg->bus.parallel.vs_pol =
2262 !!(vep.bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW);
2263 buscfg->bus.parallel.fld_pol =
2264 !!(vep.bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW);
2265 buscfg->bus.parallel.data_pol =
2266 !!(vep.bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW);
2267 break;
2204 2268
2205 mem = platform_get_resource(pdev, IORESOURCE_MEM, res); 2269 case ISP_OF_PHY_CSIPHY1:
2270 case ISP_OF_PHY_CSIPHY2:
2271 /* FIXME: always assume CSI-2 for now. */
2272 switch (vep.base.port) {
2273 case ISP_OF_PHY_CSIPHY1:
2274 buscfg->interface = ISP_INTERFACE_CSI2C_PHY1;
2275 break;
2276 case ISP_OF_PHY_CSIPHY2:
2277 buscfg->interface = ISP_INTERFACE_CSI2A_PHY2;
2278 break;
2279 }
2280 buscfg->bus.csi2.lanecfg.clk.pos = vep.bus.mipi_csi2.clock_lane;
2281 buscfg->bus.csi2.lanecfg.clk.pol =
2282 vep.bus.mipi_csi2.lane_polarities[0];
2283 dev_dbg(dev, "clock lane polarity %u, pos %u\n",
2284 buscfg->bus.csi2.lanecfg.clk.pol,
2285 buscfg->bus.csi2.lanecfg.clk.pos);
2286
2287 for (i = 0; i < ISP_CSIPHY2_NUM_DATA_LANES; i++) {
2288 buscfg->bus.csi2.lanecfg.data[i].pos =
2289 vep.bus.mipi_csi2.data_lanes[i];
2290 buscfg->bus.csi2.lanecfg.data[i].pol =
2291 vep.bus.mipi_csi2.lane_polarities[i + 1];
2292 dev_dbg(dev, "data lane %u polarity %u, pos %u\n", i,
2293 buscfg->bus.csi2.lanecfg.data[i].pol,
2294 buscfg->bus.csi2.lanecfg.data[i].pos);
2295 }
2206 2296
2207 /* map the region */ 2297 /*
2208 isp->mmio_base[res] = devm_ioremap_resource(isp->dev, mem); 2298 * FIXME: now we assume the CRC is always there.
2209 if (IS_ERR(isp->mmio_base[res])) 2299 * Implement a way to obtain this information from the
2210 return PTR_ERR(isp->mmio_base[res]); 2300 * sensor. Frame descriptors, perhaps?
2301 */
2302 buscfg->bus.csi2.crc = 1;
2303 break;
2211 2304
2212 isp->mmio_base_phys[res] = mem->start; 2305 default:
2306 dev_warn(dev, "%s: invalid interface %u\n", node->full_name,
2307 vep.base.port);
2308 break;
2309 }
2213 2310
2214 return 0; 2311 return 0;
2215} 2312}
2216 2313
2314static int isp_of_parse_nodes(struct device *dev,
2315 struct v4l2_async_notifier *notifier)
2316{
2317 struct device_node *node = NULL;
2318
2319 notifier->subdevs = devm_kcalloc(
2320 dev, ISP_MAX_SUBDEVS, sizeof(*notifier->subdevs), GFP_KERNEL);
2321 if (!notifier->subdevs)
2322 return -ENOMEM;
2323
2324 while (notifier->num_subdevs < ISP_MAX_SUBDEVS &&
2325 (node = of_graph_get_next_endpoint(dev->of_node, node))) {
2326 struct isp_async_subdev *isd;
2327
2328 isd = devm_kzalloc(dev, sizeof(*isd), GFP_KERNEL);
2329 if (!isd) {
2330 of_node_put(node);
2331 return -ENOMEM;
2332 }
2333
2334 notifier->subdevs[notifier->num_subdevs] = &isd->asd;
2335
2336 if (isp_of_parse_node(dev, node, isd)) {
2337 of_node_put(node);
2338 return -EINVAL;
2339 }
2340
2341 isd->asd.match.of.node = of_graph_get_remote_port_parent(node);
2342 of_node_put(node);
2343 if (!isd->asd.match.of.node) {
2344 dev_warn(dev, "bad remote port parent\n");
2345 return -EINVAL;
2346 }
2347
2348 isd->asd.match_type = V4L2_ASYNC_MATCH_OF;
2349 notifier->num_subdevs++;
2350 }
2351
2352 return notifier->num_subdevs;
2353}
2354
2355static int isp_subdev_notifier_bound(struct v4l2_async_notifier *async,
2356 struct v4l2_subdev *subdev,
2357 struct v4l2_async_subdev *asd)
2358{
2359 struct isp_device *isp = container_of(async, struct isp_device,
2360 notifier);
2361 struct isp_async_subdev *isd =
2362 container_of(asd, struct isp_async_subdev, asd);
2363 int ret;
2364
2365 ret = isp_link_entity(isp, &subdev->entity, isd->bus.interface);
2366 if (ret < 0)
2367 return ret;
2368
2369 isd->sd = subdev;
2370 isd->sd->host_priv = &isd->bus;
2371
2372 return ret;
2373}
2374
2375static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async)
2376{
2377 struct isp_device *isp = container_of(async, struct isp_device,
2378 notifier);
2379
2380 return v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
2381}
2382
2217/* 2383/*
2218 * isp_probe - Probe ISP platform device 2384 * isp_probe - Probe ISP platform device
2219 * @pdev: Pointer to ISP platform device 2385 * @pdev: Pointer to ISP platform device
@@ -2227,47 +2393,86 @@ static int isp_map_mem_resource(struct platform_device *pdev,
2227 */ 2393 */
2228static int isp_probe(struct platform_device *pdev) 2394static int isp_probe(struct platform_device *pdev)
2229{ 2395{
2230 struct isp_platform_data *pdata = pdev->dev.platform_data;
2231 struct isp_device *isp; 2396 struct isp_device *isp;
2397 struct resource *mem;
2232 int ret; 2398 int ret;
2233 int i, m; 2399 int i, m;
2234 2400
2235 if (pdata == NULL)
2236 return -EINVAL;
2237
2238 isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); 2401 isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL);
2239 if (!isp) { 2402 if (!isp) {
2240 dev_err(&pdev->dev, "could not allocate memory\n"); 2403 dev_err(&pdev->dev, "could not allocate memory\n");
2241 return -ENOMEM; 2404 return -ENOMEM;
2242 } 2405 }
2243 2406
2407 if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
2408 ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type",
2409 &isp->phy_type);
2410 if (ret)
2411 return ret;
2412
2413 isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
2414 "syscon");
2415 if (IS_ERR(isp->syscon))
2416 return PTR_ERR(isp->syscon);
2417
2418 ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1,
2419 &isp->syscon_offset);
2420 if (ret)
2421 return ret;
2422
2423 ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier);
2424 if (ret < 0)
2425 return ret;
2426 ret = v4l2_async_notifier_register(&isp->v4l2_dev,
2427 &isp->notifier);
2428 if (ret)
2429 return ret;
2430 } else {
2431 isp->pdata = pdev->dev.platform_data;
2432 isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0");
2433 if (IS_ERR(isp->syscon))
2434 return PTR_ERR(isp->syscon);
2435 dev_warn(&pdev->dev,
2436 "Platform data support is deprecated! Please move to DT now!\n");
2437 }
2438
2244 isp->autoidle = autoidle; 2439 isp->autoidle = autoidle;
2245 2440
2246 mutex_init(&isp->isp_mutex); 2441 mutex_init(&isp->isp_mutex);
2247 spin_lock_init(&isp->stat_lock); 2442 spin_lock_init(&isp->stat_lock);
2248 2443
2249 isp->dev = &pdev->dev; 2444 isp->dev = &pdev->dev;
2250 isp->pdata = pdata;
2251 isp->ref_count = 0; 2445 isp->ref_count = 0;
2252 2446
2253 ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); 2447 ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32));
2254 if (ret) 2448 if (ret)
2255 return ret; 2449 goto error;
2256 2450
2257 platform_set_drvdata(pdev, isp); 2451 platform_set_drvdata(pdev, isp);
2258 2452
2259 /* Regulators */ 2453 /* Regulators */
2260 isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY1"); 2454 isp->isp_csiphy1.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy1");
2261 isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "VDD_CSIPHY2"); 2455 isp->isp_csiphy2.vdd = devm_regulator_get(&pdev->dev, "vdd-csiphy2");
2262 2456
2263 /* Clocks 2457 /* Clocks
2264 * 2458 *
2265 * The ISP clock tree is revision-dependent. We thus need to enable ICLK 2459 * The ISP clock tree is revision-dependent. We thus need to enable ICLK
2266 * manually to read the revision before calling __omap3isp_get(). 2460 * manually to read the revision before calling __omap3isp_get().
2461 *
2462 * Start by mapping the ISP MMIO area, which is in two pieces.
2463 * The ISP IOMMU is in between. Map both now, and fill in the
2464 * ISP revision specific portions a little later in the
2465 * function.
2267 */ 2466 */
2268 ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN); 2467 for (i = 0; i < 2; i++) {
2269 if (ret < 0) 2468 unsigned int map_idx = i ? OMAP3_ISP_IOMEM_CSI2A_REGS1 : 0;
2270 goto error; 2469
2470 mem = platform_get_resource(pdev, IORESOURCE_MEM, i);
2471 isp->mmio_base[map_idx] =
2472 devm_ioremap_resource(isp->dev, mem);
2473 if (IS_ERR(isp->mmio_base[map_idx]))
2474 return PTR_ERR(isp->mmio_base[map_idx]);
2475 }
2271 2476
2272 ret = isp_get_clocks(isp); 2477 ret = isp_get_clocks(isp);
2273 if (ret < 0) 2478 if (ret < 0)
@@ -2308,14 +2513,23 @@ static int isp_probe(struct platform_device *pdev)
2308 goto error_isp; 2513 goto error_isp;
2309 } 2514 }
2310 2515
2311 for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) { 2516 if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) {
2312 if (isp_res_maps[m].map & 1 << i) { 2517 isp->syscon_offset = isp_res_maps[m].syscon_offset;
2313 ret = isp_map_mem_resource(pdev, isp, i); 2518 isp->phy_type = isp_res_maps[m].phy_type;
2314 if (ret)
2315 goto error_isp;
2316 }
2317 } 2519 }
2318 2520
2521 for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++)
2522 isp->mmio_base[i] =
2523 isp->mmio_base[0] + isp_res_maps[m].offset[i];
2524
2525 for (i = OMAP3_ISP_IOMEM_CSIPHY2; i < OMAP3_ISP_IOMEM_LAST; i++)
2526 isp->mmio_base[i] =
2527 isp->mmio_base[OMAP3_ISP_IOMEM_CSI2A_REGS1]
2528 + isp_res_maps[m].offset[i];
2529
2530 isp->mmio_hist_base_phys =
2531 mem->start + isp_res_maps[m].offset[OMAP3_ISP_IOMEM_HIST];
2532
2319 /* IOMMU */ 2533 /* IOMMU */
2320 ret = isp_attach_iommu(isp); 2534 ret = isp_attach_iommu(isp);
2321 if (ret < 0) { 2535 if (ret < 0) {
@@ -2343,6 +2557,9 @@ static int isp_probe(struct platform_device *pdev)
2343 if (ret < 0) 2557 if (ret < 0)
2344 goto error_iommu; 2558 goto error_iommu;
2345 2559
2560 isp->notifier.bound = isp_subdev_notifier_bound;
2561 isp->notifier.complete = isp_subdev_notifier_complete;
2562
2346 ret = isp_register_entities(isp); 2563 ret = isp_register_entities(isp);
2347 if (ret < 0) 2564 if (ret < 0)
2348 goto error_modules; 2565 goto error_modules;
@@ -2378,6 +2595,11 @@ static struct platform_device_id omap3isp_id_table[] = {
2378}; 2595};
2379MODULE_DEVICE_TABLE(platform, omap3isp_id_table); 2596MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
2380 2597
2598static const struct of_device_id omap3isp_of_table[] = {
2599 { .compatible = "ti,omap3-isp" },
2600 { },
2601};
2602
2381static struct platform_driver omap3isp_driver = { 2603static struct platform_driver omap3isp_driver = {
2382 .probe = isp_probe, 2604 .probe = isp_probe,
2383 .remove = isp_remove, 2605 .remove = isp_remove,
@@ -2385,6 +2607,7 @@ static struct platform_driver omap3isp_driver = {
2385 .driver = { 2607 .driver = {
2386 .name = "omap3isp", 2608 .name = "omap3isp",
2387 .pm = &omap3isp_pm_ops, 2609 .pm = &omap3isp_pm_ops,
2610 .of_match_table = omap3isp_of_table,
2388 }, 2611 },
2389}; 2612};
2390 2613
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h
index cfdfc8714b6b..e579943175c4 100644
--- a/drivers/media/platform/omap3isp/isp.h
+++ b/drivers/media/platform/omap3isp/isp.h
@@ -18,6 +18,7 @@
18#define OMAP3_ISP_CORE_H 18#define OMAP3_ISP_CORE_H
19 19
20#include <media/omap3isp.h> 20#include <media/omap3isp.h>
21#include <media/v4l2-async.h>
21#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
22#include <linux/clk-provider.h> 23#include <linux/clk-provider.h>
23#include <linux/device.h> 24#include <linux/device.h>
@@ -59,8 +60,6 @@ enum isp_mem_resources {
59 OMAP3_ISP_IOMEM_CSI2C_REGS1, 60 OMAP3_ISP_IOMEM_CSI2C_REGS1,
60 OMAP3_ISP_IOMEM_CSIPHY1, 61 OMAP3_ISP_IOMEM_CSIPHY1,
61 OMAP3_ISP_IOMEM_CSI2C_REGS2, 62 OMAP3_ISP_IOMEM_CSI2C_REGS2,
62 OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE,
63 OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL,
64 OMAP3_ISP_IOMEM_LAST 63 OMAP3_ISP_IOMEM_LAST
65}; 64};
66 65
@@ -93,14 +92,25 @@ enum isp_subclk_resource {
93/* ISP2P: OMAP 36xx */ 92/* ISP2P: OMAP 36xx */
94#define ISP_REVISION_15_0 0xF0 93#define ISP_REVISION_15_0 0xF0
95 94
95#define ISP_PHY_TYPE_3430 0
96#define ISP_PHY_TYPE_3630 1
97
98struct regmap;
99
96/* 100/*
97 * struct isp_res_mapping - Map ISP io resources to ISP revision. 101 * struct isp_res_mapping - Map ISP io resources to ISP revision.
98 * @isp_rev: ISP_REVISION_x_x 102 * @isp_rev: ISP_REVISION_x_x
99 * @map: bitmap for enum isp_mem_resources 103 * @offset: register offsets of various ISP sub-blocks
104 * @syscon_offset: offset of the syscon register for 343x / 3630
105 * (CONTROL_CSIRXFE / CONTROL_CAMERA_PHY_CTRL, respectively)
106 * from the syscon base address
107 * @phy_type: ISP_PHY_TYPE_{3430,3630}
100 */ 108 */
101struct isp_res_mapping { 109struct isp_res_mapping {
102 u32 isp_rev; 110 u32 isp_rev;
103 u32 map; 111 u32 offset[OMAP3_ISP_IOMEM_LAST];
112 u32 syscon_offset;
113 u32 phy_type;
104}; 114};
105 115
106/* 116/*
@@ -122,7 +132,6 @@ enum isp_xclk_id {
122struct isp_xclk { 132struct isp_xclk {
123 struct isp_device *isp; 133 struct isp_device *isp;
124 struct clk_hw hw; 134 struct clk_hw hw;
125 struct clk_lookup *lookup;
126 struct clk *clk; 135 struct clk *clk;
127 enum isp_xclk_id id; 136 enum isp_xclk_id id;
128 137
@@ -138,8 +147,11 @@ struct isp_xclk {
138 * @irq_num: Currently used IRQ number. 147 * @irq_num: Currently used IRQ number.
139 * @mmio_base: Array with kernel base addresses for ioremapped ISP register 148 * @mmio_base: Array with kernel base addresses for ioremapped ISP register
140 * regions. 149 * regions.
141 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register 150 * @mmio_hist_base_phys: Physical L4 bus address for ISP hist block register
142 * regions. 151 * region.
152 * @syscon: Regmap for the syscon register space
153 * @syscon_offset: Offset of the CSIPHY control register in syscon
154 * @phy_type: ISP_PHY_TYPE_{3430,3630}
143 * @mapping: IOMMU mapping 155 * @mapping: IOMMU mapping
144 * @stat_lock: Spinlock for handling statistics 156 * @stat_lock: Spinlock for handling statistics
145 * @isp_mutex: Mutex for serializing requests to ISP. 157 * @isp_mutex: Mutex for serializing requests to ISP.
@@ -166,6 +178,7 @@ struct isp_xclk {
166 */ 178 */
167struct isp_device { 179struct isp_device {
168 struct v4l2_device v4l2_dev; 180 struct v4l2_device v4l2_dev;
181 struct v4l2_async_notifier notifier;
169 struct media_device media_dev; 182 struct media_device media_dev;
170 struct device *dev; 183 struct device *dev;
171 u32 revision; 184 u32 revision;
@@ -175,7 +188,10 @@ struct isp_device {
175 unsigned int irq_num; 188 unsigned int irq_num;
176 189
177 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST]; 190 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
178 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST]; 191 unsigned long mmio_hist_base_phys;
192 struct regmap *syscon;
193 u32 syscon_offset;
194 u32 phy_type;
179 195
180 struct dma_iommu_mapping *mapping; 196 struct dma_iommu_mapping *mapping;
181 197
@@ -209,6 +225,15 @@ struct isp_device {
209 225
210 unsigned int sbl_resources; 226 unsigned int sbl_resources;
211 unsigned int subclk_resources; 227 unsigned int subclk_resources;
228
229#define ISP_MAX_SUBDEVS 8
230 struct v4l2_subdev *subdevs[ISP_MAX_SUBDEVS];
231};
232
233struct isp_async_subdev {
234 struct v4l2_subdev *sd;
235 struct isp_bus_cfg bus;
236 struct v4l2_async_subdev asd;
212}; 237};
213 238
214#define v4l2_dev_to_isp_device(dev) \ 239#define v4l2_dev_to_isp_device(dev) \
@@ -229,7 +254,7 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
229void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe); 254void omap3isp_pipeline_cancel_stream(struct isp_pipeline *pipe);
230void omap3isp_configure_bridge(struct isp_device *isp, 255void omap3isp_configure_bridge(struct isp_device *isp,
231 enum ccdc_input_entity input, 256 enum ccdc_input_entity input,
232 const struct isp_parallel_platform_data *pdata, 257 const struct isp_parallel_cfg *buscfg,
233 unsigned int shift, unsigned int bridge); 258 unsigned int shift, unsigned int bridge);
234 259
235struct isp_device *omap3isp_get(struct isp_device *isp); 260struct isp_device *omap3isp_get(struct isp_device *isp);
diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c
index 587489a072d5..a6a61cce43dd 100644
--- a/drivers/media/platform/omap3isp/ispccdc.c
+++ b/drivers/media/platform/omap3isp/ispccdc.c
@@ -32,7 +32,7 @@
32#define CCDC_MIN_HEIGHT 32 32#define CCDC_MIN_HEIGHT 32
33 33
34static struct v4l2_mbus_framefmt * 34static struct v4l2_mbus_framefmt *
35__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 35__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg,
36 unsigned int pad, enum v4l2_subdev_format_whence which); 36 unsigned int pad, enum v4l2_subdev_format_whence which);
37 37
38static const unsigned int ccdc_fmts[] = { 38static const unsigned int ccdc_fmts[] = {
@@ -958,11 +958,11 @@ void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
958/* 958/*
959 * ccdc_config_sync_if - Set CCDC sync interface configuration 959 * ccdc_config_sync_if - Set CCDC sync interface configuration
960 * @ccdc: Pointer to ISP CCDC device. 960 * @ccdc: Pointer to ISP CCDC device.
961 * @pdata: Parallel interface platform data (may be NULL) 961 * @parcfg: Parallel interface platform data (may be NULL)
962 * @data_size: Data size 962 * @data_size: Data size
963 */ 963 */
964static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc, 964static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
965 struct isp_parallel_platform_data *pdata, 965 struct isp_parallel_cfg *parcfg,
966 unsigned int data_size) 966 unsigned int data_size)
967{ 967{
968 struct isp_device *isp = to_isp_device(ccdc); 968 struct isp_device *isp = to_isp_device(ccdc);
@@ -1000,19 +1000,19 @@ static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
1000 break; 1000 break;
1001 } 1001 }
1002 1002
1003 if (pdata && pdata->data_pol) 1003 if (parcfg && parcfg->data_pol)
1004 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL; 1004 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
1005 1005
1006 if (pdata && pdata->hs_pol) 1006 if (parcfg && parcfg->hs_pol)
1007 syn_mode |= ISPCCDC_SYN_MODE_HDPOL; 1007 syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
1008 1008
1009 /* The polarity of the vertical sync signal output by the BT.656 1009 /* The polarity of the vertical sync signal output by the BT.656
1010 * decoder is not documented and seems to be active low. 1010 * decoder is not documented and seems to be active low.
1011 */ 1011 */
1012 if ((pdata && pdata->vs_pol) || ccdc->bt656) 1012 if ((parcfg && parcfg->vs_pol) || ccdc->bt656)
1013 syn_mode |= ISPCCDC_SYN_MODE_VDPOL; 1013 syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
1014 1014
1015 if (pdata && pdata->fld_pol) 1015 if (parcfg && parcfg->fld_pol)
1016 syn_mode |= ISPCCDC_SYN_MODE_FLDPOL; 1016 syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
1017 1017
1018 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); 1018 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
@@ -1115,7 +1115,7 @@ static const u32 ccdc_sgbrg_pattern =
1115static void ccdc_configure(struct isp_ccdc_device *ccdc) 1115static void ccdc_configure(struct isp_ccdc_device *ccdc)
1116{ 1116{
1117 struct isp_device *isp = to_isp_device(ccdc); 1117 struct isp_device *isp = to_isp_device(ccdc);
1118 struct isp_parallel_platform_data *pdata = NULL; 1118 struct isp_parallel_cfg *parcfg = NULL;
1119 struct v4l2_subdev *sensor; 1119 struct v4l2_subdev *sensor;
1120 struct v4l2_mbus_framefmt *format; 1120 struct v4l2_mbus_framefmt *format;
1121 const struct v4l2_rect *crop; 1121 const struct v4l2_rect *crop;
@@ -1145,7 +1145,7 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1145 if (!ret) 1145 if (!ret)
1146 ccdc->bt656 = cfg.type == V4L2_MBUS_BT656; 1146 ccdc->bt656 = cfg.type == V4L2_MBUS_BT656;
1147 1147
1148 pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) 1148 parcfg = &((struct isp_bus_cfg *)sensor->host_priv)
1149 ->bus.parallel; 1149 ->bus.parallel;
1150 } 1150 }
1151 1151
@@ -1175,10 +1175,10 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
1175 else 1175 else
1176 bridge = ISPCTRL_PAR_BRIDGE_DISABLE; 1176 bridge = ISPCTRL_PAR_BRIDGE_DISABLE;
1177 1177
1178 omap3isp_configure_bridge(isp, ccdc->input, pdata, shift, bridge); 1178 omap3isp_configure_bridge(isp, ccdc->input, parcfg, shift, bridge);
1179 1179
1180 /* Configure the sync interface. */ 1180 /* Configure the sync interface. */
1181 ccdc_config_sync_if(ccdc, pdata, depth_out); 1181 ccdc_config_sync_if(ccdc, parcfg, depth_out);
1182 1182
1183 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE); 1183 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1184 1184
@@ -1935,21 +1935,21 @@ static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
1935} 1935}
1936 1936
1937static struct v4l2_mbus_framefmt * 1937static struct v4l2_mbus_framefmt *
1938__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 1938__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg,
1939 unsigned int pad, enum v4l2_subdev_format_whence which) 1939 unsigned int pad, enum v4l2_subdev_format_whence which)
1940{ 1940{
1941 if (which == V4L2_SUBDEV_FORMAT_TRY) 1941 if (which == V4L2_SUBDEV_FORMAT_TRY)
1942 return v4l2_subdev_get_try_format(fh, pad); 1942 return v4l2_subdev_get_try_format(&ccdc->subdev, cfg, pad);
1943 else 1943 else
1944 return &ccdc->formats[pad]; 1944 return &ccdc->formats[pad];
1945} 1945}
1946 1946
1947static struct v4l2_rect * 1947static struct v4l2_rect *
1948__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 1948__ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg,
1949 enum v4l2_subdev_format_whence which) 1949 enum v4l2_subdev_format_whence which)
1950{ 1950{
1951 if (which == V4L2_SUBDEV_FORMAT_TRY) 1951 if (which == V4L2_SUBDEV_FORMAT_TRY)
1952 return v4l2_subdev_get_try_crop(fh, CCDC_PAD_SOURCE_OF); 1952 return v4l2_subdev_get_try_crop(&ccdc->subdev, cfg, CCDC_PAD_SOURCE_OF);
1953 else 1953 else
1954 return &ccdc->crop; 1954 return &ccdc->crop;
1955} 1955}
@@ -1957,12 +1957,12 @@ __ccdc_get_crop(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1957/* 1957/*
1958 * ccdc_try_format - Try video format on a pad 1958 * ccdc_try_format - Try video format on a pad
1959 * @ccdc: ISP CCDC device 1959 * @ccdc: ISP CCDC device
1960 * @fh : V4L2 subdev file handle 1960 * @cfg : V4L2 subdev pad configuration
1961 * @pad: Pad number 1961 * @pad: Pad number
1962 * @fmt: Format 1962 * @fmt: Format
1963 */ 1963 */
1964static void 1964static void
1965ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, 1965ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_pad_config *cfg,
1966 unsigned int pad, struct v4l2_mbus_framefmt *fmt, 1966 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
1967 enum v4l2_subdev_format_whence which) 1967 enum v4l2_subdev_format_whence which)
1968{ 1968{
@@ -1998,7 +1998,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1998 case CCDC_PAD_SOURCE_OF: 1998 case CCDC_PAD_SOURCE_OF:
1999 pixelcode = fmt->code; 1999 pixelcode = fmt->code;
2000 field = fmt->field; 2000 field = fmt->field;
2001 *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); 2001 *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which);
2002 2002
2003 /* In SYNC mode the bridge converts YUV formats from 2X8 to 2003 /* In SYNC mode the bridge converts YUV formats from 2X8 to
2004 * 1X16. In BT.656 no such conversion occurs. As we don't know 2004 * 1X16. In BT.656 no such conversion occurs. As we don't know
@@ -2023,7 +2023,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
2023 } 2023 }
2024 2024
2025 /* Hardcode the output size to the crop rectangle size. */ 2025 /* Hardcode the output size to the crop rectangle size. */
2026 crop = __ccdc_get_crop(ccdc, fh, which); 2026 crop = __ccdc_get_crop(ccdc, cfg, which);
2027 fmt->width = crop->width; 2027 fmt->width = crop->width;
2028 fmt->height = crop->height; 2028 fmt->height = crop->height;
2029 2029
@@ -2040,7 +2040,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
2040 break; 2040 break;
2041 2041
2042 case CCDC_PAD_SOURCE_VP: 2042 case CCDC_PAD_SOURCE_VP:
2043 *fmt = *__ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which); 2043 *fmt = *__ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, which);
2044 2044
2045 /* The video port interface truncates the data to 10 bits. */ 2045 /* The video port interface truncates the data to 10 bits. */
2046 info = omap3isp_video_format_info(fmt->code); 2046 info = omap3isp_video_format_info(fmt->code);
@@ -2112,12 +2112,12 @@ static void ccdc_try_crop(struct isp_ccdc_device *ccdc,
2112/* 2112/*
2113 * ccdc_enum_mbus_code - Handle pixel format enumeration 2113 * ccdc_enum_mbus_code - Handle pixel format enumeration
2114 * @sd : pointer to v4l2 subdev structure 2114 * @sd : pointer to v4l2 subdev structure
2115 * @fh : V4L2 subdev file handle 2115 * @cfg : V4L2 subdev pad configuration
2116 * @code : pointer to v4l2_subdev_mbus_code_enum structure 2116 * @code : pointer to v4l2_subdev_mbus_code_enum structure
2117 * return -EINVAL or zero on success 2117 * return -EINVAL or zero on success
2118 */ 2118 */
2119static int ccdc_enum_mbus_code(struct v4l2_subdev *sd, 2119static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
2120 struct v4l2_subdev_fh *fh, 2120 struct v4l2_subdev_pad_config *cfg,
2121 struct v4l2_subdev_mbus_code_enum *code) 2121 struct v4l2_subdev_mbus_code_enum *code)
2122{ 2122{
2123 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2123 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
@@ -2132,8 +2132,8 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
2132 break; 2132 break;
2133 2133
2134 case CCDC_PAD_SOURCE_OF: 2134 case CCDC_PAD_SOURCE_OF:
2135 format = __ccdc_get_format(ccdc, fh, code->pad, 2135 format = __ccdc_get_format(ccdc, cfg, code->pad,
2136 V4L2_SUBDEV_FORMAT_TRY); 2136 code->which);
2137 2137
2138 if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 || 2138 if (format->code == MEDIA_BUS_FMT_YUYV8_2X8 ||
2139 format->code == MEDIA_BUS_FMT_UYVY8_2X8) { 2139 format->code == MEDIA_BUS_FMT_UYVY8_2X8) {
@@ -2163,8 +2163,8 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
2163 if (code->index != 0) 2163 if (code->index != 0)
2164 return -EINVAL; 2164 return -EINVAL;
2165 2165
2166 format = __ccdc_get_format(ccdc, fh, code->pad, 2166 format = __ccdc_get_format(ccdc, cfg, code->pad,
2167 V4L2_SUBDEV_FORMAT_TRY); 2167 code->which);
2168 2168
2169 /* A pixel code equal to 0 means that the video port doesn't 2169 /* A pixel code equal to 0 means that the video port doesn't
2170 * support the input format. Don't enumerate any pixel code. 2170 * support the input format. Don't enumerate any pixel code.
@@ -2183,7 +2183,7 @@ static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
2183} 2183}
2184 2184
2185static int ccdc_enum_frame_size(struct v4l2_subdev *sd, 2185static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2186 struct v4l2_subdev_fh *fh, 2186 struct v4l2_subdev_pad_config *cfg,
2187 struct v4l2_subdev_frame_size_enum *fse) 2187 struct v4l2_subdev_frame_size_enum *fse)
2188{ 2188{
2189 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2189 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
@@ -2195,7 +2195,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2195 format.code = fse->code; 2195 format.code = fse->code;
2196 format.width = 1; 2196 format.width = 1;
2197 format.height = 1; 2197 format.height = 1;
2198 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 2198 ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which);
2199 fse->min_width = format.width; 2199 fse->min_width = format.width;
2200 fse->min_height = format.height; 2200 fse->min_height = format.height;
2201 2201
@@ -2205,7 +2205,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2205 format.code = fse->code; 2205 format.code = fse->code;
2206 format.width = -1; 2206 format.width = -1;
2207 format.height = -1; 2207 format.height = -1;
2208 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 2208 ccdc_try_format(ccdc, cfg, fse->pad, &format, fse->which);
2209 fse->max_width = format.width; 2209 fse->max_width = format.width;
2210 fse->max_height = format.height; 2210 fse->max_height = format.height;
2211 2211
@@ -2215,7 +2215,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2215/* 2215/*
2216 * ccdc_get_selection - Retrieve a selection rectangle on a pad 2216 * ccdc_get_selection - Retrieve a selection rectangle on a pad
2217 * @sd: ISP CCDC V4L2 subdevice 2217 * @sd: ISP CCDC V4L2 subdevice
2218 * @fh: V4L2 subdev file handle 2218 * @cfg: V4L2 subdev pad configuration
2219 * @sel: Selection rectangle 2219 * @sel: Selection rectangle
2220 * 2220 *
2221 * The only supported rectangles are the crop rectangles on the output formatter 2221 * The only supported rectangles are the crop rectangles on the output formatter
@@ -2223,7 +2223,7 @@ static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
2223 * 2223 *
2224 * Return 0 on success or a negative error code otherwise. 2224 * Return 0 on success or a negative error code otherwise.
2225 */ 2225 */
2226static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2226static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2227 struct v4l2_subdev_selection *sel) 2227 struct v4l2_subdev_selection *sel)
2228{ 2228{
2229 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2229 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
@@ -2239,12 +2239,12 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2239 sel->r.width = INT_MAX; 2239 sel->r.width = INT_MAX;
2240 sel->r.height = INT_MAX; 2240 sel->r.height = INT_MAX;
2241 2241
2242 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which); 2242 format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which);
2243 ccdc_try_crop(ccdc, format, &sel->r); 2243 ccdc_try_crop(ccdc, format, &sel->r);
2244 break; 2244 break;
2245 2245
2246 case V4L2_SEL_TGT_CROP: 2246 case V4L2_SEL_TGT_CROP:
2247 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); 2247 sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which);
2248 break; 2248 break;
2249 2249
2250 default: 2250 default:
@@ -2257,7 +2257,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2257/* 2257/*
2258 * ccdc_set_selection - Set a selection rectangle on a pad 2258 * ccdc_set_selection - Set a selection rectangle on a pad
2259 * @sd: ISP CCDC V4L2 subdevice 2259 * @sd: ISP CCDC V4L2 subdevice
2260 * @fh: V4L2 subdev file handle 2260 * @cfg: V4L2 subdev pad configuration
2261 * @sel: Selection rectangle 2261 * @sel: Selection rectangle
2262 * 2262 *
2263 * The only supported rectangle is the actual crop rectangle on the output 2263 * The only supported rectangle is the actual crop rectangle on the output
@@ -2265,7 +2265,7 @@ static int ccdc_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2265 * 2265 *
2266 * Return 0 on success or a negative error code otherwise. 2266 * Return 0 on success or a negative error code otherwise.
2267 */ 2267 */
2268static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2268static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2269 struct v4l2_subdev_selection *sel) 2269 struct v4l2_subdev_selection *sel)
2270{ 2270{
2271 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2271 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
@@ -2284,17 +2284,17 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2284 * rectangle. 2284 * rectangle.
2285 */ 2285 */
2286 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { 2286 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
2287 sel->r = *__ccdc_get_crop(ccdc, fh, sel->which); 2287 sel->r = *__ccdc_get_crop(ccdc, cfg, sel->which);
2288 return 0; 2288 return 0;
2289 } 2289 }
2290 2290
2291 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, sel->which); 2291 format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SINK, sel->which);
2292 ccdc_try_crop(ccdc, format, &sel->r); 2292 ccdc_try_crop(ccdc, format, &sel->r);
2293 *__ccdc_get_crop(ccdc, fh, sel->which) = sel->r; 2293 *__ccdc_get_crop(ccdc, cfg, sel->which) = sel->r;
2294 2294
2295 /* Update the source format. */ 2295 /* Update the source format. */
2296 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, sel->which); 2296 format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, sel->which);
2297 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, sel->which); 2297 ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format, sel->which);
2298 2298
2299 return 0; 2299 return 0;
2300} 2300}
@@ -2302,19 +2302,19 @@ static int ccdc_set_selection(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2302/* 2302/*
2303 * ccdc_get_format - Retrieve the video format on a pad 2303 * ccdc_get_format - Retrieve the video format on a pad
2304 * @sd : ISP CCDC V4L2 subdevice 2304 * @sd : ISP CCDC V4L2 subdevice
2305 * @fh : V4L2 subdev file handle 2305 * @cfg: V4L2 subdev pad configuration
2306 * @fmt: Format 2306 * @fmt: Format
2307 * 2307 *
2308 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond 2308 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
2309 * to the format type. 2309 * to the format type.
2310 */ 2310 */
2311static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2311static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2312 struct v4l2_subdev_format *fmt) 2312 struct v4l2_subdev_format *fmt)
2313{ 2313{
2314 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2314 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2315 struct v4l2_mbus_framefmt *format; 2315 struct v4l2_mbus_framefmt *format;
2316 2316
2317 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); 2317 format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which);
2318 if (format == NULL) 2318 if (format == NULL)
2319 return -EINVAL; 2319 return -EINVAL;
2320 2320
@@ -2325,30 +2325,30 @@ static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2325/* 2325/*
2326 * ccdc_set_format - Set the video format on a pad 2326 * ccdc_set_format - Set the video format on a pad
2327 * @sd : ISP CCDC V4L2 subdevice 2327 * @sd : ISP CCDC V4L2 subdevice
2328 * @fh : V4L2 subdev file handle 2328 * @cfg: V4L2 subdev pad configuration
2329 * @fmt: Format 2329 * @fmt: Format
2330 * 2330 *
2331 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond 2331 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
2332 * to the format type. 2332 * to the format type.
2333 */ 2333 */
2334static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2334static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2335 struct v4l2_subdev_format *fmt) 2335 struct v4l2_subdev_format *fmt)
2336{ 2336{
2337 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd); 2337 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2338 struct v4l2_mbus_framefmt *format; 2338 struct v4l2_mbus_framefmt *format;
2339 struct v4l2_rect *crop; 2339 struct v4l2_rect *crop;
2340 2340
2341 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which); 2341 format = __ccdc_get_format(ccdc, cfg, fmt->pad, fmt->which);
2342 if (format == NULL) 2342 if (format == NULL)
2343 return -EINVAL; 2343 return -EINVAL;
2344 2344
2345 ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which); 2345 ccdc_try_format(ccdc, cfg, fmt->pad, &fmt->format, fmt->which);
2346 *format = fmt->format; 2346 *format = fmt->format;
2347 2347
2348 /* Propagate the format from sink to source */ 2348 /* Propagate the format from sink to source */
2349 if (fmt->pad == CCDC_PAD_SINK) { 2349 if (fmt->pad == CCDC_PAD_SINK) {
2350 /* Reset the crop rectangle. */ 2350 /* Reset the crop rectangle. */
2351 crop = __ccdc_get_crop(ccdc, fh, fmt->which); 2351 crop = __ccdc_get_crop(ccdc, cfg, fmt->which);
2352 crop->left = 0; 2352 crop->left = 0;
2353 crop->top = 0; 2353 crop->top = 0;
2354 crop->width = fmt->format.width; 2354 crop->width = fmt->format.width;
@@ -2357,16 +2357,16 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2357 ccdc_try_crop(ccdc, &fmt->format, crop); 2357 ccdc_try_crop(ccdc, &fmt->format, crop);
2358 2358
2359 /* Update the source formats. */ 2359 /* Update the source formats. */
2360 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF, 2360 format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_OF,
2361 fmt->which); 2361 fmt->which);
2362 *format = fmt->format; 2362 *format = fmt->format;
2363 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format, 2363 ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_OF, format,
2364 fmt->which); 2364 fmt->which);
2365 2365
2366 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP, 2366 format = __ccdc_get_format(ccdc, cfg, CCDC_PAD_SOURCE_VP,
2367 fmt->which); 2367 fmt->which);
2368 *format = fmt->format; 2368 *format = fmt->format;
2369 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format, 2369 ccdc_try_format(ccdc, cfg, CCDC_PAD_SOURCE_VP, format,
2370 fmt->which); 2370 fmt->which);
2371 } 2371 }
2372 2372
@@ -2417,11 +2417,11 @@ static int ccdc_link_validate(struct v4l2_subdev *sd,
2417 2417
2418 /* We've got a parallel sensor here. */ 2418 /* We've got a parallel sensor here. */
2419 if (ccdc->input == CCDC_INPUT_PARALLEL) { 2419 if (ccdc->input == CCDC_INPUT_PARALLEL) {
2420 struct isp_parallel_platform_data *pdata = 2420 struct isp_parallel_cfg *parcfg =
2421 &((struct isp_v4l2_subdevs_group *) 2421 &((struct isp_bus_cfg *)
2422 media_entity_to_v4l2_subdev(link->source->entity) 2422 media_entity_to_v4l2_subdev(link->source->entity)
2423 ->host_priv)->bus.parallel; 2423 ->host_priv)->bus.parallel;
2424 parallel_shift = pdata->data_lane_shift * 2; 2424 parallel_shift = parcfg->data_lane_shift * 2;
2425 } else { 2425 } else {
2426 parallel_shift = 0; 2426 parallel_shift = 0;
2427 } 2427 }
@@ -2453,7 +2453,7 @@ static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
2453 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 2453 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
2454 format.format.width = 4096; 2454 format.format.width = 4096;
2455 format.format.height = 4096; 2455 format.format.height = 4096;
2456 ccdc_set_format(sd, fh, &format); 2456 ccdc_set_format(sd, fh ? fh->pad : NULL, &format);
2457 2457
2458 return 0; 2458 return 0;
2459} 2459}
diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c
index f4aedb37e41e..38e6a974c5b1 100644
--- a/drivers/media/platform/omap3isp/ispccp2.c
+++ b/drivers/media/platform/omap3isp/ispccp2.c
@@ -201,14 +201,14 @@ static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
201/* 201/*
202 * ccp2_phyif_config - Initialize CCP2 phy interface config 202 * ccp2_phyif_config - Initialize CCP2 phy interface config
203 * @ccp2: Pointer to ISP CCP2 device 203 * @ccp2: Pointer to ISP CCP2 device
204 * @pdata: CCP2 platform data 204 * @buscfg: CCP2 platform data
205 * 205 *
206 * Configure the CCP2 physical interface module from platform data. 206 * Configure the CCP2 physical interface module from platform data.
207 * 207 *
208 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success. 208 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
209 */ 209 */
210static int ccp2_phyif_config(struct isp_ccp2_device *ccp2, 210static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
211 const struct isp_ccp2_platform_data *pdata) 211 const struct isp_ccp2_cfg *buscfg)
212{ 212{
213 struct isp_device *isp = to_isp_device(ccp2); 213 struct isp_device *isp = to_isp_device(ccp2);
214 u32 val; 214 u32 val;
@@ -218,16 +218,16 @@ static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
218 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE; 218 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
219 /* Data/strobe physical layer */ 219 /* Data/strobe physical layer */
220 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK, 220 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
221 pdata->phy_layer); 221 buscfg->phy_layer);
222 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK, 222 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
223 pdata->strobe_clk_pol); 223 buscfg->strobe_clk_pol);
224 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 224 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
225 225
226 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL); 226 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
227 if (!(val & ISPCCP2_CTRL_MODE)) { 227 if (!(val & ISPCCP2_CTRL_MODE)) {
228 if (pdata->ccp2_mode == ISP_CCP2_MODE_CCP2) 228 if (buscfg->ccp2_mode == ISP_CCP2_MODE_CCP2)
229 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n"); 229 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
230 if (pdata->phy_layer == ISP_CCP2_PHY_DATA_STROBE) 230 if (buscfg->phy_layer == ISP_CCP2_PHY_DATA_STROBE)
231 /* Strobe mode requires CCP2 */ 231 /* Strobe mode requires CCP2 */
232 return -EIO; 232 return -EIO;
233 } 233 }
@@ -347,7 +347,7 @@ static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
347 */ 347 */
348static int ccp2_if_configure(struct isp_ccp2_device *ccp2) 348static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
349{ 349{
350 const struct isp_v4l2_subdevs_group *pdata; 350 const struct isp_bus_cfg *buscfg;
351 struct v4l2_mbus_framefmt *format; 351 struct v4l2_mbus_framefmt *format;
352 struct media_pad *pad; 352 struct media_pad *pad;
353 struct v4l2_subdev *sensor; 353 struct v4l2_subdev *sensor;
@@ -358,20 +358,20 @@ static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
358 358
359 pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]); 359 pad = media_entity_remote_pad(&ccp2->pads[CCP2_PAD_SINK]);
360 sensor = media_entity_to_v4l2_subdev(pad->entity); 360 sensor = media_entity_to_v4l2_subdev(pad->entity);
361 pdata = sensor->host_priv; 361 buscfg = sensor->host_priv;
362 362
363 ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2); 363 ret = ccp2_phyif_config(ccp2, &buscfg->bus.ccp2);
364 if (ret < 0) 364 if (ret < 0)
365 return ret; 365 return ret;
366 366
367 ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1); 367 ccp2_vp_config(ccp2, buscfg->bus.ccp2.vpclk_div + 1);
368 368
369 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines); 369 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
370 370
371 format = &ccp2->formats[CCP2_PAD_SINK]; 371 format = &ccp2->formats[CCP2_PAD_SINK];
372 372
373 ccp2->if_cfg.data_start = lines; 373 ccp2->if_cfg.data_start = lines;
374 ccp2->if_cfg.crc = pdata->bus.ccp2.crc; 374 ccp2->if_cfg.crc = buscfg->bus.ccp2.crc;
375 ccp2->if_cfg.format = format->code; 375 ccp2->if_cfg.format = format->code;
376 ccp2->if_cfg.data_size = format->height; 376 ccp2->if_cfg.data_size = format->height;
377 377
@@ -611,17 +611,17 @@ static const unsigned int ccp2_fmts[] = {
611/* 611/*
612 * __ccp2_get_format - helper function for getting ccp2 format 612 * __ccp2_get_format - helper function for getting ccp2 format
613 * @ccp2 : Pointer to ISP CCP2 device 613 * @ccp2 : Pointer to ISP CCP2 device
614 * @fh : V4L2 subdev file handle 614 * @cfg: V4L2 subdev pad configuration
615 * @pad : pad number 615 * @pad : pad number
616 * @which : wanted subdev format 616 * @which : wanted subdev format
617 * return format structure or NULL on error 617 * return format structure or NULL on error
618 */ 618 */
619static struct v4l2_mbus_framefmt * 619static struct v4l2_mbus_framefmt *
620__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh, 620__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_pad_config *cfg,
621 unsigned int pad, enum v4l2_subdev_format_whence which) 621 unsigned int pad, enum v4l2_subdev_format_whence which)
622{ 622{
623 if (which == V4L2_SUBDEV_FORMAT_TRY) 623 if (which == V4L2_SUBDEV_FORMAT_TRY)
624 return v4l2_subdev_get_try_format(fh, pad); 624 return v4l2_subdev_get_try_format(&ccp2->subdev, cfg, pad);
625 else 625 else
626 return &ccp2->formats[pad]; 626 return &ccp2->formats[pad];
627} 627}
@@ -629,13 +629,13 @@ __ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
629/* 629/*
630 * ccp2_try_format - Handle try format by pad subdev method 630 * ccp2_try_format - Handle try format by pad subdev method
631 * @ccp2 : Pointer to ISP CCP2 device 631 * @ccp2 : Pointer to ISP CCP2 device
632 * @fh : V4L2 subdev file handle 632 * @cfg: V4L2 subdev pad configuration
633 * @pad : pad num 633 * @pad : pad num
634 * @fmt : pointer to v4l2 mbus format structure 634 * @fmt : pointer to v4l2 mbus format structure
635 * @which : wanted subdev format 635 * @which : wanted subdev format
636 */ 636 */
637static void ccp2_try_format(struct isp_ccp2_device *ccp2, 637static void ccp2_try_format(struct isp_ccp2_device *ccp2,
638 struct v4l2_subdev_fh *fh, unsigned int pad, 638 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
639 struct v4l2_mbus_framefmt *fmt, 639 struct v4l2_mbus_framefmt *fmt,
640 enum v4l2_subdev_format_whence which) 640 enum v4l2_subdev_format_whence which)
641{ 641{
@@ -669,7 +669,7 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2,
669 * When CCP2 write to memory feature will be added this 669 * When CCP2 write to memory feature will be added this
670 * should be changed properly. 670 * should be changed properly.
671 */ 671 */
672 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which); 672 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK, which);
673 memcpy(fmt, format, sizeof(*fmt)); 673 memcpy(fmt, format, sizeof(*fmt));
674 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; 674 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
675 break; 675 break;
@@ -682,12 +682,12 @@ static void ccp2_try_format(struct isp_ccp2_device *ccp2,
682/* 682/*
683 * ccp2_enum_mbus_code - Handle pixel format enumeration 683 * ccp2_enum_mbus_code - Handle pixel format enumeration
684 * @sd : pointer to v4l2 subdev structure 684 * @sd : pointer to v4l2 subdev structure
685 * @fh : V4L2 subdev file handle 685 * @cfg: V4L2 subdev pad configuration
686 * @code : pointer to v4l2_subdev_mbus_code_enum structure 686 * @code : pointer to v4l2_subdev_mbus_code_enum structure
687 * return -EINVAL or zero on success 687 * return -EINVAL or zero on success
688 */ 688 */
689static int ccp2_enum_mbus_code(struct v4l2_subdev *sd, 689static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
690 struct v4l2_subdev_fh *fh, 690 struct v4l2_subdev_pad_config *cfg,
691 struct v4l2_subdev_mbus_code_enum *code) 691 struct v4l2_subdev_mbus_code_enum *code)
692{ 692{
693 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 693 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
@@ -702,8 +702,8 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
702 if (code->index != 0) 702 if (code->index != 0)
703 return -EINVAL; 703 return -EINVAL;
704 704
705 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, 705 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SINK,
706 V4L2_SUBDEV_FORMAT_TRY); 706 code->which);
707 code->code = format->code; 707 code->code = format->code;
708 } 708 }
709 709
@@ -711,7 +711,7 @@ static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
711} 711}
712 712
713static int ccp2_enum_frame_size(struct v4l2_subdev *sd, 713static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
714 struct v4l2_subdev_fh *fh, 714 struct v4l2_subdev_pad_config *cfg,
715 struct v4l2_subdev_frame_size_enum *fse) 715 struct v4l2_subdev_frame_size_enum *fse)
716{ 716{
717 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 717 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
@@ -723,7 +723,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
723 format.code = fse->code; 723 format.code = fse->code;
724 format.width = 1; 724 format.width = 1;
725 format.height = 1; 725 format.height = 1;
726 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 726 ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which);
727 fse->min_width = format.width; 727 fse->min_width = format.width;
728 fse->min_height = format.height; 728 fse->min_height = format.height;
729 729
@@ -733,7 +733,7 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
733 format.code = fse->code; 733 format.code = fse->code;
734 format.width = -1; 734 format.width = -1;
735 format.height = -1; 735 format.height = -1;
736 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 736 ccp2_try_format(ccp2, cfg, fse->pad, &format, fse->which);
737 fse->max_width = format.width; 737 fse->max_width = format.width;
738 fse->max_height = format.height; 738 fse->max_height = format.height;
739 739
@@ -743,17 +743,17 @@ static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
743/* 743/*
744 * ccp2_get_format - Handle get format by pads subdev method 744 * ccp2_get_format - Handle get format by pads subdev method
745 * @sd : pointer to v4l2 subdev structure 745 * @sd : pointer to v4l2 subdev structure
746 * @fh : V4L2 subdev file handle 746 * @cfg: V4L2 subdev pad configuration
747 * @fmt : pointer to v4l2 subdev format structure 747 * @fmt : pointer to v4l2 subdev format structure
748 * return -EINVAL or zero on success 748 * return -EINVAL or zero on success
749 */ 749 */
750static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 750static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
751 struct v4l2_subdev_format *fmt) 751 struct v4l2_subdev_format *fmt)
752{ 752{
753 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 753 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
754 struct v4l2_mbus_framefmt *format; 754 struct v4l2_mbus_framefmt *format;
755 755
756 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which); 756 format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which);
757 if (format == NULL) 757 if (format == NULL)
758 return -EINVAL; 758 return -EINVAL;
759 759
@@ -764,29 +764,29 @@ static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
764/* 764/*
765 * ccp2_set_format - Handle set format by pads subdev method 765 * ccp2_set_format - Handle set format by pads subdev method
766 * @sd : pointer to v4l2 subdev structure 766 * @sd : pointer to v4l2 subdev structure
767 * @fh : V4L2 subdev file handle 767 * @cfg: V4L2 subdev pad configuration
768 * @fmt : pointer to v4l2 subdev format structure 768 * @fmt : pointer to v4l2 subdev format structure
769 * returns zero 769 * returns zero
770 */ 770 */
771static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 771static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
772 struct v4l2_subdev_format *fmt) 772 struct v4l2_subdev_format *fmt)
773{ 773{
774 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd); 774 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
775 struct v4l2_mbus_framefmt *format; 775 struct v4l2_mbus_framefmt *format;
776 776
777 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which); 777 format = __ccp2_get_format(ccp2, cfg, fmt->pad, fmt->which);
778 if (format == NULL) 778 if (format == NULL)
779 return -EINVAL; 779 return -EINVAL;
780 780
781 ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which); 781 ccp2_try_format(ccp2, cfg, fmt->pad, &fmt->format, fmt->which);
782 *format = fmt->format; 782 *format = fmt->format;
783 783
784 /* Propagate the format from sink to source */ 784 /* Propagate the format from sink to source */
785 if (fmt->pad == CCP2_PAD_SINK) { 785 if (fmt->pad == CCP2_PAD_SINK) {
786 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE, 786 format = __ccp2_get_format(ccp2, cfg, CCP2_PAD_SOURCE,
787 fmt->which); 787 fmt->which);
788 *format = fmt->format; 788 *format = fmt->format;
789 ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which); 789 ccp2_try_format(ccp2, cfg, CCP2_PAD_SOURCE, format, fmt->which);
790 } 790 }
791 791
792 return 0; 792 return 0;
@@ -811,7 +811,7 @@ static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
811 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 811 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
812 format.format.width = 4096; 812 format.format.width = 4096;
813 format.format.height = 4096; 813 format.format.height = 4096;
814 ccp2_set_format(sd, fh, &format); 814 ccp2_set_format(sd, fh ? fh->pad : NULL, &format);
815 815
816 return 0; 816 return 0;
817} 817}
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c
index 09c686d96ae8..a78338d012b4 100644
--- a/drivers/media/platform/omap3isp/ispcsi2.c
+++ b/drivers/media/platform/omap3isp/ispcsi2.c
@@ -548,7 +548,8 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
548 548
549static int csi2_configure(struct isp_csi2_device *csi2) 549static int csi2_configure(struct isp_csi2_device *csi2)
550{ 550{
551 const struct isp_v4l2_subdevs_group *pdata; 551 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
552 const struct isp_bus_cfg *buscfg;
552 struct isp_device *isp = csi2->isp; 553 struct isp_device *isp = csi2->isp;
553 struct isp_csi2_timing_cfg *timing = &csi2->timing[0]; 554 struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
554 struct v4l2_subdev *sensor; 555 struct v4l2_subdev *sensor;
@@ -565,14 +566,19 @@ static int csi2_configure(struct isp_csi2_device *csi2)
565 566
566 pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]); 567 pad = media_entity_remote_pad(&csi2->pads[CSI2_PAD_SINK]);
567 sensor = media_entity_to_v4l2_subdev(pad->entity); 568 sensor = media_entity_to_v4l2_subdev(pad->entity);
568 pdata = sensor->host_priv; 569 buscfg = sensor->host_priv;
569 570
570 csi2->frame_skip = 0; 571 csi2->frame_skip = 0;
571 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip); 572 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
572 573
573 csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div; 574 csi2->ctrl.vp_out_ctrl =
575 clamp_t(unsigned int, pipe->l3_ick / pipe->external_rate - 1,
576 1, 3);
577 dev_dbg(isp->dev, "%s: l3_ick %lu, external_rate %u, vp_out_ctrl %u\n",
578 __func__, pipe->l3_ick, pipe->external_rate,
579 csi2->ctrl.vp_out_ctrl);
574 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE; 580 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
575 csi2->ctrl.ecc_enable = pdata->bus.csi2.crc; 581 csi2->ctrl.ecc_enable = buscfg->bus.csi2.crc;
576 582
577 timing->ionum = 1; 583 timing->ionum = 1;
578 timing->force_rx_mode = 1; 584 timing->force_rx_mode = 1;
@@ -829,17 +835,17 @@ static const struct isp_video_operations csi2_ispvideo_ops = {
829 */ 835 */
830 836
831static struct v4l2_mbus_framefmt * 837static struct v4l2_mbus_framefmt *
832__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, 838__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg,
833 unsigned int pad, enum v4l2_subdev_format_whence which) 839 unsigned int pad, enum v4l2_subdev_format_whence which)
834{ 840{
835 if (which == V4L2_SUBDEV_FORMAT_TRY) 841 if (which == V4L2_SUBDEV_FORMAT_TRY)
836 return v4l2_subdev_get_try_format(fh, pad); 842 return v4l2_subdev_get_try_format(&csi2->subdev, cfg, pad);
837 else 843 else
838 return &csi2->formats[pad]; 844 return &csi2->formats[pad];
839} 845}
840 846
841static void 847static void
842csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh, 848csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_pad_config *cfg,
843 unsigned int pad, struct v4l2_mbus_framefmt *fmt, 849 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
844 enum v4l2_subdev_format_whence which) 850 enum v4l2_subdev_format_whence which)
845{ 851{
@@ -869,7 +875,7 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
869 * compression. 875 * compression.
870 */ 876 */
871 pixelcode = fmt->code; 877 pixelcode = fmt->code;
872 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which); 878 format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK, which);
873 memcpy(fmt, format, sizeof(*fmt)); 879 memcpy(fmt, format, sizeof(*fmt));
874 880
875 /* 881 /*
@@ -890,12 +896,12 @@ csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
890/* 896/*
891 * csi2_enum_mbus_code - Handle pixel format enumeration 897 * csi2_enum_mbus_code - Handle pixel format enumeration
892 * @sd : pointer to v4l2 subdev structure 898 * @sd : pointer to v4l2 subdev structure
893 * @fh : V4L2 subdev file handle 899 * @cfg: V4L2 subdev pad configuration
894 * @code : pointer to v4l2_subdev_mbus_code_enum structure 900 * @code : pointer to v4l2_subdev_mbus_code_enum structure
895 * return -EINVAL or zero on success 901 * return -EINVAL or zero on success
896 */ 902 */
897static int csi2_enum_mbus_code(struct v4l2_subdev *sd, 903static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
898 struct v4l2_subdev_fh *fh, 904 struct v4l2_subdev_pad_config *cfg,
899 struct v4l2_subdev_mbus_code_enum *code) 905 struct v4l2_subdev_mbus_code_enum *code)
900{ 906{
901 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 907 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
@@ -908,8 +914,8 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
908 914
909 code->code = csi2_input_fmts[code->index]; 915 code->code = csi2_input_fmts[code->index];
910 } else { 916 } else {
911 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, 917 format = __csi2_get_format(csi2, cfg, CSI2_PAD_SINK,
912 V4L2_SUBDEV_FORMAT_TRY); 918 code->which);
913 switch (code->index) { 919 switch (code->index) {
914 case 0: 920 case 0:
915 /* Passthrough sink pad code */ 921 /* Passthrough sink pad code */
@@ -932,7 +938,7 @@ static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
932} 938}
933 939
934static int csi2_enum_frame_size(struct v4l2_subdev *sd, 940static int csi2_enum_frame_size(struct v4l2_subdev *sd,
935 struct v4l2_subdev_fh *fh, 941 struct v4l2_subdev_pad_config *cfg,
936 struct v4l2_subdev_frame_size_enum *fse) 942 struct v4l2_subdev_frame_size_enum *fse)
937{ 943{
938 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 944 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
@@ -944,7 +950,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd,
944 format.code = fse->code; 950 format.code = fse->code;
945 format.width = 1; 951 format.width = 1;
946 format.height = 1; 952 format.height = 1;
947 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 953 csi2_try_format(csi2, cfg, fse->pad, &format, fse->which);
948 fse->min_width = format.width; 954 fse->min_width = format.width;
949 fse->min_height = format.height; 955 fse->min_height = format.height;
950 956
@@ -954,7 +960,7 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd,
954 format.code = fse->code; 960 format.code = fse->code;
955 format.width = -1; 961 format.width = -1;
956 format.height = -1; 962 format.height = -1;
957 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 963 csi2_try_format(csi2, cfg, fse->pad, &format, fse->which);
958 fse->max_width = format.width; 964 fse->max_width = format.width;
959 fse->max_height = format.height; 965 fse->max_height = format.height;
960 966
@@ -964,17 +970,17 @@ static int csi2_enum_frame_size(struct v4l2_subdev *sd,
964/* 970/*
965 * csi2_get_format - Handle get format by pads subdev method 971 * csi2_get_format - Handle get format by pads subdev method
966 * @sd : pointer to v4l2 subdev structure 972 * @sd : pointer to v4l2 subdev structure
967 * @fh : V4L2 subdev file handle 973 * @cfg: V4L2 subdev pad configuration
968 * @fmt: pointer to v4l2 subdev format structure 974 * @fmt: pointer to v4l2 subdev format structure
969 * return -EINVAL or zero on success 975 * return -EINVAL or zero on success
970 */ 976 */
971static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 977static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
972 struct v4l2_subdev_format *fmt) 978 struct v4l2_subdev_format *fmt)
973{ 979{
974 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 980 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
975 struct v4l2_mbus_framefmt *format; 981 struct v4l2_mbus_framefmt *format;
976 982
977 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which); 983 format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which);
978 if (format == NULL) 984 if (format == NULL)
979 return -EINVAL; 985 return -EINVAL;
980 986
@@ -985,29 +991,29 @@ static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
985/* 991/*
986 * csi2_set_format - Handle set format by pads subdev method 992 * csi2_set_format - Handle set format by pads subdev method
987 * @sd : pointer to v4l2 subdev structure 993 * @sd : pointer to v4l2 subdev structure
988 * @fh : V4L2 subdev file handle 994 * @cfg: V4L2 subdev pad configuration
989 * @fmt: pointer to v4l2 subdev format structure 995 * @fmt: pointer to v4l2 subdev format structure
990 * return -EINVAL or zero on success 996 * return -EINVAL or zero on success
991 */ 997 */
992static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 998static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
993 struct v4l2_subdev_format *fmt) 999 struct v4l2_subdev_format *fmt)
994{ 1000{
995 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd); 1001 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
996 struct v4l2_mbus_framefmt *format; 1002 struct v4l2_mbus_framefmt *format;
997 1003
998 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which); 1004 format = __csi2_get_format(csi2, cfg, fmt->pad, fmt->which);
999 if (format == NULL) 1005 if (format == NULL)
1000 return -EINVAL; 1006 return -EINVAL;
1001 1007
1002 csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which); 1008 csi2_try_format(csi2, cfg, fmt->pad, &fmt->format, fmt->which);
1003 *format = fmt->format; 1009 *format = fmt->format;
1004 1010
1005 /* Propagate the format from sink to source */ 1011 /* Propagate the format from sink to source */
1006 if (fmt->pad == CSI2_PAD_SINK) { 1012 if (fmt->pad == CSI2_PAD_SINK) {
1007 format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE, 1013 format = __csi2_get_format(csi2, cfg, CSI2_PAD_SOURCE,
1008 fmt->which); 1014 fmt->which);
1009 *format = fmt->format; 1015 *format = fmt->format;
1010 csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which); 1016 csi2_try_format(csi2, cfg, CSI2_PAD_SOURCE, format, fmt->which);
1011 } 1017 }
1012 1018
1013 return 0; 1019 return 0;
@@ -1032,7 +1038,7 @@ static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1032 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 1038 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
1033 format.format.width = 4096; 1039 format.format.width = 4096;
1034 format.format.height = 4096; 1040 format.format.height = 4096;
1035 csi2_set_format(sd, fh, &format); 1041 csi2_set_format(sd, fh ? fh->pad : NULL, &format);
1036 1042
1037 return 0; 1043 return 0;
1038} 1044}
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c
index e033f2237a72..495447d66cfd 100644
--- a/drivers/media/platform/omap3isp/ispcsiphy.c
+++ b/drivers/media/platform/omap3isp/ispcsiphy.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/regmap.h>
19#include <linux/regulator/consumer.h> 20#include <linux/regulator/consumer.h>
20 21
21#include "isp.h" 22#include "isp.h"
@@ -26,10 +27,11 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy,
26 enum isp_interface_type iface, 27 enum isp_interface_type iface,
27 bool ccp2_strobe) 28 bool ccp2_strobe)
28{ 29{
29 u32 reg = isp_reg_readl( 30 u32 reg;
30 phy->isp, OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
31 u32 shift, mode; 31 u32 shift, mode;
32 32
33 regmap_read(phy->isp->syscon, phy->isp->syscon_offset, &reg);
34
33 switch (iface) { 35 switch (iface) {
34 default: 36 default:
35 /* Should not happen in practice, but let's keep the compiler happy. */ 37 /* Should not happen in practice, but let's keep the compiler happy. */
@@ -63,8 +65,7 @@ static void csiphy_routing_cfg_3630(struct isp_csiphy *phy,
63 reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift); 65 reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift);
64 reg |= mode << shift; 66 reg |= mode << shift;
65 67
66 isp_reg_writel(phy->isp, reg, 68 regmap_write(phy->isp->syscon, phy->isp->syscon_offset, reg);
67 OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0);
68} 69}
69 70
70static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on, 71static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on,
@@ -78,16 +79,14 @@ static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on,
78 return; 79 return;
79 80
80 if (!on) { 81 if (!on) {
81 isp_reg_writel(phy->isp, 0, 82 regmap_write(phy->isp->syscon, phy->isp->syscon_offset, 0);
82 OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
83 return; 83 return;
84 } 84 }
85 85
86 if (ccp2_strobe) 86 if (ccp2_strobe)
87 csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM; 87 csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM;
88 88
89 isp_reg_writel(phy->isp, csirxfe, 89 regmap_write(phy->isp->syscon, phy->isp->syscon_offset, csirxfe);
90 OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0);
91} 90}
92 91
93/* 92/*
@@ -106,10 +105,9 @@ static void csiphy_routing_cfg(struct isp_csiphy *phy,
106 enum isp_interface_type iface, bool on, 105 enum isp_interface_type iface, bool on,
107 bool ccp2_strobe) 106 bool ccp2_strobe)
108{ 107{
109 if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL] 108 if (phy->isp->phy_type == ISP_PHY_TYPE_3630 && on)
110 && on)
111 return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe); 109 return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe);
112 if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE]) 110 if (phy->isp->phy_type == ISP_PHY_TYPE_3430)
113 return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe); 111 return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe);
114} 112}
115 113
@@ -168,18 +166,25 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
168{ 166{
169 struct isp_csi2_device *csi2 = phy->csi2; 167 struct isp_csi2_device *csi2 = phy->csi2;
170 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); 168 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
171 struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv; 169 struct isp_bus_cfg *buscfg = pipe->external->host_priv;
172 struct isp_csiphy_lanes_cfg *lanes; 170 struct isp_csiphy_lanes_cfg *lanes;
173 int csi2_ddrclk_khz; 171 int csi2_ddrclk_khz;
174 unsigned int used_lanes = 0; 172 unsigned int used_lanes = 0;
175 unsigned int i; 173 unsigned int i;
176 u32 reg; 174 u32 reg;
177 175
178 if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1 176 if (!buscfg) {
179 || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2) 177 struct isp_async_subdev *isd =
180 lanes = &subdevs->bus.ccp2.lanecfg; 178 container_of(pipe->external->asd,
179 struct isp_async_subdev, asd);
180 buscfg = &isd->bus;
181 }
182
183 if (buscfg->interface == ISP_INTERFACE_CCP2B_PHY1
184 || buscfg->interface == ISP_INTERFACE_CCP2B_PHY2)
185 lanes = &buscfg->bus.ccp2.lanecfg;
181 else 186 else
182 lanes = &subdevs->bus.csi2.lanecfg; 187 lanes = &buscfg->bus.csi2.lanecfg;
183 188
184 /* Clock and data lanes verification */ 189 /* Clock and data lanes verification */
185 for (i = 0; i < phy->num_data_lanes; i++) { 190 for (i = 0; i < phy->num_data_lanes; i++) {
@@ -203,8 +208,8 @@ static int omap3isp_csiphy_config(struct isp_csiphy *phy)
203 * issue since the MPU power domain is forced on whilst the 208 * issue since the MPU power domain is forced on whilst the
204 * ISP is in use. 209 * ISP is in use.
205 */ 210 */
206 csiphy_routing_cfg(phy, subdevs->interface, true, 211 csiphy_routing_cfg(phy, buscfg->interface, true,
207 subdevs->bus.ccp2.phy_layer); 212 buscfg->bus.ccp2.phy_layer);
208 213
209 /* DPHY timing configuration */ 214 /* DPHY timing configuration */
210 /* CSI-2 is DDR and we only count used lanes. */ 215 /* CSI-2 is DDR and we only count used lanes. */
@@ -302,11 +307,10 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy)
302 struct isp_csi2_device *csi2 = phy->csi2; 307 struct isp_csi2_device *csi2 = phy->csi2;
303 struct isp_pipeline *pipe = 308 struct isp_pipeline *pipe =
304 to_isp_pipeline(&csi2->subdev.entity); 309 to_isp_pipeline(&csi2->subdev.entity);
305 struct isp_v4l2_subdevs_group *subdevs = 310 struct isp_bus_cfg *buscfg = pipe->external->host_priv;
306 pipe->external->host_priv;
307 311
308 csiphy_routing_cfg(phy, subdevs->interface, false, 312 csiphy_routing_cfg(phy, buscfg->interface, false,
309 subdevs->bus.ccp2.phy_layer); 313 buscfg->bus.ccp2.phy_layer);
310 csiphy_power_autoswitch_enable(phy, false); 314 csiphy_power_autoswitch_enable(phy, false);
311 csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); 315 csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
312 regulator_disable(phy->vdd); 316 regulator_disable(phy->vdd);
diff --git a/drivers/media/platform/omap3isp/isph3a_aewb.c b/drivers/media/platform/omap3isp/isph3a_aewb.c
index b208c5417146..ccaf92f39236 100644
--- a/drivers/media/platform/omap3isp/isph3a_aewb.c
+++ b/drivers/media/platform/omap3isp/isph3a_aewb.c
@@ -297,7 +297,6 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp)
297 297
298 aewb->ops = &h3a_aewb_ops; 298 aewb->ops = &h3a_aewb_ops;
299 aewb->priv = aewb_cfg; 299 aewb->priv = aewb_cfg;
300 aewb->dma_ch = -1;
301 aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB; 300 aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB;
302 aewb->isp = isp; 301 aewb->isp = isp;
303 302
diff --git a/drivers/media/platform/omap3isp/isph3a_af.c b/drivers/media/platform/omap3isp/isph3a_af.c
index 8a83e195f3e3..92937f7eecef 100644
--- a/drivers/media/platform/omap3isp/isph3a_af.c
+++ b/drivers/media/platform/omap3isp/isph3a_af.c
@@ -360,7 +360,6 @@ int omap3isp_h3a_af_init(struct isp_device *isp)
360 360
361 af->ops = &h3a_af_ops; 361 af->ops = &h3a_af_ops;
362 af->priv = af_cfg; 362 af->priv = af_cfg;
363 af->dma_ch = -1;
364 af->event_type = V4L2_EVENT_OMAP3ISP_AF; 363 af->event_type = V4L2_EVENT_OMAP3ISP_AF;
365 af->isp = isp; 364 af->isp = isp;
366 365
diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c
index ce822c34c843..7138b043a4aa 100644
--- a/drivers/media/platform/omap3isp/isphist.c
+++ b/drivers/media/platform/omap3isp/isphist.c
@@ -16,20 +16,18 @@
16 */ 16 */
17 17
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/device.h>
20#include <linux/dmaengine.h>
21#include <linux/omap-dmaengine.h>
19#include <linux/slab.h> 22#include <linux/slab.h>
20#include <linux/uaccess.h> 23#include <linux/uaccess.h>
21#include <linux/device.h>
22 24
23#include "isp.h" 25#include "isp.h"
24#include "ispreg.h" 26#include "ispreg.h"
25#include "isphist.h" 27#include "isphist.h"
26 28
27#define OMAP24XX_DMA_NO_DEVICE 0
28
29#define HIST_CONFIG_DMA 1 29#define HIST_CONFIG_DMA 1
30 30
31#define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0)
32
33/* 31/*
34 * hist_reset_mem - clear Histogram memory before start stats engine. 32 * hist_reset_mem - clear Histogram memory before start stats engine.
35 */ 33 */
@@ -62,20 +60,6 @@ static void hist_reset_mem(struct ispstat *hist)
62 hist->wait_acc_frames = conf->num_acc_frames; 60 hist->wait_acc_frames = conf->num_acc_frames;
63} 61}
64 62
65static void hist_dma_config(struct ispstat *hist)
66{
67 struct isp_device *isp = hist->isp;
68
69 hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
70 hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
71 hist->dma_config.frame_count = 1;
72 hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
73 hist->dma_config.src_start = isp->mmio_base_phys[OMAP3_ISP_IOMEM_HIST]
74 + ISPHIST_DATA;
75 hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
76 hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
77}
78
79/* 63/*
80 * hist_setup_regs - Helper function to update Histogram registers. 64 * hist_setup_regs - Helper function to update Histogram registers.
81 */ 65 */
@@ -176,17 +160,12 @@ static int hist_busy(struct ispstat *hist)
176 & ISPHIST_PCR_BUSY; 160 & ISPHIST_PCR_BUSY;
177} 161}
178 162
179static void hist_dma_cb(int lch, u16 ch_status, void *data) 163static void hist_dma_cb(void *data)
180{ 164{
181 struct ispstat *hist = data; 165 struct ispstat *hist = data;
182 166
183 if (ch_status & ~OMAP_DMA_BLOCK_IRQ) { 167 /* FIXME: The DMA engine API can't report transfer errors :-/ */
184 dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n", 168
185 ch_status);
186 omap_stop_dma(lch);
187 hist_reset_mem(hist);
188 atomic_set(&hist->buf_err, 1);
189 }
190 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, 169 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
191 ISPHIST_CNT_CLEAR); 170 ISPHIST_CNT_CLEAR);
192 171
@@ -198,24 +177,57 @@ static void hist_dma_cb(int lch, u16 ch_status, void *data)
198static int hist_buf_dma(struct ispstat *hist) 177static int hist_buf_dma(struct ispstat *hist)
199{ 178{
200 dma_addr_t dma_addr = hist->active_buf->dma_addr; 179 dma_addr_t dma_addr = hist->active_buf->dma_addr;
180 struct dma_async_tx_descriptor *tx;
181 struct dma_slave_config cfg;
182 dma_cookie_t cookie;
183 int ret;
201 184
202 if (unlikely(!dma_addr)) { 185 if (unlikely(!dma_addr)) {
203 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n"); 186 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
204 hist_reset_mem(hist); 187 goto error;
205 return STAT_NO_BUF;
206 } 188 }
207 189
208 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR); 190 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
209 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, 191 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
210 ISPHIST_CNT_CLEAR); 192 ISPHIST_CNT_CLEAR);
211 omap3isp_flush(hist->isp); 193 omap3isp_flush(hist->isp);
212 hist->dma_config.dst_start = dma_addr;
213 hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
214 omap_set_dma_params(hist->dma_ch, &hist->dma_config);
215 194
216 omap_start_dma(hist->dma_ch); 195 memset(&cfg, 0, sizeof(cfg));
196 cfg.src_addr = hist->isp->mmio_hist_base_phys + ISPHIST_DATA;
197 cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
198 cfg.src_maxburst = hist->buf_size / 4;
199
200 ret = dmaengine_slave_config(hist->dma_ch, &cfg);
201 if (ret < 0) {
202 dev_dbg(hist->isp->dev,
203 "hist: DMA slave configuration failed\n");
204 goto error;
205 }
206
207 tx = dmaengine_prep_slave_single(hist->dma_ch, dma_addr,
208 hist->buf_size, DMA_DEV_TO_MEM,
209 DMA_CTRL_ACK);
210 if (tx == NULL) {
211 dev_dbg(hist->isp->dev,
212 "hist: DMA slave preparation failed\n");
213 goto error;
214 }
215
216 tx->callback = hist_dma_cb;
217 tx->callback_param = hist;
218 cookie = tx->tx_submit(tx);
219 if (dma_submit_error(cookie)) {
220 dev_dbg(hist->isp->dev, "hist: DMA submission failed\n");
221 goto error;
222 }
223
224 dma_async_issue_pending(hist->dma_ch);
217 225
218 return STAT_BUF_WAITING_DMA; 226 return STAT_BUF_WAITING_DMA;
227
228error:
229 hist_reset_mem(hist);
230 return STAT_NO_BUF;
219} 231}
220 232
221static int hist_buf_pio(struct ispstat *hist) 233static int hist_buf_pio(struct ispstat *hist)
@@ -272,7 +284,7 @@ static int hist_buf_process(struct ispstat *hist)
272 if (--(hist->wait_acc_frames)) 284 if (--(hist->wait_acc_frames))
273 return STAT_NO_BUF; 285 return STAT_NO_BUF;
274 286
275 if (HIST_USING_DMA(hist)) 287 if (hist->dma_ch)
276 ret = hist_buf_dma(hist); 288 ret = hist_buf_dma(hist);
277 else 289 else
278 ret = hist_buf_pio(hist); 290 ret = hist_buf_pio(hist);
@@ -473,18 +485,28 @@ int omap3isp_hist_init(struct isp_device *isp)
473 485
474 hist->isp = isp; 486 hist->isp = isp;
475 487
476 if (HIST_CONFIG_DMA) 488 if (HIST_CONFIG_DMA) {
477 ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST", 489 struct platform_device *pdev = to_platform_device(isp->dev);
478 hist_dma_cb, hist, &hist->dma_ch); 490 struct resource *res;
479 if (ret) { 491 unsigned int sig = 0;
480 if (HIST_CONFIG_DMA) 492 dma_cap_mask_t mask;
481 dev_warn(isp->dev, "hist: DMA request channel failed. " 493
482 "Using PIO only.\n"); 494 dma_cap_zero(mask);
483 hist->dma_ch = -1; 495 dma_cap_set(DMA_SLAVE, mask);
484 } else { 496
485 dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch); 497 res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
486 hist_dma_config(hist); 498 "hist");
487 omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ); 499 if (res)
500 sig = res->start;
501
502 hist->dma_ch = dma_request_slave_channel_compat(mask,
503 omap_dma_filter_fn, &sig, isp->dev, "hist");
504 if (!hist->dma_ch)
505 dev_warn(isp->dev,
506 "hist: DMA channel request failed, using PIO\n");
507 else
508 dev_dbg(isp->dev, "hist: using DMA channel %s\n",
509 dma_chan_name(hist->dma_ch));
488 } 510 }
489 511
490 hist->ops = &hist_ops; 512 hist->ops = &hist_ops;
@@ -493,8 +515,8 @@ int omap3isp_hist_init(struct isp_device *isp)
493 515
494 ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops); 516 ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
495 if (ret) { 517 if (ret) {
496 if (HIST_USING_DMA(hist)) 518 if (hist->dma_ch)
497 omap_free_dma(hist->dma_ch); 519 dma_release_channel(hist->dma_ch);
498 } 520 }
499 521
500 return ret; 522 return ret;
@@ -505,7 +527,10 @@ int omap3isp_hist_init(struct isp_device *isp)
505 */ 527 */
506void omap3isp_hist_cleanup(struct isp_device *isp) 528void omap3isp_hist_cleanup(struct isp_device *isp)
507{ 529{
508 if (HIST_USING_DMA(&isp->isp_hist)) 530 struct ispstat *hist = &isp->isp_hist;
509 omap_free_dma(isp->isp_hist.dma_ch); 531
510 omap3isp_stat_cleanup(&isp->isp_hist); 532 if (hist->dma_ch)
533 dma_release_channel(hist->dma_ch);
534
535 omap3isp_stat_cleanup(hist);
511} 536}
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c
index dd9eed45d853..15cb254ccc39 100644
--- a/drivers/media/platform/omap3isp/isppreview.c
+++ b/drivers/media/platform/omap3isp/isppreview.c
@@ -1686,21 +1686,21 @@ static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1686} 1686}
1687 1687
1688static struct v4l2_mbus_framefmt * 1688static struct v4l2_mbus_framefmt *
1689__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, 1689__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg,
1690 unsigned int pad, enum v4l2_subdev_format_whence which) 1690 unsigned int pad, enum v4l2_subdev_format_whence which)
1691{ 1691{
1692 if (which == V4L2_SUBDEV_FORMAT_TRY) 1692 if (which == V4L2_SUBDEV_FORMAT_TRY)
1693 return v4l2_subdev_get_try_format(fh, pad); 1693 return v4l2_subdev_get_try_format(&prev->subdev, cfg, pad);
1694 else 1694 else
1695 return &prev->formats[pad]; 1695 return &prev->formats[pad];
1696} 1696}
1697 1697
1698static struct v4l2_rect * 1698static struct v4l2_rect *
1699__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, 1699__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_pad_config *cfg,
1700 enum v4l2_subdev_format_whence which) 1700 enum v4l2_subdev_format_whence which)
1701{ 1701{
1702 if (which == V4L2_SUBDEV_FORMAT_TRY) 1702 if (which == V4L2_SUBDEV_FORMAT_TRY)
1703 return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK); 1703 return v4l2_subdev_get_try_crop(&prev->subdev, cfg, PREV_PAD_SINK);
1704 else 1704 else
1705 return &prev->crop; 1705 return &prev->crop;
1706} 1706}
@@ -1727,7 +1727,7 @@ static const unsigned int preview_output_fmts[] = {
1727/* 1727/*
1728 * preview_try_format - Validate a format 1728 * preview_try_format - Validate a format
1729 * @prev: ISP preview engine 1729 * @prev: ISP preview engine
1730 * @fh: V4L2 subdev file handle 1730 * @cfg: V4L2 subdev pad configuration
1731 * @pad: pad number 1731 * @pad: pad number
1732 * @fmt: format to be validated 1732 * @fmt: format to be validated
1733 * @which: try/active format selector 1733 * @which: try/active format selector
@@ -1736,7 +1736,7 @@ static const unsigned int preview_output_fmts[] = {
1736 * engine limits and the format and crop rectangles on other pads. 1736 * engine limits and the format and crop rectangles on other pads.
1737 */ 1737 */
1738static void preview_try_format(struct isp_prev_device *prev, 1738static void preview_try_format(struct isp_prev_device *prev,
1739 struct v4l2_subdev_fh *fh, unsigned int pad, 1739 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
1740 struct v4l2_mbus_framefmt *fmt, 1740 struct v4l2_mbus_framefmt *fmt,
1741 enum v4l2_subdev_format_whence which) 1741 enum v4l2_subdev_format_whence which)
1742{ 1742{
@@ -1777,7 +1777,7 @@ static void preview_try_format(struct isp_prev_device *prev,
1777 1777
1778 case PREV_PAD_SOURCE: 1778 case PREV_PAD_SOURCE:
1779 pixelcode = fmt->code; 1779 pixelcode = fmt->code;
1780 *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which); 1780 *fmt = *__preview_get_format(prev, cfg, PREV_PAD_SINK, which);
1781 1781
1782 switch (pixelcode) { 1782 switch (pixelcode) {
1783 case MEDIA_BUS_FMT_YUYV8_1X16: 1783 case MEDIA_BUS_FMT_YUYV8_1X16:
@@ -1795,7 +1795,7 @@ static void preview_try_format(struct isp_prev_device *prev,
1795 * is not supported yet, hardcode the output size to the crop 1795 * is not supported yet, hardcode the output size to the crop
1796 * rectangle size. 1796 * rectangle size.
1797 */ 1797 */
1798 crop = __preview_get_crop(prev, fh, which); 1798 crop = __preview_get_crop(prev, cfg, which);
1799 fmt->width = crop->width; 1799 fmt->width = crop->width;
1800 fmt->height = crop->height; 1800 fmt->height = crop->height;
1801 1801
@@ -1864,12 +1864,12 @@ static void preview_try_crop(struct isp_prev_device *prev,
1864/* 1864/*
1865 * preview_enum_mbus_code - Handle pixel format enumeration 1865 * preview_enum_mbus_code - Handle pixel format enumeration
1866 * @sd : pointer to v4l2 subdev structure 1866 * @sd : pointer to v4l2 subdev structure
1867 * @fh : V4L2 subdev file handle 1867 * @cfg: V4L2 subdev pad configuration
1868 * @code : pointer to v4l2_subdev_mbus_code_enum structure 1868 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1869 * return -EINVAL or zero on success 1869 * return -EINVAL or zero on success
1870 */ 1870 */
1871static int preview_enum_mbus_code(struct v4l2_subdev *sd, 1871static int preview_enum_mbus_code(struct v4l2_subdev *sd,
1872 struct v4l2_subdev_fh *fh, 1872 struct v4l2_subdev_pad_config *cfg,
1873 struct v4l2_subdev_mbus_code_enum *code) 1873 struct v4l2_subdev_mbus_code_enum *code)
1874{ 1874{
1875 switch (code->pad) { 1875 switch (code->pad) {
@@ -1893,7 +1893,7 @@ static int preview_enum_mbus_code(struct v4l2_subdev *sd,
1893} 1893}
1894 1894
1895static int preview_enum_frame_size(struct v4l2_subdev *sd, 1895static int preview_enum_frame_size(struct v4l2_subdev *sd,
1896 struct v4l2_subdev_fh *fh, 1896 struct v4l2_subdev_pad_config *cfg,
1897 struct v4l2_subdev_frame_size_enum *fse) 1897 struct v4l2_subdev_frame_size_enum *fse)
1898{ 1898{
1899 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1899 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
@@ -1905,7 +1905,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1905 format.code = fse->code; 1905 format.code = fse->code;
1906 format.width = 1; 1906 format.width = 1;
1907 format.height = 1; 1907 format.height = 1;
1908 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 1908 preview_try_format(prev, cfg, fse->pad, &format, fse->which);
1909 fse->min_width = format.width; 1909 fse->min_width = format.width;
1910 fse->min_height = format.height; 1910 fse->min_height = format.height;
1911 1911
@@ -1915,7 +1915,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1915 format.code = fse->code; 1915 format.code = fse->code;
1916 format.width = -1; 1916 format.width = -1;
1917 format.height = -1; 1917 format.height = -1;
1918 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 1918 preview_try_format(prev, cfg, fse->pad, &format, fse->which);
1919 fse->max_width = format.width; 1919 fse->max_width = format.width;
1920 fse->max_height = format.height; 1920 fse->max_height = format.height;
1921 1921
@@ -1925,7 +1925,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1925/* 1925/*
1926 * preview_get_selection - Retrieve a selection rectangle on a pad 1926 * preview_get_selection - Retrieve a selection rectangle on a pad
1927 * @sd: ISP preview V4L2 subdevice 1927 * @sd: ISP preview V4L2 subdevice
1928 * @fh: V4L2 subdev file handle 1928 * @cfg: V4L2 subdev pad configuration
1929 * @sel: Selection rectangle 1929 * @sel: Selection rectangle
1930 * 1930 *
1931 * The only supported rectangles are the crop rectangles on the sink pad. 1931 * The only supported rectangles are the crop rectangles on the sink pad.
@@ -1933,7 +1933,7 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1933 * Return 0 on success or a negative error code otherwise. 1933 * Return 0 on success or a negative error code otherwise.
1934 */ 1934 */
1935static int preview_get_selection(struct v4l2_subdev *sd, 1935static int preview_get_selection(struct v4l2_subdev *sd,
1936 struct v4l2_subdev_fh *fh, 1936 struct v4l2_subdev_pad_config *cfg,
1937 struct v4l2_subdev_selection *sel) 1937 struct v4l2_subdev_selection *sel)
1938{ 1938{
1939 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1939 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
@@ -1949,13 +1949,13 @@ static int preview_get_selection(struct v4l2_subdev *sd,
1949 sel->r.width = INT_MAX; 1949 sel->r.width = INT_MAX;
1950 sel->r.height = INT_MAX; 1950 sel->r.height = INT_MAX;
1951 1951
1952 format = __preview_get_format(prev, fh, PREV_PAD_SINK, 1952 format = __preview_get_format(prev, cfg, PREV_PAD_SINK,
1953 sel->which); 1953 sel->which);
1954 preview_try_crop(prev, format, &sel->r); 1954 preview_try_crop(prev, format, &sel->r);
1955 break; 1955 break;
1956 1956
1957 case V4L2_SEL_TGT_CROP: 1957 case V4L2_SEL_TGT_CROP:
1958 sel->r = *__preview_get_crop(prev, fh, sel->which); 1958 sel->r = *__preview_get_crop(prev, cfg, sel->which);
1959 break; 1959 break;
1960 1960
1961 default: 1961 default:
@@ -1968,7 +1968,7 @@ static int preview_get_selection(struct v4l2_subdev *sd,
1968/* 1968/*
1969 * preview_set_selection - Set a selection rectangle on a pad 1969 * preview_set_selection - Set a selection rectangle on a pad
1970 * @sd: ISP preview V4L2 subdevice 1970 * @sd: ISP preview V4L2 subdevice
1971 * @fh: V4L2 subdev file handle 1971 * @cfg: V4L2 subdev pad configuration
1972 * @sel: Selection rectangle 1972 * @sel: Selection rectangle
1973 * 1973 *
1974 * The only supported rectangle is the actual crop rectangle on the sink pad. 1974 * The only supported rectangle is the actual crop rectangle on the sink pad.
@@ -1976,7 +1976,7 @@ static int preview_get_selection(struct v4l2_subdev *sd,
1976 * Return 0 on success or a negative error code otherwise. 1976 * Return 0 on success or a negative error code otherwise.
1977 */ 1977 */
1978static int preview_set_selection(struct v4l2_subdev *sd, 1978static int preview_set_selection(struct v4l2_subdev *sd,
1979 struct v4l2_subdev_fh *fh, 1979 struct v4l2_subdev_pad_config *cfg,
1980 struct v4l2_subdev_selection *sel) 1980 struct v4l2_subdev_selection *sel)
1981{ 1981{
1982 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1982 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
@@ -1995,17 +1995,17 @@ static int preview_set_selection(struct v4l2_subdev *sd,
1995 * rectangle. 1995 * rectangle.
1996 */ 1996 */
1997 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) { 1997 if (sel->flags & V4L2_SEL_FLAG_KEEP_CONFIG) {
1998 sel->r = *__preview_get_crop(prev, fh, sel->which); 1998 sel->r = *__preview_get_crop(prev, cfg, sel->which);
1999 return 0; 1999 return 0;
2000 } 2000 }
2001 2001
2002 format = __preview_get_format(prev, fh, PREV_PAD_SINK, sel->which); 2002 format = __preview_get_format(prev, cfg, PREV_PAD_SINK, sel->which);
2003 preview_try_crop(prev, format, &sel->r); 2003 preview_try_crop(prev, format, &sel->r);
2004 *__preview_get_crop(prev, fh, sel->which) = sel->r; 2004 *__preview_get_crop(prev, cfg, sel->which) = sel->r;
2005 2005
2006 /* Update the source format. */ 2006 /* Update the source format. */
2007 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, sel->which); 2007 format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE, sel->which);
2008 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, sel->which); 2008 preview_try_format(prev, cfg, PREV_PAD_SOURCE, format, sel->which);
2009 2009
2010 return 0; 2010 return 0;
2011} 2011}
@@ -2013,17 +2013,17 @@ static int preview_set_selection(struct v4l2_subdev *sd,
2013/* 2013/*
2014 * preview_get_format - Handle get format by pads subdev method 2014 * preview_get_format - Handle get format by pads subdev method
2015 * @sd : pointer to v4l2 subdev structure 2015 * @sd : pointer to v4l2 subdev structure
2016 * @fh : V4L2 subdev file handle 2016 * @cfg: V4L2 subdev pad configuration
2017 * @fmt: pointer to v4l2 subdev format structure 2017 * @fmt: pointer to v4l2 subdev format structure
2018 * return -EINVAL or zero on success 2018 * return -EINVAL or zero on success
2019 */ 2019 */
2020static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2020static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2021 struct v4l2_subdev_format *fmt) 2021 struct v4l2_subdev_format *fmt)
2022{ 2022{
2023 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 2023 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2024 struct v4l2_mbus_framefmt *format; 2024 struct v4l2_mbus_framefmt *format;
2025 2025
2026 format = __preview_get_format(prev, fh, fmt->pad, fmt->which); 2026 format = __preview_get_format(prev, cfg, fmt->pad, fmt->which);
2027 if (format == NULL) 2027 if (format == NULL)
2028 return -EINVAL; 2028 return -EINVAL;
2029 2029
@@ -2034,28 +2034,28 @@ static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2034/* 2034/*
2035 * preview_set_format - Handle set format by pads subdev method 2035 * preview_set_format - Handle set format by pads subdev method
2036 * @sd : pointer to v4l2 subdev structure 2036 * @sd : pointer to v4l2 subdev structure
2037 * @fh : V4L2 subdev file handle 2037 * @cfg: V4L2 subdev pad configuration
2038 * @fmt: pointer to v4l2 subdev format structure 2038 * @fmt: pointer to v4l2 subdev format structure
2039 * return -EINVAL or zero on success 2039 * return -EINVAL or zero on success
2040 */ 2040 */
2041static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 2041static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
2042 struct v4l2_subdev_format *fmt) 2042 struct v4l2_subdev_format *fmt)
2043{ 2043{
2044 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 2044 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
2045 struct v4l2_mbus_framefmt *format; 2045 struct v4l2_mbus_framefmt *format;
2046 struct v4l2_rect *crop; 2046 struct v4l2_rect *crop;
2047 2047
2048 format = __preview_get_format(prev, fh, fmt->pad, fmt->which); 2048 format = __preview_get_format(prev, cfg, fmt->pad, fmt->which);
2049 if (format == NULL) 2049 if (format == NULL)
2050 return -EINVAL; 2050 return -EINVAL;
2051 2051
2052 preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which); 2052 preview_try_format(prev, cfg, fmt->pad, &fmt->format, fmt->which);
2053 *format = fmt->format; 2053 *format = fmt->format;
2054 2054
2055 /* Propagate the format from sink to source */ 2055 /* Propagate the format from sink to source */
2056 if (fmt->pad == PREV_PAD_SINK) { 2056 if (fmt->pad == PREV_PAD_SINK) {
2057 /* Reset the crop rectangle. */ 2057 /* Reset the crop rectangle. */
2058 crop = __preview_get_crop(prev, fh, fmt->which); 2058 crop = __preview_get_crop(prev, cfg, fmt->which);
2059 crop->left = 0; 2059 crop->left = 0;
2060 crop->top = 0; 2060 crop->top = 0;
2061 crop->width = fmt->format.width; 2061 crop->width = fmt->format.width;
@@ -2064,9 +2064,9 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
2064 preview_try_crop(prev, &fmt->format, crop); 2064 preview_try_crop(prev, &fmt->format, crop);
2065 2065
2066 /* Update the source format. */ 2066 /* Update the source format. */
2067 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, 2067 format = __preview_get_format(prev, cfg, PREV_PAD_SOURCE,
2068 fmt->which); 2068 fmt->which);
2069 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, 2069 preview_try_format(prev, cfg, PREV_PAD_SOURCE, format,
2070 fmt->which); 2070 fmt->which);
2071 } 2071 }
2072 2072
@@ -2093,7 +2093,7 @@ static int preview_init_formats(struct v4l2_subdev *sd,
2093 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10; 2093 format.format.code = MEDIA_BUS_FMT_SGRBG10_1X10;
2094 format.format.width = 4096; 2094 format.format.width = 4096;
2095 format.format.height = 4096; 2095 format.format.height = 4096;
2096 preview_set_format(sd, fh, &format); 2096 preview_set_format(sd, fh ? fh->pad : NULL, &format);
2097 2097
2098 return 0; 2098 return 0;
2099} 2099}
diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c
index 2b9bc4839876..7cfb43dc0ffd 100644
--- a/drivers/media/platform/omap3isp/ispresizer.c
+++ b/drivers/media/platform/omap3isp/ispresizer.c
@@ -112,16 +112,16 @@ static const struct isprsz_coef filter_coefs = {
112 * __resizer_get_format - helper function for getting resizer format 112 * __resizer_get_format - helper function for getting resizer format
113 * @res : pointer to resizer private structure 113 * @res : pointer to resizer private structure
114 * @pad : pad number 114 * @pad : pad number
115 * @fh : V4L2 subdev file handle 115 * @cfg: V4L2 subdev pad configuration
116 * @which : wanted subdev format 116 * @which : wanted subdev format
117 * return zero 117 * return zero
118 */ 118 */
119static struct v4l2_mbus_framefmt * 119static struct v4l2_mbus_framefmt *
120__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh, 120__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg,
121 unsigned int pad, enum v4l2_subdev_format_whence which) 121 unsigned int pad, enum v4l2_subdev_format_whence which)
122{ 122{
123 if (which == V4L2_SUBDEV_FORMAT_TRY) 123 if (which == V4L2_SUBDEV_FORMAT_TRY)
124 return v4l2_subdev_get_try_format(fh, pad); 124 return v4l2_subdev_get_try_format(&res->subdev, cfg, pad);
125 else 125 else
126 return &res->formats[pad]; 126 return &res->formats[pad];
127} 127}
@@ -129,15 +129,15 @@ __resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
129/* 129/*
130 * __resizer_get_crop - helper function for getting resizer crop rectangle 130 * __resizer_get_crop - helper function for getting resizer crop rectangle
131 * @res : pointer to resizer private structure 131 * @res : pointer to resizer private structure
132 * @fh : V4L2 subdev file handle 132 * @cfg: V4L2 subdev pad configuration
133 * @which : wanted subdev crop rectangle 133 * @which : wanted subdev crop rectangle
134 */ 134 */
135static struct v4l2_rect * 135static struct v4l2_rect *
136__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh, 136__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_pad_config *cfg,
137 enum v4l2_subdev_format_whence which) 137 enum v4l2_subdev_format_whence which)
138{ 138{
139 if (which == V4L2_SUBDEV_FORMAT_TRY) 139 if (which == V4L2_SUBDEV_FORMAT_TRY)
140 return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK); 140 return v4l2_subdev_get_try_crop(&res->subdev, cfg, RESZ_PAD_SINK);
141 else 141 else
142 return &res->crop.request; 142 return &res->crop.request;
143} 143}
@@ -1215,7 +1215,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1215/* 1215/*
1216 * resizer_get_selection - Retrieve a selection rectangle on a pad 1216 * resizer_get_selection - Retrieve a selection rectangle on a pad
1217 * @sd: ISP resizer V4L2 subdevice 1217 * @sd: ISP resizer V4L2 subdevice
1218 * @fh: V4L2 subdev file handle 1218 * @cfg: V4L2 subdev pad configuration
1219 * @sel: Selection rectangle 1219 * @sel: Selection rectangle
1220 * 1220 *
1221 * The only supported rectangles are the crop rectangles on the sink pad. 1221 * The only supported rectangles are the crop rectangles on the sink pad.
@@ -1223,7 +1223,7 @@ static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1223 * Return 0 on success or a negative error code otherwise. 1223 * Return 0 on success or a negative error code otherwise.
1224 */ 1224 */
1225static int resizer_get_selection(struct v4l2_subdev *sd, 1225static int resizer_get_selection(struct v4l2_subdev *sd,
1226 struct v4l2_subdev_fh *fh, 1226 struct v4l2_subdev_pad_config *cfg,
1227 struct v4l2_subdev_selection *sel) 1227 struct v4l2_subdev_selection *sel)
1228{ 1228{
1229 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1229 struct isp_res_device *res = v4l2_get_subdevdata(sd);
@@ -1234,9 +1234,9 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
1234 if (sel->pad != RESZ_PAD_SINK) 1234 if (sel->pad != RESZ_PAD_SINK)
1235 return -EINVAL; 1235 return -EINVAL;
1236 1236
1237 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, 1237 format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK,
1238 sel->which); 1238 sel->which);
1239 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, 1239 format_source = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE,
1240 sel->which); 1240 sel->which);
1241 1241
1242 switch (sel->target) { 1242 switch (sel->target) {
@@ -1251,7 +1251,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
1251 break; 1251 break;
1252 1252
1253 case V4L2_SEL_TGT_CROP: 1253 case V4L2_SEL_TGT_CROP:
1254 sel->r = *__resizer_get_crop(res, fh, sel->which); 1254 sel->r = *__resizer_get_crop(res, cfg, sel->which);
1255 resizer_calc_ratios(res, &sel->r, format_source, &ratio); 1255 resizer_calc_ratios(res, &sel->r, format_source, &ratio);
1256 break; 1256 break;
1257 1257
@@ -1265,7 +1265,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
1265/* 1265/*
1266 * resizer_set_selection - Set a selection rectangle on a pad 1266 * resizer_set_selection - Set a selection rectangle on a pad
1267 * @sd: ISP resizer V4L2 subdevice 1267 * @sd: ISP resizer V4L2 subdevice
1268 * @fh: V4L2 subdev file handle 1268 * @cfg: V4L2 subdev pad configuration
1269 * @sel: Selection rectangle 1269 * @sel: Selection rectangle
1270 * 1270 *
1271 * The only supported rectangle is the actual crop rectangle on the sink pad. 1271 * The only supported rectangle is the actual crop rectangle on the sink pad.
@@ -1276,7 +1276,7 @@ static int resizer_get_selection(struct v4l2_subdev *sd,
1276 * Return 0 on success or a negative error code otherwise. 1276 * Return 0 on success or a negative error code otherwise.
1277 */ 1277 */
1278static int resizer_set_selection(struct v4l2_subdev *sd, 1278static int resizer_set_selection(struct v4l2_subdev *sd,
1279 struct v4l2_subdev_fh *fh, 1279 struct v4l2_subdev_pad_config *cfg,
1280 struct v4l2_subdev_selection *sel) 1280 struct v4l2_subdev_selection *sel)
1281{ 1281{
1282 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1282 struct isp_res_device *res = v4l2_get_subdevdata(sd);
@@ -1290,9 +1290,9 @@ static int resizer_set_selection(struct v4l2_subdev *sd,
1290 sel->pad != RESZ_PAD_SINK) 1290 sel->pad != RESZ_PAD_SINK)
1291 return -EINVAL; 1291 return -EINVAL;
1292 1292
1293 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK, 1293 format_sink = __resizer_get_format(res, cfg, RESZ_PAD_SINK,
1294 sel->which); 1294 sel->which);
1295 format_source = *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, 1295 format_source = *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE,
1296 sel->which); 1296 sel->which);
1297 1297
1298 dev_dbg(isp->dev, "%s(%s): req %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", 1298 dev_dbg(isp->dev, "%s(%s): req %ux%u -> (%d,%d)/%ux%u -> %ux%u\n",
@@ -1310,7 +1310,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd,
1310 * stored the mangled rectangle. 1310 * stored the mangled rectangle.
1311 */ 1311 */
1312 resizer_try_crop(format_sink, &format_source, &sel->r); 1312 resizer_try_crop(format_sink, &format_source, &sel->r);
1313 *__resizer_get_crop(res, fh, sel->which) = sel->r; 1313 *__resizer_get_crop(res, cfg, sel->which) = sel->r;
1314 resizer_calc_ratios(res, &sel->r, &format_source, &ratio); 1314 resizer_calc_ratios(res, &sel->r, &format_source, &ratio);
1315 1315
1316 dev_dbg(isp->dev, "%s(%s): got %ux%u -> (%d,%d)/%ux%u -> %ux%u\n", 1316 dev_dbg(isp->dev, "%s(%s): got %ux%u -> (%d,%d)/%ux%u -> %ux%u\n",
@@ -1320,7 +1320,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd,
1320 format_source.width, format_source.height); 1320 format_source.width, format_source.height);
1321 1321
1322 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { 1322 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1323 *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, sel->which) = 1323 *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) =
1324 format_source; 1324 format_source;
1325 return 0; 1325 return 0;
1326 } 1326 }
@@ -1331,7 +1331,7 @@ static int resizer_set_selection(struct v4l2_subdev *sd,
1331 */ 1331 */
1332 spin_lock_irqsave(&res->lock, flags); 1332 spin_lock_irqsave(&res->lock, flags);
1333 1333
1334 *__resizer_get_format(res, fh, RESZ_PAD_SOURCE, sel->which) = 1334 *__resizer_get_format(res, cfg, RESZ_PAD_SOURCE, sel->which) =
1335 format_source; 1335 format_source;
1336 1336
1337 res->ratio = ratio; 1337 res->ratio = ratio;
@@ -1368,13 +1368,13 @@ static unsigned int resizer_max_in_width(struct isp_res_device *res)
1368/* 1368/*
1369 * resizer_try_format - Handle try format by pad subdev method 1369 * resizer_try_format - Handle try format by pad subdev method
1370 * @res : ISP resizer device 1370 * @res : ISP resizer device
1371 * @fh : V4L2 subdev file handle 1371 * @cfg: V4L2 subdev pad configuration
1372 * @pad : pad num 1372 * @pad : pad num
1373 * @fmt : pointer to v4l2 format structure 1373 * @fmt : pointer to v4l2 format structure
1374 * @which : wanted subdev format 1374 * @which : wanted subdev format
1375 */ 1375 */
1376static void resizer_try_format(struct isp_res_device *res, 1376static void resizer_try_format(struct isp_res_device *res,
1377 struct v4l2_subdev_fh *fh, unsigned int pad, 1377 struct v4l2_subdev_pad_config *cfg, unsigned int pad,
1378 struct v4l2_mbus_framefmt *fmt, 1378 struct v4l2_mbus_framefmt *fmt,
1379 enum v4l2_subdev_format_whence which) 1379 enum v4l2_subdev_format_whence which)
1380{ 1380{
@@ -1395,10 +1395,10 @@ static void resizer_try_format(struct isp_res_device *res,
1395 break; 1395 break;
1396 1396
1397 case RESZ_PAD_SOURCE: 1397 case RESZ_PAD_SOURCE:
1398 format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which); 1398 format = __resizer_get_format(res, cfg, RESZ_PAD_SINK, which);
1399 fmt->code = format->code; 1399 fmt->code = format->code;
1400 1400
1401 crop = *__resizer_get_crop(res, fh, which); 1401 crop = *__resizer_get_crop(res, cfg, which);
1402 resizer_calc_ratios(res, &crop, fmt, &ratio); 1402 resizer_calc_ratios(res, &crop, fmt, &ratio);
1403 break; 1403 break;
1404 } 1404 }
@@ -1410,12 +1410,12 @@ static void resizer_try_format(struct isp_res_device *res,
1410/* 1410/*
1411 * resizer_enum_mbus_code - Handle pixel format enumeration 1411 * resizer_enum_mbus_code - Handle pixel format enumeration
1412 * @sd : pointer to v4l2 subdev structure 1412 * @sd : pointer to v4l2 subdev structure
1413 * @fh : V4L2 subdev file handle 1413 * @cfg: V4L2 subdev pad configuration
1414 * @code : pointer to v4l2_subdev_mbus_code_enum structure 1414 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1415 * return -EINVAL or zero on success 1415 * return -EINVAL or zero on success
1416 */ 1416 */
1417static int resizer_enum_mbus_code(struct v4l2_subdev *sd, 1417static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1418 struct v4l2_subdev_fh *fh, 1418 struct v4l2_subdev_pad_config *cfg,
1419 struct v4l2_subdev_mbus_code_enum *code) 1419 struct v4l2_subdev_mbus_code_enum *code)
1420{ 1420{
1421 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1421 struct isp_res_device *res = v4l2_get_subdevdata(sd);
@@ -1430,8 +1430,8 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1430 if (code->index != 0) 1430 if (code->index != 0)
1431 return -EINVAL; 1431 return -EINVAL;
1432 1432
1433 format = __resizer_get_format(res, fh, RESZ_PAD_SINK, 1433 format = __resizer_get_format(res, cfg, RESZ_PAD_SINK,
1434 V4L2_SUBDEV_FORMAT_TRY); 1434 code->which);
1435 code->code = format->code; 1435 code->code = format->code;
1436 } 1436 }
1437 1437
@@ -1439,7 +1439,7 @@ static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1439} 1439}
1440 1440
1441static int resizer_enum_frame_size(struct v4l2_subdev *sd, 1441static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1442 struct v4l2_subdev_fh *fh, 1442 struct v4l2_subdev_pad_config *cfg,
1443 struct v4l2_subdev_frame_size_enum *fse) 1443 struct v4l2_subdev_frame_size_enum *fse)
1444{ 1444{
1445 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1445 struct isp_res_device *res = v4l2_get_subdevdata(sd);
@@ -1451,7 +1451,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1451 format.code = fse->code; 1451 format.code = fse->code;
1452 format.width = 1; 1452 format.width = 1;
1453 format.height = 1; 1453 format.height = 1;
1454 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 1454 resizer_try_format(res, cfg, fse->pad, &format, fse->which);
1455 fse->min_width = format.width; 1455 fse->min_width = format.width;
1456 fse->min_height = format.height; 1456 fse->min_height = format.height;
1457 1457
@@ -1461,7 +1461,7 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1461 format.code = fse->code; 1461 format.code = fse->code;
1462 format.width = -1; 1462 format.width = -1;
1463 format.height = -1; 1463 format.height = -1;
1464 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY); 1464 resizer_try_format(res, cfg, fse->pad, &format, fse->which);
1465 fse->max_width = format.width; 1465 fse->max_width = format.width;
1466 fse->max_height = format.height; 1466 fse->max_height = format.height;
1467 1467
@@ -1471,17 +1471,17 @@ static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1471/* 1471/*
1472 * resizer_get_format - Handle get format by pads subdev method 1472 * resizer_get_format - Handle get format by pads subdev method
1473 * @sd : pointer to v4l2 subdev structure 1473 * @sd : pointer to v4l2 subdev structure
1474 * @fh : V4L2 subdev file handle 1474 * @cfg: V4L2 subdev pad configuration
1475 * @fmt : pointer to v4l2 subdev format structure 1475 * @fmt : pointer to v4l2 subdev format structure
1476 * return -EINVAL or zero on success 1476 * return -EINVAL or zero on success
1477 */ 1477 */
1478static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1478static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
1479 struct v4l2_subdev_format *fmt) 1479 struct v4l2_subdev_format *fmt)
1480{ 1480{
1481 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1481 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1482 struct v4l2_mbus_framefmt *format; 1482 struct v4l2_mbus_framefmt *format;
1483 1483
1484 format = __resizer_get_format(res, fh, fmt->pad, fmt->which); 1484 format = __resizer_get_format(res, cfg, fmt->pad, fmt->which);
1485 if (format == NULL) 1485 if (format == NULL)
1486 return -EINVAL; 1486 return -EINVAL;
1487 1487
@@ -1492,37 +1492,37 @@ static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1492/* 1492/*
1493 * resizer_set_format - Handle set format by pads subdev method 1493 * resizer_set_format - Handle set format by pads subdev method
1494 * @sd : pointer to v4l2 subdev structure 1494 * @sd : pointer to v4l2 subdev structure
1495 * @fh : V4L2 subdev file handle 1495 * @cfg: V4L2 subdev pad configuration
1496 * @fmt : pointer to v4l2 subdev format structure 1496 * @fmt : pointer to v4l2 subdev format structure
1497 * return -EINVAL or zero on success 1497 * return -EINVAL or zero on success
1498 */ 1498 */
1499static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh, 1499static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
1500 struct v4l2_subdev_format *fmt) 1500 struct v4l2_subdev_format *fmt)
1501{ 1501{
1502 struct isp_res_device *res = v4l2_get_subdevdata(sd); 1502 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1503 struct v4l2_mbus_framefmt *format; 1503 struct v4l2_mbus_framefmt *format;
1504 struct v4l2_rect *crop; 1504 struct v4l2_rect *crop;
1505 1505
1506 format = __resizer_get_format(res, fh, fmt->pad, fmt->which); 1506 format = __resizer_get_format(res, cfg, fmt->pad, fmt->which);
1507 if (format == NULL) 1507 if (format == NULL)
1508 return -EINVAL; 1508 return -EINVAL;
1509 1509
1510 resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which); 1510 resizer_try_format(res, cfg, fmt->pad, &fmt->format, fmt->which);
1511 *format = fmt->format; 1511 *format = fmt->format;
1512 1512
1513 if (fmt->pad == RESZ_PAD_SINK) { 1513 if (fmt->pad == RESZ_PAD_SINK) {
1514 /* reset crop rectangle */ 1514 /* reset crop rectangle */
1515 crop = __resizer_get_crop(res, fh, fmt->which); 1515 crop = __resizer_get_crop(res, cfg, fmt->which);
1516 crop->left = 0; 1516 crop->left = 0;
1517 crop->top = 0; 1517 crop->top = 0;
1518 crop->width = fmt->format.width; 1518 crop->width = fmt->format.width;
1519 crop->height = fmt->format.height; 1519 crop->height = fmt->format.height;
1520 1520
1521 /* Propagate the format from sink to source */ 1521 /* Propagate the format from sink to source */
1522 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, 1522 format = __resizer_get_format(res, cfg, RESZ_PAD_SOURCE,
1523 fmt->which); 1523 fmt->which);
1524 *format = fmt->format; 1524 *format = fmt->format;
1525 resizer_try_format(res, fh, RESZ_PAD_SOURCE, format, 1525 resizer_try_format(res, cfg, RESZ_PAD_SOURCE, format,
1526 fmt->which); 1526 fmt->which);
1527 } 1527 }
1528 1528
@@ -1573,7 +1573,7 @@ static int resizer_init_formats(struct v4l2_subdev *sd,
1573 format.format.code = MEDIA_BUS_FMT_YUYV8_1X16; 1573 format.format.code = MEDIA_BUS_FMT_YUYV8_1X16;
1574 format.format.width = 4096; 1574 format.format.width = 4096;
1575 format.format.height = 4096; 1575 format.format.height = 4096;
1576 resizer_set_format(sd, fh, &format); 1576 resizer_set_format(sd, fh ? fh->pad : NULL, &format);
1577 1577
1578 return 0; 1578 return 0;
1579} 1579}
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c
index a94e8340508f..20434e83e801 100644
--- a/drivers/media/platform/omap3isp/ispstat.c
+++ b/drivers/media/platform/omap3isp/ispstat.c
@@ -21,7 +21,7 @@
21 21
22#include "isp.h" 22#include "isp.h"
23 23
24#define ISP_STAT_USES_DMAENGINE(stat) ((stat)->dma_ch >= 0) 24#define ISP_STAT_USES_DMAENGINE(stat) ((stat)->dma_ch != NULL)
25 25
26/* 26/*
27 * MAGIC_SIZE must always be the greatest common divisor of 27 * MAGIC_SIZE must always be the greatest common divisor of
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h
index b32b29677e2c..b79380d83fcf 100644
--- a/drivers/media/platform/omap3isp/ispstat.h
+++ b/drivers/media/platform/omap3isp/ispstat.h
@@ -20,7 +20,6 @@
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/omap3isp.h> 22#include <linux/omap3isp.h>
23#include <linux/omap-dma.h>
24#include <media/v4l2-event.h> 23#include <media/v4l2-event.h>
25 24
26#include "isp.h" 25#include "isp.h"
@@ -33,6 +32,7 @@
33#define STAT_NO_BUF 1 /* An error has occurred */ 32#define STAT_NO_BUF 1 /* An error has occurred */
34#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */ 33#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */
35 34
35struct dma_chan;
36struct ispstat; 36struct ispstat;
37 37
38struct ispstat_buffer { 38struct ispstat_buffer {
@@ -96,7 +96,6 @@ struct ispstat {
96 u8 inc_config; 96 u8 inc_config;
97 atomic_t buf_err; 97 atomic_t buf_err;
98 enum ispstat_state_t state; /* enabling/disabling state */ 98 enum ispstat_state_t state; /* enabling/disabling state */
99 struct omap_dma_channel_params dma_config;
100 struct isp_device *isp; 99 struct isp_device *isp;
101 void *priv; /* pointer to priv config struct */ 100 void *priv; /* pointer to priv config struct */
102 void *recover_priv; /* pointer to recover priv configuration */ 101 void *recover_priv; /* pointer to recover priv configuration */
@@ -110,7 +109,7 @@ struct ispstat {
110 u32 frame_number; 109 u32 frame_number;
111 u32 buf_size; 110 u32 buf_size;
112 u32 buf_alloc_size; 111 u32 buf_alloc_size;
113 int dma_ch; 112 struct dma_chan *dma_ch;
114 unsigned long event_type; 113 unsigned long event_type;
115 struct ispstat_buffer *buf; 114 struct ispstat_buffer *buf;
116 struct ispstat_buffer *active_buf; 115 struct ispstat_buffer *active_buf;
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c
index 3fe9047ef466..d285af18df7f 100644
--- a/drivers/media/platform/omap3isp/ispvideo.c
+++ b/drivers/media/platform/omap3isp/ispvideo.c
@@ -452,7 +452,6 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
452 enum isp_pipeline_state state; 452 enum isp_pipeline_state state;
453 struct isp_buffer *buf; 453 struct isp_buffer *buf;
454 unsigned long flags; 454 unsigned long flags;
455 struct timespec ts;
456 455
457 spin_lock_irqsave(&video->irqlock, flags); 456 spin_lock_irqsave(&video->irqlock, flags);
458 if (WARN_ON(list_empty(&video->dmaqueue))) { 457 if (WARN_ON(list_empty(&video->dmaqueue))) {
@@ -465,9 +464,7 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
465 list_del(&buf->irqlist); 464 list_del(&buf->irqlist);
466 spin_unlock_irqrestore(&video->irqlock, flags); 465 spin_unlock_irqrestore(&video->irqlock, flags);
467 466
468 ktime_get_ts(&ts); 467 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
469 buf->vb.v4l2_buf.timestamp.tv_sec = ts.tv_sec;
470 buf->vb.v4l2_buf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
471 468
472 /* Do frame number propagation only if this is the output video node. 469 /* Do frame number propagation only if this is the output video node.
473 * Frame number either comes from the CSI receivers or it gets 470 * Frame number either comes from the CSI receivers or it gets
@@ -524,7 +521,6 @@ struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video)
524 521
525 buf = list_first_entry(&video->dmaqueue, struct isp_buffer, 522 buf = list_first_entry(&video->dmaqueue, struct isp_buffer,
526 irqlist); 523 irqlist);
527 buf->vb.state = VB2_BUF_STATE_ACTIVE;
528 524
529 spin_unlock_irqrestore(&video->irqlock, flags); 525 spin_unlock_irqrestore(&video->irqlock, flags);
530 526
@@ -1022,7 +1018,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1022 1018
1023 pipe->entities = 0; 1019 pipe->entities = 0;
1024 1020
1025 if (video->isp->pdata->set_constraints) 1021 if (video->isp->pdata && video->isp->pdata->set_constraints)
1026 video->isp->pdata->set_constraints(video->isp, true); 1022 video->isp->pdata->set_constraints(video->isp, true);
1027 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); 1023 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
1028 pipe->max_rate = pipe->l3_ick; 1024 pipe->max_rate = pipe->l3_ick;
@@ -1104,7 +1100,7 @@ err_set_stream:
1104err_check_format: 1100err_check_format:
1105 media_entity_pipeline_stop(&video->video.entity); 1101 media_entity_pipeline_stop(&video->video.entity);
1106err_pipeline_start: 1102err_pipeline_start:
1107 if (video->isp->pdata->set_constraints) 1103 if (video->isp->pdata && video->isp->pdata->set_constraints)
1108 video->isp->pdata->set_constraints(video->isp, false); 1104 video->isp->pdata->set_constraints(video->isp, false);
1109 /* The DMA queue must be emptied here, otherwise CCDC interrupts that 1105 /* The DMA queue must be emptied here, otherwise CCDC interrupts that
1110 * will get triggered the next time the CCDC is powered up will try to 1106 * will get triggered the next time the CCDC is powered up will try to
@@ -1165,7 +1161,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1165 video->queue = NULL; 1161 video->queue = NULL;
1166 video->error = false; 1162 video->error = false;
1167 1163
1168 if (video->isp->pdata->set_constraints) 1164 if (video->isp->pdata && video->isp->pdata->set_constraints)
1169 video->isp->pdata->set_constraints(video->isp, false); 1165 video->isp->pdata->set_constraints(video->isp, false);
1170 media_entity_pipeline_stop(&video->video.entity); 1166 media_entity_pipeline_stop(&video->video.entity);
1171 1167
@@ -1326,14 +1322,8 @@ static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1326static int isp_video_mmap(struct file *file, struct vm_area_struct *vma) 1322static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1327{ 1323{
1328 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data); 1324 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1329 struct isp_video *video = video_drvdata(file);
1330 int ret;
1331
1332 mutex_lock(&video->queue_lock);
1333 ret = vb2_mmap(&vfh->queue, vma);
1334 mutex_unlock(&video->queue_lock);
1335 1325
1336 return ret; 1326 return vb2_mmap(&vfh->queue, vma);
1337} 1327}
1338 1328
1339static struct v4l2_file_operations isp_video_fops = { 1329static struct v4l2_file_operations isp_video_fops = {
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c
index 54479d60cc0d..f6a61b9ceff4 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -1219,7 +1219,7 @@ static const u32 camif_mbus_formats[] = {
1219 */ 1219 */
1220 1220
1221static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd, 1221static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1222 struct v4l2_subdev_fh *fh, 1222 struct v4l2_subdev_pad_config *cfg,
1223 struct v4l2_subdev_mbus_code_enum *code) 1223 struct v4l2_subdev_mbus_code_enum *code)
1224{ 1224{
1225 if (code->index >= ARRAY_SIZE(camif_mbus_formats)) 1225 if (code->index >= ARRAY_SIZE(camif_mbus_formats))
@@ -1230,14 +1230,14 @@ static int s3c_camif_subdev_enum_mbus_code(struct v4l2_subdev *sd,
1230} 1230}
1231 1231
1232static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd, 1232static int s3c_camif_subdev_get_fmt(struct v4l2_subdev *sd,
1233 struct v4l2_subdev_fh *fh, 1233 struct v4l2_subdev_pad_config *cfg,
1234 struct v4l2_subdev_format *fmt) 1234 struct v4l2_subdev_format *fmt)
1235{ 1235{
1236 struct camif_dev *camif = v4l2_get_subdevdata(sd); 1236 struct camif_dev *camif = v4l2_get_subdevdata(sd);
1237 struct v4l2_mbus_framefmt *mf = &fmt->format; 1237 struct v4l2_mbus_framefmt *mf = &fmt->format;
1238 1238
1239 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1239 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1240 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1240 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1241 fmt->format = *mf; 1241 fmt->format = *mf;
1242 return 0; 1242 return 0;
1243 } 1243 }
@@ -1297,7 +1297,7 @@ static void __camif_subdev_try_format(struct camif_dev *camif,
1297} 1297}
1298 1298
1299static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd, 1299static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
1300 struct v4l2_subdev_fh *fh, 1300 struct v4l2_subdev_pad_config *cfg,
1301 struct v4l2_subdev_format *fmt) 1301 struct v4l2_subdev_format *fmt)
1302{ 1302{
1303 struct camif_dev *camif = v4l2_get_subdevdata(sd); 1303 struct camif_dev *camif = v4l2_get_subdevdata(sd);
@@ -1325,7 +1325,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
1325 __camif_subdev_try_format(camif, mf, fmt->pad); 1325 __camif_subdev_try_format(camif, mf, fmt->pad);
1326 1326
1327 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { 1327 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1328 mf = v4l2_subdev_get_try_format(fh, fmt->pad); 1328 mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
1329 *mf = fmt->format; 1329 *mf = fmt->format;
1330 mutex_unlock(&camif->lock); 1330 mutex_unlock(&camif->lock);
1331 return 0; 1331 return 0;
@@ -1364,7 +1364,7 @@ static int s3c_camif_subdev_set_fmt(struct v4l2_subdev *sd,
1364} 1364}
1365 1365
1366static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd, 1366static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd,
1367 struct v4l2_subdev_fh *fh, 1367 struct v4l2_subdev_pad_config *cfg,
1368 struct v4l2_subdev_selection *sel) 1368 struct v4l2_subdev_selection *sel)
1369{ 1369{
1370 struct camif_dev *camif = v4l2_get_subdevdata(sd); 1370 struct camif_dev *camif = v4l2_get_subdevdata(sd);
@@ -1377,7 +1377,7 @@ static int s3c_camif_subdev_get_selection(struct v4l2_subdev *sd,
1377 return -EINVAL; 1377 return -EINVAL;
1378 1378
1379 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { 1379 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1380 sel->r = *v4l2_subdev_get_try_crop(fh, sel->pad); 1380 sel->r = *v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
1381 return 0; 1381 return 0;
1382 } 1382 }
1383 1383
@@ -1451,7 +1451,7 @@ static void __camif_try_crop(struct camif_dev *camif, struct v4l2_rect *r)
1451} 1451}
1452 1452
1453static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd, 1453static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd,
1454 struct v4l2_subdev_fh *fh, 1454 struct v4l2_subdev_pad_config *cfg,
1455 struct v4l2_subdev_selection *sel) 1455 struct v4l2_subdev_selection *sel)
1456{ 1456{
1457 struct camif_dev *camif = v4l2_get_subdevdata(sd); 1457 struct camif_dev *camif = v4l2_get_subdevdata(sd);
@@ -1465,7 +1465,7 @@ static int s3c_camif_subdev_set_selection(struct v4l2_subdev *sd,
1465 __camif_try_crop(camif, &sel->r); 1465 __camif_try_crop(camif, &sel->r);
1466 1466
1467 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) { 1467 if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
1468 *v4l2_subdev_get_try_crop(fh, sel->pad) = sel->r; 1468 *v4l2_subdev_get_try_crop(sd, cfg, sel->pad) = sel->r;
1469 } else { 1469 } else {
1470 unsigned long flags; 1470 unsigned long flags;
1471 unsigned int i; 1471 unsigned int i;
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c
index a92ff4249d10..bfbf1575677c 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c
@@ -621,6 +621,7 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
621 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; 621 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
622 return ctx->subsampling; 622 return ctx->subsampling;
623 case SJPEG_EXYNOS3250: 623 case SJPEG_EXYNOS3250:
624 case SJPEG_EXYNOS5420:
624 if (ctx->subsampling > 3) 625 if (ctx->subsampling > 3)
625 return V4L2_JPEG_CHROMA_SUBSAMPLING_411; 626 return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
626 return exynos3250_decoded_subsampling[ctx->subsampling]; 627 return exynos3250_decoded_subsampling[ctx->subsampling];
@@ -1142,13 +1143,13 @@ static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1142 w_step = 1 << walign; 1143 w_step = 1 << walign;
1143 h_step = 1 << halign; 1144 h_step = 1 << halign;
1144 1145
1145 if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) { 1146 if (ctx->jpeg->variant->hw3250_compat) {
1146 /* 1147 /*
1147 * Rightmost and bottommost pixels are cropped by the 1148 * Rightmost and bottommost pixels are cropped by the
1148 * Exynos3250 JPEG IP for RGB formats, for the specific 1149 * Exynos3250/compatible JPEG IP for RGB formats, for the
1149 * width and height values respectively. This assignment 1150 * specific width and height values respectively. This
1150 * will result in v4l_bound_align_image returning dimensions 1151 * assignment will result in v4l_bound_align_image returning
1151 * reduced by 1 for the aforementioned cases. 1152 * dimensions reduced by 1 for the aforementioned cases.
1152 */ 1153 */
1153 if (w_step == 4 && ((width & 3) == 1)) { 1154 if (w_step == 4 && ((width & 3) == 1)) {
1154 wmax = width; 1155 wmax = width;
@@ -1384,12 +1385,12 @@ static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1384 1385
1385 /* 1386 /*
1386 * Prevent downscaling to YUV420 format by more than 2 1387 * Prevent downscaling to YUV420 format by more than 2
1387 * for Exynos3250 SoC as it produces broken raw image 1388 * for Exynos3250/compatible SoC as it produces broken raw image
1388 * in such cases. 1389 * in such cases.
1389 */ 1390 */
1390 if (ct->mode == S5P_JPEG_DECODE && 1391 if (ct->mode == S5P_JPEG_DECODE &&
1391 f_type == FMT_TYPE_CAPTURE && 1392 f_type == FMT_TYPE_CAPTURE &&
1392 ct->jpeg->variant->version == SJPEG_EXYNOS3250 && 1393 ct->jpeg->variant->hw3250_compat &&
1393 pix->pixelformat == V4L2_PIX_FMT_YUV420 && 1394 pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1394 ct->scale_factor > 2) { 1395 ct->scale_factor > 2) {
1395 scale_rect.width = ct->out_q.w / 2; 1396 scale_rect.width = ct->out_q.w / 2;
@@ -1569,12 +1570,12 @@ static int s5p_jpeg_s_selection(struct file *file, void *fh,
1569 if (s->target == V4L2_SEL_TGT_COMPOSE) { 1570 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1570 if (ctx->mode != S5P_JPEG_DECODE) 1571 if (ctx->mode != S5P_JPEG_DECODE)
1571 return -EINVAL; 1572 return -EINVAL;
1572 if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) 1573 if (ctx->jpeg->variant->hw3250_compat)
1573 ret = exynos3250_jpeg_try_downscale(ctx, rect); 1574 ret = exynos3250_jpeg_try_downscale(ctx, rect);
1574 } else if (s->target == V4L2_SEL_TGT_CROP) { 1575 } else if (s->target == V4L2_SEL_TGT_CROP) {
1575 if (ctx->mode != S5P_JPEG_ENCODE) 1576 if (ctx->mode != S5P_JPEG_ENCODE)
1576 return -EINVAL; 1577 return -EINVAL;
1577 if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) 1578 if (ctx->jpeg->variant->hw3250_compat)
1578 ret = exynos3250_jpeg_try_crop(ctx, rect); 1579 ret = exynos3250_jpeg_try_crop(ctx, rect);
1579 } 1580 }
1580 1581
@@ -1604,8 +1605,9 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1604 case SJPEG_S5P: 1605 case SJPEG_S5P:
1605 return 0; 1606 return 0;
1606 case SJPEG_EXYNOS3250: 1607 case SJPEG_EXYNOS3250:
1608 case SJPEG_EXYNOS5420:
1607 /* 1609 /*
1608 * The exynos3250 device can produce JPEG image only 1610 * The exynos3250/compatible device can produce JPEG image only
1609 * of 4:4:4 subsampling when given RGB32 source image. 1611 * of 4:4:4 subsampling when given RGB32 source image.
1610 */ 1612 */
1611 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) 1613 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
@@ -1624,7 +1626,7 @@ static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1624 } 1626 }
1625 1627
1626 /* 1628 /*
1627 * The exynos4x12 and exynos3250 devices require resulting 1629 * The exynos4x12 and exynos3250/compatible devices require resulting
1628 * jpeg subsampling not to be lower than the input raw image 1630 * jpeg subsampling not to be lower than the input raw image
1629 * subsampling. 1631 * subsampling.
1630 */ 1632 */
@@ -1842,7 +1844,7 @@ static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1842 struct s5p_jpeg *jpeg = ctx->jpeg; 1844 struct s5p_jpeg *jpeg = ctx->jpeg;
1843 struct s5p_jpeg_fmt *fmt; 1845 struct s5p_jpeg_fmt *fmt;
1844 struct vb2_buffer *vb; 1846 struct vb2_buffer *vb;
1845 struct s5p_jpeg_addr jpeg_addr; 1847 struct s5p_jpeg_addr jpeg_addr = {};
1846 u32 pix_size, padding_bytes = 0; 1848 u32 pix_size, padding_bytes = 0;
1847 1849
1848 jpeg_addr.cb = 0; 1850 jpeg_addr.cb = 0;
@@ -1946,7 +1948,7 @@ static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1946 struct s5p_jpeg *jpeg = ctx->jpeg; 1948 struct s5p_jpeg *jpeg = ctx->jpeg;
1947 struct s5p_jpeg_fmt *fmt; 1949 struct s5p_jpeg_fmt *fmt;
1948 struct vb2_buffer *vb; 1950 struct vb2_buffer *vb;
1949 struct s5p_jpeg_addr jpeg_addr; 1951 struct s5p_jpeg_addr jpeg_addr = {};
1950 u32 pix_size; 1952 u32 pix_size;
1951 1953
1952 pix_size = ctx->cap_q.w * ctx->cap_q.h; 1954 pix_size = ctx->cap_q.w * ctx->cap_q.h;
@@ -2020,6 +2022,16 @@ static void exynos3250_jpeg_device_run(void *priv)
2020 exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); 2022 exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2021 exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); 2023 exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2022 2024
2025 /*
2026 * Some SoCs require setting Huffman tables before each run
2027 */
2028 if (jpeg->variant->htbl_reinit) {
2029 s5p_jpeg_set_hdctbl(jpeg->regs);
2030 s5p_jpeg_set_hdctblg(jpeg->regs);
2031 s5p_jpeg_set_hactbl(jpeg->regs);
2032 s5p_jpeg_set_hactblg(jpeg->regs);
2033 }
2034
2023 /* Y, Cb, Cr use Huffman table 0 */ 2035 /* Y, Cb, Cr use Huffman table 0 */
2024 exynos3250_jpeg_htbl_ac(jpeg->regs, 1); 2036 exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2025 exynos3250_jpeg_htbl_dc(jpeg->regs, 1); 2037 exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
@@ -2663,13 +2675,12 @@ static int s5p_jpeg_runtime_resume(struct device *dev)
2663 /* 2675 /*
2664 * JPEG IP allows storing two Huffman tables for each component. 2676 * JPEG IP allows storing two Huffman tables for each component.
2665 * We fill table 0 for each component and do this here only 2677 * We fill table 0 for each component and do this here only
2666 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires 2678 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2667 * programming its Huffman tables each time the encoding process 2679 * require programming their Huffman tables each time the encoding
2668 * is initialized, and thus it is accomplished in the device_run 2680 * process is initialized, and thus it is accomplished in the
2669 * callback of m2m_ops. 2681 * device_run callback of m2m_ops.
2670 */ 2682 */
2671 if (jpeg->variant->version == SJPEG_S5P || 2683 if (!jpeg->variant->htbl_reinit) {
2672 jpeg->variant->version == SJPEG_EXYNOS3250) {
2673 s5p_jpeg_set_hdctbl(jpeg->regs); 2684 s5p_jpeg_set_hdctbl(jpeg->regs);
2674 s5p_jpeg_set_hdctblg(jpeg->regs); 2685 s5p_jpeg_set_hdctblg(jpeg->regs);
2675 s5p_jpeg_set_hactbl(jpeg->regs); 2686 s5p_jpeg_set_hactbl(jpeg->regs);
@@ -2717,6 +2728,7 @@ static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
2717 .jpeg_irq = exynos3250_jpeg_irq, 2728 .jpeg_irq = exynos3250_jpeg_irq,
2718 .m2m_ops = &exynos3250_jpeg_m2m_ops, 2729 .m2m_ops = &exynos3250_jpeg_m2m_ops,
2719 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, 2730 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
2731 .hw3250_compat = 1,
2720}; 2732};
2721 2733
2722static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { 2734static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
@@ -2724,6 +2736,16 @@ static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2724 .jpeg_irq = exynos4_jpeg_irq, 2736 .jpeg_irq = exynos4_jpeg_irq,
2725 .m2m_ops = &exynos4_jpeg_m2m_ops, 2737 .m2m_ops = &exynos4_jpeg_m2m_ops,
2726 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4, 2738 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
2739 .htbl_reinit = 1,
2740};
2741
2742static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
2743 .version = SJPEG_EXYNOS5420,
2744 .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */
2745 .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */
2746 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */
2747 .hw3250_compat = 1,
2748 .htbl_reinit = 1,
2727}; 2749};
2728 2750
2729static const struct of_device_id samsung_jpeg_match[] = { 2751static const struct of_device_id samsung_jpeg_match[] = {
@@ -2739,6 +2761,9 @@ static const struct of_device_id samsung_jpeg_match[] = {
2739 }, { 2761 }, {
2740 .compatible = "samsung,exynos4212-jpeg", 2762 .compatible = "samsung,exynos4212-jpeg",
2741 .data = &exynos4_jpeg_drvdata, 2763 .data = &exynos4_jpeg_drvdata,
2764 }, {
2765 .compatible = "samsung,exynos5420-jpeg",
2766 .data = &exynos5420_jpeg_drvdata,
2742 }, 2767 },
2743 {}, 2768 {},
2744}; 2769};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h
index 764b32de326b..7d9a9ed19cea 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-core.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h
@@ -67,10 +67,12 @@
67#define SJPEG_SUBSAMPLING_420 0x22 67#define SJPEG_SUBSAMPLING_420 0x22
68 68
69/* Version numbers */ 69/* Version numbers */
70 70enum sjpeg_version {
71#define SJPEG_S5P 1 71 SJPEG_S5P,
72#define SJPEG_EXYNOS3250 2 72 SJPEG_EXYNOS3250,
73#define SJPEG_EXYNOS4 3 73 SJPEG_EXYNOS4,
74 SJPEG_EXYNOS5420,
75};
74 76
75enum exynos4_jpeg_result { 77enum exynos4_jpeg_result {
76 OK_ENC_OR_DEC, 78 OK_ENC_OR_DEC,
@@ -130,6 +132,8 @@ struct s5p_jpeg {
130struct s5p_jpeg_variant { 132struct s5p_jpeg_variant {
131 unsigned int version; 133 unsigned int version;
132 unsigned int fmt_ver_flag; 134 unsigned int fmt_ver_flag;
135 unsigned int hw3250_compat:1;
136 unsigned int htbl_reinit:1;
133 struct v4l2_m2m_ops *m2m_ops; 137 struct v4l2_m2m_ops *m2m_ops;
134 irqreturn_t (*jpeg_irq)(int irq, void *priv); 138 irqreturn_t (*jpeg_irq)(int irq, void *priv);
135}; 139};
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
index e3b8e67e005f..b5f20e722b63 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.c
@@ -51,18 +51,6 @@ void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
51 writel(reg, regs + S5P_JPGCMOD); 51 writel(reg, regs + S5P_JPGCMOD);
52} 52}
53 53
54void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16)
55{
56 unsigned long reg;
57
58 reg = readl(regs + S5P_JPGCMOD);
59 if (y16)
60 reg |= S5P_MODE_Y16;
61 else
62 reg &= ~S5P_MODE_Y16_MASK;
63 writel(reg, regs + S5P_JPGCMOD);
64}
65
66void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode) 54void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode)
67{ 55{
68 unsigned long reg, m; 56 unsigned long reg, m;
@@ -208,26 +196,6 @@ void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl)
208 writel(reg, regs + S5P_JPGINTSE); 196 writel(reg, regs + S5P_JPGINTSE);
209} 197}
210 198
211void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val)
212{
213 unsigned long reg;
214
215 reg = readl(regs + S5P_JPG_TIMER_SE);
216 reg |= S5P_TIMER_INT_EN;
217 reg &= ~S5P_TIMER_INIT_MASK;
218 reg |= val & S5P_TIMER_INIT_MASK;
219 writel(reg, regs + S5P_JPG_TIMER_SE);
220}
221
222void s5p_jpeg_timer_disable(void __iomem *regs)
223{
224 unsigned long reg;
225
226 reg = readl(regs + S5P_JPG_TIMER_SE);
227 reg &= ~S5P_TIMER_INT_EN_MASK;
228 writel(reg, regs + S5P_JPG_TIMER_SE);
229}
230
231int s5p_jpeg_timer_stat(void __iomem *regs) 199int s5p_jpeg_timer_stat(void __iomem *regs)
232{ 200{
233 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK) 201 return (int)((readl(regs + S5P_JPG_TIMER_ST) & S5P_TIMER_INT_STAT_MASK)
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
index c11ebe86b9c9..f208fa3ed738 100644
--- a/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
+++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-s5p.h
@@ -29,7 +29,6 @@
29void s5p_jpeg_reset(void __iomem *regs); 29void s5p_jpeg_reset(void __iomem *regs);
30void s5p_jpeg_poweron(void __iomem *regs); 30void s5p_jpeg_poweron(void __iomem *regs);
31void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode); 31void s5p_jpeg_input_raw_mode(void __iomem *regs, unsigned long mode);
32void s5p_jpeg_input_raw_y16(void __iomem *regs, bool y16);
33void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode); 32void s5p_jpeg_proc_mode(void __iomem *regs, unsigned long mode);
34void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); 33void s5p_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode);
35unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs); 34unsigned int s5p_jpeg_get_subsampling_mode(void __iomem *regs);
@@ -42,8 +41,6 @@ void s5p_jpeg_x(void __iomem *regs, unsigned int x);
42void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable); 41void s5p_jpeg_rst_int_enable(void __iomem *regs, bool enable);
43void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable); 42void s5p_jpeg_data_num_int_enable(void __iomem *regs, bool enable);
44void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl); 43void s5p_jpeg_final_mcu_num_int_enable(void __iomem *regs, bool enbl);
45void s5p_jpeg_timer_enable(void __iomem *regs, unsigned long val);
46void s5p_jpeg_timer_disable(void __iomem *regs);
47int s5p_jpeg_timer_stat(void __iomem *regs); 44int s5p_jpeg_timer_stat(void __iomem *regs);
48void s5p_jpeg_clear_timer_stat(void __iomem *regs); 45void s5p_jpeg_clear_timer_stat(void __iomem *regs);
49void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size); 46void s5p_jpeg_enc_stream_int(void __iomem *regs, unsigned long size);
diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
index 98374e8bad3e..8333fbc2fe96 100644
--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
+++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
@@ -844,6 +844,13 @@ static int s5p_mfc_open(struct file *file)
844 ret = -ENOENT; 844 ret = -ENOENT;
845 goto err_queue_init; 845 goto err_queue_init;
846 } 846 }
847 /* One way to indicate end-of-stream for MFC is to set the
848 * bytesused == 0. However by default videobuf2 handles bytesused
849 * equal to 0 as a special case and changes its value to the size
850 * of the buffer. Set the allow_zero_bytesused flag so that videobuf2
851 * will keep the value of bytesused intact.
852 */
853 q->allow_zero_bytesused = 1;
847 q->mem_ops = &vb2_dma_contig_memops; 854 q->mem_ops = &vb2_dma_contig_memops;
848 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 855 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
849 ret = vb2_queue_init(q); 856 ret = vb2_queue_init(q);
diff --git a/drivers/media/platform/s5p-tv/mixer_video.c b/drivers/media/platform/s5p-tv/mixer_video.c
index 72d4f2e1efc0..751f3b618337 100644
--- a/drivers/media/platform/s5p-tv/mixer_video.c
+++ b/drivers/media/platform/s5p-tv/mixer_video.c
@@ -287,7 +287,7 @@ static void mxr_mplane_fill(struct v4l2_plane_pix_format *planes,
287 u32 bl_width = divup(width, blk->width); 287 u32 bl_width = divup(width, blk->width);
288 u32 bl_height = divup(height, blk->height); 288 u32 bl_height = divup(height, blk->height);
289 u32 sizeimage = bl_width * bl_height * blk->size; 289 u32 sizeimage = bl_width * bl_height * blk->size;
290 u16 bytesperline = bl_width * blk->size / blk->height; 290 u32 bytesperline = bl_width * blk->size / blk->height;
291 291
292 plane->sizeimage += sizeimage; 292 plane->sizeimage += sizeimage;
293 plane->bytesperline = max(plane->bytesperline, bytesperline); 293 plane->bytesperline = max(plane->bytesperline, bytesperline);
diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c
index 261f1195b49f..dde1ccc730be 100644
--- a/drivers/media/platform/sh_vou.c
+++ b/drivers/media/platform/sh_vou.c
@@ -62,7 +62,7 @@ enum sh_vou_status {
62 62
63struct sh_vou_device { 63struct sh_vou_device {
64 struct v4l2_device v4l2_dev; 64 struct v4l2_device v4l2_dev;
65 struct video_device *vdev; 65 struct video_device vdev;
66 atomic_t use_count; 66 atomic_t use_count;
67 struct sh_vou_pdata *pdata; 67 struct sh_vou_pdata *pdata;
68 spinlock_t lock; 68 spinlock_t lock;
@@ -890,7 +890,7 @@ static int sh_vou_s_std(struct file *file, void *priv, v4l2_std_id std_id)
890 890
891 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, std_id); 891 dev_dbg(vou_dev->v4l2_dev.dev, "%s(): 0x%llx\n", __func__, std_id);
892 892
893 if (std_id & ~vou_dev->vdev->tvnorms) 893 if (std_id & ~vou_dev->vdev.tvnorms)
894 return -EINVAL; 894 return -EINVAL;
895 895
896 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, 896 ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video,
@@ -1168,10 +1168,10 @@ static int sh_vou_open(struct file *file)
1168 1168
1169 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); 1169 dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__);
1170 1170
1171 file->private_data = vou_file; 1171 if (mutex_lock_interruptible(&vou_dev->fop_lock)) {
1172 1172 kfree(vou_file);
1173 if (mutex_lock_interruptible(&vou_dev->fop_lock))
1174 return -ERESTARTSYS; 1173 return -ERESTARTSYS;
1174 }
1175 if (atomic_inc_return(&vou_dev->use_count) == 1) { 1175 if (atomic_inc_return(&vou_dev->use_count) == 1) {
1176 int ret; 1176 int ret;
1177 /* First open */ 1177 /* First open */
@@ -1183,6 +1183,7 @@ static int sh_vou_open(struct file *file)
1183 pm_runtime_put(vou_dev->v4l2_dev.dev); 1183 pm_runtime_put(vou_dev->v4l2_dev.dev);
1184 vou_dev->status = SH_VOU_IDLE; 1184 vou_dev->status = SH_VOU_IDLE;
1185 mutex_unlock(&vou_dev->fop_lock); 1185 mutex_unlock(&vou_dev->fop_lock);
1186 kfree(vou_file);
1186 return ret; 1187 return ret;
1187 } 1188 }
1188 } 1189 }
@@ -1192,9 +1193,11 @@ static int sh_vou_open(struct file *file)
1192 V4L2_BUF_TYPE_VIDEO_OUTPUT, 1193 V4L2_BUF_TYPE_VIDEO_OUTPUT,
1193 V4L2_FIELD_NONE, 1194 V4L2_FIELD_NONE,
1194 sizeof(struct videobuf_buffer), 1195 sizeof(struct videobuf_buffer),
1195 vou_dev->vdev, &vou_dev->fop_lock); 1196 &vou_dev->vdev, &vou_dev->fop_lock);
1196 mutex_unlock(&vou_dev->fop_lock); 1197 mutex_unlock(&vou_dev->fop_lock);
1197 1198
1199 file->private_data = vou_file;
1200
1198 return 0; 1201 return 0;
1199} 1202}
1200 1203
@@ -1358,21 +1361,14 @@ static int sh_vou_probe(struct platform_device *pdev)
1358 goto ev4l2devreg; 1361 goto ev4l2devreg;
1359 } 1362 }
1360 1363
1361 /* Allocate memory for video device */ 1364 vdev = &vou_dev->vdev;
1362 vdev = video_device_alloc();
1363 if (vdev == NULL) {
1364 ret = -ENOMEM;
1365 goto evdevalloc;
1366 }
1367
1368 *vdev = sh_vou_video_template; 1365 *vdev = sh_vou_video_template;
1369 if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT) 1366 if (vou_pdata->bus_fmt == SH_VOU_BUS_8BIT)
1370 vdev->tvnorms |= V4L2_STD_PAL; 1367 vdev->tvnorms |= V4L2_STD_PAL;
1371 vdev->v4l2_dev = &vou_dev->v4l2_dev; 1368 vdev->v4l2_dev = &vou_dev->v4l2_dev;
1372 vdev->release = video_device_release; 1369 vdev->release = video_device_release_empty;
1373 vdev->lock = &vou_dev->fop_lock; 1370 vdev->lock = &vou_dev->fop_lock;
1374 1371
1375 vou_dev->vdev = vdev;
1376 video_set_drvdata(vdev, vou_dev); 1372 video_set_drvdata(vdev, vou_dev);
1377 1373
1378 pm_runtime_enable(&pdev->dev); 1374 pm_runtime_enable(&pdev->dev);
@@ -1406,9 +1402,7 @@ ei2cnd:
1406ereset: 1402ereset:
1407 i2c_put_adapter(i2c_adap); 1403 i2c_put_adapter(i2c_adap);
1408ei2cgadap: 1404ei2cgadap:
1409 video_device_release(vdev);
1410 pm_runtime_disable(&pdev->dev); 1405 pm_runtime_disable(&pdev->dev);
1411evdevalloc:
1412 v4l2_device_unregister(&vou_dev->v4l2_dev); 1406 v4l2_device_unregister(&vou_dev->v4l2_dev);
1413ev4l2devreg: 1407ev4l2devreg:
1414 free_irq(irq, vou_dev); 1408 free_irq(irq, vou_dev);
@@ -1435,7 +1429,7 @@ static int sh_vou_remove(struct platform_device *pdev)
1435 if (irq > 0) 1429 if (irq > 0)
1436 free_irq(irq, vou_dev); 1430 free_irq(irq, vou_dev);
1437 pm_runtime_disable(&pdev->dev); 1431 pm_runtime_disable(&pdev->dev);
1438 video_unregister_device(vou_dev->vdev); 1432 video_unregister_device(&vou_dev->vdev);
1439 i2c_put_adapter(client->adapter); 1433 i2c_put_adapter(client->adapter);
1440 v4l2_device_unregister(&vou_dev->v4l2_dev); 1434 v4l2_device_unregister(&vou_dev->v4l2_dev);
1441 iounmap(vou_dev->base); 1435 iounmap(vou_dev->base);
diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c
index 279ab9f6ae38..9351f64dee7b 100644
--- a/drivers/media/platform/soc_camera/rcar_vin.c
+++ b/drivers/media/platform/soc_camera/rcar_vin.c
@@ -977,19 +977,6 @@ static void rcar_vin_remove_device(struct soc_camera_device *icd)
977 icd->devnum); 977 icd->devnum);
978} 978}
979 979
980/* Called with .host_lock held */
981static int rcar_vin_clock_start(struct soc_camera_host *ici)
982{
983 /* VIN does not have "mclk" */
984 return 0;
985}
986
987/* Called with .host_lock held */
988static void rcar_vin_clock_stop(struct soc_camera_host *ici)
989{
990 /* VIN does not have "mclk" */
991}
992
993static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs) 980static void set_coeff(struct rcar_vin_priv *priv, unsigned short xs)
994{ 981{
995 int i; 982 int i;
@@ -1803,8 +1790,6 @@ static struct soc_camera_host_ops rcar_vin_host_ops = {
1803 .owner = THIS_MODULE, 1790 .owner = THIS_MODULE,
1804 .add = rcar_vin_add_device, 1791 .add = rcar_vin_add_device,
1805 .remove = rcar_vin_remove_device, 1792 .remove = rcar_vin_remove_device,
1806 .clock_start = rcar_vin_clock_start,
1807 .clock_stop = rcar_vin_clock_stop,
1808 .get_formats = rcar_vin_get_formats, 1793 .get_formats = rcar_vin_get_formats,
1809 .put_formats = rcar_vin_put_formats, 1794 .put_formats = rcar_vin_put_formats,
1810 .get_crop = rcar_vin_get_crop, 1795 .get_crop = rcar_vin_get_crop,
diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
index c4e7aa0ee7e1..cd93241eb497 100644
--- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c
+++ b/drivers/media/platform/soc_camera/sh_mobile_csi2.c
@@ -380,7 +380,6 @@ static int sh_csi2_remove(struct platform_device *pdev)
380 struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); 380 struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev);
381 381
382 v4l2_async_unregister_subdev(&priv->subdev); 382 v4l2_async_unregister_subdev(&priv->subdev);
383 v4l2_device_unregister_subdev(subdev);
384 pm_runtime_disable(&pdev->dev); 383 pm_runtime_disable(&pdev->dev);
385 384
386 return 0; 385 return 0;
diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c
index 66634b469c98..55370d74ff57 100644
--- a/drivers/media/platform/soc_camera/soc_camera.c
+++ b/drivers/media/platform/soc_camera/soc_camera.c
@@ -177,6 +177,30 @@ static int __soc_camera_power_off(struct soc_camera_device *icd)
177 return 0; 177 return 0;
178} 178}
179 179
180static int soc_camera_clock_start(struct soc_camera_host *ici)
181{
182 int ret;
183
184 if (!ici->ops->clock_start)
185 return 0;
186
187 mutex_lock(&ici->clk_lock);
188 ret = ici->ops->clock_start(ici);
189 mutex_unlock(&ici->clk_lock);
190
191 return ret;
192}
193
194static void soc_camera_clock_stop(struct soc_camera_host *ici)
195{
196 if (!ici->ops->clock_stop)
197 return;
198
199 mutex_lock(&ici->clk_lock);
200 ici->ops->clock_stop(ici);
201 mutex_unlock(&ici->clk_lock);
202}
203
180const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 204const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
181 struct soc_camera_device *icd, unsigned int fourcc) 205 struct soc_camera_device *icd, unsigned int fourcc)
182{ 206{
@@ -584,9 +608,7 @@ static int soc_camera_add_device(struct soc_camera_device *icd)
584 return -EBUSY; 608 return -EBUSY;
585 609
586 if (!icd->clk) { 610 if (!icd->clk) {
587 mutex_lock(&ici->clk_lock); 611 ret = soc_camera_clock_start(ici);
588 ret = ici->ops->clock_start(ici);
589 mutex_unlock(&ici->clk_lock);
590 if (ret < 0) 612 if (ret < 0)
591 return ret; 613 return ret;
592 } 614 }
@@ -602,11 +624,8 @@ static int soc_camera_add_device(struct soc_camera_device *icd)
602 return 0; 624 return 0;
603 625
604eadd: 626eadd:
605 if (!icd->clk) { 627 if (!icd->clk)
606 mutex_lock(&ici->clk_lock); 628 soc_camera_clock_stop(ici);
607 ici->ops->clock_stop(ici);
608 mutex_unlock(&ici->clk_lock);
609 }
610 return ret; 629 return ret;
611} 630}
612 631
@@ -619,11 +638,8 @@ static void soc_camera_remove_device(struct soc_camera_device *icd)
619 638
620 if (ici->ops->remove) 639 if (ici->ops->remove)
621 ici->ops->remove(icd); 640 ici->ops->remove(icd);
622 if (!icd->clk) { 641 if (!icd->clk)
623 mutex_lock(&ici->clk_lock); 642 soc_camera_clock_stop(ici);
624 ici->ops->clock_stop(ici);
625 mutex_unlock(&ici->clk_lock);
626 }
627 ici->icd = NULL; 643 ici->icd = NULL;
628} 644}
629 645
@@ -688,7 +704,8 @@ static int soc_camera_open(struct file *file)
688 704
689 /* The camera could have been already on, try to reset */ 705 /* The camera could have been already on, try to reset */
690 if (sdesc->subdev_desc.reset) 706 if (sdesc->subdev_desc.reset)
691 sdesc->subdev_desc.reset(icd->pdev); 707 if (icd->control)
708 sdesc->subdev_desc.reset(icd->control);
692 709
693 ret = soc_camera_add_device(icd); 710 ret = soc_camera_add_device(icd);
694 if (ret < 0) { 711 if (ret < 0) {
@@ -1159,7 +1176,8 @@ static void scan_add_host(struct soc_camera_host *ici)
1159 1176
1160 /* The camera could have been already on, try to reset */ 1177 /* The camera could have been already on, try to reset */
1161 if (ssdd->reset) 1178 if (ssdd->reset)
1162 ssdd->reset(icd->pdev); 1179 if (icd->control)
1180 ssdd->reset(icd->control);
1163 1181
1164 icd->parent = ici->v4l2_dev.dev; 1182 icd->parent = ici->v4l2_dev.dev;
1165 1183
@@ -1178,7 +1196,6 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk)
1178{ 1196{
1179 struct soc_camera_device *icd = clk->priv; 1197 struct soc_camera_device *icd = clk->priv;
1180 struct soc_camera_host *ici; 1198 struct soc_camera_host *ici;
1181 int ret;
1182 1199
1183 if (!icd || !icd->parent) 1200 if (!icd || !icd->parent)
1184 return -ENODEV; 1201 return -ENODEV;
@@ -1192,10 +1209,7 @@ static int soc_camera_clk_enable(struct v4l2_clk *clk)
1192 * If a different client is currently being probed, the host will tell 1209 * If a different client is currently being probed, the host will tell
1193 * you to go 1210 * you to go
1194 */ 1211 */
1195 mutex_lock(&ici->clk_lock); 1212 return soc_camera_clock_start(ici);
1196 ret = ici->ops->clock_start(ici);
1197 mutex_unlock(&ici->clk_lock);
1198 return ret;
1199} 1213}
1200 1214
1201static void soc_camera_clk_disable(struct v4l2_clk *clk) 1215static void soc_camera_clk_disable(struct v4l2_clk *clk)
@@ -1208,9 +1222,7 @@ static void soc_camera_clk_disable(struct v4l2_clk *clk)
1208 1222
1209 ici = to_soc_camera_host(icd->parent); 1223 ici = to_soc_camera_host(icd->parent);
1210 1224
1211 mutex_lock(&ici->clk_lock); 1225 soc_camera_clock_stop(ici);
1212 ici->ops->clock_stop(ici);
1213 mutex_unlock(&ici->clk_lock);
1214 1226
1215 module_put(ici->ops->owner); 1227 module_put(ici->ops->owner);
1216} 1228}
@@ -1364,7 +1376,7 @@ static int soc_camera_i2c_init(struct soc_camera_device *icd,
1364 snprintf(clk_name, sizeof(clk_name), "%d-%04x", 1376 snprintf(clk_name, sizeof(clk_name), "%d-%04x",
1365 shd->i2c_adapter_id, shd->board_info->addr); 1377 shd->i2c_adapter_id, shd->board_info->addr);
1366 1378
1367 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); 1379 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd);
1368 if (IS_ERR(icd->clk)) { 1380 if (IS_ERR(icd->clk)) {
1369 ret = PTR_ERR(icd->clk); 1381 ret = PTR_ERR(icd->clk);
1370 goto eclkreg; 1382 goto eclkreg;
@@ -1445,7 +1457,7 @@ static int soc_camera_async_bound(struct v4l2_async_notifier *notifier,
1445 memcpy(&sdesc->subdev_desc, ssdd, 1457 memcpy(&sdesc->subdev_desc, ssdd,
1446 sizeof(sdesc->subdev_desc)); 1458 sizeof(sdesc->subdev_desc));
1447 if (ssdd->reset) 1459 if (ssdd->reset)
1448 ssdd->reset(icd->pdev); 1460 ssdd->reset(&client->dev);
1449 } 1461 }
1450 1462
1451 icd->control = &client->dev; 1463 icd->control = &client->dev;
@@ -1545,7 +1557,7 @@ static int scan_async_group(struct soc_camera_host *ici,
1545 snprintf(clk_name, sizeof(clk_name), "%d-%04x", 1557 snprintf(clk_name, sizeof(clk_name), "%d-%04x",
1546 sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address); 1558 sasd->asd.match.i2c.adapter_id, sasd->asd.match.i2c.address);
1547 1559
1548 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); 1560 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd);
1549 if (IS_ERR(icd->clk)) { 1561 if (IS_ERR(icd->clk)) {
1550 ret = PTR_ERR(icd->clk); 1562 ret = PTR_ERR(icd->clk);
1551 goto eclkreg; 1563 goto eclkreg;
@@ -1650,7 +1662,7 @@ static int soc_of_bind(struct soc_camera_host *ici,
1650 snprintf(clk_name, sizeof(clk_name), "of-%s", 1662 snprintf(clk_name, sizeof(clk_name), "of-%s",
1651 of_node_full_name(remote)); 1663 of_node_full_name(remote));
1652 1664
1653 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, "mclk", icd); 1665 icd->clk = v4l2_clk_register(&soc_camera_clk_ops, clk_name, icd);
1654 if (IS_ERR(icd->clk)) { 1666 if (IS_ERR(icd->clk)) {
1655 ret = PTR_ERR(icd->clk); 1667 ret = PTR_ERR(icd->clk);
1656 goto eclkreg; 1668 goto eclkreg;
@@ -1659,6 +1671,8 @@ static int soc_of_bind(struct soc_camera_host *ici,
1659 ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier); 1671 ret = v4l2_async_notifier_register(&ici->v4l2_dev, &sasc->notifier);
1660 if (!ret) 1672 if (!ret)
1661 return 0; 1673 return 0;
1674
1675 v4l2_clk_unregister(icd->clk);
1662eclkreg: 1676eclkreg:
1663 icd->clk = NULL; 1677 icd->clk = NULL;
1664 platform_device_del(sasc->pdev); 1678 platform_device_del(sasc->pdev);
@@ -1750,9 +1764,7 @@ static int soc_camera_probe(struct soc_camera_host *ici,
1750 ret = -EINVAL; 1764 ret = -EINVAL;
1751 goto eadd; 1765 goto eadd;
1752 } else { 1766 } else {
1753 mutex_lock(&ici->clk_lock); 1767 ret = soc_camera_clock_start(ici);
1754 ret = ici->ops->clock_start(ici);
1755 mutex_unlock(&ici->clk_lock);
1756 if (ret < 0) 1768 if (ret < 0)
1757 goto eadd; 1769 goto eadd;
1758 1770
@@ -1792,9 +1804,7 @@ efinish:
1792 module_put(control->driver->owner); 1804 module_put(control->driver->owner);
1793enodrv: 1805enodrv:
1794eadddev: 1806eadddev:
1795 mutex_lock(&ici->clk_lock); 1807 soc_camera_clock_stop(ici);
1796 ici->ops->clock_stop(ici);
1797 mutex_unlock(&ici->clk_lock);
1798 } 1808 }
1799eadd: 1809eadd:
1800 if (icd->vdev) { 1810 if (icd->vdev) {
@@ -1888,22 +1898,34 @@ static int default_enum_framesizes(struct soc_camera_device *icd,
1888 int ret; 1898 int ret;
1889 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 1899 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1890 const struct soc_camera_format_xlate *xlate; 1900 const struct soc_camera_format_xlate *xlate;
1891 __u32 pixfmt = fsize->pixel_format; 1901 struct v4l2_subdev_frame_size_enum fse = {
1892 struct v4l2_frmsizeenum fsize_mbus = *fsize; 1902 .index = fsize->index,
1903 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1904 };
1893 1905
1894 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1906 xlate = soc_camera_xlate_by_fourcc(icd, fsize->pixel_format);
1895 if (!xlate) 1907 if (!xlate)
1896 return -EINVAL; 1908 return -EINVAL;
1897 /* map xlate-code to pixel_format, sensor only handle xlate-code*/ 1909 fse.code = xlate->code;
1898 fsize_mbus.pixel_format = xlate->code;
1899 1910
1900 ret = v4l2_subdev_call(sd, video, enum_framesizes, &fsize_mbus); 1911 ret = v4l2_subdev_call(sd, pad, enum_frame_size, NULL, &fse);
1901 if (ret < 0) 1912 if (ret < 0)
1902 return ret; 1913 return ret;
1903 1914
1904 *fsize = fsize_mbus; 1915 if (fse.min_width == fse.max_width &&
1905 fsize->pixel_format = pixfmt; 1916 fse.min_height == fse.max_height) {
1906 1917 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
1918 fsize->discrete.width = fse.min_width;
1919 fsize->discrete.height = fse.min_height;
1920 return 0;
1921 }
1922 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
1923 fsize->stepwise.min_width = fse.min_width;
1924 fsize->stepwise.max_width = fse.max_width;
1925 fsize->stepwise.min_height = fse.min_height;
1926 fsize->stepwise.max_height = fse.max_height;
1927 fsize->stepwise.step_width = 1;
1928 fsize->stepwise.step_height = 1;
1907 return 0; 1929 return 0;
1908} 1930}
1909 1931
@@ -1920,8 +1942,6 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1920 ((!ici->ops->init_videobuf || 1942 ((!ici->ops->init_videobuf ||
1921 !ici->ops->reqbufs) && 1943 !ici->ops->reqbufs) &&
1922 !ici->ops->init_videobuf2) || 1944 !ici->ops->init_videobuf2) ||
1923 !ici->ops->clock_start ||
1924 !ici->ops->clock_stop ||
1925 !ici->ops->poll || 1945 !ici->ops->poll ||
1926 !ici->v4l2_dev.dev) 1946 !ici->v4l2_dev.dev)
1927 return -EINVAL; 1947 return -EINVAL;
diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c
index 86989d86abfa..678ed9f353cb 100644
--- a/drivers/media/platform/via-camera.c
+++ b/drivers/media/platform/via-camera.c
@@ -1147,12 +1147,23 @@ static int viacam_enum_frameintervals(struct file *filp, void *priv,
1147 struct v4l2_frmivalenum *interval) 1147 struct v4l2_frmivalenum *interval)
1148{ 1148{
1149 struct via_camera *cam = priv; 1149 struct via_camera *cam = priv;
1150 struct v4l2_subdev_frame_interval_enum fie = {
1151 .index = interval->index,
1152 .code = cam->mbus_code,
1153 .width = cam->sensor_format.width,
1154 .height = cam->sensor_format.height,
1155 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
1156 };
1150 int ret; 1157 int ret;
1151 1158
1152 mutex_lock(&cam->lock); 1159 mutex_lock(&cam->lock);
1153 ret = sensor_call(cam, video, enum_frameintervals, interval); 1160 ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie);
1154 mutex_unlock(&cam->lock); 1161 mutex_unlock(&cam->lock);
1155 return ret; 1162 if (ret)
1163 return ret;
1164 interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1165 interval->discrete = fie.interval;
1166 return 0;
1156} 1167}
1157 1168
1158 1169
diff --git a/drivers/media/platform/vim2m.c b/drivers/media/platform/vim2m.c
index d9d844aab39b..4d6b4cc57c57 100644
--- a/drivers/media/platform/vim2m.c
+++ b/drivers/media/platform/vim2m.c
@@ -142,7 +142,7 @@ static struct vim2m_fmt *find_format(struct v4l2_format *f)
142 142
143struct vim2m_dev { 143struct vim2m_dev {
144 struct v4l2_device v4l2_dev; 144 struct v4l2_device v4l2_dev;
145 struct video_device *vfd; 145 struct video_device vfd;
146 146
147 atomic_t num_inst; 147 atomic_t num_inst;
148 struct mutex dev_mutex; 148 struct mutex dev_mutex;
@@ -968,7 +968,7 @@ static struct video_device vim2m_videodev = {
968 .fops = &vim2m_fops, 968 .fops = &vim2m_fops,
969 .ioctl_ops = &vim2m_ioctl_ops, 969 .ioctl_ops = &vim2m_ioctl_ops,
970 .minor = -1, 970 .minor = -1,
971 .release = video_device_release, 971 .release = video_device_release_empty,
972}; 972};
973 973
974static struct v4l2_m2m_ops m2m_ops = { 974static struct v4l2_m2m_ops m2m_ops = {
@@ -996,26 +996,19 @@ static int vim2m_probe(struct platform_device *pdev)
996 atomic_set(&dev->num_inst, 0); 996 atomic_set(&dev->num_inst, 0);
997 mutex_init(&dev->dev_mutex); 997 mutex_init(&dev->dev_mutex);
998 998
999 vfd = video_device_alloc(); 999 dev->vfd = vim2m_videodev;
1000 if (!vfd) { 1000 vfd = &dev->vfd;
1001 v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
1002 ret = -ENOMEM;
1003 goto unreg_dev;
1004 }
1005
1006 *vfd = vim2m_videodev;
1007 vfd->lock = &dev->dev_mutex; 1001 vfd->lock = &dev->dev_mutex;
1008 vfd->v4l2_dev = &dev->v4l2_dev; 1002 vfd->v4l2_dev = &dev->v4l2_dev;
1009 1003
1010 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); 1004 ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
1011 if (ret) { 1005 if (ret) {
1012 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); 1006 v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
1013 goto rel_vdev; 1007 goto unreg_dev;
1014 } 1008 }
1015 1009
1016 video_set_drvdata(vfd, dev); 1010 video_set_drvdata(vfd, dev);
1017 snprintf(vfd->name, sizeof(vfd->name), "%s", vim2m_videodev.name); 1011 snprintf(vfd->name, sizeof(vfd->name), "%s", vim2m_videodev.name);
1018 dev->vfd = vfd;
1019 v4l2_info(&dev->v4l2_dev, 1012 v4l2_info(&dev->v4l2_dev,
1020 "Device registered as /dev/video%d\n", vfd->num); 1013 "Device registered as /dev/video%d\n", vfd->num);
1021 1014
@@ -1033,9 +1026,7 @@ static int vim2m_probe(struct platform_device *pdev)
1033 1026
1034err_m2m: 1027err_m2m:
1035 v4l2_m2m_release(dev->m2m_dev); 1028 v4l2_m2m_release(dev->m2m_dev);
1036 video_unregister_device(dev->vfd); 1029 video_unregister_device(&dev->vfd);
1037rel_vdev:
1038 video_device_release(vfd);
1039unreg_dev: 1030unreg_dev:
1040 v4l2_device_unregister(&dev->v4l2_dev); 1031 v4l2_device_unregister(&dev->v4l2_dev);
1041 1032
@@ -1049,7 +1040,7 @@ static int vim2m_remove(struct platform_device *pdev)
1049 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME); 1040 v4l2_info(&dev->v4l2_dev, "Removing " MEM2MEM_NAME);
1050 v4l2_m2m_release(dev->m2m_dev); 1041 v4l2_m2m_release(dev->m2m_dev);
1051 del_timer_sync(&dev->timer); 1042 del_timer_sync(&dev->timer);
1052 video_unregister_device(dev->vfd); 1043 video_unregister_device(&dev->vfd);
1053 v4l2_device_unregister(&dev->v4l2_dev); 1044 v4l2_device_unregister(&dev->v4l2_dev);
1054 1045
1055 return 0; 1046 return 0;
diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c
index a7e033a5d291..d33f16495dbc 100644
--- a/drivers/media/platform/vivid/vivid-core.c
+++ b/drivers/media/platform/vivid/vivid-core.c
@@ -26,6 +26,7 @@
26#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
27#include <linux/font.h> 27#include <linux/font.h>
28#include <linux/mutex.h> 28#include <linux/mutex.h>
29#include <linux/platform_device.h>
29#include <linux/videodev2.h> 30#include <linux/videodev2.h>
30#include <linux/v4l2-dv-timings.h> 31#include <linux/v4l2-dv-timings.h>
31#include <media/videobuf2-vmalloc.h> 32#include <media/videobuf2-vmalloc.h>
@@ -618,7 +619,23 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = {
618 Initialization and module stuff 619 Initialization and module stuff
619 ------------------------------------------------------------------*/ 620 ------------------------------------------------------------------*/
620 621
621static int __init vivid_create_instance(int inst) 622static void vivid_dev_release(struct v4l2_device *v4l2_dev)
623{
624 struct vivid_dev *dev = container_of(v4l2_dev, struct vivid_dev, v4l2_dev);
625
626 vivid_free_controls(dev);
627 v4l2_device_unregister(&dev->v4l2_dev);
628 vfree(dev->scaled_line);
629 vfree(dev->blended_line);
630 vfree(dev->edid);
631 vfree(dev->bitmap_cap);
632 vfree(dev->bitmap_out);
633 tpg_free(&dev->tpg);
634 kfree(dev->query_dv_timings_qmenu);
635 kfree(dev);
636}
637
638static int vivid_create_instance(struct platform_device *pdev, int inst)
622{ 639{
623 static const struct v4l2_dv_timings def_dv_timings = 640 static const struct v4l2_dv_timings def_dv_timings =
624 V4L2_DV_BT_CEA_1280X720P60; 641 V4L2_DV_BT_CEA_1280X720P60;
@@ -646,9 +663,12 @@ static int __init vivid_create_instance(int inst)
646 /* register v4l2_device */ 663 /* register v4l2_device */
647 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), 664 snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
648 "%s-%03d", VIVID_MODULE_NAME, inst); 665 "%s-%03d", VIVID_MODULE_NAME, inst);
649 ret = v4l2_device_register(NULL, &dev->v4l2_dev); 666 ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
650 if (ret) 667 if (ret) {
651 goto free_dev; 668 kfree(dev);
669 return ret;
670 }
671 dev->v4l2_dev.release = vivid_dev_release;
652 672
653 /* start detecting feature set */ 673 /* start detecting feature set */
654 674
@@ -1256,15 +1276,8 @@ unreg_dev:
1256 video_unregister_device(&dev->vbi_cap_dev); 1276 video_unregister_device(&dev->vbi_cap_dev);
1257 video_unregister_device(&dev->vid_out_dev); 1277 video_unregister_device(&dev->vid_out_dev);
1258 video_unregister_device(&dev->vid_cap_dev); 1278 video_unregister_device(&dev->vid_cap_dev);
1259 vivid_free_controls(dev);
1260 v4l2_device_unregister(&dev->v4l2_dev);
1261free_dev: 1279free_dev:
1262 vfree(dev->scaled_line); 1280 v4l2_device_put(&dev->v4l2_dev);
1263 vfree(dev->blended_line);
1264 vfree(dev->edid);
1265 tpg_free(&dev->tpg);
1266 kfree(dev->query_dv_timings_qmenu);
1267 kfree(dev);
1268 return ret; 1281 return ret;
1269} 1282}
1270 1283
@@ -1274,7 +1287,7 @@ free_dev:
1274 will succeed. This is limited to the maximum number of devices that 1287 will succeed. This is limited to the maximum number of devices that
1275 videodev supports, which is equal to VIDEO_NUM_DEVICES. 1288 videodev supports, which is equal to VIDEO_NUM_DEVICES.
1276 */ 1289 */
1277static int __init vivid_init(void) 1290static int vivid_probe(struct platform_device *pdev)
1278{ 1291{
1279 const struct font_desc *font = find_font("VGA8x16"); 1292 const struct font_desc *font = find_font("VGA8x16");
1280 int ret = 0, i; 1293 int ret = 0, i;
@@ -1289,7 +1302,7 @@ static int __init vivid_init(void)
1289 n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS); 1302 n_devs = clamp_t(unsigned, n_devs, 1, VIVID_MAX_DEVS);
1290 1303
1291 for (i = 0; i < n_devs; i++) { 1304 for (i = 0; i < n_devs; i++) {
1292 ret = vivid_create_instance(i); 1305 ret = vivid_create_instance(pdev, i);
1293 if (ret) { 1306 if (ret) {
1294 /* If some instantiations succeeded, keep driver */ 1307 /* If some instantiations succeeded, keep driver */
1295 if (i) 1308 if (i)
@@ -1309,7 +1322,7 @@ static int __init vivid_init(void)
1309 return ret; 1322 return ret;
1310} 1323}
1311 1324
1312static void __exit vivid_exit(void) 1325static int vivid_remove(struct platform_device *pdev)
1313{ 1326{
1314 struct vivid_dev *dev; 1327 struct vivid_dev *dev;
1315 unsigned i; 1328 unsigned i;
@@ -1358,18 +1371,48 @@ static void __exit vivid_exit(void)
1358 unregister_framebuffer(&dev->fb_info); 1371 unregister_framebuffer(&dev->fb_info);
1359 vivid_fb_release_buffers(dev); 1372 vivid_fb_release_buffers(dev);
1360 } 1373 }
1361 v4l2_device_unregister(&dev->v4l2_dev); 1374 v4l2_device_put(&dev->v4l2_dev);
1362 vivid_free_controls(dev);
1363 vfree(dev->scaled_line);
1364 vfree(dev->blended_line);
1365 vfree(dev->edid);
1366 vfree(dev->bitmap_cap);
1367 vfree(dev->bitmap_out);
1368 tpg_free(&dev->tpg);
1369 kfree(dev->query_dv_timings_qmenu);
1370 kfree(dev);
1371 vivid_devs[i] = NULL; 1375 vivid_devs[i] = NULL;
1372 } 1376 }
1377 return 0;
1378}
1379
1380static void vivid_pdev_release(struct device *dev)
1381{
1382}
1383
1384static struct platform_device vivid_pdev = {
1385 .name = "vivid",
1386 .dev.release = vivid_pdev_release,
1387};
1388
1389static struct platform_driver vivid_pdrv = {
1390 .probe = vivid_probe,
1391 .remove = vivid_remove,
1392 .driver = {
1393 .name = "vivid",
1394 },
1395};
1396
1397static int __init vivid_init(void)
1398{
1399 int ret;
1400
1401 ret = platform_device_register(&vivid_pdev);
1402 if (ret)
1403 return ret;
1404
1405 ret = platform_driver_register(&vivid_pdrv);
1406 if (ret)
1407 platform_device_unregister(&vivid_pdev);
1408
1409 return ret;
1410}
1411
1412static void __exit vivid_exit(void)
1413{
1414 platform_driver_unregister(&vivid_pdrv);
1415 platform_device_unregister(&vivid_pdev);
1373} 1416}
1374 1417
1375module_init(vivid_init); 1418module_init(vivid_init);
diff --git a/drivers/media/platform/vivid/vivid-core.h b/drivers/media/platform/vivid/vivid-core.h
index 4b497df4b6a4..9e15aee9a52e 100644
--- a/drivers/media/platform/vivid/vivid-core.h
+++ b/drivers/media/platform/vivid/vivid-core.h
@@ -79,12 +79,14 @@ extern unsigned vivid_debug;
79struct vivid_fmt { 79struct vivid_fmt {
80 const char *name; 80 const char *name;
81 u32 fourcc; /* v4l2 format id */ 81 u32 fourcc; /* v4l2 format id */
82 u8 depth;
83 bool is_yuv; 82 bool is_yuv;
84 bool can_do_overlay; 83 bool can_do_overlay;
84 u8 vdownsampling[TPG_MAX_PLANES];
85 u32 alpha_mask; 85 u32 alpha_mask;
86 u8 planes; 86 u8 planes;
87 u32 data_offset[2]; 87 u8 buffers;
88 u32 data_offset[TPG_MAX_PLANES];
89 u32 bit_depth[TPG_MAX_PLANES];
88}; 90};
89 91
90extern struct vivid_fmt vivid_formats[]; 92extern struct vivid_fmt vivid_formats[];
@@ -332,7 +334,7 @@ struct vivid_dev {
332 u32 ycbcr_enc_out; 334 u32 ycbcr_enc_out;
333 u32 quantization_out; 335 u32 quantization_out;
334 u32 service_set_out; 336 u32 service_set_out;
335 u32 bytesperline_out[2]; 337 unsigned bytesperline_out[TPG_MAX_PLANES];
336 unsigned tv_field_out; 338 unsigned tv_field_out;
337 unsigned tv_audio_output; 339 unsigned tv_audio_output;
338 bool vbi_out_have_wss; 340 bool vbi_out_have_wss;
diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c
index 32a798f2d953..2b9070098b08 100644
--- a/drivers/media/platform/vivid/vivid-ctrls.c
+++ b/drivers/media/platform/vivid/vivid-ctrls.c
@@ -818,7 +818,7 @@ static int vivid_vid_out_s_ctrl(struct v4l2_ctrl *ctrl)
818 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D; 818 dev->dvi_d_out = ctrl->val == V4L2_DV_TX_MODE_DVI_D;
819 if (!vivid_is_hdmi_out(dev)) 819 if (!vivid_is_hdmi_out(dev))
820 break; 820 break;
821 if (!dev->dvi_d_out && (bt->standards & V4L2_DV_BT_STD_CEA861)) { 821 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
822 if (bt->width == 720 && bt->height <= 576) 822 if (bt->width == 720 && bt->height <= 576)
823 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 823 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
824 else 824 else
diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c
index 39a67cfae120..1727f5453f0b 100644
--- a/drivers/media/platform/vivid/vivid-kthread-cap.c
+++ b/drivers/media/platform/vivid/vivid-kthread-cap.c
@@ -229,14 +229,29 @@ static void vivid_precalc_copy_rects(struct vivid_dev *dev)
229 dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top); 229 dev->loop_vid_overlay_cap.left, dev->loop_vid_overlay_cap.top);
230} 230}
231 231
232static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf,
233 unsigned p, unsigned bpl[TPG_MAX_PLANES], unsigned h)
234{
235 unsigned i;
236 void *vbuf;
237
238 if (p == 0 || tpg_g_buffers(tpg) > 1)
239 return vb2_plane_vaddr(&buf->vb, p);
240 vbuf = vb2_plane_vaddr(&buf->vb, 0);
241 for (i = 0; i < p; i++)
242 vbuf += bpl[i] * h / tpg->vdownsampling[i];
243 return vbuf;
244}
245
232static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, 246static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
233 struct vivid_buffer *vid_cap_buf) 247 struct vivid_buffer *vid_cap_buf)
234{ 248{
235 bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index]; 249 bool blank = dev->must_blank[vid_cap_buf->vb.v4l2_buf.index];
236 struct tpg_data *tpg = &dev->tpg; 250 struct tpg_data *tpg = &dev->tpg;
237 struct vivid_buffer *vid_out_buf = NULL; 251 struct vivid_buffer *vid_out_buf = NULL;
238 unsigned pixsize = tpg_g_twopixelsize(tpg, p) / 2; 252 unsigned vdiv = dev->fmt_out->vdownsampling[p];
239 unsigned img_width = dev->compose_cap.width; 253 unsigned twopixsize = tpg_g_twopixelsize(tpg, p);
254 unsigned img_width = tpg_hdiv(tpg, p, dev->compose_cap.width);
240 unsigned img_height = dev->compose_cap.height; 255 unsigned img_height = dev->compose_cap.height;
241 unsigned stride_cap = tpg->bytesperline[p]; 256 unsigned stride_cap = tpg->bytesperline[p];
242 unsigned stride_out = dev->bytesperline_out[p]; 257 unsigned stride_out = dev->bytesperline_out[p];
@@ -255,6 +270,7 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
255 unsigned vid_overlay_fract_part = 0; 270 unsigned vid_overlay_fract_part = 0;
256 unsigned vid_overlay_y = 0; 271 unsigned vid_overlay_y = 0;
257 unsigned vid_overlay_error = 0; 272 unsigned vid_overlay_error = 0;
273 unsigned vid_cap_left = tpg_hdiv(tpg, p, dev->loop_vid_cap.left);
258 unsigned vid_cap_right; 274 unsigned vid_cap_right;
259 bool quick; 275 bool quick;
260 276
@@ -269,25 +285,29 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
269 285
270 vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field; 286 vid_cap_buf->vb.v4l2_buf.field = vid_out_buf->vb.v4l2_buf.field;
271 287
272 voutbuf = vb2_plane_vaddr(&vid_out_buf->vb, p) + 288 voutbuf = plane_vaddr(tpg, vid_out_buf, p,
273 vid_out_buf->vb.v4l2_planes[p].data_offset; 289 dev->bytesperline_out, dev->fmt_out_rect.height);
274 voutbuf += dev->loop_vid_out.left * pixsize + dev->loop_vid_out.top * stride_out; 290 if (p < dev->fmt_out->buffers)
275 vcapbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride_cap; 291 voutbuf += vid_out_buf->vb.v4l2_planes[p].data_offset;
292 voutbuf += tpg_hdiv(tpg, p, dev->loop_vid_out.left) +
293 (dev->loop_vid_out.top / vdiv) * stride_out;
294 vcapbuf += tpg_hdiv(tpg, p, dev->compose_cap.left) +
295 (dev->compose_cap.top / vdiv) * stride_cap;
276 296
277 if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) { 297 if (dev->loop_vid_copy.width == 0 || dev->loop_vid_copy.height == 0) {
278 /* 298 /*
279 * If there is nothing to copy, then just fill the capture window 299 * If there is nothing to copy, then just fill the capture window
280 * with black. 300 * with black.
281 */ 301 */
282 for (y = 0; y < hmax; y++, vcapbuf += stride_cap) 302 for (y = 0; y < hmax / vdiv; y++, vcapbuf += stride_cap)
283 memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize); 303 memcpy(vcapbuf, tpg->black_line[p], img_width);
284 return 0; 304 return 0;
285 } 305 }
286 306
287 if (dev->overlay_out_enabled && 307 if (dev->overlay_out_enabled &&
288 dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) { 308 dev->loop_vid_overlay.width && dev->loop_vid_overlay.height) {
289 vosdbuf = dev->video_vbase; 309 vosdbuf = dev->video_vbase;
290 vosdbuf += dev->loop_fb_copy.left * pixsize + 310 vosdbuf += (dev->loop_fb_copy.left * twopixsize) / 2 +
291 dev->loop_fb_copy.top * stride_osd; 311 dev->loop_fb_copy.top * stride_osd;
292 vid_overlay_int_part = dev->loop_vid_overlay.height / 312 vid_overlay_int_part = dev->loop_vid_overlay.height /
293 dev->loop_vid_overlay_cap.height; 313 dev->loop_vid_overlay_cap.height;
@@ -295,12 +315,12 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
295 dev->loop_vid_overlay_cap.height; 315 dev->loop_vid_overlay_cap.height;
296 } 316 }
297 317
298 vid_cap_right = dev->loop_vid_cap.left + dev->loop_vid_cap.width; 318 vid_cap_right = tpg_hdiv(tpg, p, dev->loop_vid_cap.left + dev->loop_vid_cap.width);
299 /* quick is true if no video scaling is needed */ 319 /* quick is true if no video scaling is needed */
300 quick = dev->loop_vid_out.width == dev->loop_vid_cap.width; 320 quick = dev->loop_vid_out.width == dev->loop_vid_cap.width;
301 321
302 dev->cur_scaled_line = dev->loop_vid_out.height; 322 dev->cur_scaled_line = dev->loop_vid_out.height;
303 for (y = 0; y < hmax; y++, vcapbuf += stride_cap) { 323 for (y = 0; y < hmax; y += vdiv, vcapbuf += stride_cap) {
304 /* osdline is true if this line requires overlay blending */ 324 /* osdline is true if this line requires overlay blending */
305 bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top && 325 bool osdline = vosdbuf && y >= dev->loop_vid_overlay_cap.top &&
306 y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height; 326 y < dev->loop_vid_overlay_cap.top + dev->loop_vid_overlay_cap.height;
@@ -311,34 +331,34 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
311 */ 331 */
312 if (y < dev->loop_vid_cap.top || 332 if (y < dev->loop_vid_cap.top ||
313 y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) { 333 y >= dev->loop_vid_cap.top + dev->loop_vid_cap.height) {
314 memcpy(vcapbuf, tpg->black_line[p], img_width * pixsize); 334 memcpy(vcapbuf, tpg->black_line[p], img_width);
315 continue; 335 continue;
316 } 336 }
317 337
318 /* fill the left border with black */ 338 /* fill the left border with black */
319 if (dev->loop_vid_cap.left) 339 if (dev->loop_vid_cap.left)
320 memcpy(vcapbuf, tpg->black_line[p], dev->loop_vid_cap.left * pixsize); 340 memcpy(vcapbuf, tpg->black_line[p], vid_cap_left);
321 341
322 /* fill the right border with black */ 342 /* fill the right border with black */
323 if (vid_cap_right < img_width) 343 if (vid_cap_right < img_width)
324 memcpy(vcapbuf + vid_cap_right * pixsize, 344 memcpy(vcapbuf + vid_cap_right, tpg->black_line[p],
325 tpg->black_line[p], (img_width - vid_cap_right) * pixsize); 345 img_width - vid_cap_right);
326 346
327 if (quick && !osdline) { 347 if (quick && !osdline) {
328 memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, 348 memcpy(vcapbuf + vid_cap_left,
329 voutbuf + vid_out_y * stride_out, 349 voutbuf + vid_out_y * stride_out,
330 dev->loop_vid_cap.width * pixsize); 350 tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
331 goto update_vid_out_y; 351 goto update_vid_out_y;
332 } 352 }
333 if (dev->cur_scaled_line == vid_out_y) { 353 if (dev->cur_scaled_line == vid_out_y) {
334 memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, 354 memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
335 dev->scaled_line, 355 tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
336 dev->loop_vid_cap.width * pixsize);
337 goto update_vid_out_y; 356 goto update_vid_out_y;
338 } 357 }
339 if (!osdline) { 358 if (!osdline) {
340 scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line, 359 scale_line(voutbuf + vid_out_y * stride_out, dev->scaled_line,
341 dev->loop_vid_out.width, dev->loop_vid_cap.width, 360 tpg_hdiv(tpg, p, dev->loop_vid_out.width),
361 tpg_hdiv(tpg, p, dev->loop_vid_cap.width),
342 tpg_g_twopixelsize(tpg, p)); 362 tpg_g_twopixelsize(tpg, p));
343 } else { 363 } else {
344 /* 364 /*
@@ -346,7 +366,8 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
346 * loop_vid_overlay rectangle. 366 * loop_vid_overlay rectangle.
347 */ 367 */
348 unsigned offset = 368 unsigned offset =
349 (dev->loop_vid_overlay.left - dev->loop_vid_copy.left) * pixsize; 369 ((dev->loop_vid_overlay.left - dev->loop_vid_copy.left) *
370 twopixsize) / 2;
350 u8 *osd = vosdbuf + vid_overlay_y * stride_osd; 371 u8 *osd = vosdbuf + vid_overlay_y * stride_osd;
351 372
352 scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line, 373 scale_line(voutbuf + vid_out_y * stride_out, dev->blended_line,
@@ -356,18 +377,17 @@ static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf,
356 blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top, 377 blend_line(dev, vid_overlay_y + dev->loop_vid_overlay.top,
357 dev->loop_vid_overlay.left, 378 dev->loop_vid_overlay.left,
358 dev->blended_line + offset, osd, 379 dev->blended_line + offset, osd,
359 dev->loop_vid_overlay.width, pixsize); 380 dev->loop_vid_overlay.width, twopixsize / 2);
360 else 381 else
361 memcpy(dev->blended_line + offset, 382 memcpy(dev->blended_line + offset,
362 osd, dev->loop_vid_overlay.width * pixsize); 383 osd, (dev->loop_vid_overlay.width * twopixsize) / 2);
363 scale_line(dev->blended_line, dev->scaled_line, 384 scale_line(dev->blended_line, dev->scaled_line,
364 dev->loop_vid_copy.width, dev->loop_vid_cap.width, 385 dev->loop_vid_copy.width, dev->loop_vid_cap.width,
365 tpg_g_twopixelsize(tpg, p)); 386 tpg_g_twopixelsize(tpg, p));
366 } 387 }
367 dev->cur_scaled_line = vid_out_y; 388 dev->cur_scaled_line = vid_out_y;
368 memcpy(vcapbuf + dev->loop_vid_cap.left * pixsize, 389 memcpy(vcapbuf + vid_cap_left, dev->scaled_line,
369 dev->scaled_line, 390 tpg_hdiv(tpg, p, dev->loop_vid_cap.width));
370 dev->loop_vid_cap.width * pixsize);
371 391
372update_vid_out_y: 392update_vid_out_y:
373 if (osdline) { 393 if (osdline) {
@@ -380,21 +400,22 @@ update_vid_out_y:
380 } 400 }
381 vid_out_y += vid_out_int_part; 401 vid_out_y += vid_out_int_part;
382 vid_out_error += vid_out_fract_part; 402 vid_out_error += vid_out_fract_part;
383 if (vid_out_error >= dev->loop_vid_cap.height) { 403 if (vid_out_error >= dev->loop_vid_cap.height / vdiv) {
384 vid_out_error -= dev->loop_vid_cap.height; 404 vid_out_error -= dev->loop_vid_cap.height / vdiv;
385 vid_out_y++; 405 vid_out_y++;
386 } 406 }
387 } 407 }
388 408
389 if (!blank) 409 if (!blank)
390 return 0; 410 return 0;
391 for (; y < img_height; y++, vcapbuf += stride_cap) 411 for (; y < img_height; y += vdiv, vcapbuf += stride_cap)
392 memcpy(vcapbuf, tpg->contrast_line[p], img_width * pixsize); 412 memcpy(vcapbuf, tpg->contrast_line[p], img_width);
393 return 0; 413 return 0;
394} 414}
395 415
396static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) 416static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
397{ 417{
418 struct tpg_data *tpg = &dev->tpg;
398 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; 419 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1;
399 unsigned line_height = 16 / factor; 420 unsigned line_height = 16 / factor;
400 bool is_tv = vivid_is_sdtv_cap(dev); 421 bool is_tv = vivid_is_sdtv_cap(dev);
@@ -427,7 +448,7 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
427 * standards. 448 * standards.
428 */ 449 */
429 buf->vb.v4l2_buf.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ? 450 buf->vb.v4l2_buf.field = ((dev->vid_cap_seq_count & 1) ^ is_60hz) ?
430 V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM; 451 V4L2_FIELD_BOTTOM : V4L2_FIELD_TOP;
431 /* 452 /*
432 * The sequence counter counts frames, not fields. So divide 453 * The sequence counter counts frames, not fields. So divide
433 * by two. 454 * by two.
@@ -436,27 +457,29 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
436 } else { 457 } else {
437 buf->vb.v4l2_buf.field = dev->field_cap; 458 buf->vb.v4l2_buf.field = dev->field_cap;
438 } 459 }
439 tpg_s_field(&dev->tpg, buf->vb.v4l2_buf.field); 460 tpg_s_field(tpg, buf->vb.v4l2_buf.field,
440 tpg_s_perc_fill_blank(&dev->tpg, dev->must_blank[buf->vb.v4l2_buf.index]); 461 dev->field_cap == V4L2_FIELD_ALTERNATE);
462 tpg_s_perc_fill_blank(tpg, dev->must_blank[buf->vb.v4l2_buf.index]);
441 463
442 vivid_precalc_copy_rects(dev); 464 vivid_precalc_copy_rects(dev);
443 465
444 for (p = 0; p < tpg_g_planes(&dev->tpg); p++) { 466 for (p = 0; p < tpg_g_planes(tpg); p++) {
445 void *vbuf = vb2_plane_vaddr(&buf->vb, p); 467 void *vbuf = plane_vaddr(tpg, buf, p,
468 tpg->bytesperline, tpg->buf_height);
446 469
447 /* 470 /*
448 * The first plane of a multiplanar format has a non-zero 471 * The first plane of a multiplanar format has a non-zero
449 * data_offset. This helps testing whether the application 472 * data_offset. This helps testing whether the application
450 * correctly supports non-zero data offsets. 473 * correctly supports non-zero data offsets.
451 */ 474 */
452 if (dev->fmt_cap->data_offset[p]) { 475 if (p < tpg_g_buffers(tpg) && dev->fmt_cap->data_offset[p]) {
453 memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff, 476 memset(vbuf, dev->fmt_cap->data_offset[p] & 0xff,
454 dev->fmt_cap->data_offset[p]); 477 dev->fmt_cap->data_offset[p]);
455 vbuf += dev->fmt_cap->data_offset[p]; 478 vbuf += dev->fmt_cap->data_offset[p];
456 } 479 }
457 tpg_calc_text_basep(&dev->tpg, basep, p, vbuf); 480 tpg_calc_text_basep(tpg, basep, p, vbuf);
458 if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf)) 481 if (!is_loop || vivid_copy_buffer(dev, p, vbuf, buf))
459 tpg_fillbuffer(&dev->tpg, vivid_get_std_cap(dev), p, vbuf); 482 tpg_fill_plane_buffer(tpg, vivid_get_std_cap(dev), p, vbuf);
460 } 483 }
461 dev->must_blank[buf->vb.v4l2_buf.index] = false; 484 dev->must_blank[buf->vb.v4l2_buf.index] = false;
462 485
@@ -475,12 +498,12 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
475 (dev->field_cap == V4L2_FIELD_ALTERNATE) ? 498 (dev->field_cap == V4L2_FIELD_ALTERNATE) ?
476 (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ? 499 (buf->vb.v4l2_buf.field == V4L2_FIELD_TOP ?
477 " top" : " bottom") : ""); 500 " top" : " bottom") : "");
478 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 501 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
479 } 502 }
480 if (dev->osd_mode == 0) { 503 if (dev->osd_mode == 0) {
481 snprintf(str, sizeof(str), " %dx%d, input %d ", 504 snprintf(str, sizeof(str), " %dx%d, input %d ",
482 dev->src_rect.width, dev->src_rect.height, dev->input); 505 dev->src_rect.width, dev->src_rect.height, dev->input);
483 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 506 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
484 507
485 gain = v4l2_ctrl_g_ctrl(dev->gain); 508 gain = v4l2_ctrl_g_ctrl(dev->gain);
486 mutex_lock(dev->ctrl_hdl_user_vid.lock); 509 mutex_lock(dev->ctrl_hdl_user_vid.lock);
@@ -490,38 +513,38 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf)
490 dev->contrast->cur.val, 513 dev->contrast->cur.val,
491 dev->saturation->cur.val, 514 dev->saturation->cur.val,
492 dev->hue->cur.val); 515 dev->hue->cur.val);
493 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 516 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
494 snprintf(str, sizeof(str), 517 snprintf(str, sizeof(str),
495 " autogain %d, gain %3d, alpha 0x%02x ", 518 " autogain %d, gain %3d, alpha 0x%02x ",
496 dev->autogain->cur.val, gain, dev->alpha->cur.val); 519 dev->autogain->cur.val, gain, dev->alpha->cur.val);
497 mutex_unlock(dev->ctrl_hdl_user_vid.lock); 520 mutex_unlock(dev->ctrl_hdl_user_vid.lock);
498 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 521 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
499 mutex_lock(dev->ctrl_hdl_user_aud.lock); 522 mutex_lock(dev->ctrl_hdl_user_aud.lock);
500 snprintf(str, sizeof(str), 523 snprintf(str, sizeof(str),
501 " volume %3d, mute %d ", 524 " volume %3d, mute %d ",
502 dev->volume->cur.val, dev->mute->cur.val); 525 dev->volume->cur.val, dev->mute->cur.val);
503 mutex_unlock(dev->ctrl_hdl_user_aud.lock); 526 mutex_unlock(dev->ctrl_hdl_user_aud.lock);
504 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 527 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
505 mutex_lock(dev->ctrl_hdl_user_gen.lock); 528 mutex_lock(dev->ctrl_hdl_user_gen.lock);
506 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ", 529 snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
507 dev->int32->cur.val, 530 dev->int32->cur.val,
508 *dev->int64->p_cur.p_s64, 531 *dev->int64->p_cur.p_s64,
509 dev->bitmask->cur.val); 532 dev->bitmask->cur.val);
510 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 533 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
511 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ", 534 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
512 dev->boolean->cur.val, 535 dev->boolean->cur.val,
513 dev->menu->qmenu[dev->menu->cur.val], 536 dev->menu->qmenu[dev->menu->cur.val],
514 dev->string->p_cur.p_char); 537 dev->string->p_cur.p_char);
515 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 538 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
516 snprintf(str, sizeof(str), " integer_menu %lld, value %d ", 539 snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
517 dev->int_menu->qmenu_int[dev->int_menu->cur.val], 540 dev->int_menu->qmenu_int[dev->int_menu->cur.val],
518 dev->int_menu->cur.val); 541 dev->int_menu->cur.val);
519 mutex_unlock(dev->ctrl_hdl_user_gen.lock); 542 mutex_unlock(dev->ctrl_hdl_user_gen.lock);
520 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 543 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
521 if (dev->button_pressed) { 544 if (dev->button_pressed) {
522 dev->button_pressed--; 545 dev->button_pressed--;
523 snprintf(str, sizeof(str), " button pressed!"); 546 snprintf(str, sizeof(str), " button pressed!");
524 tpg_gen_text(&dev->tpg, basep, line++ * line_height, 16, str); 547 tpg_gen_text(tpg, basep, line++ * line_height, 16, str);
525 } 548 }
526 } 549 }
527 550
@@ -585,6 +608,12 @@ static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf)
585 bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0; 608 bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0;
586 int x, y, w, out_x = 0; 609 int x, y, w, out_x = 0;
587 610
611 /*
612 * Overlay support is only supported for formats that have a twopixelsize
613 * that's >= 2. Warn and bail out if that's not the case.
614 */
615 if (WARN_ON(pixsize == 0))
616 return;
588 if ((dev->overlay_cap_field == V4L2_FIELD_TOP || 617 if ((dev->overlay_cap_field == V4L2_FIELD_TOP ||
589 dev->overlay_cap_field == V4L2_FIELD_BOTTOM) && 618 dev->overlay_cap_field == V4L2_FIELD_BOTTOM) &&
590 dev->overlay_cap_field != buf->vb.v4l2_buf.field) 619 dev->overlay_cap_field != buf->vb.v4l2_buf.field)
diff --git a/drivers/media/platform/vivid/vivid-sdr-cap.c b/drivers/media/platform/vivid/vivid-sdr-cap.c
index 4af55f18829f..caf131666e37 100644
--- a/drivers/media/platform/vivid/vivid-sdr-cap.c
+++ b/drivers/media/platform/vivid/vivid-sdr-cap.c
@@ -27,6 +27,7 @@
27#include <media/v4l2-common.h> 27#include <media/v4l2-common.h>
28#include <media/v4l2-event.h> 28#include <media/v4l2-event.h>
29#include <media/v4l2-dv-timings.h> 29#include <media/v4l2-dv-timings.h>
30#include <linux/fixp-arith.h>
30 31
31#include "vivid-core.h" 32#include "vivid-core.h"
32#include "vivid-ctrls.h" 33#include "vivid-ctrls.h"
@@ -423,40 +424,19 @@ int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
423 return 0; 424 return 0;
424} 425}
425 426
426#define FIXP_FRAC (1 << 15) 427#define FIXP_N (15)
427#define FIXP_PI ((int)(FIXP_FRAC * 3.141592653589)) 428#define FIXP_FRAC (1 << FIXP_N)
428 429#define FIXP_2PI ((int)(2 * 3.141592653589 * FIXP_FRAC))
429/* cos() from cx88 driver: cx88-dsp.c */
430static s32 fixp_cos(unsigned int x)
431{
432 u32 t2, t4, t6, t8;
433 u16 period = x / FIXP_PI;
434
435 if (period % 2)
436 return -fixp_cos(x - FIXP_PI);
437 x = x % FIXP_PI;
438 if (x > FIXP_PI/2)
439 return -fixp_cos(FIXP_PI/2 - (x % (FIXP_PI/2)));
440 /* Now x is between 0 and FIXP_PI/2.
441 * To calculate cos(x) we use it's Taylor polinom. */
442 t2 = x*x/FIXP_FRAC/2;
443 t4 = t2*x/FIXP_FRAC*x/FIXP_FRAC/3/4;
444 t6 = t4*x/FIXP_FRAC*x/FIXP_FRAC/5/6;
445 t8 = t6*x/FIXP_FRAC*x/FIXP_FRAC/7/8;
446 return FIXP_FRAC-t2+t4-t6+t8;
447}
448
449static inline s32 fixp_sin(unsigned int x)
450{
451 return -fixp_cos(x + (FIXP_PI / 2));
452}
453 430
454void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf) 431void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
455{ 432{
456 u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0); 433 u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0);
457 unsigned long i; 434 unsigned long i;
458 unsigned long plane_size = vb2_plane_size(&buf->vb, 0); 435 unsigned long plane_size = vb2_plane_size(&buf->vb, 0);
459 int fixp_src_phase_step, fixp_i, fixp_q; 436 s32 src_phase_step;
437 s32 mod_phase_step;
438 s32 fixp_i;
439 s32 fixp_q;
460 440
461 /* 441 /*
462 * TODO: Generated beep tone goes very crackly when sample rate is 442 * TODO: Generated beep tone goes very crackly when sample rate is
@@ -466,28 +446,36 @@ void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
466 446
467 /* calculate phase step */ 447 /* calculate phase step */
468 #define BEEP_FREQ 1000 /* 1kHz beep */ 448 #define BEEP_FREQ 1000 /* 1kHz beep */
469 fixp_src_phase_step = DIV_ROUND_CLOSEST(2 * FIXP_PI * BEEP_FREQ, 449 src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
470 dev->sdr_adc_freq); 450 dev->sdr_adc_freq);
471 451
472 for (i = 0; i < plane_size; i += 2) { 452 for (i = 0; i < plane_size; i += 2) {
473 dev->sdr_fixp_mod_phase += fixp_cos(dev->sdr_fixp_src_phase); 453 mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
474 dev->sdr_fixp_src_phase += fixp_src_phase_step; 454 FIXP_2PI) >> (31 - FIXP_N);
455
456 dev->sdr_fixp_src_phase += src_phase_step;
457 dev->sdr_fixp_mod_phase += mod_phase_step / 4;
475 458
476 /* 459 /*
477 * Transfer phases to [0 / 2xPI] in order to avoid variable 460 * Transfer phases to [0 / 2xPI] in order to avoid variable
478 * overflow and make it suitable for cosine implementation 461 * overflow and make it suitable for cosine implementation
479 * used, which does not support negative angles. 462 * used, which does not support negative angles.
480 */ 463 */
481 while (dev->sdr_fixp_mod_phase < (0 * FIXP_PI)) 464 while (dev->sdr_fixp_mod_phase < FIXP_2PI)
482 dev->sdr_fixp_mod_phase += (2 * FIXP_PI); 465 dev->sdr_fixp_mod_phase += FIXP_2PI;
483 while (dev->sdr_fixp_mod_phase > (2 * FIXP_PI)) 466 while (dev->sdr_fixp_mod_phase > FIXP_2PI)
484 dev->sdr_fixp_mod_phase -= (2 * FIXP_PI); 467 dev->sdr_fixp_mod_phase -= FIXP_2PI;
468
469 while (dev->sdr_fixp_src_phase > FIXP_2PI)
470 dev->sdr_fixp_src_phase -= FIXP_2PI;
485 471
486 while (dev->sdr_fixp_src_phase > (2 * FIXP_PI)) 472 fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
487 dev->sdr_fixp_src_phase -= (2 * FIXP_PI); 473 fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
488 474
489 fixp_i = fixp_cos(dev->sdr_fixp_mod_phase); 475 /* Normalize fraction values represented with 32 bit precision
490 fixp_q = fixp_sin(dev->sdr_fixp_mod_phase); 476 * to fixed point representation with FIXP_N bits */
477 fixp_i >>= (31 - FIXP_N);
478 fixp_q >>= (31 - FIXP_N);
491 479
492 /* convert 'fixp float' to u8 */ 480 /* convert 'fixp float' to u8 */
493 /* u8 = X * 127.5f + 127.5f; where X is float [-1.0 / +1.0] */ 481 /* u8 = X * 127.5f + 127.5f; where X is float [-1.0 / +1.0] */
diff --git a/drivers/media/platform/vivid/vivid-tpg.c b/drivers/media/platform/vivid/vivid-tpg.c
index 34493f435d5a..cb766eb154e7 100644
--- a/drivers/media/platform/vivid/vivid-tpg.c
+++ b/drivers/media/platform/vivid/vivid-tpg.c
@@ -35,7 +35,10 @@ const char * const tpg_pattern_strings[] = {
35 "100% Green", 35 "100% Green",
36 "100% Blue", 36 "100% Blue",
37 "16x16 Checkers", 37 "16x16 Checkers",
38 "2x2 Checkers",
38 "1x1 Checkers", 39 "1x1 Checkers",
40 "2x2 Red/Green Checkers",
41 "1x1 Red/Green Checkers",
39 "Alternating Hor Lines", 42 "Alternating Hor Lines",
40 "Alternating Vert Lines", 43 "Alternating Vert Lines",
41 "One Pixel Wide Cross", 44 "One Pixel Wide Cross",
@@ -120,15 +123,20 @@ int tpg_alloc(struct tpg_data *tpg, unsigned max_w)
120 tpg->max_line_width = max_w; 123 tpg->max_line_width = max_w;
121 for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) { 124 for (pat = 0; pat < TPG_MAX_PAT_LINES; pat++) {
122 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 125 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
123 unsigned pixelsz = plane ? 1 : 4; 126 unsigned pixelsz = plane ? 2 : 4;
124 127
125 tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz); 128 tpg->lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
126 if (!tpg->lines[pat][plane]) 129 if (!tpg->lines[pat][plane])
127 return -ENOMEM; 130 return -ENOMEM;
131 if (plane == 0)
132 continue;
133 tpg->downsampled_lines[pat][plane] = vzalloc(max_w * 2 * pixelsz);
134 if (!tpg->downsampled_lines[pat][plane])
135 return -ENOMEM;
128 } 136 }
129 } 137 }
130 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 138 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
131 unsigned pixelsz = plane ? 1 : 4; 139 unsigned pixelsz = plane ? 2 : 4;
132 140
133 tpg->contrast_line[plane] = vzalloc(max_w * pixelsz); 141 tpg->contrast_line[plane] = vzalloc(max_w * pixelsz);
134 if (!tpg->contrast_line[plane]) 142 if (!tpg->contrast_line[plane])
@@ -152,6 +160,10 @@ void tpg_free(struct tpg_data *tpg)
152 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 160 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
153 vfree(tpg->lines[pat][plane]); 161 vfree(tpg->lines[pat][plane]);
154 tpg->lines[pat][plane] = NULL; 162 tpg->lines[pat][plane] = NULL;
163 if (plane == 0)
164 continue;
165 vfree(tpg->downsampled_lines[pat][plane]);
166 tpg->downsampled_lines[pat][plane] = NULL;
155 } 167 }
156 for (plane = 0; plane < TPG_MAX_PLANES; plane++) { 168 for (plane = 0; plane < TPG_MAX_PLANES; plane++) {
157 vfree(tpg->contrast_line[plane]); 169 vfree(tpg->contrast_line[plane]);
@@ -167,14 +179,38 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
167{ 179{
168 tpg->fourcc = fourcc; 180 tpg->fourcc = fourcc;
169 tpg->planes = 1; 181 tpg->planes = 1;
182 tpg->buffers = 1;
170 tpg->recalc_colors = true; 183 tpg->recalc_colors = true;
184 tpg->interleaved = false;
185 tpg->vdownsampling[0] = 1;
186 tpg->hdownsampling[0] = 1;
187 tpg->hmask[0] = ~0;
188 tpg->hmask[1] = ~0;
189 tpg->hmask[2] = ~0;
190
171 switch (fourcc) { 191 switch (fourcc) {
192 case V4L2_PIX_FMT_SBGGR8:
193 case V4L2_PIX_FMT_SGBRG8:
194 case V4L2_PIX_FMT_SGRBG8:
195 case V4L2_PIX_FMT_SRGGB8:
196 tpg->interleaved = true;
197 tpg->vdownsampling[1] = 1;
198 tpg->hdownsampling[1] = 1;
199 tpg->planes = 2;
200 /* fall through */
201 case V4L2_PIX_FMT_RGB332:
172 case V4L2_PIX_FMT_RGB565: 202 case V4L2_PIX_FMT_RGB565:
173 case V4L2_PIX_FMT_RGB565X: 203 case V4L2_PIX_FMT_RGB565X:
204 case V4L2_PIX_FMT_RGB444:
205 case V4L2_PIX_FMT_XRGB444:
206 case V4L2_PIX_FMT_ARGB444:
174 case V4L2_PIX_FMT_RGB555: 207 case V4L2_PIX_FMT_RGB555:
175 case V4L2_PIX_FMT_XRGB555: 208 case V4L2_PIX_FMT_XRGB555:
176 case V4L2_PIX_FMT_ARGB555: 209 case V4L2_PIX_FMT_ARGB555:
177 case V4L2_PIX_FMT_RGB555X: 210 case V4L2_PIX_FMT_RGB555X:
211 case V4L2_PIX_FMT_XRGB555X:
212 case V4L2_PIX_FMT_ARGB555X:
213 case V4L2_PIX_FMT_BGR666:
178 case V4L2_PIX_FMT_RGB24: 214 case V4L2_PIX_FMT_RGB24:
179 case V4L2_PIX_FMT_BGR24: 215 case V4L2_PIX_FMT_BGR24:
180 case V4L2_PIX_FMT_RGB32: 216 case V4L2_PIX_FMT_RGB32:
@@ -183,16 +219,72 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
183 case V4L2_PIX_FMT_XBGR32: 219 case V4L2_PIX_FMT_XBGR32:
184 case V4L2_PIX_FMT_ARGB32: 220 case V4L2_PIX_FMT_ARGB32:
185 case V4L2_PIX_FMT_ABGR32: 221 case V4L2_PIX_FMT_ABGR32:
222 case V4L2_PIX_FMT_GREY:
186 tpg->is_yuv = false; 223 tpg->is_yuv = false;
187 break; 224 break;
225 case V4L2_PIX_FMT_YUV444:
226 case V4L2_PIX_FMT_YUV555:
227 case V4L2_PIX_FMT_YUV565:
228 case V4L2_PIX_FMT_YUV32:
229 tpg->is_yuv = true;
230 break;
231 case V4L2_PIX_FMT_YUV420M:
232 case V4L2_PIX_FMT_YVU420M:
233 tpg->buffers = 3;
234 /* fall through */
235 case V4L2_PIX_FMT_YUV420:
236 case V4L2_PIX_FMT_YVU420:
237 tpg->vdownsampling[1] = 2;
238 tpg->vdownsampling[2] = 2;
239 tpg->hdownsampling[1] = 2;
240 tpg->hdownsampling[2] = 2;
241 tpg->planes = 3;
242 tpg->is_yuv = true;
243 break;
244 case V4L2_PIX_FMT_YUV422P:
245 tpg->vdownsampling[1] = 1;
246 tpg->vdownsampling[2] = 1;
247 tpg->hdownsampling[1] = 2;
248 tpg->hdownsampling[2] = 2;
249 tpg->planes = 3;
250 tpg->is_yuv = true;
251 break;
188 case V4L2_PIX_FMT_NV16M: 252 case V4L2_PIX_FMT_NV16M:
189 case V4L2_PIX_FMT_NV61M: 253 case V4L2_PIX_FMT_NV61M:
254 tpg->buffers = 2;
255 /* fall through */
256 case V4L2_PIX_FMT_NV16:
257 case V4L2_PIX_FMT_NV61:
258 tpg->vdownsampling[1] = 1;
259 tpg->hdownsampling[1] = 1;
260 tpg->hmask[1] = ~1;
190 tpg->planes = 2; 261 tpg->planes = 2;
191 /* fall-through */ 262 tpg->is_yuv = true;
263 break;
264 case V4L2_PIX_FMT_NV12M:
265 case V4L2_PIX_FMT_NV21M:
266 tpg->buffers = 2;
267 /* fall through */
268 case V4L2_PIX_FMT_NV12:
269 case V4L2_PIX_FMT_NV21:
270 tpg->vdownsampling[1] = 2;
271 tpg->hdownsampling[1] = 1;
272 tpg->hmask[1] = ~1;
273 tpg->planes = 2;
274 tpg->is_yuv = true;
275 break;
276 case V4L2_PIX_FMT_NV24:
277 case V4L2_PIX_FMT_NV42:
278 tpg->vdownsampling[1] = 1;
279 tpg->hdownsampling[1] = 1;
280 tpg->planes = 2;
281 tpg->is_yuv = true;
282 break;
192 case V4L2_PIX_FMT_YUYV: 283 case V4L2_PIX_FMT_YUYV:
193 case V4L2_PIX_FMT_UYVY: 284 case V4L2_PIX_FMT_UYVY:
194 case V4L2_PIX_FMT_YVYU: 285 case V4L2_PIX_FMT_YVYU:
195 case V4L2_PIX_FMT_VYUY: 286 case V4L2_PIX_FMT_VYUY:
287 tpg->hmask[0] = ~1;
196 tpg->is_yuv = true; 288 tpg->is_yuv = true;
197 break; 289 break;
198 default: 290 default:
@@ -200,35 +292,75 @@ bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc)
200 } 292 }
201 293
202 switch (fourcc) { 294 switch (fourcc) {
295 case V4L2_PIX_FMT_RGB332:
296 tpg->twopixelsize[0] = 2;
297 break;
203 case V4L2_PIX_FMT_RGB565: 298 case V4L2_PIX_FMT_RGB565:
204 case V4L2_PIX_FMT_RGB565X: 299 case V4L2_PIX_FMT_RGB565X:
300 case V4L2_PIX_FMT_RGB444:
301 case V4L2_PIX_FMT_XRGB444:
302 case V4L2_PIX_FMT_ARGB444:
205 case V4L2_PIX_FMT_RGB555: 303 case V4L2_PIX_FMT_RGB555:
206 case V4L2_PIX_FMT_XRGB555: 304 case V4L2_PIX_FMT_XRGB555:
207 case V4L2_PIX_FMT_ARGB555: 305 case V4L2_PIX_FMT_ARGB555:
208 case V4L2_PIX_FMT_RGB555X: 306 case V4L2_PIX_FMT_RGB555X:
307 case V4L2_PIX_FMT_XRGB555X:
308 case V4L2_PIX_FMT_ARGB555X:
209 case V4L2_PIX_FMT_YUYV: 309 case V4L2_PIX_FMT_YUYV:
210 case V4L2_PIX_FMT_UYVY: 310 case V4L2_PIX_FMT_UYVY:
211 case V4L2_PIX_FMT_YVYU: 311 case V4L2_PIX_FMT_YVYU:
212 case V4L2_PIX_FMT_VYUY: 312 case V4L2_PIX_FMT_VYUY:
313 case V4L2_PIX_FMT_YUV444:
314 case V4L2_PIX_FMT_YUV555:
315 case V4L2_PIX_FMT_YUV565:
213 tpg->twopixelsize[0] = 2 * 2; 316 tpg->twopixelsize[0] = 2 * 2;
214 break; 317 break;
215 case V4L2_PIX_FMT_RGB24: 318 case V4L2_PIX_FMT_RGB24:
216 case V4L2_PIX_FMT_BGR24: 319 case V4L2_PIX_FMT_BGR24:
217 tpg->twopixelsize[0] = 2 * 3; 320 tpg->twopixelsize[0] = 2 * 3;
218 break; 321 break;
322 case V4L2_PIX_FMT_BGR666:
219 case V4L2_PIX_FMT_RGB32: 323 case V4L2_PIX_FMT_RGB32:
220 case V4L2_PIX_FMT_BGR32: 324 case V4L2_PIX_FMT_BGR32:
221 case V4L2_PIX_FMT_XRGB32: 325 case V4L2_PIX_FMT_XRGB32:
222 case V4L2_PIX_FMT_XBGR32: 326 case V4L2_PIX_FMT_XBGR32:
223 case V4L2_PIX_FMT_ARGB32: 327 case V4L2_PIX_FMT_ARGB32:
224 case V4L2_PIX_FMT_ABGR32: 328 case V4L2_PIX_FMT_ABGR32:
329 case V4L2_PIX_FMT_YUV32:
225 tpg->twopixelsize[0] = 2 * 4; 330 tpg->twopixelsize[0] = 2 * 4;
226 break; 331 break;
332 case V4L2_PIX_FMT_GREY:
333 tpg->twopixelsize[0] = 2;
334 break;
335 case V4L2_PIX_FMT_NV12:
336 case V4L2_PIX_FMT_NV21:
337 case V4L2_PIX_FMT_NV12M:
338 case V4L2_PIX_FMT_NV21M:
339 case V4L2_PIX_FMT_NV16:
340 case V4L2_PIX_FMT_NV61:
227 case V4L2_PIX_FMT_NV16M: 341 case V4L2_PIX_FMT_NV16M:
228 case V4L2_PIX_FMT_NV61M: 342 case V4L2_PIX_FMT_NV61M:
343 case V4L2_PIX_FMT_SBGGR8:
344 case V4L2_PIX_FMT_SGBRG8:
345 case V4L2_PIX_FMT_SGRBG8:
346 case V4L2_PIX_FMT_SRGGB8:
229 tpg->twopixelsize[0] = 2; 347 tpg->twopixelsize[0] = 2;
230 tpg->twopixelsize[1] = 2; 348 tpg->twopixelsize[1] = 2;
231 break; 349 break;
350 case V4L2_PIX_FMT_YUV422P:
351 case V4L2_PIX_FMT_YUV420:
352 case V4L2_PIX_FMT_YVU420:
353 case V4L2_PIX_FMT_YUV420M:
354 case V4L2_PIX_FMT_YVU420M:
355 tpg->twopixelsize[0] = 2;
356 tpg->twopixelsize[1] = 2;
357 tpg->twopixelsize[2] = 2;
358 break;
359 case V4L2_PIX_FMT_NV24:
360 case V4L2_PIX_FMT_NV42:
361 tpg->twopixelsize[0] = 2;
362 tpg->twopixelsize[1] = 4;
363 break;
232 } 364 }
233 return true; 365 return true;
234} 366}
@@ -267,7 +399,8 @@ void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
267 tpg->compose.width = width; 399 tpg->compose.width = width;
268 tpg->compose.height = tpg->buf_height; 400 tpg->compose.height = tpg->buf_height;
269 for (p = 0; p < tpg->planes; p++) 401 for (p = 0; p < tpg->planes; p++)
270 tpg->bytesperline[p] = width * tpg->twopixelsize[p] / 2; 402 tpg->bytesperline[p] = (width * tpg->twopixelsize[p]) /
403 (2 * tpg->hdownsampling[p]);
271 tpg->recalc_square_border = true; 404 tpg->recalc_square_border = true;
272} 405}
273 406
@@ -347,9 +480,9 @@ static void color_to_ycbcr(struct tpg_data *tpg, int r, int g, int b,
347 { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) }, 480 { COEFF(0.5, 224), COEFF(-0.445, 224), COEFF(-0.055, 224) },
348 }; 481 };
349 static const int bt2020[3][3] = { 482 static const int bt2020[3][3] = {
350 { COEFF(0.2726, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) }, 483 { COEFF(0.2627, 219), COEFF(0.6780, 219), COEFF(0.0593, 219) },
351 { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) }, 484 { COEFF(-0.1396, 224), COEFF(-0.3604, 224), COEFF(0.5, 224) },
352 { COEFF(0.5, 224), COEFF(-0.4629, 224), COEFF(-0.0405, 224) }, 485 { COEFF(0.5, 224), COEFF(-0.4598, 224), COEFF(-0.0402, 224) },
353 }; 486 };
354 bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE; 487 bool full = tpg->real_quantization == V4L2_QUANTIZATION_FULL_RANGE;
355 unsigned y_offset = full ? 0 : 16; 488 unsigned y_offset = full ? 0 : 16;
@@ -524,10 +657,10 @@ static void precalculate_color(struct tpg_data *tpg, int k)
524 g <<= 4; 657 g <<= 4;
525 b <<= 4; 658 b <<= 4;
526 } 659 }
527 if (tpg->qual == TPG_QUAL_GRAY) { 660 if (tpg->qual == TPG_QUAL_GRAY || tpg->fourcc == V4L2_PIX_FMT_GREY) {
528 /* Rec. 709 Luma function */ 661 /* Rec. 709 Luma function */
529 /* (0.2126, 0.7152, 0.0722) * (255 * 256) */ 662 /* (0.2126, 0.7152, 0.0722) * (255 * 256) */
530 r = g = b = ((13879 * r + 46688 * g + 4713 * b) >> 16) + (16 << 4); 663 r = g = b = (13879 * r + 46688 * g + 4713 * b) >> 16;
531 } 664 }
532 665
533 /* 666 /*
@@ -601,9 +734,29 @@ static void precalculate_color(struct tpg_data *tpg, int k)
601 cb = clamp(cb, 16 << 4, 240 << 4); 734 cb = clamp(cb, 16 << 4, 240 << 4);
602 cr = clamp(cr, 16 << 4, 240 << 4); 735 cr = clamp(cr, 16 << 4, 240 << 4);
603 } 736 }
604 tpg->colors[k][0] = clamp(y >> 4, 1, 254); 737 y = clamp(y >> 4, 1, 254);
605 tpg->colors[k][1] = clamp(cb >> 4, 1, 254); 738 cb = clamp(cb >> 4, 1, 254);
606 tpg->colors[k][2] = clamp(cr >> 4, 1, 254); 739 cr = clamp(cr >> 4, 1, 254);
740 switch (tpg->fourcc) {
741 case V4L2_PIX_FMT_YUV444:
742 y >>= 4;
743 cb >>= 4;
744 cr >>= 4;
745 break;
746 case V4L2_PIX_FMT_YUV555:
747 y >>= 3;
748 cb >>= 3;
749 cr >>= 3;
750 break;
751 case V4L2_PIX_FMT_YUV565:
752 y >>= 3;
753 cb >>= 2;
754 cr >>= 3;
755 break;
756 }
757 tpg->colors[k][0] = y;
758 tpg->colors[k][1] = cb;
759 tpg->colors[k][2] = cr;
607 } else { 760 } else {
608 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) { 761 if (tpg->real_quantization == V4L2_QUANTIZATION_LIM_RANGE) {
609 r = (r * 219) / 255 + (16 << 4); 762 r = (r * 219) / 255 + (16 << 4);
@@ -611,20 +764,39 @@ static void precalculate_color(struct tpg_data *tpg, int k)
611 b = (b * 219) / 255 + (16 << 4); 764 b = (b * 219) / 255 + (16 << 4);
612 } 765 }
613 switch (tpg->fourcc) { 766 switch (tpg->fourcc) {
767 case V4L2_PIX_FMT_RGB332:
768 r >>= 9;
769 g >>= 9;
770 b >>= 10;
771 break;
614 case V4L2_PIX_FMT_RGB565: 772 case V4L2_PIX_FMT_RGB565:
615 case V4L2_PIX_FMT_RGB565X: 773 case V4L2_PIX_FMT_RGB565X:
616 r >>= 7; 774 r >>= 7;
617 g >>= 6; 775 g >>= 6;
618 b >>= 7; 776 b >>= 7;
619 break; 777 break;
778 case V4L2_PIX_FMT_RGB444:
779 case V4L2_PIX_FMT_XRGB444:
780 case V4L2_PIX_FMT_ARGB444:
781 r >>= 8;
782 g >>= 8;
783 b >>= 8;
784 break;
620 case V4L2_PIX_FMT_RGB555: 785 case V4L2_PIX_FMT_RGB555:
621 case V4L2_PIX_FMT_XRGB555: 786 case V4L2_PIX_FMT_XRGB555:
622 case V4L2_PIX_FMT_ARGB555: 787 case V4L2_PIX_FMT_ARGB555:
623 case V4L2_PIX_FMT_RGB555X: 788 case V4L2_PIX_FMT_RGB555X:
789 case V4L2_PIX_FMT_XRGB555X:
790 case V4L2_PIX_FMT_ARGB555X:
624 r >>= 7; 791 r >>= 7;
625 g >>= 7; 792 g >>= 7;
626 b >>= 7; 793 b >>= 7;
627 break; 794 break;
795 case V4L2_PIX_FMT_BGR666:
796 r >>= 6;
797 g >>= 6;
798 b >>= 6;
799 break;
628 default: 800 default:
629 r >>= 4; 801 r >>= 4;
630 g >>= 4; 802 g >>= 4;
@@ -665,31 +837,120 @@ static void gen_twopix(struct tpg_data *tpg,
665 b_v = tpg->colors[color][2]; /* B or precalculated V */ 837 b_v = tpg->colors[color][2]; /* B or precalculated V */
666 838
667 switch (tpg->fourcc) { 839 switch (tpg->fourcc) {
840 case V4L2_PIX_FMT_GREY:
841 buf[0][offset] = r_y;
842 break;
843 case V4L2_PIX_FMT_YUV422P:
844 case V4L2_PIX_FMT_YUV420:
845 case V4L2_PIX_FMT_YUV420M:
846 buf[0][offset] = r_y;
847 if (odd) {
848 buf[1][0] = (buf[1][0] + g_u) / 2;
849 buf[2][0] = (buf[2][0] + b_v) / 2;
850 buf[1][1] = buf[1][0];
851 buf[2][1] = buf[2][0];
852 break;
853 }
854 buf[1][0] = g_u;
855 buf[2][0] = b_v;
856 break;
857 case V4L2_PIX_FMT_YVU420:
858 case V4L2_PIX_FMT_YVU420M:
859 buf[0][offset] = r_y;
860 if (odd) {
861 buf[1][0] = (buf[1][0] + b_v) / 2;
862 buf[2][0] = (buf[2][0] + g_u) / 2;
863 buf[1][1] = buf[1][0];
864 buf[2][1] = buf[2][0];
865 break;
866 }
867 buf[1][0] = b_v;
868 buf[2][0] = g_u;
869 break;
870
871 case V4L2_PIX_FMT_NV12:
872 case V4L2_PIX_FMT_NV12M:
873 case V4L2_PIX_FMT_NV16:
668 case V4L2_PIX_FMT_NV16M: 874 case V4L2_PIX_FMT_NV16M:
669 buf[0][offset] = r_y; 875 buf[0][offset] = r_y;
670 buf[1][offset] = odd ? b_v : g_u; 876 if (odd) {
877 buf[1][0] = (buf[1][0] + g_u) / 2;
878 buf[1][1] = (buf[1][1] + b_v) / 2;
879 break;
880 }
881 buf[1][0] = g_u;
882 buf[1][1] = b_v;
671 break; 883 break;
884 case V4L2_PIX_FMT_NV21:
885 case V4L2_PIX_FMT_NV21M:
886 case V4L2_PIX_FMT_NV61:
672 case V4L2_PIX_FMT_NV61M: 887 case V4L2_PIX_FMT_NV61M:
673 buf[0][offset] = r_y; 888 buf[0][offset] = r_y;
674 buf[1][offset] = odd ? g_u : b_v; 889 if (odd) {
890 buf[1][0] = (buf[1][0] + b_v) / 2;
891 buf[1][1] = (buf[1][1] + g_u) / 2;
892 break;
893 }
894 buf[1][0] = b_v;
895 buf[1][1] = g_u;
896 break;
897
898 case V4L2_PIX_FMT_NV24:
899 buf[0][offset] = r_y;
900 buf[1][2 * offset] = g_u;
901 buf[1][2 * offset + 1] = b_v;
902 break;
903
904 case V4L2_PIX_FMT_NV42:
905 buf[0][offset] = r_y;
906 buf[1][2 * offset] = b_v;
907 buf[1][2 * offset + 1] = g_u;
675 break; 908 break;
676 909
677 case V4L2_PIX_FMT_YUYV: 910 case V4L2_PIX_FMT_YUYV:
678 buf[0][offset] = r_y; 911 buf[0][offset] = r_y;
679 buf[0][offset + 1] = odd ? b_v : g_u; 912 if (odd) {
913 buf[0][1] = (buf[0][1] + g_u) / 2;
914 buf[0][3] = (buf[0][3] + b_v) / 2;
915 break;
916 }
917 buf[0][1] = g_u;
918 buf[0][3] = b_v;
680 break; 919 break;
681 case V4L2_PIX_FMT_UYVY: 920 case V4L2_PIX_FMT_UYVY:
682 buf[0][offset] = odd ? b_v : g_u;
683 buf[0][offset + 1] = r_y; 921 buf[0][offset + 1] = r_y;
922 if (odd) {
923 buf[0][0] = (buf[0][0] + g_u) / 2;
924 buf[0][2] = (buf[0][2] + b_v) / 2;
925 break;
926 }
927 buf[0][0] = g_u;
928 buf[0][2] = b_v;
684 break; 929 break;
685 case V4L2_PIX_FMT_YVYU: 930 case V4L2_PIX_FMT_YVYU:
686 buf[0][offset] = r_y; 931 buf[0][offset] = r_y;
687 buf[0][offset + 1] = odd ? g_u : b_v; 932 if (odd) {
933 buf[0][1] = (buf[0][1] + b_v) / 2;
934 buf[0][3] = (buf[0][3] + g_u) / 2;
935 break;
936 }
937 buf[0][1] = b_v;
938 buf[0][3] = g_u;
688 break; 939 break;
689 case V4L2_PIX_FMT_VYUY: 940 case V4L2_PIX_FMT_VYUY:
690 buf[0][offset] = odd ? g_u : b_v;
691 buf[0][offset + 1] = r_y; 941 buf[0][offset + 1] = r_y;
942 if (odd) {
943 buf[0][0] = (buf[0][0] + b_v) / 2;
944 buf[0][2] = (buf[0][2] + g_u) / 2;
945 break;
946 }
947 buf[0][0] = b_v;
948 buf[0][2] = g_u;
949 break;
950 case V4L2_PIX_FMT_RGB332:
951 buf[0][offset] = (r_y << 5) | (g_u << 2) | b_v;
692 break; 952 break;
953 case V4L2_PIX_FMT_YUV565:
693 case V4L2_PIX_FMT_RGB565: 954 case V4L2_PIX_FMT_RGB565:
694 buf[0][offset] = (g_u << 5) | b_v; 955 buf[0][offset] = (g_u << 5) | b_v;
695 buf[0][offset + 1] = (r_y << 3) | (g_u >> 3); 956 buf[0][offset + 1] = (r_y << 3) | (g_u >> 3);
@@ -698,15 +959,29 @@ static void gen_twopix(struct tpg_data *tpg,
698 buf[0][offset] = (r_y << 3) | (g_u >> 3); 959 buf[0][offset] = (r_y << 3) | (g_u >> 3);
699 buf[0][offset + 1] = (g_u << 5) | b_v; 960 buf[0][offset + 1] = (g_u << 5) | b_v;
700 break; 961 break;
962 case V4L2_PIX_FMT_RGB444:
963 case V4L2_PIX_FMT_XRGB444:
964 alpha = 0;
965 /* fall through */
966 case V4L2_PIX_FMT_YUV444:
967 case V4L2_PIX_FMT_ARGB444:
968 buf[0][offset] = (g_u << 4) | b_v;
969 buf[0][offset + 1] = (alpha & 0xf0) | r_y;
970 break;
701 case V4L2_PIX_FMT_RGB555: 971 case V4L2_PIX_FMT_RGB555:
702 case V4L2_PIX_FMT_XRGB555: 972 case V4L2_PIX_FMT_XRGB555:
703 alpha = 0; 973 alpha = 0;
704 /* fall through */ 974 /* fall through */
975 case V4L2_PIX_FMT_YUV555:
705 case V4L2_PIX_FMT_ARGB555: 976 case V4L2_PIX_FMT_ARGB555:
706 buf[0][offset] = (g_u << 5) | b_v; 977 buf[0][offset] = (g_u << 5) | b_v;
707 buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); 978 buf[0][offset + 1] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
708 break; 979 break;
709 case V4L2_PIX_FMT_RGB555X: 980 case V4L2_PIX_FMT_RGB555X:
981 case V4L2_PIX_FMT_XRGB555X:
982 alpha = 0;
983 /* fall through */
984 case V4L2_PIX_FMT_ARGB555X:
710 buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3); 985 buf[0][offset] = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
711 buf[0][offset + 1] = (g_u << 5) | b_v; 986 buf[0][offset + 1] = (g_u << 5) | b_v;
712 break; 987 break;
@@ -720,10 +995,17 @@ static void gen_twopix(struct tpg_data *tpg,
720 buf[0][offset + 1] = g_u; 995 buf[0][offset + 1] = g_u;
721 buf[0][offset + 2] = r_y; 996 buf[0][offset + 2] = r_y;
722 break; 997 break;
998 case V4L2_PIX_FMT_BGR666:
999 buf[0][offset] = (b_v << 2) | (g_u >> 4);
1000 buf[0][offset + 1] = (g_u << 4) | (r_y >> 2);
1001 buf[0][offset + 2] = r_y << 6;
1002 buf[0][offset + 3] = 0;
1003 break;
723 case V4L2_PIX_FMT_RGB32: 1004 case V4L2_PIX_FMT_RGB32:
724 case V4L2_PIX_FMT_XRGB32: 1005 case V4L2_PIX_FMT_XRGB32:
725 alpha = 0; 1006 alpha = 0;
726 /* fall through */ 1007 /* fall through */
1008 case V4L2_PIX_FMT_YUV32:
727 case V4L2_PIX_FMT_ARGB32: 1009 case V4L2_PIX_FMT_ARGB32:
728 buf[0][offset] = alpha; 1010 buf[0][offset] = alpha;
729 buf[0][offset + 1] = r_y; 1011 buf[0][offset + 1] = r_y;
@@ -740,15 +1022,47 @@ static void gen_twopix(struct tpg_data *tpg,
740 buf[0][offset + 2] = r_y; 1022 buf[0][offset + 2] = r_y;
741 buf[0][offset + 3] = alpha; 1023 buf[0][offset + 3] = alpha;
742 break; 1024 break;
1025 case V4L2_PIX_FMT_SBGGR8:
1026 buf[0][offset] = odd ? g_u : b_v;
1027 buf[1][offset] = odd ? r_y : g_u;
1028 break;
1029 case V4L2_PIX_FMT_SGBRG8:
1030 buf[0][offset] = odd ? b_v : g_u;
1031 buf[1][offset] = odd ? g_u : r_y;
1032 break;
1033 case V4L2_PIX_FMT_SGRBG8:
1034 buf[0][offset] = odd ? r_y : g_u;
1035 buf[1][offset] = odd ? g_u : b_v;
1036 break;
1037 case V4L2_PIX_FMT_SRGGB8:
1038 buf[0][offset] = odd ? g_u : r_y;
1039 buf[1][offset] = odd ? b_v : g_u;
1040 break;
1041 }
1042}
1043
1044unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line)
1045{
1046 switch (tpg->fourcc) {
1047 case V4L2_PIX_FMT_SBGGR8:
1048 case V4L2_PIX_FMT_SGBRG8:
1049 case V4L2_PIX_FMT_SGRBG8:
1050 case V4L2_PIX_FMT_SRGGB8:
1051 return buf_line & 1;
1052 default:
1053 return 0;
743 } 1054 }
744} 1055}
745 1056
746/* Return how many pattern lines are used by the current pattern. */ 1057/* Return how many pattern lines are used by the current pattern. */
747static unsigned tpg_get_pat_lines(struct tpg_data *tpg) 1058static unsigned tpg_get_pat_lines(const struct tpg_data *tpg)
748{ 1059{
749 switch (tpg->pattern) { 1060 switch (tpg->pattern) {
750 case TPG_PAT_CHECKERS_16X16: 1061 case TPG_PAT_CHECKERS_16X16:
1062 case TPG_PAT_CHECKERS_2X2:
751 case TPG_PAT_CHECKERS_1X1: 1063 case TPG_PAT_CHECKERS_1X1:
1064 case TPG_PAT_COLOR_CHECKERS_2X2:
1065 case TPG_PAT_COLOR_CHECKERS_1X1:
752 case TPG_PAT_ALTERNATING_HLINES: 1066 case TPG_PAT_ALTERNATING_HLINES:
753 case TPG_PAT_CROSS_1_PIXEL: 1067 case TPG_PAT_CROSS_1_PIXEL:
754 case TPG_PAT_CROSS_2_PIXELS: 1068 case TPG_PAT_CROSS_2_PIXELS:
@@ -763,14 +1077,18 @@ static unsigned tpg_get_pat_lines(struct tpg_data *tpg)
763} 1077}
764 1078
765/* Which pattern line should be used for the given frame line. */ 1079/* Which pattern line should be used for the given frame line. */
766static unsigned tpg_get_pat_line(struct tpg_data *tpg, unsigned line) 1080static unsigned tpg_get_pat_line(const struct tpg_data *tpg, unsigned line)
767{ 1081{
768 switch (tpg->pattern) { 1082 switch (tpg->pattern) {
769 case TPG_PAT_CHECKERS_16X16: 1083 case TPG_PAT_CHECKERS_16X16:
770 return (line >> 4) & 1; 1084 return (line >> 4) & 1;
771 case TPG_PAT_CHECKERS_1X1: 1085 case TPG_PAT_CHECKERS_1X1:
1086 case TPG_PAT_COLOR_CHECKERS_1X1:
772 case TPG_PAT_ALTERNATING_HLINES: 1087 case TPG_PAT_ALTERNATING_HLINES:
773 return line & 1; 1088 return line & 1;
1089 case TPG_PAT_CHECKERS_2X2:
1090 case TPG_PAT_COLOR_CHECKERS_2X2:
1091 return (line & 2) >> 1;
774 case TPG_PAT_100_COLORSQUARES: 1092 case TPG_PAT_100_COLORSQUARES:
775 case TPG_PAT_100_HCOLORBAR: 1093 case TPG_PAT_100_HCOLORBAR:
776 return (line * 8) / tpg->src_height; 1094 return (line * 8) / tpg->src_height;
@@ -789,7 +1107,8 @@ static unsigned tpg_get_pat_line(struct tpg_data *tpg, unsigned line)
789 * Which color should be used for the given pattern line and X coordinate. 1107 * Which color should be used for the given pattern line and X coordinate.
790 * Note: x is in the range 0 to 2 * tpg->src_width. 1108 * Note: x is in the range 0 to 2 * tpg->src_width.
791 */ 1109 */
792static enum tpg_color tpg_get_color(struct tpg_data *tpg, unsigned pat_line, unsigned x) 1110static enum tpg_color tpg_get_color(const struct tpg_data *tpg,
1111 unsigned pat_line, unsigned x)
793{ 1112{
794 /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code 1113 /* Maximum number of bars are TPG_COLOR_MAX - otherwise, the input print code
795 should be modified */ 1114 should be modified */
@@ -836,6 +1155,15 @@ static enum tpg_color tpg_get_color(struct tpg_data *tpg, unsigned pat_line, uns
836 case TPG_PAT_CHECKERS_1X1: 1155 case TPG_PAT_CHECKERS_1X1:
837 return ((x & 1) ^ (pat_line & 1)) ? 1156 return ((x & 1) ^ (pat_line & 1)) ?
838 TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; 1157 TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1158 case TPG_PAT_COLOR_CHECKERS_1X1:
1159 return ((x & 1) ^ (pat_line & 1)) ?
1160 TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
1161 case TPG_PAT_CHECKERS_2X2:
1162 return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1163 TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
1164 case TPG_PAT_COLOR_CHECKERS_2X2:
1165 return (((x >> 1) & 1) ^ (pat_line & 1)) ?
1166 TPG_COLOR_100_RED : TPG_COLOR_100_BLUE;
839 case TPG_PAT_ALTERNATING_HLINES: 1167 case TPG_PAT_ALTERNATING_HLINES:
840 return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK; 1168 return pat_line ? TPG_COLOR_100_WHITE : TPG_COLOR_100_BLACK;
841 case TPG_PAT_ALTERNATING_VLINES: 1169 case TPG_PAT_ALTERNATING_VLINES:
@@ -948,6 +1276,7 @@ static void tpg_calculate_square_border(struct tpg_data *tpg)
948static void tpg_precalculate_line(struct tpg_data *tpg) 1276static void tpg_precalculate_line(struct tpg_data *tpg)
949{ 1277{
950 enum tpg_color contrast; 1278 enum tpg_color contrast;
1279 u8 pix[TPG_MAX_PLANES][8];
951 unsigned pat; 1280 unsigned pat;
952 unsigned p; 1281 unsigned p;
953 unsigned x; 1282 unsigned x;
@@ -974,7 +1303,6 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
974 for (x = 0; x < tpg->scaled_width * 2; x += 2) { 1303 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
975 unsigned real_x = src_x; 1304 unsigned real_x = src_x;
976 enum tpg_color color1, color2; 1305 enum tpg_color color1, color2;
977 u8 pix[TPG_MAX_PLANES][8];
978 1306
979 real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x; 1307 real_x = tpg->hflip ? tpg->src_width * 2 - real_x - 2 : real_x;
980 color1 = tpg_get_color(tpg, pat, real_x); 1308 color1 = tpg_get_color(tpg, pat, real_x);
@@ -1001,39 +1329,53 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
1001 gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1); 1329 gen_twopix(tpg, pix, tpg->hflip ? color1 : color2, 1);
1002 for (p = 0; p < tpg->planes; p++) { 1330 for (p = 0; p < tpg->planes; p++) {
1003 unsigned twopixsize = tpg->twopixelsize[p]; 1331 unsigned twopixsize = tpg->twopixelsize[p];
1004 u8 *pos = tpg->lines[pat][p] + x * twopixsize / 2; 1332 unsigned hdiv = tpg->hdownsampling[p];
1333 u8 *pos = tpg->lines[pat][p] + tpg_hdiv(tpg, p, x);
1005 1334
1006 memcpy(pos, pix[p], twopixsize); 1335 memcpy(pos, pix[p], twopixsize / hdiv);
1007 } 1336 }
1008 } 1337 }
1009 } 1338 }
1010 for (x = 0; x < tpg->scaled_width; x += 2) {
1011 u8 pix[TPG_MAX_PLANES][8];
1012 1339
1013 gen_twopix(tpg, pix, contrast, 0); 1340 if (tpg->vdownsampling[tpg->planes - 1] > 1) {
1014 gen_twopix(tpg, pix, contrast, 1); 1341 unsigned pat_lines = tpg_get_pat_lines(tpg);
1015 for (p = 0; p < tpg->planes; p++) {
1016 unsigned twopixsize = tpg->twopixelsize[p];
1017 u8 *pos = tpg->contrast_line[p] + x * twopixsize / 2;
1018 1342
1019 memcpy(pos, pix[p], twopixsize); 1343 for (pat = 0; pat < pat_lines; pat++) {
1344 unsigned next_pat = (pat + 1) % pat_lines;
1345
1346 for (p = 1; p < tpg->planes; p++) {
1347 unsigned w = tpg_hdiv(tpg, p, tpg->scaled_width * 2);
1348 u8 *pos1 = tpg->lines[pat][p];
1349 u8 *pos2 = tpg->lines[next_pat][p];
1350 u8 *dest = tpg->downsampled_lines[pat][p];
1351
1352 for (x = 0; x < w; x++, pos1++, pos2++, dest++)
1353 *dest = ((u16)*pos1 + (u16)*pos2) / 2;
1354 }
1020 } 1355 }
1021 } 1356 }
1022 for (x = 0; x < tpg->scaled_width; x += 2) {
1023 u8 pix[TPG_MAX_PLANES][8];
1024 1357
1025 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0); 1358 gen_twopix(tpg, pix, contrast, 0);
1026 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1); 1359 gen_twopix(tpg, pix, contrast, 1);
1027 for (p = 0; p < tpg->planes; p++) { 1360 for (p = 0; p < tpg->planes; p++) {
1028 unsigned twopixsize = tpg->twopixelsize[p]; 1361 unsigned twopixsize = tpg->twopixelsize[p];
1029 u8 *pos = tpg->black_line[p] + x * twopixsize / 2; 1362 u8 *pos = tpg->contrast_line[p];
1030 1363
1364 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1365 memcpy(pos, pix[p], twopixsize);
1366 }
1367
1368 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 0);
1369 gen_twopix(tpg, pix, TPG_COLOR_100_BLACK, 1);
1370 for (p = 0; p < tpg->planes; p++) {
1371 unsigned twopixsize = tpg->twopixelsize[p];
1372 u8 *pos = tpg->black_line[p];
1373
1374 for (x = 0; x < tpg->scaled_width; x += 2, pos += twopixsize)
1031 memcpy(pos, pix[p], twopixsize); 1375 memcpy(pos, pix[p], twopixsize);
1032 }
1033 } 1376 }
1034 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1035 u8 pix[TPG_MAX_PLANES][8];
1036 1377
1378 for (x = 0; x < tpg->scaled_width * 2; x += 2) {
1037 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0); 1379 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 0);
1038 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1); 1380 gen_twopix(tpg, pix, TPG_COLOR_RANDOM, 1);
1039 for (p = 0; p < tpg->planes; p++) { 1381 for (p = 0; p < tpg->planes; p++) {
@@ -1043,6 +1385,7 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
1043 memcpy(pos, pix[p], twopixsize); 1385 memcpy(pos, pix[p], twopixsize);
1044 } 1386 }
1045 } 1387 }
1388
1046 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0); 1389 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 0);
1047 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1); 1390 gen_twopix(tpg, tpg->textbg, TPG_COLOR_TEXTBG, 1);
1048 gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0); 1391 gen_twopix(tpg, tpg->textfg, TPG_COLOR_TEXTFG, 0);
@@ -1052,8 +1395,8 @@ static void tpg_precalculate_line(struct tpg_data *tpg)
1052/* need this to do rgb24 rendering */ 1395/* need this to do rgb24 rendering */
1053typedef struct { u16 __; u8 _; } __packed x24; 1396typedef struct { u16 __; u8 _; } __packed x24;
1054 1397
1055void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2], 1398void tpg_gen_text(const struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1056 int y, int x, char *text) 1399 int y, int x, char *text)
1057{ 1400{
1058 int line; 1401 int line;
1059 unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1; 1402 unsigned step = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
@@ -1083,24 +1426,37 @@ void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1083 div = 2; 1426 div = 2;
1084 1427
1085 for (p = 0; p < tpg->planes; p++) { 1428 for (p = 0; p < tpg->planes; p++) {
1086 /* Print stream time */ 1429 unsigned vdiv = tpg->vdownsampling[p];
1430 unsigned hdiv = tpg->hdownsampling[p];
1431
1432 /* Print text */
1087#define PRINTSTR(PIXTYPE) do { \ 1433#define PRINTSTR(PIXTYPE) do { \
1088 PIXTYPE fg; \ 1434 PIXTYPE fg; \
1089 PIXTYPE bg; \ 1435 PIXTYPE bg; \
1090 memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \ 1436 memcpy(&fg, tpg->textfg[p], sizeof(PIXTYPE)); \
1091 memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \ 1437 memcpy(&bg, tpg->textbg[p], sizeof(PIXTYPE)); \
1092 \ 1438 \
1093 for (line = first; line < 16; line += step) { \ 1439 for (line = first; line < 16; line += vdiv * step) { \
1094 int l = tpg->vflip ? 15 - line : line; \ 1440 int l = tpg->vflip ? 15 - line : line; \
1095 PIXTYPE *pos = (PIXTYPE *)(basep[p][line & 1] + \ 1441 PIXTYPE *pos = (PIXTYPE *)(basep[p][(line / vdiv) & 1] + \
1096 ((y * step + l) / div) * tpg->bytesperline[p] + \ 1442 ((y * step + l) / (vdiv * div)) * tpg->bytesperline[p] + \
1097 x * sizeof(PIXTYPE)); \ 1443 (x / hdiv) * sizeof(PIXTYPE)); \
1098 unsigned s; \ 1444 unsigned s; \
1099 \ 1445 \
1100 for (s = 0; s < len; s++) { \ 1446 for (s = 0; s < len; s++) { \
1101 u8 chr = font8x16[text[s] * 16 + line]; \ 1447 u8 chr = font8x16[text[s] * 16 + line]; \
1102 \ 1448 \
1103 if (tpg->hflip) { \ 1449 if (hdiv == 2 && tpg->hflip) { \
1450 pos[3] = (chr & (0x01 << 6) ? fg : bg); \
1451 pos[2] = (chr & (0x01 << 4) ? fg : bg); \
1452 pos[1] = (chr & (0x01 << 2) ? fg : bg); \
1453 pos[0] = (chr & (0x01 << 0) ? fg : bg); \
1454 } else if (hdiv == 2) { \
1455 pos[0] = (chr & (0x01 << 7) ? fg : bg); \
1456 pos[1] = (chr & (0x01 << 5) ? fg : bg); \
1457 pos[2] = (chr & (0x01 << 3) ? fg : bg); \
1458 pos[3] = (chr & (0x01 << 1) ? fg : bg); \
1459 } else if (tpg->hflip) { \
1104 pos[7] = (chr & (0x01 << 7) ? fg : bg); \ 1460 pos[7] = (chr & (0x01 << 7) ? fg : bg); \
1105 pos[6] = (chr & (0x01 << 6) ? fg : bg); \ 1461 pos[6] = (chr & (0x01 << 6) ? fg : bg); \
1106 pos[5] = (chr & (0x01 << 5) ? fg : bg); \ 1462 pos[5] = (chr & (0x01 << 5) ? fg : bg); \
@@ -1120,7 +1476,7 @@ void tpg_gen_text(struct tpg_data *tpg, u8 *basep[TPG_MAX_PLANES][2],
1120 pos[7] = (chr & (0x01 << 0) ? fg : bg); \ 1476 pos[7] = (chr & (0x01 << 0) ? fg : bg); \
1121 } \ 1477 } \
1122 \ 1478 \
1123 pos += tpg->hflip ? -8 : 8; \ 1479 pos += (tpg->hflip ? -8 : 8) / hdiv; \
1124 } \ 1480 } \
1125 } \ 1481 } \
1126} while (0) 1482} while (0)
@@ -1187,7 +1543,7 @@ void tpg_update_mv_step(struct tpg_data *tpg)
1187} 1543}
1188 1544
1189/* Map the line number relative to the crop rectangle to a frame line number */ 1545/* Map the line number relative to the crop rectangle to a frame line number */
1190static unsigned tpg_calc_frameline(struct tpg_data *tpg, unsigned src_y, 1546static unsigned tpg_calc_frameline(const struct tpg_data *tpg, unsigned src_y,
1191 unsigned field) 1547 unsigned field)
1192{ 1548{
1193 switch (field) { 1549 switch (field) {
@@ -1204,7 +1560,7 @@ static unsigned tpg_calc_frameline(struct tpg_data *tpg, unsigned src_y,
1204 * Map the line number relative to the compose rectangle to a destination 1560 * Map the line number relative to the compose rectangle to a destination
1205 * buffer line number. 1561 * buffer line number.
1206 */ 1562 */
1207static unsigned tpg_calc_buffer_line(struct tpg_data *tpg, unsigned y, 1563static unsigned tpg_calc_buffer_line(const struct tpg_data *tpg, unsigned y,
1208 unsigned field) 1564 unsigned field)
1209{ 1565{
1210 y += tpg->compose.top; 1566 y += tpg->compose.top;
@@ -1265,6 +1621,10 @@ static void tpg_recalc(struct tpg_data *tpg)
1265 V4L2_QUANTIZATION_LIM_RANGE; 1621 V4L2_QUANTIZATION_LIM_RANGE;
1266 break; 1622 break;
1267 } 1623 }
1624 } else if (tpg->colorspace == V4L2_COLORSPACE_BT2020) {
1625 /* R'G'B' BT.2020 is limited range */
1626 tpg->real_quantization =
1627 V4L2_QUANTIZATION_LIM_RANGE;
1268 } 1628 }
1269 } 1629 }
1270 tpg_precalculate_colors(tpg); 1630 tpg_precalculate_colors(tpg);
@@ -1283,191 +1643,388 @@ void tpg_calc_text_basep(struct tpg_data *tpg,
1283 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf) 1643 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf)
1284{ 1644{
1285 unsigned stride = tpg->bytesperline[p]; 1645 unsigned stride = tpg->bytesperline[p];
1646 unsigned h = tpg->buf_height;
1286 1647
1287 tpg_recalc(tpg); 1648 tpg_recalc(tpg);
1288 1649
1289 basep[p][0] = vbuf; 1650 basep[p][0] = vbuf;
1290 basep[p][1] = vbuf; 1651 basep[p][1] = vbuf;
1652 h /= tpg->vdownsampling[p];
1291 if (tpg->field == V4L2_FIELD_SEQ_TB) 1653 if (tpg->field == V4L2_FIELD_SEQ_TB)
1292 basep[p][1] += tpg->buf_height * stride / 2; 1654 basep[p][1] += h * stride / 2;
1293 else if (tpg->field == V4L2_FIELD_SEQ_BT) 1655 else if (tpg->field == V4L2_FIELD_SEQ_BT)
1294 basep[p][0] += tpg->buf_height * stride / 2; 1656 basep[p][0] += h * stride / 2;
1657 if (p == 0 && tpg->interleaved)
1658 tpg_calc_text_basep(tpg, basep, 1, vbuf);
1295} 1659}
1296 1660
1297void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf) 1661static int tpg_pattern_avg(const struct tpg_data *tpg,
1662 unsigned pat1, unsigned pat2)
1298{ 1663{
1299 bool is_tv = std; 1664 unsigned pat_lines = tpg_get_pat_lines(tpg);
1300 bool is_60hz = is_tv && (std & V4L2_STD_525_60); 1665
1301 unsigned mv_hor_old = tpg->mv_hor_count % tpg->src_width; 1666 if (pat1 == (pat2 + 1) % pat_lines)
1302 unsigned mv_hor_new = (tpg->mv_hor_count + tpg->mv_hor_step) % tpg->src_width; 1667 return pat2;
1303 unsigned mv_vert_old = tpg->mv_vert_count % tpg->src_height; 1668 if (pat2 == (pat1 + 1) % pat_lines)
1304 unsigned mv_vert_new = (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height; 1669 return pat1;
1670 return -1;
1671}
1672
1673/*
1674 * This struct contains common parameters used by both the drawing of the
1675 * test pattern and the drawing of the extras (borders, square, etc.)
1676 */
1677struct tpg_draw_params {
1678 /* common data */
1679 bool is_tv;
1680 bool is_60hz;
1681 unsigned twopixsize;
1682 unsigned img_width;
1683 unsigned stride;
1684 unsigned hmax;
1685 unsigned frame_line;
1686 unsigned frame_line_next;
1687
1688 /* test pattern */
1689 unsigned mv_hor_old;
1690 unsigned mv_hor_new;
1691 unsigned mv_vert_old;
1692 unsigned mv_vert_new;
1693
1694 /* extras */
1305 unsigned wss_width; 1695 unsigned wss_width;
1306 unsigned f; 1696 unsigned wss_random_offset;
1307 int hmax = (tpg->compose.height * tpg->perc_fill) / 100; 1697 unsigned sav_eav_f;
1308 int h; 1698 unsigned left_pillar_width;
1309 unsigned twopixsize = tpg->twopixelsize[p]; 1699 unsigned right_pillar_start;
1310 unsigned img_width = tpg->compose.width * twopixsize / 2; 1700};
1311 unsigned line_offset;
1312 unsigned left_pillar_width = 0;
1313 unsigned right_pillar_start = img_width;
1314 unsigned stride = tpg->bytesperline[p];
1315 unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
1316 u8 *orig_vbuf = vbuf;
1317 1701
1318 /* Coarse scaling with Bresenham */ 1702static void tpg_fill_params_pattern(const struct tpg_data *tpg, unsigned p,
1319 unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height; 1703 struct tpg_draw_params *params)
1320 unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height; 1704{
1321 unsigned src_y = 0; 1705 params->mv_hor_old =
1322 unsigned error = 0; 1706 tpg_hscale_div(tpg, p, tpg->mv_hor_count % tpg->src_width);
1707 params->mv_hor_new =
1708 tpg_hscale_div(tpg, p, (tpg->mv_hor_count + tpg->mv_hor_step) %
1709 tpg->src_width);
1710 params->mv_vert_old = tpg->mv_vert_count % tpg->src_height;
1711 params->mv_vert_new =
1712 (tpg->mv_vert_count + tpg->mv_vert_step) % tpg->src_height;
1713}
1323 1714
1324 tpg_recalc(tpg); 1715static void tpg_fill_params_extras(const struct tpg_data *tpg,
1716 unsigned p,
1717 struct tpg_draw_params *params)
1718{
1719 unsigned left_pillar_width = 0;
1720 unsigned right_pillar_start = params->img_width;
1721
1722 params->wss_width = tpg->crop.left < tpg->src_width / 2 ?
1723 tpg->src_width / 2 - tpg->crop.left : 0;
1724 if (params->wss_width > tpg->crop.width)
1725 params->wss_width = tpg->crop.width;
1726 params->wss_width = tpg_hscale_div(tpg, p, params->wss_width);
1727 params->wss_random_offset =
1728 params->twopixsize * prandom_u32_max(tpg->src_width / 2);
1325 1729
1326 mv_hor_old = (mv_hor_old * tpg->scaled_width / tpg->src_width) & ~1;
1327 mv_hor_new = (mv_hor_new * tpg->scaled_width / tpg->src_width) & ~1;
1328 wss_width = tpg->crop.left < tpg->src_width / 2 ?
1329 tpg->src_width / 2 - tpg->crop.left : 0;
1330 if (wss_width > tpg->crop.width)
1331 wss_width = tpg->crop.width;
1332 wss_width = wss_width * tpg->scaled_width / tpg->src_width;
1333
1334 vbuf += tpg->compose.left * twopixsize / 2;
1335 line_offset = tpg->crop.left * tpg->scaled_width / tpg->src_width;
1336 line_offset = (line_offset & ~1) * twopixsize / 2;
1337 if (tpg->crop.left < tpg->border.left) { 1730 if (tpg->crop.left < tpg->border.left) {
1338 left_pillar_width = tpg->border.left - tpg->crop.left; 1731 left_pillar_width = tpg->border.left - tpg->crop.left;
1339 if (left_pillar_width > tpg->crop.width) 1732 if (left_pillar_width > tpg->crop.width)
1340 left_pillar_width = tpg->crop.width; 1733 left_pillar_width = tpg->crop.width;
1341 left_pillar_width = (left_pillar_width * tpg->scaled_width) / tpg->src_width; 1734 left_pillar_width = tpg_hscale_div(tpg, p, left_pillar_width);
1342 left_pillar_width = (left_pillar_width & ~1) * twopixsize / 2;
1343 } 1735 }
1344 if (tpg->crop.left + tpg->crop.width > tpg->border.left + tpg->border.width) { 1736 params->left_pillar_width = left_pillar_width;
1345 right_pillar_start = tpg->border.left + tpg->border.width - tpg->crop.left; 1737
1346 right_pillar_start = (right_pillar_start * tpg->scaled_width) / tpg->src_width; 1738 if (tpg->crop.left + tpg->crop.width >
1347 right_pillar_start = (right_pillar_start & ~1) * twopixsize / 2; 1739 tpg->border.left + tpg->border.width) {
1348 if (right_pillar_start > img_width) 1740 right_pillar_start =
1349 right_pillar_start = img_width; 1741 tpg->border.left + tpg->border.width - tpg->crop.left;
1742 right_pillar_start =
1743 tpg_hscale_div(tpg, p, right_pillar_start);
1744 if (right_pillar_start > params->img_width)
1745 right_pillar_start = params->img_width;
1350 } 1746 }
1747 params->right_pillar_start = right_pillar_start;
1351 1748
1352 f = tpg->field == (is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM); 1749 params->sav_eav_f = tpg->field ==
1750 (params->is_60hz ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
1751}
1353 1752
1354 for (h = 0; h < tpg->compose.height; h++) { 1753static void tpg_fill_plane_extras(const struct tpg_data *tpg,
1355 bool even; 1754 const struct tpg_draw_params *params,
1356 bool fill_blank = false; 1755 unsigned p, unsigned h, u8 *vbuf)
1357 unsigned frame_line; 1756{
1358 unsigned buf_line; 1757 unsigned twopixsize = params->twopixsize;
1359 unsigned pat_line_old; 1758 unsigned img_width = params->img_width;
1360 unsigned pat_line_new; 1759 unsigned frame_line = params->frame_line;
1361 u8 *linestart_older; 1760 const struct v4l2_rect *sq = &tpg->square;
1362 u8 *linestart_newer; 1761 const struct v4l2_rect *b = &tpg->border;
1363 u8 *linestart_top; 1762 const struct v4l2_rect *c = &tpg->crop;
1364 u8 *linestart_bottom; 1763
1365 1764 if (params->is_tv && !params->is_60hz &&
1366 frame_line = tpg_calc_frameline(tpg, src_y, tpg->field); 1765 frame_line == 0 && params->wss_width) {
1367 even = !(frame_line & 1); 1766 /*
1368 buf_line = tpg_calc_buffer_line(tpg, h, tpg->field); 1767 * Replace the first half of the top line of a 50 Hz frame
1369 src_y += int_part; 1768 * with random data to simulate a WSS signal.
1370 error += fract_part; 1769 */
1371 if (error >= tpg->compose.height) { 1770 u8 *wss = tpg->random_line[p] + params->wss_random_offset;
1372 error -= tpg->compose.height;
1373 src_y++;
1374 }
1375 1771
1376 if (h >= hmax) { 1772 memcpy(vbuf, wss, params->wss_width);
1377 if (hmax == tpg->compose.height) 1773 }
1378 continue; 1774
1379 if (!tpg->perc_fill_blank) 1775 if (tpg->show_border && frame_line >= b->top &&
1380 continue; 1776 frame_line < b->top + b->height) {
1381 fill_blank = true; 1777 unsigned bottom = b->top + b->height - 1;
1382 } 1778 unsigned left = params->left_pillar_width;
1779 unsigned right = params->right_pillar_start;
1383 1780
1384 if (tpg->vflip) 1781 if (frame_line == b->top || frame_line == b->top + 1 ||
1385 frame_line = tpg->src_height - frame_line - 1; 1782 frame_line == bottom || frame_line == bottom - 1) {
1386 1783 memcpy(vbuf + left, tpg->contrast_line[p],
1387 if (fill_blank) { 1784 right - left);
1388 linestart_older = tpg->contrast_line[p];
1389 linestart_newer = tpg->contrast_line[p];
1390 } else if (tpg->qual != TPG_QUAL_NOISE &&
1391 (frame_line < tpg->border.top ||
1392 frame_line >= tpg->border.top + tpg->border.height)) {
1393 linestart_older = tpg->black_line[p];
1394 linestart_newer = tpg->black_line[p];
1395 } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
1396 linestart_older = tpg->random_line[p] +
1397 twopixsize * prandom_u32_max(tpg->src_width / 2);
1398 linestart_newer = tpg->random_line[p] +
1399 twopixsize * prandom_u32_max(tpg->src_width / 2);
1400 } else { 1785 } else {
1401 pat_line_old = tpg_get_pat_line(tpg, 1786 if (b->left >= c->left &&
1402 (frame_line + mv_vert_old) % tpg->src_height); 1787 b->left < c->left + c->width)
1403 pat_line_new = tpg_get_pat_line(tpg, 1788 memcpy(vbuf + left,
1404 (frame_line + mv_vert_new) % tpg->src_height); 1789 tpg->contrast_line[p], twopixsize);
1405 linestart_older = tpg->lines[pat_line_old][p] + 1790 if (b->left + b->width > c->left &&
1406 mv_hor_old * twopixsize / 2; 1791 b->left + b->width <= c->left + c->width)
1407 linestart_newer = tpg->lines[pat_line_new][p] + 1792 memcpy(vbuf + right - twopixsize,
1408 mv_hor_new * twopixsize / 2; 1793 tpg->contrast_line[p], twopixsize);
1409 linestart_older += line_offset;
1410 linestart_newer += line_offset;
1411 } 1794 }
1412 if (is_60hz) { 1795 }
1413 linestart_top = linestart_newer; 1796 if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top &&
1414 linestart_bottom = linestart_older; 1797 frame_line < b->top + b->height) {
1415 } else { 1798 memcpy(vbuf, tpg->black_line[p], params->left_pillar_width);
1416 linestart_top = linestart_older; 1799 memcpy(vbuf + params->right_pillar_start, tpg->black_line[p],
1417 linestart_bottom = linestart_newer; 1800 img_width - params->right_pillar_start);
1801 }
1802 if (tpg->show_square && frame_line >= sq->top &&
1803 frame_line < sq->top + sq->height &&
1804 sq->left < c->left + c->width &&
1805 sq->left + sq->width >= c->left) {
1806 unsigned left = sq->left;
1807 unsigned width = sq->width;
1808
1809 if (c->left > left) {
1810 width -= c->left - left;
1811 left = c->left;
1418 } 1812 }
1813 if (c->left + c->width < left + width)
1814 width -= left + width - c->left - c->width;
1815 left -= c->left;
1816 left = tpg_hscale_div(tpg, p, left);
1817 width = tpg_hscale_div(tpg, p, width);
1818 memcpy(vbuf + left, tpg->contrast_line[p], width);
1819 }
1820 if (tpg->insert_sav) {
1821 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width / 3);
1822 u8 *p = vbuf + offset;
1823 unsigned vact = 0, hact = 0;
1824
1825 p[0] = 0xff;
1826 p[1] = 0;
1827 p[2] = 0;
1828 p[3] = 0x80 | (params->sav_eav_f << 6) |
1829 (vact << 5) | (hact << 4) |
1830 ((hact ^ vact) << 3) |
1831 ((hact ^ params->sav_eav_f) << 2) |
1832 ((params->sav_eav_f ^ vact) << 1) |
1833 (hact ^ vact ^ params->sav_eav_f);
1834 }
1835 if (tpg->insert_eav) {
1836 unsigned offset = tpg_hdiv(tpg, p, tpg->compose.width * 2 / 3);
1837 u8 *p = vbuf + offset;
1838 unsigned vact = 0, hact = 1;
1839
1840 p[0] = 0xff;
1841 p[1] = 0;
1842 p[2] = 0;
1843 p[3] = 0x80 | (params->sav_eav_f << 6) |
1844 (vact << 5) | (hact << 4) |
1845 ((hact ^ vact) << 3) |
1846 ((hact ^ params->sav_eav_f) << 2) |
1847 ((params->sav_eav_f ^ vact) << 1) |
1848 (hact ^ vact ^ params->sav_eav_f);
1849 }
1850}
1419 1851
1420 switch (tpg->field) { 1852static void tpg_fill_plane_pattern(const struct tpg_data *tpg,
1421 case V4L2_FIELD_INTERLACED: 1853 const struct tpg_draw_params *params,
1422 case V4L2_FIELD_INTERLACED_TB: 1854 unsigned p, unsigned h, u8 *vbuf)
1423 case V4L2_FIELD_SEQ_TB: 1855{
1424 case V4L2_FIELD_SEQ_BT: 1856 unsigned twopixsize = params->twopixsize;
1425 if (even) 1857 unsigned img_width = params->img_width;
1426 memcpy(vbuf + buf_line * stride, linestart_top, img_width); 1858 unsigned mv_hor_old = params->mv_hor_old;
1427 else 1859 unsigned mv_hor_new = params->mv_hor_new;
1428 memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); 1860 unsigned mv_vert_old = params->mv_vert_old;
1429 break; 1861 unsigned mv_vert_new = params->mv_vert_new;
1430 case V4L2_FIELD_INTERLACED_BT: 1862 unsigned frame_line = params->frame_line;
1431 if (even) 1863 unsigned frame_line_next = params->frame_line_next;
1432 memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); 1864 unsigned line_offset = tpg_hscale_div(tpg, p, tpg->crop.left);
1433 else 1865 bool even;
1434 memcpy(vbuf + buf_line * stride, linestart_top, img_width); 1866 bool fill_blank = false;
1435 break; 1867 unsigned pat_line_old;
1436 case V4L2_FIELD_TOP: 1868 unsigned pat_line_new;
1437 memcpy(vbuf + buf_line * stride, linestart_top, img_width); 1869 u8 *linestart_older;
1438 break; 1870 u8 *linestart_newer;
1439 case V4L2_FIELD_BOTTOM: 1871 u8 *linestart_top;
1440 memcpy(vbuf + buf_line * stride, linestart_bottom, img_width); 1872 u8 *linestart_bottom;
1441 break; 1873
1442 case V4L2_FIELD_NONE: 1874 even = !(frame_line & 1);
1443 default: 1875
1444 memcpy(vbuf + buf_line * stride, linestart_older, img_width); 1876 if (h >= params->hmax) {
1445 break; 1877 if (params->hmax == tpg->compose.height)
1446 } 1878 return;
1879 if (!tpg->perc_fill_blank)
1880 return;
1881 fill_blank = true;
1882 }
1447 1883
1448 if (is_tv && !is_60hz && frame_line == 0 && wss_width) { 1884 if (tpg->vflip) {
1449 /* 1885 frame_line = tpg->src_height - frame_line - 1;
1450 * Replace the first half of the top line of a 50 Hz frame 1886 frame_line_next = tpg->src_height - frame_line_next - 1;
1451 * with random data to simulate a WSS signal. 1887 }
1452 */ 1888
1453 u8 *wss = tpg->random_line[p] + 1889 if (fill_blank) {
1890 linestart_older = tpg->contrast_line[p];
1891 linestart_newer = tpg->contrast_line[p];
1892 } else if (tpg->qual != TPG_QUAL_NOISE &&
1893 (frame_line < tpg->border.top ||
1894 frame_line >= tpg->border.top + tpg->border.height)) {
1895 linestart_older = tpg->black_line[p];
1896 linestart_newer = tpg->black_line[p];
1897 } else if (tpg->pattern == TPG_PAT_NOISE || tpg->qual == TPG_QUAL_NOISE) {
1898 linestart_older = tpg->random_line[p] +
1899 twopixsize * prandom_u32_max(tpg->src_width / 2);
1900 linestart_newer = tpg->random_line[p] +
1454 twopixsize * prandom_u32_max(tpg->src_width / 2); 1901 twopixsize * prandom_u32_max(tpg->src_width / 2);
1902 } else {
1903 unsigned frame_line_old =
1904 (frame_line + mv_vert_old) % tpg->src_height;
1905 unsigned frame_line_new =
1906 (frame_line + mv_vert_new) % tpg->src_height;
1907 unsigned pat_line_next_old;
1908 unsigned pat_line_next_new;
1455 1909
1456 memcpy(vbuf + buf_line * stride, wss, wss_width * twopixsize / 2); 1910 pat_line_old = tpg_get_pat_line(tpg, frame_line_old);
1911 pat_line_new = tpg_get_pat_line(tpg, frame_line_new);
1912 linestart_older = tpg->lines[pat_line_old][p] + mv_hor_old;
1913 linestart_newer = tpg->lines[pat_line_new][p] + mv_hor_new;
1914
1915 if (tpg->vdownsampling[p] > 1 && frame_line != frame_line_next) {
1916 int avg_pat;
1917
1918 /*
1919 * Now decide whether we need to use downsampled_lines[].
1920 * That's necessary if the two lines use different patterns.
1921 */
1922 pat_line_next_old = tpg_get_pat_line(tpg,
1923 (frame_line_next + mv_vert_old) % tpg->src_height);
1924 pat_line_next_new = tpg_get_pat_line(tpg,
1925 (frame_line_next + mv_vert_new) % tpg->src_height);
1926
1927 switch (tpg->field) {
1928 case V4L2_FIELD_INTERLACED:
1929 case V4L2_FIELD_INTERLACED_BT:
1930 case V4L2_FIELD_INTERLACED_TB:
1931 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_new);
1932 if (avg_pat < 0)
1933 break;
1934 linestart_older = tpg->downsampled_lines[avg_pat][p] + mv_hor_old;
1935 linestart_newer = linestart_older;
1936 break;
1937 case V4L2_FIELD_NONE:
1938 case V4L2_FIELD_TOP:
1939 case V4L2_FIELD_BOTTOM:
1940 case V4L2_FIELD_SEQ_BT:
1941 case V4L2_FIELD_SEQ_TB:
1942 avg_pat = tpg_pattern_avg(tpg, pat_line_old, pat_line_next_old);
1943 if (avg_pat >= 0)
1944 linestart_older = tpg->downsampled_lines[avg_pat][p] +
1945 mv_hor_old;
1946 avg_pat = tpg_pattern_avg(tpg, pat_line_new, pat_line_next_new);
1947 if (avg_pat >= 0)
1948 linestart_newer = tpg->downsampled_lines[avg_pat][p] +
1949 mv_hor_new;
1950 break;
1951 }
1457 } 1952 }
1953 linestart_older += line_offset;
1954 linestart_newer += line_offset;
1955 }
1956 if (tpg->field_alternate) {
1957 linestart_top = linestart_bottom = linestart_older;
1958 } else if (params->is_60hz) {
1959 linestart_top = linestart_newer;
1960 linestart_bottom = linestart_older;
1961 } else {
1962 linestart_top = linestart_older;
1963 linestart_bottom = linestart_newer;
1964 }
1965
1966 switch (tpg->field) {
1967 case V4L2_FIELD_INTERLACED:
1968 case V4L2_FIELD_INTERLACED_TB:
1969 case V4L2_FIELD_SEQ_TB:
1970 case V4L2_FIELD_SEQ_BT:
1971 if (even)
1972 memcpy(vbuf, linestart_top, img_width);
1973 else
1974 memcpy(vbuf, linestart_bottom, img_width);
1975 break;
1976 case V4L2_FIELD_INTERLACED_BT:
1977 if (even)
1978 memcpy(vbuf, linestart_bottom, img_width);
1979 else
1980 memcpy(vbuf, linestart_top, img_width);
1981 break;
1982 case V4L2_FIELD_TOP:
1983 memcpy(vbuf, linestart_top, img_width);
1984 break;
1985 case V4L2_FIELD_BOTTOM:
1986 memcpy(vbuf, linestart_bottom, img_width);
1987 break;
1988 case V4L2_FIELD_NONE:
1989 default:
1990 memcpy(vbuf, linestart_older, img_width);
1991 break;
1458 } 1992 }
1993}
1994
1995void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
1996 unsigned p, u8 *vbuf)
1997{
1998 struct tpg_draw_params params;
1999 unsigned factor = V4L2_FIELD_HAS_T_OR_B(tpg->field) ? 2 : 1;
2000
2001 /* Coarse scaling with Bresenham */
2002 unsigned int_part = (tpg->crop.height / factor) / tpg->compose.height;
2003 unsigned fract_part = (tpg->crop.height / factor) % tpg->compose.height;
2004 unsigned src_y = 0;
2005 unsigned error = 0;
2006 unsigned h;
2007
2008 tpg_recalc(tpg);
2009
2010 params.is_tv = std;
2011 params.is_60hz = std & V4L2_STD_525_60;
2012 params.twopixsize = tpg->twopixelsize[p];
2013 params.img_width = tpg_hdiv(tpg, p, tpg->compose.width);
2014 params.stride = tpg->bytesperline[p];
2015 params.hmax = (tpg->compose.height * tpg->perc_fill) / 100;
2016
2017 tpg_fill_params_pattern(tpg, p, &params);
2018 tpg_fill_params_extras(tpg, p, &params);
2019
2020 vbuf += tpg_hdiv(tpg, p, tpg->compose.left);
1459 2021
1460 vbuf = orig_vbuf;
1461 vbuf += tpg->compose.left * twopixsize / 2;
1462 src_y = 0;
1463 error = 0;
1464 for (h = 0; h < tpg->compose.height; h++) { 2022 for (h = 0; h < tpg->compose.height; h++) {
1465 unsigned frame_line = tpg_calc_frameline(tpg, src_y, tpg->field); 2023 unsigned buf_line;
1466 unsigned buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
1467 const struct v4l2_rect *sq = &tpg->square;
1468 const struct v4l2_rect *b = &tpg->border;
1469 const struct v4l2_rect *c = &tpg->crop;
1470 2024
2025 params.frame_line = tpg_calc_frameline(tpg, src_y, tpg->field);
2026 params.frame_line_next = params.frame_line;
2027 buf_line = tpg_calc_buffer_line(tpg, h, tpg->field);
1471 src_y += int_part; 2028 src_y += int_part;
1472 error += fract_part; 2029 error += fract_part;
1473 if (error >= tpg->compose.height) { 2030 if (error >= tpg->compose.height) {
@@ -1475,80 +2032,61 @@ void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
1475 src_y++; 2032 src_y++;
1476 } 2033 }
1477 2034
1478 if (tpg->show_border && frame_line >= b->top && 2035 /*
1479 frame_line < b->top + b->height) { 2036 * For line-interleaved formats determine the 'plane'
1480 unsigned bottom = b->top + b->height - 1; 2037 * based on the buffer line.
1481 unsigned left = left_pillar_width; 2038 */
1482 unsigned right = right_pillar_start; 2039 if (tpg_g_interleaved(tpg))
2040 p = tpg_g_interleaved_plane(tpg, buf_line);
1483 2041
1484 if (frame_line == b->top || frame_line == b->top + 1 || 2042 if (tpg->vdownsampling[p] > 1) {
1485 frame_line == bottom || frame_line == bottom - 1) { 2043 /*
1486 memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p], 2044 * When doing vertical downsampling the field setting
1487 right - left); 2045 * matters: for SEQ_BT/TB we downsample each field
2046 * separately (i.e. lines 0+2 are combined, as are
2047 * lines 1+3), for the other field settings we combine
2048 * odd and even lines. Doing that for SEQ_BT/TB would
2049 * be really weird.
2050 */
2051 if (tpg->field == V4L2_FIELD_SEQ_BT ||
2052 tpg->field == V4L2_FIELD_SEQ_TB) {
2053 unsigned next_src_y = src_y;
2054
2055 if ((h & 3) >= 2)
2056 continue;
2057 next_src_y += int_part;
2058 if (error + fract_part >= tpg->compose.height)
2059 next_src_y++;
2060 params.frame_line_next =
2061 tpg_calc_frameline(tpg, next_src_y, tpg->field);
1488 } else { 2062 } else {
1489 if (b->left >= c->left && 2063 if (h & 1)
1490 b->left < c->left + c->width) 2064 continue;
1491 memcpy(vbuf + buf_line * stride + left, 2065 params.frame_line_next =
1492 tpg->contrast_line[p], twopixsize); 2066 tpg_calc_frameline(tpg, src_y, tpg->field);
1493 if (b->left + b->width > c->left &&
1494 b->left + b->width <= c->left + c->width)
1495 memcpy(vbuf + buf_line * stride + right - twopixsize,
1496 tpg->contrast_line[p], twopixsize);
1497 } 2067 }
2068
2069 buf_line /= tpg->vdownsampling[p];
1498 } 2070 }
1499 if (tpg->qual != TPG_QUAL_NOISE && frame_line >= b->top && 2071 tpg_fill_plane_pattern(tpg, &params, p, h,
1500 frame_line < b->top + b->height) { 2072 vbuf + buf_line * params.stride);
1501 memcpy(vbuf + buf_line * stride, tpg->black_line[p], left_pillar_width); 2073 tpg_fill_plane_extras(tpg, &params, p, h,
1502 memcpy(vbuf + buf_line * stride + right_pillar_start, tpg->black_line[p], 2074 vbuf + buf_line * params.stride);
1503 img_width - right_pillar_start); 2075 }
1504 } 2076}
1505 if (tpg->show_square && frame_line >= sq->top && 2077
1506 frame_line < sq->top + sq->height && 2078void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf)
1507 sq->left < c->left + c->width && 2079{
1508 sq->left + sq->width >= c->left) { 2080 unsigned offset = 0;
1509 unsigned left = sq->left; 2081 unsigned i;
1510 unsigned width = sq->width; 2082
1511 2083 if (tpg->buffers > 1) {
1512 if (c->left > left) { 2084 tpg_fill_plane_buffer(tpg, std, p, vbuf);
1513 width -= c->left - left; 2085 return;
1514 left = c->left; 2086 }
1515 } 2087
1516 if (c->left + c->width < left + width) 2088 for (i = 0; i < tpg_g_planes(tpg); i++) {
1517 width -= left + width - c->left - c->width; 2089 tpg_fill_plane_buffer(tpg, std, i, vbuf + offset);
1518 left -= c->left; 2090 offset += tpg_calc_plane_size(tpg, i);
1519 left = (left * tpg->scaled_width) / tpg->src_width;
1520 left = (left & ~1) * twopixsize / 2;
1521 width = (width * tpg->scaled_width) / tpg->src_width;
1522 width = (width & ~1) * twopixsize / 2;
1523 memcpy(vbuf + buf_line * stride + left, tpg->contrast_line[p], width);
1524 }
1525 if (tpg->insert_sav) {
1526 unsigned offset = (tpg->compose.width / 6) * twopixsize;
1527 u8 *p = vbuf + buf_line * stride + offset;
1528 unsigned vact = 0, hact = 0;
1529
1530 p[0] = 0xff;
1531 p[1] = 0;
1532 p[2] = 0;
1533 p[3] = 0x80 | (f << 6) | (vact << 5) | (hact << 4) |
1534 ((hact ^ vact) << 3) |
1535 ((hact ^ f) << 2) |
1536 ((f ^ vact) << 1) |
1537 (hact ^ vact ^ f);
1538 }
1539 if (tpg->insert_eav) {
1540 unsigned offset = (tpg->compose.width / 6) * 2 * twopixsize;
1541 u8 *p = vbuf + buf_line * stride + offset;
1542 unsigned vact = 0, hact = 1;
1543
1544 p[0] = 0xff;
1545 p[1] = 0;
1546 p[2] = 0;
1547 p[3] = 0x80 | (f << 6) | (vact << 5) | (hact << 4) |
1548 ((hact ^ vact) << 3) |
1549 ((hact ^ f) << 2) |
1550 ((f ^ vact) << 1) |
1551 (hact ^ vact ^ f);
1552 }
1553 } 2091 }
1554} 2092}
diff --git a/drivers/media/platform/vivid/vivid-tpg.h b/drivers/media/platform/vivid/vivid-tpg.h
index bd8b1c760b3f..a50cd2e2535b 100644
--- a/drivers/media/platform/vivid/vivid-tpg.h
+++ b/drivers/media/platform/vivid/vivid-tpg.h
@@ -41,7 +41,10 @@ enum tpg_pattern {
41 TPG_PAT_GREEN, 41 TPG_PAT_GREEN,
42 TPG_PAT_BLUE, 42 TPG_PAT_BLUE,
43 TPG_PAT_CHECKERS_16X16, 43 TPG_PAT_CHECKERS_16X16,
44 TPG_PAT_CHECKERS_2X2,
44 TPG_PAT_CHECKERS_1X1, 45 TPG_PAT_CHECKERS_1X1,
46 TPG_PAT_COLOR_CHECKERS_2X2,
47 TPG_PAT_COLOR_CHECKERS_1X1,
45 TPG_PAT_ALTERNATING_HLINES, 48 TPG_PAT_ALTERNATING_HLINES,
46 TPG_PAT_ALTERNATING_VLINES, 49 TPG_PAT_ALTERNATING_VLINES,
47 TPG_PAT_CROSS_1_PIXEL, 50 TPG_PAT_CROSS_1_PIXEL,
@@ -87,7 +90,7 @@ enum tpg_move_mode {
87 90
88extern const char * const tpg_aspect_strings[]; 91extern const char * const tpg_aspect_strings[];
89 92
90#define TPG_MAX_PLANES 2 93#define TPG_MAX_PLANES 3
91#define TPG_MAX_PAT_LINES 8 94#define TPG_MAX_PAT_LINES 8
92 95
93struct tpg_data { 96struct tpg_data {
@@ -98,6 +101,7 @@ struct tpg_data {
98 /* Scaled output frame size */ 101 /* Scaled output frame size */
99 unsigned scaled_width; 102 unsigned scaled_width;
100 u32 field; 103 u32 field;
104 bool field_alternate;
101 /* crop coordinates are frame-based */ 105 /* crop coordinates are frame-based */
102 struct v4l2_rect crop; 106 struct v4l2_rect crop;
103 /* compose coordinates are format-based */ 107 /* compose coordinates are format-based */
@@ -134,7 +138,16 @@ struct tpg_data {
134 enum tpg_pixel_aspect pix_aspect; 138 enum tpg_pixel_aspect pix_aspect;
135 unsigned rgb_range; 139 unsigned rgb_range;
136 unsigned real_rgb_range; 140 unsigned real_rgb_range;
141 unsigned buffers;
137 unsigned planes; 142 unsigned planes;
143 bool interleaved;
144 u8 vdownsampling[TPG_MAX_PLANES];
145 u8 hdownsampling[TPG_MAX_PLANES];
146 /*
147 * horizontal positions must be ANDed with this value to enforce
148 * correct boundaries for packed YUYV values.
149 */
150 unsigned hmask[TPG_MAX_PLANES];
138 /* Used to store the colors in native format, either RGB or YUV */ 151 /* Used to store the colors in native format, either RGB or YUV */
139 u8 colors[TPG_COLOR_MAX][3]; 152 u8 colors[TPG_COLOR_MAX][3];
140 u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8]; 153 u8 textfg[TPG_MAX_PLANES][8], textbg[TPG_MAX_PLANES][8];
@@ -168,6 +181,7 @@ struct tpg_data {
168 /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */ 181 /* Used to store TPG_MAX_PAT_LINES lines, each with up to two planes */
169 unsigned max_line_width; 182 unsigned max_line_width;
170 u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES]; 183 u8 *lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
184 u8 *downsampled_lines[TPG_MAX_PAT_LINES][TPG_MAX_PLANES];
171 u8 *random_line[TPG_MAX_PLANES]; 185 u8 *random_line[TPG_MAX_PLANES];
172 u8 *contrast_line[TPG_MAX_PLANES]; 186 u8 *contrast_line[TPG_MAX_PLANES];
173 u8 *black_line[TPG_MAX_PLANES]; 187 u8 *black_line[TPG_MAX_PLANES];
@@ -180,11 +194,15 @@ void tpg_reset_source(struct tpg_data *tpg, unsigned width, unsigned height,
180 u32 field); 194 u32 field);
181 195
182void tpg_set_font(const u8 *f); 196void tpg_set_font(const u8 *f);
183void tpg_gen_text(struct tpg_data *tpg, 197void tpg_gen_text(const struct tpg_data *tpg,
184 u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text); 198 u8 *basep[TPG_MAX_PLANES][2], int y, int x, char *text);
185void tpg_calc_text_basep(struct tpg_data *tpg, 199void tpg_calc_text_basep(struct tpg_data *tpg,
186 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf); 200 u8 *basep[TPG_MAX_PLANES][2], unsigned p, u8 *vbuf);
187void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std, unsigned p, u8 *vbuf); 201unsigned tpg_g_interleaved_plane(const struct tpg_data *tpg, unsigned buf_line);
202void tpg_fill_plane_buffer(struct tpg_data *tpg, v4l2_std_id std,
203 unsigned p, u8 *vbuf);
204void tpg_fillbuffer(struct tpg_data *tpg, v4l2_std_id std,
205 unsigned p, u8 *vbuf);
188bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc); 206bool tpg_s_fourcc(struct tpg_data *tpg, u32 fourcc);
189void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop, 207void tpg_s_crop_compose(struct tpg_data *tpg, const struct v4l2_rect *crop,
190 const struct v4l2_rect *compose); 208 const struct v4l2_rect *compose);
@@ -323,9 +341,19 @@ static inline u32 tpg_g_quantization(const struct tpg_data *tpg)
323 return tpg->quantization; 341 return tpg->quantization;
324} 342}
325 343
344static inline unsigned tpg_g_buffers(const struct tpg_data *tpg)
345{
346 return tpg->buffers;
347}
348
326static inline unsigned tpg_g_planes(const struct tpg_data *tpg) 349static inline unsigned tpg_g_planes(const struct tpg_data *tpg)
327{ 350{
328 return tpg->planes; 351 return tpg->interleaved ? 1 : tpg->planes;
352}
353
354static inline bool tpg_g_interleaved(const struct tpg_data *tpg)
355{
356 return tpg->interleaved;
329} 357}
330 358
331static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane) 359static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned plane)
@@ -333,6 +361,24 @@ static inline unsigned tpg_g_twopixelsize(const struct tpg_data *tpg, unsigned p
333 return tpg->twopixelsize[plane]; 361 return tpg->twopixelsize[plane];
334} 362}
335 363
364static inline unsigned tpg_hdiv(const struct tpg_data *tpg,
365 unsigned plane, unsigned x)
366{
367 return ((x / tpg->hdownsampling[plane]) & tpg->hmask[plane]) *
368 tpg->twopixelsize[plane] / 2;
369}
370
371static inline unsigned tpg_hscale(const struct tpg_data *tpg, unsigned x)
372{
373 return (x * tpg->scaled_width) / tpg->src_width;
374}
375
376static inline unsigned tpg_hscale_div(const struct tpg_data *tpg,
377 unsigned plane, unsigned x)
378{
379 return tpg_hdiv(tpg, plane, tpg_hscale(tpg, x));
380}
381
336static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane) 382static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned plane)
337{ 383{
338 return tpg->bytesperline[plane]; 384 return tpg->bytesperline[plane];
@@ -340,7 +386,60 @@ static inline unsigned tpg_g_bytesperline(const struct tpg_data *tpg, unsigned p
340 386
341static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl) 387static inline void tpg_s_bytesperline(struct tpg_data *tpg, unsigned plane, unsigned bpl)
342{ 388{
343 tpg->bytesperline[plane] = bpl; 389 unsigned p;
390
391 if (tpg->buffers > 1) {
392 tpg->bytesperline[plane] = bpl;
393 return;
394 }
395
396 for (p = 0; p < tpg_g_planes(tpg); p++) {
397 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
398
399 tpg->bytesperline[p] = plane_w / tpg->hdownsampling[p];
400 }
401}
402
403
404static inline unsigned tpg_g_line_width(const struct tpg_data *tpg, unsigned plane)
405{
406 unsigned w = 0;
407 unsigned p;
408
409 if (tpg->buffers > 1)
410 return tpg_g_bytesperline(tpg, plane);
411 for (p = 0; p < tpg_g_planes(tpg); p++) {
412 unsigned plane_w = tpg_g_bytesperline(tpg, p);
413
414 w += plane_w / tpg->vdownsampling[p];
415 }
416 return w;
417}
418
419static inline unsigned tpg_calc_line_width(const struct tpg_data *tpg,
420 unsigned plane, unsigned bpl)
421{
422 unsigned w = 0;
423 unsigned p;
424
425 if (tpg->buffers > 1)
426 return bpl;
427 for (p = 0; p < tpg_g_planes(tpg); p++) {
428 unsigned plane_w = bpl * tpg->twopixelsize[p] / tpg->twopixelsize[0];
429
430 plane_w /= tpg->hdownsampling[p];
431 w += plane_w / tpg->vdownsampling[p];
432 }
433 return w;
434}
435
436static inline unsigned tpg_calc_plane_size(const struct tpg_data *tpg, unsigned plane)
437{
438 if (plane >= tpg_g_planes(tpg))
439 return 0;
440
441 return tpg_g_bytesperline(tpg, plane) * tpg->buf_height /
442 tpg->vdownsampling[plane];
344} 443}
345 444
346static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h) 445static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
@@ -348,9 +447,10 @@ static inline void tpg_s_buf_height(struct tpg_data *tpg, unsigned h)
348 tpg->buf_height = h; 447 tpg->buf_height = h;
349} 448}
350 449
351static inline void tpg_s_field(struct tpg_data *tpg, unsigned field) 450static inline void tpg_s_field(struct tpg_data *tpg, unsigned field, bool alternate)
352{ 451{
353 tpg->field = field; 452 tpg->field = field;
453 tpg->field_alternate = alternate;
354} 454}
355 455
356static inline void tpg_s_perc_fill(struct tpg_data *tpg, 456static inline void tpg_s_perc_fill(struct tpg_data *tpg,
diff --git a/drivers/media/platform/vivid/vivid-vid-cap.c b/drivers/media/platform/vivid/vivid-vid-cap.c
index 867a29a6d18f..dab5990f45a0 100644
--- a/drivers/media/platform/vivid/vivid-vid-cap.c
+++ b/drivers/media/platform/vivid/vivid-vid-cap.c
@@ -42,20 +42,26 @@ static const struct vivid_fmt formats_ovl[] = {
42 { 42 {
43 .name = "RGB565 (LE)", 43 .name = "RGB565 (LE)",
44 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 44 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
45 .depth = 16, 45 .vdownsampling = { 1 },
46 .bit_depth = { 16 },
46 .planes = 1, 47 .planes = 1,
48 .buffers = 1,
47 }, 49 },
48 { 50 {
49 .name = "XRGB555 (LE)", 51 .name = "XRGB555 (LE)",
50 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ 52 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */
51 .depth = 16, 53 .vdownsampling = { 1 },
54 .bit_depth = { 16 },
52 .planes = 1, 55 .planes = 1,
56 .buffers = 1,
53 }, 57 },
54 { 58 {
55 .name = "ARGB555 (LE)", 59 .name = "ARGB555 (LE)",
56 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ 60 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
57 .depth = 16, 61 .vdownsampling = { 1 },
62 .bit_depth = { 16 },
58 .planes = 1, 63 .planes = 1,
64 .buffers = 1,
59 }, 65 },
60}; 66};
61 67
@@ -94,7 +100,7 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
94 unsigned sizes[], void *alloc_ctxs[]) 100 unsigned sizes[], void *alloc_ctxs[])
95{ 101{
96 struct vivid_dev *dev = vb2_get_drv_priv(vq); 102 struct vivid_dev *dev = vb2_get_drv_priv(vq);
97 unsigned planes = tpg_g_planes(&dev->tpg); 103 unsigned buffers = tpg_g_buffers(&dev->tpg);
98 unsigned h = dev->fmt_cap_rect.height; 104 unsigned h = dev->fmt_cap_rect.height;
99 unsigned p; 105 unsigned p;
100 106
@@ -127,39 +133,36 @@ static int vid_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
127 mp = &fmt->fmt.pix_mp; 133 mp = &fmt->fmt.pix_mp;
128 /* 134 /*
129 * Check if the number of planes in the specified format match 135 * Check if the number of planes in the specified format match
130 * the number of planes in the current format. You can't mix that. 136 * the number of buffers in the current format. You can't mix that.
131 */ 137 */
132 if (mp->num_planes != planes) 138 if (mp->num_planes != buffers)
133 return -EINVAL; 139 return -EINVAL;
134 vfmt = vivid_get_format(dev, mp->pixelformat); 140 vfmt = vivid_get_format(dev, mp->pixelformat);
135 for (p = 0; p < planes; p++) { 141 for (p = 0; p < buffers; p++) {
136 sizes[p] = mp->plane_fmt[p].sizeimage; 142 sizes[p] = mp->plane_fmt[p].sizeimage;
137 if (sizes[0] < tpg_g_bytesperline(&dev->tpg, 0) * h + 143 if (sizes[p] < tpg_g_line_width(&dev->tpg, p) * h +
138 vfmt->data_offset[p]) 144 vfmt->data_offset[p])
139 return -EINVAL; 145 return -EINVAL;
140 } 146 }
141 } else { 147 } else {
142 for (p = 0; p < planes; p++) 148 for (p = 0; p < buffers; p++)
143 sizes[p] = tpg_g_bytesperline(&dev->tpg, p) * h + 149 sizes[p] = tpg_g_line_width(&dev->tpg, p) * h +
144 dev->fmt_cap->data_offset[p]; 150 dev->fmt_cap->data_offset[p];
145 } 151 }
146 152
147 if (vq->num_buffers + *nbuffers < 2) 153 if (vq->num_buffers + *nbuffers < 2)
148 *nbuffers = 2 - vq->num_buffers; 154 *nbuffers = 2 - vq->num_buffers;
149 155
150 *nplanes = planes; 156 *nplanes = buffers;
151 157
152 /* 158 /*
153 * videobuf2-vmalloc allocator is context-less so no need to set 159 * videobuf2-vmalloc allocator is context-less so no need to set
154 * alloc_ctxs array. 160 * alloc_ctxs array.
155 */ 161 */
156 162
157 if (planes == 2) 163 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
158 dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, 164 for (p = 0; p < buffers; p++)
159 *nbuffers, sizes[0], sizes[1]); 165 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
160 else
161 dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__,
162 *nbuffers, sizes[0]);
163 166
164 return 0; 167 return 0;
165} 168}
@@ -168,7 +171,7 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
168{ 171{
169 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 172 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
170 unsigned long size; 173 unsigned long size;
171 unsigned planes = tpg_g_planes(&dev->tpg); 174 unsigned buffers = tpg_g_buffers(&dev->tpg);
172 unsigned p; 175 unsigned p;
173 176
174 dprintk(dev, 1, "%s\n", __func__); 177 dprintk(dev, 1, "%s\n", __func__);
@@ -184,13 +187,13 @@ static int vid_cap_buf_prepare(struct vb2_buffer *vb)
184 dev->buf_prepare_error = false; 187 dev->buf_prepare_error = false;
185 return -EINVAL; 188 return -EINVAL;
186 } 189 }
187 for (p = 0; p < planes; p++) { 190 for (p = 0; p < buffers; p++) {
188 size = tpg_g_bytesperline(&dev->tpg, p) * dev->fmt_cap_rect.height + 191 size = tpg_g_line_width(&dev->tpg, p) * dev->fmt_cap_rect.height +
189 dev->fmt_cap->data_offset[p]; 192 dev->fmt_cap->data_offset[p];
190 193
191 if (vb2_plane_size(vb, 0) < size) { 194 if (vb2_plane_size(vb, p) < size) {
192 dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n", 195 dprintk(dev, 1, "%s data will not fit into plane %u (%lu < %lu)\n",
193 __func__, p, vb2_plane_size(vb, 0), size); 196 __func__, p, vb2_plane_size(vb, p), size);
194 return -EINVAL; 197 return -EINVAL;
195 } 198 }
196 199
@@ -441,7 +444,7 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls)
441 */ 444 */
442 if (keep_controls || !dev->colorspace) 445 if (keep_controls || !dev->colorspace)
443 break; 446 break;
444 if (bt->standards & V4L2_DV_BT_STD_CEA861) { 447 if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
445 if (bt->width == 720 && bt->height <= 576) 448 if (bt->width == 720 && bt->height <= 576)
446 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 449 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
447 else 450 else
@@ -526,11 +529,11 @@ int vivid_g_fmt_vid_cap(struct file *file, void *priv,
526 mp->colorspace = vivid_colorspace_cap(dev); 529 mp->colorspace = vivid_colorspace_cap(dev);
527 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev); 530 mp->ycbcr_enc = vivid_ycbcr_enc_cap(dev);
528 mp->quantization = vivid_quantization_cap(dev); 531 mp->quantization = vivid_quantization_cap(dev);
529 mp->num_planes = dev->fmt_cap->planes; 532 mp->num_planes = dev->fmt_cap->buffers;
530 for (p = 0; p < mp->num_planes; p++) { 533 for (p = 0; p < mp->num_planes; p++) {
531 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p); 534 mp->plane_fmt[p].bytesperline = tpg_g_bytesperline(&dev->tpg, p);
532 mp->plane_fmt[p].sizeimage = 535 mp->plane_fmt[p].sizeimage =
533 mp->plane_fmt[p].bytesperline * mp->height + 536 tpg_g_line_width(&dev->tpg, p) * mp->height +
534 dev->fmt_cap->data_offset[p]; 537 dev->fmt_cap->data_offset[p];
535 } 538 }
536 return 0; 539 return 0;
@@ -596,18 +599,19 @@ int vivid_try_fmt_vid_cap(struct file *file, void *priv,
596 599
597 /* This driver supports custom bytesperline values */ 600 /* This driver supports custom bytesperline values */
598 601
599 /* Calculate the minimum supported bytesperline value */ 602 mp->num_planes = fmt->buffers;
600 bytesperline = (mp->width * fmt->depth) >> 3;
601 /* Calculate the maximum supported bytesperline value */
602 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->depth) >> 3;
603 mp->num_planes = fmt->planes;
604 for (p = 0; p < mp->num_planes; p++) { 603 for (p = 0; p < mp->num_planes; p++) {
604 /* Calculate the minimum supported bytesperline value */
605 bytesperline = (mp->width * fmt->bit_depth[p]) >> 3;
606 /* Calculate the maximum supported bytesperline value */
607 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[p]) >> 3;
608
605 if (pfmt[p].bytesperline > max_bpl) 609 if (pfmt[p].bytesperline > max_bpl)
606 pfmt[p].bytesperline = max_bpl; 610 pfmt[p].bytesperline = max_bpl;
607 if (pfmt[p].bytesperline < bytesperline) 611 if (pfmt[p].bytesperline < bytesperline)
608 pfmt[p].bytesperline = bytesperline; 612 pfmt[p].bytesperline = bytesperline;
609 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height + 613 pfmt[p].sizeimage = tpg_calc_line_width(&dev->tpg, p, pfmt[p].bytesperline) *
610 fmt->data_offset[p]; 614 mp->height + fmt->data_offset[p];
611 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 615 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
612 } 616 }
613 mp->colorspace = vivid_colorspace_cap(dev); 617 mp->colorspace = vivid_colorspace_cap(dev);
@@ -627,6 +631,7 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv,
627 struct vb2_queue *q = &dev->vb_vid_cap_q; 631 struct vb2_queue *q = &dev->vb_vid_cap_q;
628 int ret = vivid_try_fmt_vid_cap(file, priv, f); 632 int ret = vivid_try_fmt_vid_cap(file, priv, f);
629 unsigned factor = 1; 633 unsigned factor = 1;
634 unsigned p;
630 unsigned i; 635 unsigned i;
631 636
632 if (ret < 0) 637 if (ret < 0)
@@ -729,13 +734,15 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv,
729 dev->fmt_cap_rect.width = mp->width; 734 dev->fmt_cap_rect.width = mp->width;
730 dev->fmt_cap_rect.height = mp->height; 735 dev->fmt_cap_rect.height = mp->height;
731 tpg_s_buf_height(&dev->tpg, mp->height); 736 tpg_s_buf_height(&dev->tpg, mp->height);
732 tpg_s_bytesperline(&dev->tpg, 0, mp->plane_fmt[0].bytesperline); 737 tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
733 if (tpg_g_planes(&dev->tpg) > 1) 738 for (p = 0; p < tpg_g_buffers(&dev->tpg); p++)
734 tpg_s_bytesperline(&dev->tpg, 1, mp->plane_fmt[1].bytesperline); 739 tpg_s_bytesperline(&dev->tpg, p, mp->plane_fmt[p].bytesperline);
735 dev->field_cap = mp->field; 740 dev->field_cap = mp->field;
736 tpg_s_field(&dev->tpg, dev->field_cap); 741 if (dev->field_cap == V4L2_FIELD_ALTERNATE)
742 tpg_s_field(&dev->tpg, V4L2_FIELD_TOP, true);
743 else
744 tpg_s_field(&dev->tpg, dev->field_cap, false);
737 tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap); 745 tpg_s_crop_compose(&dev->tpg, &dev->crop_cap, &dev->compose_cap);
738 tpg_s_fourcc(&dev->tpg, dev->fmt_cap->fourcc);
739 if (vivid_is_sdtv_cap(dev)) 746 if (vivid_is_sdtv_cap(dev))
740 dev->tv_field_cap = mp->field; 747 dev->tv_field_cap = mp->field;
741 tpg_update_mv_step(&dev->tpg); 748 tpg_update_mv_step(&dev->tpg);
@@ -1012,8 +1019,12 @@ int vivid_vid_cap_cropcap(struct file *file, void *priv,
1012int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, 1019int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv,
1013 struct v4l2_fmtdesc *f) 1020 struct v4l2_fmtdesc *f)
1014{ 1021{
1022 struct vivid_dev *dev = video_drvdata(file);
1015 const struct vivid_fmt *fmt; 1023 const struct vivid_fmt *fmt;
1016 1024
1025 if (dev->multiplanar)
1026 return -ENOTTY;
1027
1017 if (f->index >= ARRAY_SIZE(formats_ovl)) 1028 if (f->index >= ARRAY_SIZE(formats_ovl))
1018 return -EINVAL; 1029 return -EINVAL;
1019 1030
@@ -1032,6 +1043,9 @@ int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
1032 struct v4l2_window *win = &f->fmt.win; 1043 struct v4l2_window *win = &f->fmt.win;
1033 unsigned clipcount = win->clipcount; 1044 unsigned clipcount = win->clipcount;
1034 1045
1046 if (dev->multiplanar)
1047 return -ENOTTY;
1048
1035 win->w.top = dev->overlay_cap_top; 1049 win->w.top = dev->overlay_cap_top;
1036 win->w.left = dev->overlay_cap_left; 1050 win->w.left = dev->overlay_cap_left;
1037 win->w.width = compose->width; 1051 win->w.width = compose->width;
@@ -1063,6 +1077,9 @@ int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
1063 struct v4l2_window *win = &f->fmt.win; 1077 struct v4l2_window *win = &f->fmt.win;
1064 int i, j; 1078 int i, j;
1065 1079
1080 if (dev->multiplanar)
1081 return -ENOTTY;
1082
1066 win->w.left = clamp_t(int, win->w.left, 1083 win->w.left = clamp_t(int, win->w.left,
1067 -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width); 1084 -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width);
1068 win->w.top = clamp_t(int, win->w.top, 1085 win->w.top = clamp_t(int, win->w.top,
@@ -1150,6 +1167,9 @@ int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i)
1150{ 1167{
1151 struct vivid_dev *dev = video_drvdata(file); 1168 struct vivid_dev *dev = video_drvdata(file);
1152 1169
1170 if (dev->multiplanar)
1171 return -ENOTTY;
1172
1153 if (i && dev->fb_vbase_cap == NULL) 1173 if (i && dev->fb_vbase_cap == NULL)
1154 return -EINVAL; 1174 return -EINVAL;
1155 1175
@@ -1169,6 +1189,9 @@ int vivid_vid_cap_g_fbuf(struct file *file, void *fh,
1169{ 1189{
1170 struct vivid_dev *dev = video_drvdata(file); 1190 struct vivid_dev *dev = video_drvdata(file);
1171 1191
1192 if (dev->multiplanar)
1193 return -ENOTTY;
1194
1172 *a = dev->fb_cap; 1195 *a = dev->fb_cap;
1173 a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING | 1196 a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING |
1174 V4L2_FBUF_CAP_LIST_CLIPPING; 1197 V4L2_FBUF_CAP_LIST_CLIPPING;
@@ -1185,6 +1208,9 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
1185 struct vivid_dev *dev = video_drvdata(file); 1208 struct vivid_dev *dev = video_drvdata(file);
1186 const struct vivid_fmt *fmt; 1209 const struct vivid_fmt *fmt;
1187 1210
1211 if (dev->multiplanar)
1212 return -ENOTTY;
1213
1188 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) 1214 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
1189 return -EPERM; 1215 return -EPERM;
1190 1216
@@ -1202,7 +1228,7 @@ int vivid_vid_cap_s_fbuf(struct file *file, void *fh,
1202 fmt = vivid_get_format(dev, a->fmt.pixelformat); 1228 fmt = vivid_get_format(dev, a->fmt.pixelformat);
1203 if (!fmt || !fmt->can_do_overlay) 1229 if (!fmt || !fmt->can_do_overlay)
1204 return -EINVAL; 1230 return -EINVAL;
1205 if (a->fmt.bytesperline < (a->fmt.width * fmt->depth) / 8) 1231 if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8)
1206 return -EINVAL; 1232 return -EINVAL;
1207 if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage) 1233 if (a->fmt.height * a->fmt.bytesperline < a->fmt.sizeimage)
1208 return -EINVAL; 1234 return -EINVAL;
@@ -1332,7 +1358,7 @@ int vidioc_s_input(struct file *file, void *priv, unsigned i)
1332 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 1358 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
1333 break; 1359 break;
1334 case HDMI: 1360 case HDMI:
1335 if (bt->standards & V4L2_DV_BT_STD_CEA861) { 1361 if (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) {
1336 if (dev->src_rect.width == 720 && dev->src_rect.height <= 576) 1362 if (dev->src_rect.width == 720 && dev->src_rect.height <= 576)
1337 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M); 1363 v4l2_ctrl_s_ctrl(dev->colorspace, VIVID_CS_170M);
1338 else 1364 else
@@ -1552,6 +1578,65 @@ int vivid_vid_cap_s_std(struct file *file, void *priv, v4l2_std_id id)
1552 return 0; 1578 return 0;
1553} 1579}
1554 1580
1581static void find_aspect_ratio(u32 width, u32 height,
1582 u32 *num, u32 *denom)
1583{
1584 if (!(height % 3) && ((height * 4 / 3) == width)) {
1585 *num = 4;
1586 *denom = 3;
1587 } else if (!(height % 9) && ((height * 16 / 9) == width)) {
1588 *num = 16;
1589 *denom = 9;
1590 } else if (!(height % 10) && ((height * 16 / 10) == width)) {
1591 *num = 16;
1592 *denom = 10;
1593 } else if (!(height % 4) && ((height * 5 / 4) == width)) {
1594 *num = 5;
1595 *denom = 4;
1596 } else if (!(height % 9) && ((height * 15 / 9) == width)) {
1597 *num = 15;
1598 *denom = 9;
1599 } else { /* default to 16:9 */
1600 *num = 16;
1601 *denom = 9;
1602 }
1603}
1604
1605static bool valid_cvt_gtf_timings(struct v4l2_dv_timings *timings)
1606{
1607 struct v4l2_bt_timings *bt = &timings->bt;
1608 u32 total_h_pixel;
1609 u32 total_v_lines;
1610 u32 h_freq;
1611
1612 if (!v4l2_valid_dv_timings(timings, &vivid_dv_timings_cap,
1613 NULL, NULL))
1614 return false;
1615
1616 total_h_pixel = V4L2_DV_BT_FRAME_WIDTH(bt);
1617 total_v_lines = V4L2_DV_BT_FRAME_HEIGHT(bt);
1618
1619 h_freq = (u32)bt->pixelclock / total_h_pixel;
1620
1621 if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_CVT)) {
1622 if (v4l2_detect_cvt(total_v_lines, h_freq, bt->vsync,
1623 bt->polarities, timings))
1624 return true;
1625 }
1626
1627 if (bt->standards == 0 || (bt->standards & V4L2_DV_BT_STD_GTF)) {
1628 struct v4l2_fract aspect_ratio;
1629
1630 find_aspect_ratio(bt->width, bt->height,
1631 &aspect_ratio.numerator,
1632 &aspect_ratio.denominator);
1633 if (v4l2_detect_gtf(total_v_lines, h_freq, bt->vsync,
1634 bt->polarities, aspect_ratio, timings))
1635 return true;
1636 }
1637 return false;
1638}
1639
1555int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh, 1640int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
1556 struct v4l2_dv_timings *timings) 1641 struct v4l2_dv_timings *timings)
1557{ 1642{
@@ -1559,13 +1644,16 @@ int vivid_vid_cap_s_dv_timings(struct file *file, void *_fh,
1559 1644
1560 if (!vivid_is_hdmi_cap(dev)) 1645 if (!vivid_is_hdmi_cap(dev))
1561 return -ENODATA; 1646 return -ENODATA;
1562 if (vb2_is_busy(&dev->vb_vid_cap_q))
1563 return -EBUSY;
1564 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, 1647 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
1565 0, NULL, NULL)) 1648 0, NULL, NULL) &&
1649 !valid_cvt_gtf_timings(timings))
1566 return -EINVAL; 1650 return -EINVAL;
1651
1567 if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap, 0)) 1652 if (v4l2_match_dv_timings(timings, &dev->dv_timings_cap, 0))
1568 return 0; 1653 return 0;
1654 if (vb2_is_busy(&dev->vb_vid_cap_q))
1655 return -EBUSY;
1656
1569 dev->dv_timings_cap = *timings; 1657 dev->dv_timings_cap = *timings;
1570 vivid_update_format_cap(dev, false); 1658 vivid_update_format_cap(dev, false);
1571 return 0; 1659 return 0;
@@ -1663,18 +1751,14 @@ int vidioc_enum_frameintervals(struct file *file, void *priv,
1663 return -EINVAL; 1751 return -EINVAL;
1664 1752
1665 if (!vivid_is_webcam(dev)) { 1753 if (!vivid_is_webcam(dev)) {
1666 static const struct v4l2_fract step = { 1, 1 };
1667
1668 if (fival->index) 1754 if (fival->index)
1669 return -EINVAL; 1755 return -EINVAL;
1670 if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM) 1756 if (fival->width < MIN_WIDTH || fival->width > MAX_WIDTH * MAX_ZOOM)
1671 return -EINVAL; 1757 return -EINVAL;
1672 if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM) 1758 if (fival->height < MIN_HEIGHT || fival->height > MAX_HEIGHT * MAX_ZOOM)
1673 return -EINVAL; 1759 return -EINVAL;
1674 fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; 1760 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
1675 fival->stepwise.min = tpf_min; 1761 fival->discrete = dev->timeperframe_vid_cap;
1676 fival->stepwise.max = tpf_max;
1677 fival->stepwise.step = step;
1678 return 0; 1762 return 0;
1679 } 1763 }
1680 1764
diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c
index 6bef1e6d6788..aa446271ad34 100644
--- a/drivers/media/platform/vivid/vivid-vid-common.c
+++ b/drivers/media/platform/vivid/vivid-vid-common.c
@@ -33,8 +33,9 @@ const struct v4l2_dv_timings_cap vivid_dv_timings_cap = {
33 .type = V4L2_DV_BT_656_1120, 33 .type = V4L2_DV_BT_656_1120,
34 /* keep this initialization for compatibility with GCC < 4.4.6 */ 34 /* keep this initialization for compatibility with GCC < 4.4.6 */
35 .reserved = { 0 }, 35 .reserved = { 0 },
36 V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 25000000, 600000000, 36 V4L2_INIT_BT_TIMINGS(0, MAX_WIDTH, 0, MAX_HEIGHT, 14000000, 775000000,
37 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT, 37 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
38 V4L2_DV_BT_STD_CVT | V4L2_DV_BT_STD_GTF,
38 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED) 39 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED)
39}; 40};
40 41
@@ -46,145 +47,435 @@ struct vivid_fmt vivid_formats[] = {
46 { 47 {
47 .name = "4:2:2, packed, YUYV", 48 .name = "4:2:2, packed, YUYV",
48 .fourcc = V4L2_PIX_FMT_YUYV, 49 .fourcc = V4L2_PIX_FMT_YUYV,
49 .depth = 16, 50 .vdownsampling = { 1 },
51 .bit_depth = { 16 },
50 .is_yuv = true, 52 .is_yuv = true,
51 .planes = 1, 53 .planes = 1,
52 .data_offset = { PLANE0_DATA_OFFSET, 0 }, 54 .buffers = 1,
55 .data_offset = { PLANE0_DATA_OFFSET },
53 }, 56 },
54 { 57 {
55 .name = "4:2:2, packed, UYVY", 58 .name = "4:2:2, packed, UYVY",
56 .fourcc = V4L2_PIX_FMT_UYVY, 59 .fourcc = V4L2_PIX_FMT_UYVY,
57 .depth = 16, 60 .vdownsampling = { 1 },
61 .bit_depth = { 16 },
58 .is_yuv = true, 62 .is_yuv = true,
59 .planes = 1, 63 .planes = 1,
64 .buffers = 1,
60 }, 65 },
61 { 66 {
62 .name = "4:2:2, packed, YVYU", 67 .name = "4:2:2, packed, YVYU",
63 .fourcc = V4L2_PIX_FMT_YVYU, 68 .fourcc = V4L2_PIX_FMT_YVYU,
64 .depth = 16, 69 .vdownsampling = { 1 },
70 .bit_depth = { 16 },
65 .is_yuv = true, 71 .is_yuv = true,
66 .planes = 1, 72 .planes = 1,
73 .buffers = 1,
67 }, 74 },
68 { 75 {
69 .name = "4:2:2, packed, VYUY", 76 .name = "4:2:2, packed, VYUY",
70 .fourcc = V4L2_PIX_FMT_VYUY, 77 .fourcc = V4L2_PIX_FMT_VYUY,
71 .depth = 16, 78 .vdownsampling = { 1 },
79 .bit_depth = { 16 },
80 .is_yuv = true,
81 .planes = 1,
82 .buffers = 1,
83 },
84 {
85 .name = "YUV 4:2:2 triplanar",
86 .fourcc = V4L2_PIX_FMT_YUV422P,
87 .vdownsampling = { 1, 1, 1 },
88 .bit_depth = { 8, 4, 4 },
89 .is_yuv = true,
90 .planes = 3,
91 .buffers = 1,
92 },
93 {
94 .name = "YUV 4:2:0 triplanar",
95 .fourcc = V4L2_PIX_FMT_YUV420,
96 .vdownsampling = { 1, 2, 2 },
97 .bit_depth = { 8, 4, 4 },
98 .is_yuv = true,
99 .planes = 3,
100 .buffers = 1,
101 },
102 {
103 .name = "YVU 4:2:0 triplanar",
104 .fourcc = V4L2_PIX_FMT_YVU420,
105 .vdownsampling = { 1, 2, 2 },
106 .bit_depth = { 8, 4, 4 },
107 .is_yuv = true,
108 .planes = 3,
109 .buffers = 1,
110 },
111 {
112 .name = "YUV 4:2:0 biplanar",
113 .fourcc = V4L2_PIX_FMT_NV12,
114 .vdownsampling = { 1, 2 },
115 .bit_depth = { 8, 8 },
116 .is_yuv = true,
117 .planes = 2,
118 .buffers = 1,
119 },
120 {
121 .name = "YVU 4:2:0 biplanar",
122 .fourcc = V4L2_PIX_FMT_NV21,
123 .vdownsampling = { 1, 2 },
124 .bit_depth = { 8, 8 },
125 .is_yuv = true,
126 .planes = 2,
127 .buffers = 1,
128 },
129 {
130 .name = "YUV 4:2:2 biplanar",
131 .fourcc = V4L2_PIX_FMT_NV16,
132 .vdownsampling = { 1, 1 },
133 .bit_depth = { 8, 8 },
134 .is_yuv = true,
135 .planes = 2,
136 .buffers = 1,
137 },
138 {
139 .name = "YVU 4:2:2 biplanar",
140 .fourcc = V4L2_PIX_FMT_NV61,
141 .vdownsampling = { 1, 1 },
142 .bit_depth = { 8, 8 },
143 .is_yuv = true,
144 .planes = 2,
145 .buffers = 1,
146 },
147 {
148 .name = "YUV 4:4:4 biplanar",
149 .fourcc = V4L2_PIX_FMT_NV24,
150 .vdownsampling = { 1, 1 },
151 .bit_depth = { 8, 16 },
152 .is_yuv = true,
153 .planes = 2,
154 .buffers = 1,
155 },
156 {
157 .name = "YVU 4:4:4 biplanar",
158 .fourcc = V4L2_PIX_FMT_NV42,
159 .vdownsampling = { 1, 1 },
160 .bit_depth = { 8, 16 },
161 .is_yuv = true,
162 .planes = 2,
163 .buffers = 1,
164 },
165 {
166 .name = "YUV555 (LE)",
167 .fourcc = V4L2_PIX_FMT_YUV555, /* uuuvvvvv ayyyyyuu */
168 .vdownsampling = { 1 },
169 .bit_depth = { 16 },
170 .planes = 1,
171 .buffers = 1,
172 .alpha_mask = 0x8000,
173 },
174 {
175 .name = "YUV565 (LE)",
176 .fourcc = V4L2_PIX_FMT_YUV565, /* uuuvvvvv yyyyyuuu */
177 .vdownsampling = { 1 },
178 .bit_depth = { 16 },
179 .planes = 1,
180 .buffers = 1,
181 },
182 {
183 .name = "YUV444",
184 .fourcc = V4L2_PIX_FMT_YUV444, /* uuuuvvvv aaaayyyy */
185 .vdownsampling = { 1 },
186 .bit_depth = { 16 },
187 .planes = 1,
188 .buffers = 1,
189 .alpha_mask = 0xf000,
190 },
191 {
192 .name = "YUV32 (LE)",
193 .fourcc = V4L2_PIX_FMT_YUV32, /* ayuv */
194 .vdownsampling = { 1 },
195 .bit_depth = { 32 },
196 .planes = 1,
197 .buffers = 1,
198 .alpha_mask = 0x000000ff,
199 },
200 {
201 .name = "Monochrome",
202 .fourcc = V4L2_PIX_FMT_GREY,
203 .vdownsampling = { 1 },
204 .bit_depth = { 8 },
72 .is_yuv = true, 205 .is_yuv = true,
73 .planes = 1, 206 .planes = 1,
207 .buffers = 1,
208 },
209 {
210 .name = "RGB332",
211 .fourcc = V4L2_PIX_FMT_RGB332, /* rrrgggbb */
212 .vdownsampling = { 1 },
213 .bit_depth = { 8 },
214 .planes = 1,
215 .buffers = 1,
74 }, 216 },
75 { 217 {
76 .name = "RGB565 (LE)", 218 .name = "RGB565 (LE)",
77 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ 219 .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
78 .depth = 16, 220 .vdownsampling = { 1 },
221 .bit_depth = { 16 },
79 .planes = 1, 222 .planes = 1,
223 .buffers = 1,
80 .can_do_overlay = true, 224 .can_do_overlay = true,
81 }, 225 },
82 { 226 {
83 .name = "RGB565 (BE)", 227 .name = "RGB565 (BE)",
84 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */ 228 .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
85 .depth = 16, 229 .vdownsampling = { 1 },
230 .bit_depth = { 16 },
86 .planes = 1, 231 .planes = 1,
232 .buffers = 1,
87 .can_do_overlay = true, 233 .can_do_overlay = true,
88 }, 234 },
89 { 235 {
236 .name = "RGB444",
237 .fourcc = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */
238 .vdownsampling = { 1 },
239 .bit_depth = { 16 },
240 .planes = 1,
241 .buffers = 1,
242 },
243 {
244 .name = "XRGB444",
245 .fourcc = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */
246 .vdownsampling = { 1 },
247 .bit_depth = { 16 },
248 .planes = 1,
249 .buffers = 1,
250 },
251 {
252 .name = "ARGB444",
253 .fourcc = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */
254 .vdownsampling = { 1 },
255 .bit_depth = { 16 },
256 .planes = 1,
257 .buffers = 1,
258 .alpha_mask = 0x00f0,
259 },
260 {
90 .name = "RGB555 (LE)", 261 .name = "RGB555 (LE)",
91 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */ 262 .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb xrrrrrgg */
92 .depth = 16, 263 .vdownsampling = { 1 },
264 .bit_depth = { 16 },
93 .planes = 1, 265 .planes = 1,
266 .buffers = 1,
94 .can_do_overlay = true, 267 .can_do_overlay = true,
95 }, 268 },
96 { 269 {
97 .name = "XRGB555 (LE)", 270 .name = "XRGB555 (LE)",
98 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ 271 .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb xrrrrrgg */
99 .depth = 16, 272 .vdownsampling = { 1 },
273 .bit_depth = { 16 },
100 .planes = 1, 274 .planes = 1,
275 .buffers = 1,
101 .can_do_overlay = true, 276 .can_do_overlay = true,
102 }, 277 },
103 { 278 {
104 .name = "ARGB555 (LE)", 279 .name = "ARGB555 (LE)",
105 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ 280 .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */
106 .depth = 16, 281 .vdownsampling = { 1 },
282 .bit_depth = { 16 },
107 .planes = 1, 283 .planes = 1,
284 .buffers = 1,
108 .can_do_overlay = true, 285 .can_do_overlay = true,
109 .alpha_mask = 0x8000, 286 .alpha_mask = 0x8000,
110 }, 287 },
111 { 288 {
112 .name = "RGB555 (BE)", 289 .name = "RGB555 (BE)",
113 .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */ 290 .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */
114 .depth = 16, 291 .vdownsampling = { 1 },
292 .bit_depth = { 16 },
115 .planes = 1, 293 .planes = 1,
116 .can_do_overlay = true, 294 .buffers = 1,
295 },
296 {
297 .name = "XRGB555 (BE)",
298 .fourcc = V4L2_PIX_FMT_XRGB555X, /* xrrrrrgg gggbbbbb */
299 .vdownsampling = { 1 },
300 .bit_depth = { 16 },
301 .planes = 1,
302 .buffers = 1,
303 },
304 {
305 .name = "ARGB555 (BE)",
306 .fourcc = V4L2_PIX_FMT_ARGB555X, /* arrrrrgg gggbbbbb */
307 .vdownsampling = { 1 },
308 .bit_depth = { 16 },
309 .planes = 1,
310 .buffers = 1,
311 .alpha_mask = 0x0080,
117 }, 312 },
118 { 313 {
119 .name = "RGB24 (LE)", 314 .name = "RGB24 (LE)",
120 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */ 315 .fourcc = V4L2_PIX_FMT_RGB24, /* rgb */
121 .depth = 24, 316 .vdownsampling = { 1 },
317 .bit_depth = { 24 },
122 .planes = 1, 318 .planes = 1,
319 .buffers = 1,
123 }, 320 },
124 { 321 {
125 .name = "RGB24 (BE)", 322 .name = "RGB24 (BE)",
126 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */ 323 .fourcc = V4L2_PIX_FMT_BGR24, /* bgr */
127 .depth = 24, 324 .vdownsampling = { 1 },
325 .bit_depth = { 24 },
128 .planes = 1, 326 .planes = 1,
327 .buffers = 1,
328 },
329 {
330 .name = "BGR666",
331 .fourcc = V4L2_PIX_FMT_BGR666, /* bbbbbbgg ggggrrrr rrxxxxxx */
332 .vdownsampling = { 1 },
333 .bit_depth = { 32 },
334 .planes = 1,
335 .buffers = 1,
129 }, 336 },
130 { 337 {
131 .name = "RGB32 (LE)", 338 .name = "RGB32 (LE)",
132 .fourcc = V4L2_PIX_FMT_RGB32, /* argb */ 339 .fourcc = V4L2_PIX_FMT_RGB32, /* xrgb */
133 .depth = 32, 340 .vdownsampling = { 1 },
341 .bit_depth = { 32 },
134 .planes = 1, 342 .planes = 1,
343 .buffers = 1,
135 }, 344 },
136 { 345 {
137 .name = "RGB32 (BE)", 346 .name = "RGB32 (BE)",
138 .fourcc = V4L2_PIX_FMT_BGR32, /* bgra */ 347 .fourcc = V4L2_PIX_FMT_BGR32, /* bgrx */
139 .depth = 32, 348 .vdownsampling = { 1 },
349 .bit_depth = { 32 },
140 .planes = 1, 350 .planes = 1,
351 .buffers = 1,
141 }, 352 },
142 { 353 {
143 .name = "XRGB32 (LE)", 354 .name = "XRGB32 (LE)",
144 .fourcc = V4L2_PIX_FMT_XRGB32, /* argb */ 355 .fourcc = V4L2_PIX_FMT_XRGB32, /* xrgb */
145 .depth = 32, 356 .vdownsampling = { 1 },
357 .bit_depth = { 32 },
146 .planes = 1, 358 .planes = 1,
359 .buffers = 1,
147 }, 360 },
148 { 361 {
149 .name = "XRGB32 (BE)", 362 .name = "XRGB32 (BE)",
150 .fourcc = V4L2_PIX_FMT_XBGR32, /* bgra */ 363 .fourcc = V4L2_PIX_FMT_XBGR32, /* bgrx */
151 .depth = 32, 364 .vdownsampling = { 1 },
365 .bit_depth = { 32 },
152 .planes = 1, 366 .planes = 1,
367 .buffers = 1,
153 }, 368 },
154 { 369 {
155 .name = "ARGB32 (LE)", 370 .name = "ARGB32 (LE)",
156 .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */ 371 .fourcc = V4L2_PIX_FMT_ARGB32, /* argb */
157 .depth = 32, 372 .vdownsampling = { 1 },
373 .bit_depth = { 32 },
158 .planes = 1, 374 .planes = 1,
375 .buffers = 1,
159 .alpha_mask = 0x000000ff, 376 .alpha_mask = 0x000000ff,
160 }, 377 },
161 { 378 {
162 .name = "ARGB32 (BE)", 379 .name = "ARGB32 (BE)",
163 .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */ 380 .fourcc = V4L2_PIX_FMT_ABGR32, /* bgra */
164 .depth = 32, 381 .vdownsampling = { 1 },
382 .bit_depth = { 32 },
165 .planes = 1, 383 .planes = 1,
384 .buffers = 1,
166 .alpha_mask = 0xff000000, 385 .alpha_mask = 0xff000000,
167 }, 386 },
168 { 387 {
169 .name = "4:2:2, planar, YUV", 388 .name = "Bayer BG/GR",
389 .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */
390 .vdownsampling = { 1 },
391 .bit_depth = { 8 },
392 .planes = 1,
393 .buffers = 1,
394 },
395 {
396 .name = "Bayer GB/RG",
397 .fourcc = V4L2_PIX_FMT_SGBRG8, /* Bayer GB/RG */
398 .vdownsampling = { 1 },
399 .bit_depth = { 8 },
400 .planes = 1,
401 .buffers = 1,
402 },
403 {
404 .name = "Bayer GR/BG",
405 .fourcc = V4L2_PIX_FMT_SGRBG8, /* Bayer GR/BG */
406 .vdownsampling = { 1 },
407 .bit_depth = { 8 },
408 .planes = 1,
409 .buffers = 1,
410 },
411 {
412 .name = "Bayer RG/GB",
413 .fourcc = V4L2_PIX_FMT_SRGGB8, /* Bayer RG/GB */
414 .vdownsampling = { 1 },
415 .bit_depth = { 8 },
416 .planes = 1,
417 .buffers = 1,
418 },
419 {
420 .name = "4:2:2, biplanar, YUV",
170 .fourcc = V4L2_PIX_FMT_NV16M, 421 .fourcc = V4L2_PIX_FMT_NV16M,
171 .depth = 8, 422 .vdownsampling = { 1, 1 },
423 .bit_depth = { 8, 8 },
172 .is_yuv = true, 424 .is_yuv = true,
173 .planes = 2, 425 .planes = 2,
426 .buffers = 2,
174 .data_offset = { PLANE0_DATA_OFFSET, 0 }, 427 .data_offset = { PLANE0_DATA_OFFSET, 0 },
175 }, 428 },
176 { 429 {
177 .name = "4:2:2, planar, YVU", 430 .name = "4:2:2, biplanar, YVU",
178 .fourcc = V4L2_PIX_FMT_NV61M, 431 .fourcc = V4L2_PIX_FMT_NV61M,
179 .depth = 8, 432 .vdownsampling = { 1, 1 },
433 .bit_depth = { 8, 8 },
180 .is_yuv = true, 434 .is_yuv = true,
181 .planes = 2, 435 .planes = 2,
436 .buffers = 2,
182 .data_offset = { 0, PLANE0_DATA_OFFSET }, 437 .data_offset = { 0, PLANE0_DATA_OFFSET },
183 }, 438 },
439 {
440 .name = "4:2:0, triplanar, YUV",
441 .fourcc = V4L2_PIX_FMT_YUV420M,
442 .vdownsampling = { 1, 2, 2 },
443 .bit_depth = { 8, 4, 4 },
444 .is_yuv = true,
445 .planes = 3,
446 .buffers = 3,
447 },
448 {
449 .name = "4:2:0, triplanar, YVU",
450 .fourcc = V4L2_PIX_FMT_YVU420M,
451 .vdownsampling = { 1, 2, 2 },
452 .bit_depth = { 8, 4, 4 },
453 .is_yuv = true,
454 .planes = 3,
455 .buffers = 3,
456 },
457 {
458 .name = "4:2:0, biplanar, YUV",
459 .fourcc = V4L2_PIX_FMT_NV12M,
460 .vdownsampling = { 1, 2 },
461 .bit_depth = { 8, 8 },
462 .is_yuv = true,
463 .planes = 2,
464 .buffers = 2,
465 },
466 {
467 .name = "4:2:0, biplanar, YVU",
468 .fourcc = V4L2_PIX_FMT_NV21M,
469 .vdownsampling = { 1, 2 },
470 .bit_depth = { 8, 8 },
471 .is_yuv = true,
472 .planes = 2,
473 .buffers = 2,
474 },
184}; 475};
185 476
186/* There are 2 multiplanar formats in the list */ 477/* There are 6 multiplanar formats in the list */
187#define VIVID_MPLANAR_FORMATS 2 478#define VIVID_MPLANAR_FORMATS 6
188 479
189const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat) 480const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
190{ 481{
@@ -194,7 +485,7 @@ const struct vivid_fmt *vivid_get_format(struct vivid_dev *dev, u32 pixelformat)
194 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) { 485 for (k = 0; k < ARRAY_SIZE(vivid_formats); k++) {
195 fmt = &vivid_formats[k]; 486 fmt = &vivid_formats[k];
196 if (fmt->fourcc == pixelformat) 487 if (fmt->fourcc == pixelformat)
197 if (fmt->planes == 1 || dev->multiplanar) 488 if (fmt->buffers == 1 || dev->multiplanar)
198 return fmt; 489 return fmt;
199 } 490 }
200 491
@@ -210,6 +501,13 @@ bool vivid_vid_can_loop(struct vivid_dev *dev)
210 return false; 501 return false;
211 if (dev->field_cap != dev->field_out) 502 if (dev->field_cap != dev->field_out)
212 return false; 503 return false;
504 /*
505 * While this can be supported, it is just too much work
506 * to actually implement.
507 */
508 if (dev->field_cap == V4L2_FIELD_SEQ_TB ||
509 dev->field_cap == V4L2_FIELD_SEQ_BT)
510 return false;
213 if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) { 511 if (vivid_is_svid_cap(dev) && vivid_is_svid_out(dev)) {
214 if (!(dev->std_cap & V4L2_STD_525_60) != 512 if (!(dev->std_cap & V4L2_STD_525_60) !=
215 !(dev->std_out & V4L2_STD_525_60)) 513 !(dev->std_out & V4L2_STD_525_60))
@@ -397,6 +695,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
397 unsigned w = r->width; 695 unsigned w = r->width;
398 unsigned h = r->height; 696 unsigned h = r->height;
399 697
698 /* sanitize w and h in case someone passes ~0 as the value */
699 w &= 0xffff;
700 h &= 0xffff;
400 if (!(flags & V4L2_SEL_FLAG_LE)) { 701 if (!(flags & V4L2_SEL_FLAG_LE)) {
401 w++; 702 w++;
402 h++; 703 h++;
@@ -421,8 +722,9 @@ int vivid_vid_adjust_sel(unsigned flags, struct v4l2_rect *r)
421 r->top = 0; 722 r->top = 0;
422 if (r->left < 0) 723 if (r->left < 0)
423 r->left = 0; 724 r->left = 0;
424 r->left &= ~1; 725 /* sanitize left and top in case someone passes ~0 as the value */
425 r->top &= ~1; 726 r->left &= 0xfffe;
727 r->top &= 0xfffe;
426 if (r->left + w > MAX_WIDTH) 728 if (r->left + w > MAX_WIDTH)
427 r->left = MAX_WIDTH - w; 729 r->left = MAX_WIDTH - w;
428 if (r->top + h > MAX_HEIGHT) 730 if (r->top + h > MAX_HEIGHT)
diff --git a/drivers/media/platform/vivid/vivid-vid-out.c b/drivers/media/platform/vivid/vivid-vid-out.c
index 39ff79f6aa67..0af43dc7715c 100644
--- a/drivers/media/platform/vivid/vivid-vid-out.c
+++ b/drivers/media/platform/vivid/vivid-vid-out.c
@@ -36,9 +36,14 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
36 unsigned sizes[], void *alloc_ctxs[]) 36 unsigned sizes[], void *alloc_ctxs[])
37{ 37{
38 struct vivid_dev *dev = vb2_get_drv_priv(vq); 38 struct vivid_dev *dev = vb2_get_drv_priv(vq);
39 unsigned planes = dev->fmt_out->planes; 39 const struct vivid_fmt *vfmt = dev->fmt_out;
40 unsigned planes = vfmt->buffers;
40 unsigned h = dev->fmt_out_rect.height; 41 unsigned h = dev->fmt_out_rect.height;
41 unsigned size = dev->bytesperline_out[0] * h; 42 unsigned size = dev->bytesperline_out[0] * h;
43 unsigned p;
44
45 for (p = vfmt->buffers; p < vfmt->planes; p++)
46 size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p];
42 47
43 if (dev->field_out == V4L2_FIELD_ALTERNATE) { 48 if (dev->field_out == V4L2_FIELD_ALTERNATE) {
44 /* 49 /*
@@ -74,21 +79,16 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
74 if (mp->num_planes != planes) 79 if (mp->num_planes != planes)
75 return -EINVAL; 80 return -EINVAL;
76 sizes[0] = mp->plane_fmt[0].sizeimage; 81 sizes[0] = mp->plane_fmt[0].sizeimage;
77 if (planes == 2) { 82 if (sizes[0] < size)
78 sizes[1] = mp->plane_fmt[1].sizeimage;
79 if (sizes[0] < dev->bytesperline_out[0] * h ||
80 sizes[1] < dev->bytesperline_out[1] * h)
81 return -EINVAL;
82 } else if (sizes[0] < size) {
83 return -EINVAL; 83 return -EINVAL;
84 for (p = 1; p < planes; p++) {
85 sizes[p] = mp->plane_fmt[p].sizeimage;
86 if (sizes[p] < dev->bytesperline_out[p] * h)
87 return -EINVAL;
84 } 88 }
85 } else { 89 } else {
86 if (planes == 2) { 90 for (p = 0; p < planes; p++)
87 sizes[0] = dev->bytesperline_out[0] * h; 91 sizes[p] = p ? dev->bytesperline_out[p] * h : size;
88 sizes[1] = dev->bytesperline_out[1] * h;
89 } else {
90 sizes[0] = size;
91 }
92 } 92 }
93 93
94 if (vq->num_buffers + *nbuffers < 2) 94 if (vq->num_buffers + *nbuffers < 2)
@@ -101,12 +101,9 @@ static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *f
101 * alloc_ctxs array. 101 * alloc_ctxs array.
102 */ 102 */
103 103
104 if (planes == 2) 104 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers);
105 dprintk(dev, 1, "%s, count=%d, sizes=%u, %u\n", __func__, 105 for (p = 0; p < planes; p++)
106 *nbuffers, sizes[0], sizes[1]); 106 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]);
107 else
108 dprintk(dev, 1, "%s, count=%d, size=%u\n", __func__,
109 *nbuffers, sizes[0]);
110 return 0; 107 return 0;
111} 108}
112 109
@@ -114,7 +111,7 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)
114{ 111{
115 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 112 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
116 unsigned long size; 113 unsigned long size;
117 unsigned planes = dev->fmt_out->planes; 114 unsigned planes;
118 unsigned p; 115 unsigned p;
119 116
120 dprintk(dev, 1, "%s\n", __func__); 117 dprintk(dev, 1, "%s\n", __func__);
@@ -122,6 +119,8 @@ static int vid_out_buf_prepare(struct vb2_buffer *vb)
122 if (WARN_ON(NULL == dev->fmt_out)) 119 if (WARN_ON(NULL == dev->fmt_out))
123 return -EINVAL; 120 return -EINVAL;
124 121
122 planes = dev->fmt_out->planes;
123
125 if (dev->buf_prepare_error) { 124 if (dev->buf_prepare_error) {
126 /* 125 /*
127 * Error injection: test what happens if buf_prepare() returns 126 * Error injection: test what happens if buf_prepare() returns
@@ -220,7 +219,7 @@ const struct vb2_ops vivid_vid_out_qops = {
220void vivid_update_format_out(struct vivid_dev *dev) 219void vivid_update_format_out(struct vivid_dev *dev)
221{ 220{
222 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 221 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt;
223 unsigned size; 222 unsigned size, p;
224 223
225 switch (dev->output_type[dev->output]) { 224 switch (dev->output_type[dev->output]) {
226 case SVID: 225 case SVID:
@@ -249,7 +248,7 @@ void vivid_update_format_out(struct vivid_dev *dev)
249 dev->field_out = V4L2_FIELD_ALTERNATE; 248 dev->field_out = V4L2_FIELD_ALTERNATE;
250 else 249 else
251 dev->field_out = V4L2_FIELD_NONE; 250 dev->field_out = V4L2_FIELD_NONE;
252 if (!dev->dvi_d_out && (bt->standards & V4L2_DV_BT_STD_CEA861)) { 251 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
253 if (bt->width == 720 && bt->height <= 576) 252 if (bt->width == 720 && bt->height <= 576)
254 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 253 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M;
255 else 254 else
@@ -267,9 +266,9 @@ void vivid_update_format_out(struct vivid_dev *dev)
267 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) 266 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out))
268 dev->crop_out.height /= 2; 267 dev->crop_out.height /= 2;
269 dev->fmt_out_rect = dev->crop_out; 268 dev->fmt_out_rect = dev->crop_out;
270 dev->bytesperline_out[0] = (dev->sink_rect.width * dev->fmt_out->depth) / 8; 269 for (p = 0; p < dev->fmt_out->planes; p++)
271 if (dev->fmt_out->planes == 2) 270 dev->bytesperline_out[p] =
272 dev->bytesperline_out[1] = (dev->sink_rect.width * dev->fmt_out->depth) / 8; 271 (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8;
273} 272}
274 273
275/* Map the field to something that is valid for the current output */ 274/* Map the field to something that is valid for the current output */
@@ -313,21 +312,28 @@ int vivid_g_fmt_vid_out(struct file *file, void *priv,
313{ 312{
314 struct vivid_dev *dev = video_drvdata(file); 313 struct vivid_dev *dev = video_drvdata(file);
315 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 314 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp;
315 const struct vivid_fmt *fmt = dev->fmt_out;
316 unsigned p; 316 unsigned p;
317 317
318 mp->width = dev->fmt_out_rect.width; 318 mp->width = dev->fmt_out_rect.width;
319 mp->height = dev->fmt_out_rect.height; 319 mp->height = dev->fmt_out_rect.height;
320 mp->field = dev->field_out; 320 mp->field = dev->field_out;
321 mp->pixelformat = dev->fmt_out->fourcc; 321 mp->pixelformat = fmt->fourcc;
322 mp->colorspace = dev->colorspace_out; 322 mp->colorspace = dev->colorspace_out;
323 mp->ycbcr_enc = dev->ycbcr_enc_out; 323 mp->ycbcr_enc = dev->ycbcr_enc_out;
324 mp->quantization = dev->quantization_out; 324 mp->quantization = dev->quantization_out;
325 mp->num_planes = dev->fmt_out->planes; 325 mp->num_planes = fmt->buffers;
326 for (p = 0; p < mp->num_planes; p++) { 326 for (p = 0; p < mp->num_planes; p++) {
327 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; 327 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p];
328 mp->plane_fmt[p].sizeimage = 328 mp->plane_fmt[p].sizeimage =
329 mp->plane_fmt[p].bytesperline * mp->height; 329 mp->plane_fmt[p].bytesperline * mp->height;
330 } 330 }
331 for (p = fmt->buffers; p < fmt->planes; p++) {
332 unsigned stride = dev->bytesperline_out[p];
333
334 mp->plane_fmt[0].sizeimage +=
335 (stride * mp->height) / fmt->vdownsampling[p];
336 }
331 return 0; 337 return 0;
332} 338}
333 339
@@ -386,10 +392,10 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
386 /* This driver supports custom bytesperline values */ 392 /* This driver supports custom bytesperline values */
387 393
388 /* Calculate the minimum supported bytesperline value */ 394 /* Calculate the minimum supported bytesperline value */
389 bytesperline = (mp->width * fmt->depth) >> 3; 395 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3;
390 /* Calculate the maximum supported bytesperline value */ 396 /* Calculate the maximum supported bytesperline value */
391 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->depth) >> 3; 397 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3;
392 mp->num_planes = fmt->planes; 398 mp->num_planes = fmt->buffers;
393 for (p = 0; p < mp->num_planes; p++) { 399 for (p = 0; p < mp->num_planes; p++) {
394 if (pfmt[p].bytesperline > max_bpl) 400 if (pfmt[p].bytesperline > max_bpl)
395 pfmt[p].bytesperline = max_bpl; 401 pfmt[p].bytesperline = max_bpl;
@@ -398,11 +404,14 @@ int vivid_try_fmt_vid_out(struct file *file, void *priv,
398 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; 404 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height;
399 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 405 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved));
400 } 406 }
407 for (p = fmt->buffers; p < fmt->planes; p++)
408 pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) /
409 (fmt->bit_depth[0] * fmt->vdownsampling[p]);
401 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 410 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
402 mp->quantization = V4L2_QUANTIZATION_DEFAULT; 411 mp->quantization = V4L2_QUANTIZATION_DEFAULT;
403 if (vivid_is_svid_out(dev)) { 412 if (vivid_is_svid_out(dev)) {
404 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 413 mp->colorspace = V4L2_COLORSPACE_SMPTE170M;
405 } else if (dev->dvi_d_out || !(bt->standards & V4L2_DV_BT_STD_CEA861)) { 414 } else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) {
406 mp->colorspace = V4L2_COLORSPACE_SRGB; 415 mp->colorspace = V4L2_COLORSPACE_SRGB;
407 if (dev->dvi_d_out) 416 if (dev->dvi_d_out)
408 mp->quantization = V4L2_QUANTIZATION_LIM_RANGE; 417 mp->quantization = V4L2_QUANTIZATION_LIM_RANGE;
@@ -429,6 +438,7 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv,
429 struct vb2_queue *q = &dev->vb_vid_out_q; 438 struct vb2_queue *q = &dev->vb_vid_out_q;
430 int ret = vivid_try_fmt_vid_out(file, priv, f); 439 int ret = vivid_try_fmt_vid_out(file, priv, f);
431 unsigned factor = 1; 440 unsigned factor = 1;
441 unsigned p;
432 442
433 if (ret < 0) 443 if (ret < 0)
434 return ret; 444 return ret;
@@ -524,9 +534,12 @@ int vivid_s_fmt_vid_out(struct file *file, void *priv,
524 534
525 dev->fmt_out_rect.width = mp->width; 535 dev->fmt_out_rect.width = mp->width;
526 dev->fmt_out_rect.height = mp->height; 536 dev->fmt_out_rect.height = mp->height;
527 dev->bytesperline_out[0] = mp->plane_fmt[0].bytesperline; 537 for (p = 0; p < mp->num_planes; p++)
528 if (mp->num_planes > 1) 538 dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline;
529 dev->bytesperline_out[1] = mp->plane_fmt[1].bytesperline; 539 for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++)
540 dev->bytesperline_out[p] =
541 (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) /
542 dev->fmt_out->bit_depth[0];
530 dev->field_out = mp->field; 543 dev->field_out = mp->field;
531 if (vivid_is_svid_out(dev)) 544 if (vivid_is_svid_out(dev))
532 dev->tv_field_out = mp->field; 545 dev->tv_field_out = mp->field;
@@ -1114,13 +1127,13 @@ int vivid_vid_out_s_dv_timings(struct file *file, void *_fh,
1114 1127
1115 if (!vivid_is_hdmi_out(dev)) 1128 if (!vivid_is_hdmi_out(dev))
1116 return -ENODATA; 1129 return -ENODATA;
1117 if (vb2_is_busy(&dev->vb_vid_out_q))
1118 return -EBUSY;
1119 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, 1130 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap,
1120 0, NULL, NULL)) 1131 0, NULL, NULL))
1121 return -EINVAL; 1132 return -EINVAL;
1122 if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0)) 1133 if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0))
1123 return 0; 1134 return 0;
1135 if (vb2_is_busy(&dev->vb_vid_out_q))
1136 return -EBUSY;
1124 dev->dv_timings_out = *timings; 1137 dev->dv_timings_out = *timings;
1125 vivid_update_format_out(dev); 1138 vivid_update_format_out(dev);
1126 return 0; 1139 return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_bru.c b/drivers/media/platform/vsp1/vsp1_bru.c
index 401e2b77a0b6..7dd763311c0f 100644
--- a/drivers/media/platform/vsp1/vsp1_bru.c
+++ b/drivers/media/platform/vsp1/vsp1_bru.c
@@ -183,13 +183,14 @@ static int bru_s_stream(struct v4l2_subdev *subdev, int enable)
183 */ 183 */
184 184
185static int bru_enum_mbus_code(struct v4l2_subdev *subdev, 185static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
186 struct v4l2_subdev_fh *fh, 186 struct v4l2_subdev_pad_config *cfg,
187 struct v4l2_subdev_mbus_code_enum *code) 187 struct v4l2_subdev_mbus_code_enum *code)
188{ 188{
189 static const unsigned int codes[] = { 189 static const unsigned int codes[] = {
190 MEDIA_BUS_FMT_ARGB8888_1X32, 190 MEDIA_BUS_FMT_ARGB8888_1X32,
191 MEDIA_BUS_FMT_AYUV8_1X32, 191 MEDIA_BUS_FMT_AYUV8_1X32,
192 }; 192 };
193 struct vsp1_bru *bru = to_bru(subdev);
193 struct v4l2_mbus_framefmt *format; 194 struct v4l2_mbus_framefmt *format;
194 195
195 if (code->pad == BRU_PAD_SINK(0)) { 196 if (code->pad == BRU_PAD_SINK(0)) {
@@ -201,7 +202,8 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
201 if (code->index) 202 if (code->index)
202 return -EINVAL; 203 return -EINVAL;
203 204
204 format = v4l2_subdev_get_try_format(fh, BRU_PAD_SINK(0)); 205 format = vsp1_entity_get_pad_format(&bru->entity, cfg,
206 BRU_PAD_SINK(0), code->which);
205 code->code = format->code; 207 code->code = format->code;
206 } 208 }
207 209
@@ -209,7 +211,7 @@ static int bru_enum_mbus_code(struct v4l2_subdev *subdev,
209} 211}
210 212
211static int bru_enum_frame_size(struct v4l2_subdev *subdev, 213static int bru_enum_frame_size(struct v4l2_subdev *subdev,
212 struct v4l2_subdev_fh *fh, 214 struct v4l2_subdev_pad_config *cfg,
213 struct v4l2_subdev_frame_size_enum *fse) 215 struct v4l2_subdev_frame_size_enum *fse)
214{ 216{
215 if (fse->index) 217 if (fse->index)
@@ -228,12 +230,12 @@ static int bru_enum_frame_size(struct v4l2_subdev *subdev,
228} 230}
229 231
230static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru, 232static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru,
231 struct v4l2_subdev_fh *fh, 233 struct v4l2_subdev_pad_config *cfg,
232 unsigned int pad, u32 which) 234 unsigned int pad, u32 which)
233{ 235{
234 switch (which) { 236 switch (which) {
235 case V4L2_SUBDEV_FORMAT_TRY: 237 case V4L2_SUBDEV_FORMAT_TRY:
236 return v4l2_subdev_get_try_crop(fh, pad); 238 return v4l2_subdev_get_try_crop(&bru->entity.subdev, cfg, pad);
237 case V4L2_SUBDEV_FORMAT_ACTIVE: 239 case V4L2_SUBDEV_FORMAT_ACTIVE:
238 return &bru->inputs[pad].compose; 240 return &bru->inputs[pad].compose;
239 default: 241 default:
@@ -241,18 +243,18 @@ static struct v4l2_rect *bru_get_compose(struct vsp1_bru *bru,
241 } 243 }
242} 244}
243 245
244static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 246static int bru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
245 struct v4l2_subdev_format *fmt) 247 struct v4l2_subdev_format *fmt)
246{ 248{
247 struct vsp1_bru *bru = to_bru(subdev); 249 struct vsp1_bru *bru = to_bru(subdev);
248 250
249 fmt->format = *vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad, 251 fmt->format = *vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
250 fmt->which); 252 fmt->which);
251 253
252 return 0; 254 return 0;
253} 255}
254 256
255static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh, 257static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_pad_config *cfg,
256 unsigned int pad, struct v4l2_mbus_framefmt *fmt, 258 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
257 enum v4l2_subdev_format_whence which) 259 enum v4l2_subdev_format_whence which)
258{ 260{
@@ -268,7 +270,7 @@ static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh,
268 270
269 default: 271 default:
270 /* The BRU can't perform format conversion. */ 272 /* The BRU can't perform format conversion. */
271 format = vsp1_entity_get_pad_format(&bru->entity, fh, 273 format = vsp1_entity_get_pad_format(&bru->entity, cfg,
272 BRU_PAD_SINK(0), which); 274 BRU_PAD_SINK(0), which);
273 fmt->code = format->code; 275 fmt->code = format->code;
274 break; 276 break;
@@ -280,15 +282,15 @@ static void bru_try_format(struct vsp1_bru *bru, struct v4l2_subdev_fh *fh,
280 fmt->colorspace = V4L2_COLORSPACE_SRGB; 282 fmt->colorspace = V4L2_COLORSPACE_SRGB;
281} 283}
282 284
283static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 285static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
284 struct v4l2_subdev_format *fmt) 286 struct v4l2_subdev_format *fmt)
285{ 287{
286 struct vsp1_bru *bru = to_bru(subdev); 288 struct vsp1_bru *bru = to_bru(subdev);
287 struct v4l2_mbus_framefmt *format; 289 struct v4l2_mbus_framefmt *format;
288 290
289 bru_try_format(bru, fh, fmt->pad, &fmt->format, fmt->which); 291 bru_try_format(bru, cfg, fmt->pad, &fmt->format, fmt->which);
290 292
291 format = vsp1_entity_get_pad_format(&bru->entity, fh, fmt->pad, 293 format = vsp1_entity_get_pad_format(&bru->entity, cfg, fmt->pad,
292 fmt->which); 294 fmt->which);
293 *format = fmt->format; 295 *format = fmt->format;
294 296
@@ -296,7 +298,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
296 if (fmt->pad != BRU_PAD_SOURCE) { 298 if (fmt->pad != BRU_PAD_SOURCE) {
297 struct v4l2_rect *compose; 299 struct v4l2_rect *compose;
298 300
299 compose = bru_get_compose(bru, fh, fmt->pad, fmt->which); 301 compose = bru_get_compose(bru, cfg, fmt->pad, fmt->which);
300 compose->left = 0; 302 compose->left = 0;
301 compose->top = 0; 303 compose->top = 0;
302 compose->width = format->width; 304 compose->width = format->width;
@@ -308,7 +310,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
308 unsigned int i; 310 unsigned int i;
309 311
310 for (i = 0; i <= BRU_PAD_SOURCE; ++i) { 312 for (i = 0; i <= BRU_PAD_SOURCE; ++i) {
311 format = vsp1_entity_get_pad_format(&bru->entity, fh, 313 format = vsp1_entity_get_pad_format(&bru->entity, cfg,
312 i, fmt->which); 314 i, fmt->which);
313 format->code = fmt->format.code; 315 format->code = fmt->format.code;
314 } 316 }
@@ -318,7 +320,7 @@ static int bru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
318} 320}
319 321
320static int bru_get_selection(struct v4l2_subdev *subdev, 322static int bru_get_selection(struct v4l2_subdev *subdev,
321 struct v4l2_subdev_fh *fh, 323 struct v4l2_subdev_pad_config *cfg,
322 struct v4l2_subdev_selection *sel) 324 struct v4l2_subdev_selection *sel)
323{ 325{
324 struct vsp1_bru *bru = to_bru(subdev); 326 struct vsp1_bru *bru = to_bru(subdev);
@@ -335,7 +337,7 @@ static int bru_get_selection(struct v4l2_subdev *subdev,
335 return 0; 337 return 0;
336 338
337 case V4L2_SEL_TGT_COMPOSE: 339 case V4L2_SEL_TGT_COMPOSE:
338 sel->r = *bru_get_compose(bru, fh, sel->pad, sel->which); 340 sel->r = *bru_get_compose(bru, cfg, sel->pad, sel->which);
339 return 0; 341 return 0;
340 342
341 default: 343 default:
@@ -344,7 +346,7 @@ static int bru_get_selection(struct v4l2_subdev *subdev,
344} 346}
345 347
346static int bru_set_selection(struct v4l2_subdev *subdev, 348static int bru_set_selection(struct v4l2_subdev *subdev,
347 struct v4l2_subdev_fh *fh, 349 struct v4l2_subdev_pad_config *cfg,
348 struct v4l2_subdev_selection *sel) 350 struct v4l2_subdev_selection *sel)
349{ 351{
350 struct vsp1_bru *bru = to_bru(subdev); 352 struct vsp1_bru *bru = to_bru(subdev);
@@ -360,7 +362,7 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
360 /* The compose rectangle top left corner must be inside the output 362 /* The compose rectangle top left corner must be inside the output
361 * frame. 363 * frame.
362 */ 364 */
363 format = vsp1_entity_get_pad_format(&bru->entity, fh, BRU_PAD_SOURCE, 365 format = vsp1_entity_get_pad_format(&bru->entity, cfg, BRU_PAD_SOURCE,
364 sel->which); 366 sel->which);
365 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1); 367 sel->r.left = clamp_t(unsigned int, sel->r.left, 0, format->width - 1);
366 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1); 368 sel->r.top = clamp_t(unsigned int, sel->r.top, 0, format->height - 1);
@@ -368,12 +370,12 @@ static int bru_set_selection(struct v4l2_subdev *subdev,
368 /* Scaling isn't supported, the compose rectangle size must be identical 370 /* Scaling isn't supported, the compose rectangle size must be identical
369 * to the sink format size. 371 * to the sink format size.
370 */ 372 */
371 format = vsp1_entity_get_pad_format(&bru->entity, fh, sel->pad, 373 format = vsp1_entity_get_pad_format(&bru->entity, cfg, sel->pad,
372 sel->which); 374 sel->which);
373 sel->r.width = format->width; 375 sel->r.width = format->width;
374 sel->r.height = format->height; 376 sel->r.height = format->height;
375 377
376 compose = bru_get_compose(bru, fh, sel->pad, sel->which); 378 compose = bru_get_compose(bru, cfg, sel->pad, sel->which);
377 *compose = sel->r; 379 *compose = sel->r;
378 380
379 return 0; 381 return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c
index 79af71d5e270..a453bb4ddd37 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.c
+++ b/drivers/media/platform/vsp1/vsp1_entity.c
@@ -63,12 +63,12 @@ int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming)
63 63
64struct v4l2_mbus_framefmt * 64struct v4l2_mbus_framefmt *
65vsp1_entity_get_pad_format(struct vsp1_entity *entity, 65vsp1_entity_get_pad_format(struct vsp1_entity *entity,
66 struct v4l2_subdev_fh *fh, 66 struct v4l2_subdev_pad_config *cfg,
67 unsigned int pad, u32 which) 67 unsigned int pad, u32 which)
68{ 68{
69 switch (which) { 69 switch (which) {
70 case V4L2_SUBDEV_FORMAT_TRY: 70 case V4L2_SUBDEV_FORMAT_TRY:
71 return v4l2_subdev_get_try_format(fh, pad); 71 return v4l2_subdev_get_try_format(&entity->subdev, cfg, pad);
72 case V4L2_SUBDEV_FORMAT_ACTIVE: 72 case V4L2_SUBDEV_FORMAT_ACTIVE:
73 return &entity->formats[pad]; 73 return &entity->formats[pad];
74 default: 74 default:
@@ -79,14 +79,14 @@ vsp1_entity_get_pad_format(struct vsp1_entity *entity,
79/* 79/*
80 * vsp1_entity_init_formats - Initialize formats on all pads 80 * vsp1_entity_init_formats - Initialize formats on all pads
81 * @subdev: V4L2 subdevice 81 * @subdev: V4L2 subdevice
82 * @fh: V4L2 subdev file handle 82 * @cfg: V4L2 subdev pad configuration
83 * 83 *
84 * Initialize all pad formats with default values. If fh is not NULL, try 84 * Initialize all pad formats with default values. If cfg is not NULL, try
85 * formats are initialized on the file handle. Otherwise active formats are 85 * formats are initialized on the file handle. Otherwise active formats are
86 * initialized on the device. 86 * initialized on the device.
87 */ 87 */
88void vsp1_entity_init_formats(struct v4l2_subdev *subdev, 88void vsp1_entity_init_formats(struct v4l2_subdev *subdev,
89 struct v4l2_subdev_fh *fh) 89 struct v4l2_subdev_pad_config *cfg)
90{ 90{
91 struct v4l2_subdev_format format; 91 struct v4l2_subdev_format format;
92 unsigned int pad; 92 unsigned int pad;
@@ -95,17 +95,17 @@ void vsp1_entity_init_formats(struct v4l2_subdev *subdev,
95 memset(&format, 0, sizeof(format)); 95 memset(&format, 0, sizeof(format));
96 96
97 format.pad = pad; 97 format.pad = pad;
98 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY 98 format.which = cfg ? V4L2_SUBDEV_FORMAT_TRY
99 : V4L2_SUBDEV_FORMAT_ACTIVE; 99 : V4L2_SUBDEV_FORMAT_ACTIVE;
100 100
101 v4l2_subdev_call(subdev, pad, set_fmt, fh, &format); 101 v4l2_subdev_call(subdev, pad, set_fmt, cfg, &format);
102 } 102 }
103} 103}
104 104
105static int vsp1_entity_open(struct v4l2_subdev *subdev, 105static int vsp1_entity_open(struct v4l2_subdev *subdev,
106 struct v4l2_subdev_fh *fh) 106 struct v4l2_subdev_fh *fh)
107{ 107{
108 vsp1_entity_init_formats(subdev, fh); 108 vsp1_entity_init_formats(subdev, fh->pad);
109 109
110 return 0; 110 return 0;
111} 111}
diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h
index aa20aaa58208..62c768d1c6aa 100644
--- a/drivers/media/platform/vsp1/vsp1_entity.h
+++ b/drivers/media/platform/vsp1/vsp1_entity.h
@@ -91,10 +91,10 @@ extern const struct media_entity_operations vsp1_media_ops;
91 91
92struct v4l2_mbus_framefmt * 92struct v4l2_mbus_framefmt *
93vsp1_entity_get_pad_format(struct vsp1_entity *entity, 93vsp1_entity_get_pad_format(struct vsp1_entity *entity,
94 struct v4l2_subdev_fh *fh, 94 struct v4l2_subdev_pad_config *cfg,
95 unsigned int pad, u32 which); 95 unsigned int pad, u32 which);
96void vsp1_entity_init_formats(struct v4l2_subdev *subdev, 96void vsp1_entity_init_formats(struct v4l2_subdev *subdev,
97 struct v4l2_subdev_fh *fh); 97 struct v4l2_subdev_pad_config *cfg);
98 98
99bool vsp1_entity_is_streaming(struct vsp1_entity *entity); 99bool vsp1_entity_is_streaming(struct vsp1_entity *entity);
100int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming); 100int vsp1_entity_set_streaming(struct vsp1_entity *entity, bool streaming);
diff --git a/drivers/media/platform/vsp1/vsp1_hsit.c b/drivers/media/platform/vsp1/vsp1_hsit.c
index 0bc0471746c9..8ffb817ae525 100644
--- a/drivers/media/platform/vsp1/vsp1_hsit.c
+++ b/drivers/media/platform/vsp1/vsp1_hsit.c
@@ -55,7 +55,7 @@ static int hsit_s_stream(struct v4l2_subdev *subdev, int enable)
55 */ 55 */
56 56
57static int hsit_enum_mbus_code(struct v4l2_subdev *subdev, 57static int hsit_enum_mbus_code(struct v4l2_subdev *subdev,
58 struct v4l2_subdev_fh *fh, 58 struct v4l2_subdev_pad_config *cfg,
59 struct v4l2_subdev_mbus_code_enum *code) 59 struct v4l2_subdev_mbus_code_enum *code)
60{ 60{
61 struct vsp1_hsit *hsit = to_hsit(subdev); 61 struct vsp1_hsit *hsit = to_hsit(subdev);
@@ -73,12 +73,14 @@ static int hsit_enum_mbus_code(struct v4l2_subdev *subdev,
73} 73}
74 74
75static int hsit_enum_frame_size(struct v4l2_subdev *subdev, 75static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
76 struct v4l2_subdev_fh *fh, 76 struct v4l2_subdev_pad_config *cfg,
77 struct v4l2_subdev_frame_size_enum *fse) 77 struct v4l2_subdev_frame_size_enum *fse)
78{ 78{
79 struct vsp1_hsit *hsit = to_hsit(subdev);
79 struct v4l2_mbus_framefmt *format; 80 struct v4l2_mbus_framefmt *format;
80 81
81 format = v4l2_subdev_get_try_format(fh, fse->pad); 82 format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fse->pad,
83 fse->which);
82 84
83 if (fse->index || fse->code != format->code) 85 if (fse->index || fse->code != format->code)
84 return -EINVAL; 86 return -EINVAL;
@@ -102,25 +104,25 @@ static int hsit_enum_frame_size(struct v4l2_subdev *subdev,
102} 104}
103 105
104static int hsit_get_format(struct v4l2_subdev *subdev, 106static int hsit_get_format(struct v4l2_subdev *subdev,
105 struct v4l2_subdev_fh *fh, 107 struct v4l2_subdev_pad_config *cfg,
106 struct v4l2_subdev_format *fmt) 108 struct v4l2_subdev_format *fmt)
107{ 109{
108 struct vsp1_hsit *hsit = to_hsit(subdev); 110 struct vsp1_hsit *hsit = to_hsit(subdev);
109 111
110 fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad, 112 fmt->format = *vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
111 fmt->which); 113 fmt->which);
112 114
113 return 0; 115 return 0;
114} 116}
115 117
116static int hsit_set_format(struct v4l2_subdev *subdev, 118static int hsit_set_format(struct v4l2_subdev *subdev,
117 struct v4l2_subdev_fh *fh, 119 struct v4l2_subdev_pad_config *cfg,
118 struct v4l2_subdev_format *fmt) 120 struct v4l2_subdev_format *fmt)
119{ 121{
120 struct vsp1_hsit *hsit = to_hsit(subdev); 122 struct vsp1_hsit *hsit = to_hsit(subdev);
121 struct v4l2_mbus_framefmt *format; 123 struct v4l2_mbus_framefmt *format;
122 124
123 format = vsp1_entity_get_pad_format(&hsit->entity, fh, fmt->pad, 125 format = vsp1_entity_get_pad_format(&hsit->entity, cfg, fmt->pad,
124 fmt->which); 126 fmt->which);
125 127
126 if (fmt->pad == HSIT_PAD_SOURCE) { 128 if (fmt->pad == HSIT_PAD_SOURCE) {
@@ -143,7 +145,7 @@ static int hsit_set_format(struct v4l2_subdev *subdev,
143 fmt->format = *format; 145 fmt->format = *format;
144 146
145 /* Propagate the format to the source pad. */ 147 /* Propagate the format to the source pad. */
146 format = vsp1_entity_get_pad_format(&hsit->entity, fh, HSIT_PAD_SOURCE, 148 format = vsp1_entity_get_pad_format(&hsit->entity, cfg, HSIT_PAD_SOURCE,
147 fmt->which); 149 fmt->which);
148 *format = fmt->format; 150 *format = fmt->format;
149 format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32 151 format->code = hsit->inverse ? MEDIA_BUS_FMT_ARGB8888_1X32
diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c
index 17a6ca7dafe6..39fa5ef20fbb 100644
--- a/drivers/media/platform/vsp1/vsp1_lif.c
+++ b/drivers/media/platform/vsp1/vsp1_lif.c
@@ -74,13 +74,14 @@ static int lif_s_stream(struct v4l2_subdev *subdev, int enable)
74 */ 74 */
75 75
76static int lif_enum_mbus_code(struct v4l2_subdev *subdev, 76static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
77 struct v4l2_subdev_fh *fh, 77 struct v4l2_subdev_pad_config *cfg,
78 struct v4l2_subdev_mbus_code_enum *code) 78 struct v4l2_subdev_mbus_code_enum *code)
79{ 79{
80 static const unsigned int codes[] = { 80 static const unsigned int codes[] = {
81 MEDIA_BUS_FMT_ARGB8888_1X32, 81 MEDIA_BUS_FMT_ARGB8888_1X32,
82 MEDIA_BUS_FMT_AYUV8_1X32, 82 MEDIA_BUS_FMT_AYUV8_1X32,
83 }; 83 };
84 struct vsp1_lif *lif = to_lif(subdev);
84 85
85 if (code->pad == LIF_PAD_SINK) { 86 if (code->pad == LIF_PAD_SINK) {
86 if (code->index >= ARRAY_SIZE(codes)) 87 if (code->index >= ARRAY_SIZE(codes))
@@ -96,7 +97,8 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
96 if (code->index) 97 if (code->index)
97 return -EINVAL; 98 return -EINVAL;
98 99
99 format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); 100 format = vsp1_entity_get_pad_format(&lif->entity, cfg,
101 LIF_PAD_SINK, code->which);
100 code->code = format->code; 102 code->code = format->code;
101 } 103 }
102 104
@@ -104,12 +106,14 @@ static int lif_enum_mbus_code(struct v4l2_subdev *subdev,
104} 106}
105 107
106static int lif_enum_frame_size(struct v4l2_subdev *subdev, 108static int lif_enum_frame_size(struct v4l2_subdev *subdev,
107 struct v4l2_subdev_fh *fh, 109 struct v4l2_subdev_pad_config *cfg,
108 struct v4l2_subdev_frame_size_enum *fse) 110 struct v4l2_subdev_frame_size_enum *fse)
109{ 111{
112 struct vsp1_lif *lif = to_lif(subdev);
110 struct v4l2_mbus_framefmt *format; 113 struct v4l2_mbus_framefmt *format;
111 114
112 format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); 115 format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SINK,
116 fse->which);
113 117
114 if (fse->index || fse->code != format->code) 118 if (fse->index || fse->code != format->code)
115 return -EINVAL; 119 return -EINVAL;
@@ -129,18 +133,18 @@ static int lif_enum_frame_size(struct v4l2_subdev *subdev,
129 return 0; 133 return 0;
130} 134}
131 135
132static int lif_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 136static int lif_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
133 struct v4l2_subdev_format *fmt) 137 struct v4l2_subdev_format *fmt)
134{ 138{
135 struct vsp1_lif *lif = to_lif(subdev); 139 struct vsp1_lif *lif = to_lif(subdev);
136 140
137 fmt->format = *vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, 141 fmt->format = *vsp1_entity_get_pad_format(&lif->entity, cfg, fmt->pad,
138 fmt->which); 142 fmt->which);
139 143
140 return 0; 144 return 0;
141} 145}
142 146
143static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 147static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
144 struct v4l2_subdev_format *fmt) 148 struct v4l2_subdev_format *fmt)
145{ 149{
146 struct vsp1_lif *lif = to_lif(subdev); 150 struct vsp1_lif *lif = to_lif(subdev);
@@ -151,7 +155,7 @@ static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
151 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) 155 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
152 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; 156 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
153 157
154 format = vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, 158 format = vsp1_entity_get_pad_format(&lif->entity, cfg, fmt->pad,
155 fmt->which); 159 fmt->which);
156 160
157 if (fmt->pad == LIF_PAD_SOURCE) { 161 if (fmt->pad == LIF_PAD_SOURCE) {
@@ -173,7 +177,7 @@ static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
173 fmt->format = *format; 177 fmt->format = *format;
174 178
175 /* Propagate the format to the source pad. */ 179 /* Propagate the format to the source pad. */
176 format = vsp1_entity_get_pad_format(&lif->entity, fh, LIF_PAD_SOURCE, 180 format = vsp1_entity_get_pad_format(&lif->entity, cfg, LIF_PAD_SOURCE,
177 fmt->which); 181 fmt->which);
178 *format = fmt->format; 182 *format = fmt->format;
179 183
diff --git a/drivers/media/platform/vsp1/vsp1_lut.c b/drivers/media/platform/vsp1/vsp1_lut.c
index 6f185c3621fe..656ec272a414 100644
--- a/drivers/media/platform/vsp1/vsp1_lut.c
+++ b/drivers/media/platform/vsp1/vsp1_lut.c
@@ -82,7 +82,7 @@ static int lut_s_stream(struct v4l2_subdev *subdev, int enable)
82 */ 82 */
83 83
84static int lut_enum_mbus_code(struct v4l2_subdev *subdev, 84static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
85 struct v4l2_subdev_fh *fh, 85 struct v4l2_subdev_pad_config *cfg,
86 struct v4l2_subdev_mbus_code_enum *code) 86 struct v4l2_subdev_mbus_code_enum *code)
87{ 87{
88 static const unsigned int codes[] = { 88 static const unsigned int codes[] = {
@@ -90,6 +90,7 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
90 MEDIA_BUS_FMT_AHSV8888_1X32, 90 MEDIA_BUS_FMT_AHSV8888_1X32,
91 MEDIA_BUS_FMT_AYUV8_1X32, 91 MEDIA_BUS_FMT_AYUV8_1X32,
92 }; 92 };
93 struct vsp1_lut *lut = to_lut(subdev);
93 struct v4l2_mbus_framefmt *format; 94 struct v4l2_mbus_framefmt *format;
94 95
95 if (code->pad == LUT_PAD_SINK) { 96 if (code->pad == LUT_PAD_SINK) {
@@ -104,7 +105,8 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
104 if (code->index) 105 if (code->index)
105 return -EINVAL; 106 return -EINVAL;
106 107
107 format = v4l2_subdev_get_try_format(fh, LUT_PAD_SINK); 108 format = vsp1_entity_get_pad_format(&lut->entity, cfg,
109 LUT_PAD_SINK, code->which);
108 code->code = format->code; 110 code->code = format->code;
109 } 111 }
110 112
@@ -112,12 +114,14 @@ static int lut_enum_mbus_code(struct v4l2_subdev *subdev,
112} 114}
113 115
114static int lut_enum_frame_size(struct v4l2_subdev *subdev, 116static int lut_enum_frame_size(struct v4l2_subdev *subdev,
115 struct v4l2_subdev_fh *fh, 117 struct v4l2_subdev_pad_config *cfg,
116 struct v4l2_subdev_frame_size_enum *fse) 118 struct v4l2_subdev_frame_size_enum *fse)
117{ 119{
120 struct vsp1_lut *lut = to_lut(subdev);
118 struct v4l2_mbus_framefmt *format; 121 struct v4l2_mbus_framefmt *format;
119 122
120 format = v4l2_subdev_get_try_format(fh, fse->pad); 123 format = vsp1_entity_get_pad_format(&lut->entity, cfg,
124 fse->pad, fse->which);
121 125
122 if (fse->index || fse->code != format->code) 126 if (fse->index || fse->code != format->code)
123 return -EINVAL; 127 return -EINVAL;
@@ -140,18 +144,18 @@ static int lut_enum_frame_size(struct v4l2_subdev *subdev,
140 return 0; 144 return 0;
141} 145}
142 146
143static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 147static int lut_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
144 struct v4l2_subdev_format *fmt) 148 struct v4l2_subdev_format *fmt)
145{ 149{
146 struct vsp1_lut *lut = to_lut(subdev); 150 struct vsp1_lut *lut = to_lut(subdev);
147 151
148 fmt->format = *vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, 152 fmt->format = *vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad,
149 fmt->which); 153 fmt->which);
150 154
151 return 0; 155 return 0;
152} 156}
153 157
154static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 158static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
155 struct v4l2_subdev_format *fmt) 159 struct v4l2_subdev_format *fmt)
156{ 160{
157 struct vsp1_lut *lut = to_lut(subdev); 161 struct vsp1_lut *lut = to_lut(subdev);
@@ -163,7 +167,7 @@ static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
163 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) 167 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
164 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; 168 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
165 169
166 format = vsp1_entity_get_pad_format(&lut->entity, fh, fmt->pad, 170 format = vsp1_entity_get_pad_format(&lut->entity, cfg, fmt->pad,
167 fmt->which); 171 fmt->which);
168 172
169 if (fmt->pad == LUT_PAD_SOURCE) { 173 if (fmt->pad == LUT_PAD_SOURCE) {
@@ -182,7 +186,7 @@ static int lut_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
182 fmt->format = *format; 186 fmt->format = *format;
183 187
184 /* Propagate the format to the source pad. */ 188 /* Propagate the format to the source pad. */
185 format = vsp1_entity_get_pad_format(&lut->entity, fh, LUT_PAD_SOURCE, 189 format = vsp1_entity_get_pad_format(&lut->entity, cfg, LUT_PAD_SOURCE,
186 fmt->which); 190 fmt->which);
187 *format = fmt->format; 191 *format = fmt->format;
188 192
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c
index 1f1ba26a834a..fa71f4695e16 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.c
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, 27int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev,
28 struct v4l2_subdev_fh *fh, 28 struct v4l2_subdev_pad_config *cfg,
29 struct v4l2_subdev_mbus_code_enum *code) 29 struct v4l2_subdev_mbus_code_enum *code)
30{ 30{
31 static const unsigned int codes[] = { 31 static const unsigned int codes[] = {
@@ -42,13 +42,14 @@ int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev,
42} 42}
43 43
44int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, 44int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
45 struct v4l2_subdev_fh *fh, 45 struct v4l2_subdev_pad_config *cfg,
46 struct v4l2_subdev_frame_size_enum *fse) 46 struct v4l2_subdev_frame_size_enum *fse)
47{ 47{
48 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 48 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
49 struct v4l2_mbus_framefmt *format; 49 struct v4l2_mbus_framefmt *format;
50 50
51 format = v4l2_subdev_get_try_format(fh, fse->pad); 51 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fse->pad,
52 fse->which);
52 53
53 if (fse->index || fse->code != format->code) 54 if (fse->index || fse->code != format->code)
54 return -EINVAL; 55 return -EINVAL;
@@ -72,11 +73,11 @@ int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
72} 73}
73 74
74static struct v4l2_rect * 75static struct v4l2_rect *
75vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_fh *fh, u32 which) 76vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_pad_config *cfg, u32 which)
76{ 77{
77 switch (which) { 78 switch (which) {
78 case V4L2_SUBDEV_FORMAT_TRY: 79 case V4L2_SUBDEV_FORMAT_TRY:
79 return v4l2_subdev_get_try_crop(fh, RWPF_PAD_SINK); 80 return v4l2_subdev_get_try_crop(&rwpf->entity.subdev, cfg, RWPF_PAD_SINK);
80 case V4L2_SUBDEV_FORMAT_ACTIVE: 81 case V4L2_SUBDEV_FORMAT_ACTIVE:
81 return &rwpf->crop; 82 return &rwpf->crop;
82 default: 83 default:
@@ -84,18 +85,18 @@ vsp1_rwpf_get_crop(struct vsp1_rwpf *rwpf, struct v4l2_subdev_fh *fh, u32 which)
84 } 85 }
85} 86}
86 87
87int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 88int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
88 struct v4l2_subdev_format *fmt) 89 struct v4l2_subdev_format *fmt)
89{ 90{
90 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 91 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
91 92
92 fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, 93 fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
93 fmt->which); 94 fmt->which);
94 95
95 return 0; 96 return 0;
96} 97}
97 98
98int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 99int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
99 struct v4l2_subdev_format *fmt) 100 struct v4l2_subdev_format *fmt)
100{ 101{
101 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 102 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
@@ -107,7 +108,7 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
107 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32) 108 fmt->format.code != MEDIA_BUS_FMT_AYUV8_1X32)
108 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32; 109 fmt->format.code = MEDIA_BUS_FMT_AYUV8_1X32;
109 110
110 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, 111 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, fmt->pad,
111 fmt->which); 112 fmt->which);
112 113
113 if (fmt->pad == RWPF_PAD_SOURCE) { 114 if (fmt->pad == RWPF_PAD_SOURCE) {
@@ -130,14 +131,14 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
130 fmt->format = *format; 131 fmt->format = *format;
131 132
132 /* Update the sink crop rectangle. */ 133 /* Update the sink crop rectangle. */
133 crop = vsp1_rwpf_get_crop(rwpf, fh, fmt->which); 134 crop = vsp1_rwpf_get_crop(rwpf, cfg, fmt->which);
134 crop->left = 0; 135 crop->left = 0;
135 crop->top = 0; 136 crop->top = 0;
136 crop->width = fmt->format.width; 137 crop->width = fmt->format.width;
137 crop->height = fmt->format.height; 138 crop->height = fmt->format.height;
138 139
139 /* Propagate the format to the source pad. */ 140 /* Propagate the format to the source pad. */
140 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, 141 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE,
141 fmt->which); 142 fmt->which);
142 *format = fmt->format; 143 *format = fmt->format;
143 144
@@ -145,7 +146,7 @@ int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh,
145} 146}
146 147
147int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, 148int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
148 struct v4l2_subdev_fh *fh, 149 struct v4l2_subdev_pad_config *cfg,
149 struct v4l2_subdev_selection *sel) 150 struct v4l2_subdev_selection *sel)
150{ 151{
151 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 152 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
@@ -157,11 +158,11 @@ int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
157 158
158 switch (sel->target) { 159 switch (sel->target) {
159 case V4L2_SEL_TGT_CROP: 160 case V4L2_SEL_TGT_CROP:
160 sel->r = *vsp1_rwpf_get_crop(rwpf, fh, sel->which); 161 sel->r = *vsp1_rwpf_get_crop(rwpf, cfg, sel->which);
161 break; 162 break;
162 163
163 case V4L2_SEL_TGT_CROP_BOUNDS: 164 case V4L2_SEL_TGT_CROP_BOUNDS:
164 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, 165 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg,
165 RWPF_PAD_SINK, sel->which); 166 RWPF_PAD_SINK, sel->which);
166 sel->r.left = 0; 167 sel->r.left = 0;
167 sel->r.top = 0; 168 sel->r.top = 0;
@@ -177,7 +178,7 @@ int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
177} 178}
178 179
179int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, 180int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
180 struct v4l2_subdev_fh *fh, 181 struct v4l2_subdev_pad_config *cfg,
181 struct v4l2_subdev_selection *sel) 182 struct v4l2_subdev_selection *sel)
182{ 183{
183 struct vsp1_rwpf *rwpf = to_rwpf(subdev); 184 struct vsp1_rwpf *rwpf = to_rwpf(subdev);
@@ -194,7 +195,7 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
194 /* Make sure the crop rectangle is entirely contained in the image. The 195 /* Make sure the crop rectangle is entirely contained in the image. The
195 * WPF top and left offsets are limited to 255. 196 * WPF top and left offsets are limited to 255.
196 */ 197 */
197 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SINK, 198 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SINK,
198 sel->which); 199 sel->which);
199 sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2); 200 sel->r.left = min_t(unsigned int, sel->r.left, format->width - 2);
200 sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2); 201 sel->r.top = min_t(unsigned int, sel->r.top, format->height - 2);
@@ -207,11 +208,11 @@ int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
207 sel->r.height = min_t(unsigned int, sel->r.height, 208 sel->r.height = min_t(unsigned int, sel->r.height,
208 format->height - sel->r.top); 209 format->height - sel->r.top);
209 210
210 crop = vsp1_rwpf_get_crop(rwpf, fh, sel->which); 211 crop = vsp1_rwpf_get_crop(rwpf, cfg, sel->which);
211 *crop = sel->r; 212 *crop = sel->r;
212 213
213 /* Propagate the format to the source pad. */ 214 /* Propagate the format to the source pad. */
214 format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, 215 format = vsp1_entity_get_pad_format(&rwpf->entity, cfg, RWPF_PAD_SOURCE,
215 sel->which); 216 sel->which);
216 format->width = crop->width; 217 format->width = crop->width;
217 format->height = crop->height; 218 format->height = crop->height;
diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h
index 2cf1f13d3bf9..f452dce1a931 100644
--- a/drivers/media/platform/vsp1/vsp1_rwpf.h
+++ b/drivers/media/platform/vsp1/vsp1_rwpf.h
@@ -51,20 +51,20 @@ struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index);
51struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); 51struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index);
52 52
53int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, 53int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev,
54 struct v4l2_subdev_fh *fh, 54 struct v4l2_subdev_pad_config *cfg,
55 struct v4l2_subdev_mbus_code_enum *code); 55 struct v4l2_subdev_mbus_code_enum *code);
56int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, 56int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev,
57 struct v4l2_subdev_fh *fh, 57 struct v4l2_subdev_pad_config *cfg,
58 struct v4l2_subdev_frame_size_enum *fse); 58 struct v4l2_subdev_frame_size_enum *fse);
59int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 59int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
60 struct v4l2_subdev_format *fmt); 60 struct v4l2_subdev_format *fmt);
61int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 61int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
62 struct v4l2_subdev_format *fmt); 62 struct v4l2_subdev_format *fmt);
63int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev, 63int vsp1_rwpf_get_selection(struct v4l2_subdev *subdev,
64 struct v4l2_subdev_fh *fh, 64 struct v4l2_subdev_pad_config *cfg,
65 struct v4l2_subdev_selection *sel); 65 struct v4l2_subdev_selection *sel);
66int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev, 66int vsp1_rwpf_set_selection(struct v4l2_subdev *subdev,
67 struct v4l2_subdev_fh *fh, 67 struct v4l2_subdev_pad_config *cfg,
68 struct v4l2_subdev_selection *sel); 68 struct v4l2_subdev_selection *sel);
69 69
70#endif /* __VSP1_RWPF_H__ */ 70#endif /* __VSP1_RWPF_H__ */
diff --git a/drivers/media/platform/vsp1/vsp1_sru.c b/drivers/media/platform/vsp1/vsp1_sru.c
index 1129494c7cfc..6310acab60e7 100644
--- a/drivers/media/platform/vsp1/vsp1_sru.c
+++ b/drivers/media/platform/vsp1/vsp1_sru.c
@@ -166,13 +166,14 @@ static int sru_s_stream(struct v4l2_subdev *subdev, int enable)
166 */ 166 */
167 167
168static int sru_enum_mbus_code(struct v4l2_subdev *subdev, 168static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
169 struct v4l2_subdev_fh *fh, 169 struct v4l2_subdev_pad_config *cfg,
170 struct v4l2_subdev_mbus_code_enum *code) 170 struct v4l2_subdev_mbus_code_enum *code)
171{ 171{
172 static const unsigned int codes[] = { 172 static const unsigned int codes[] = {
173 MEDIA_BUS_FMT_ARGB8888_1X32, 173 MEDIA_BUS_FMT_ARGB8888_1X32,
174 MEDIA_BUS_FMT_AYUV8_1X32, 174 MEDIA_BUS_FMT_AYUV8_1X32,
175 }; 175 };
176 struct vsp1_sru *sru = to_sru(subdev);
176 struct v4l2_mbus_framefmt *format; 177 struct v4l2_mbus_framefmt *format;
177 178
178 if (code->pad == SRU_PAD_SINK) { 179 if (code->pad == SRU_PAD_SINK) {
@@ -187,7 +188,8 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
187 if (code->index) 188 if (code->index)
188 return -EINVAL; 189 return -EINVAL;
189 190
190 format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK); 191 format = vsp1_entity_get_pad_format(&sru->entity, cfg,
192 SRU_PAD_SINK, code->which);
191 code->code = format->code; 193 code->code = format->code;
192 } 194 }
193 195
@@ -195,12 +197,14 @@ static int sru_enum_mbus_code(struct v4l2_subdev *subdev,
195} 197}
196 198
197static int sru_enum_frame_size(struct v4l2_subdev *subdev, 199static int sru_enum_frame_size(struct v4l2_subdev *subdev,
198 struct v4l2_subdev_fh *fh, 200 struct v4l2_subdev_pad_config *cfg,
199 struct v4l2_subdev_frame_size_enum *fse) 201 struct v4l2_subdev_frame_size_enum *fse)
200{ 202{
203 struct vsp1_sru *sru = to_sru(subdev);
201 struct v4l2_mbus_framefmt *format; 204 struct v4l2_mbus_framefmt *format;
202 205
203 format = v4l2_subdev_get_try_format(fh, SRU_PAD_SINK); 206 format = vsp1_entity_get_pad_format(&sru->entity, cfg,
207 SRU_PAD_SINK, fse->which);
204 208
205 if (fse->index || fse->code != format->code) 209 if (fse->index || fse->code != format->code)
206 return -EINVAL; 210 return -EINVAL;
@@ -226,18 +230,18 @@ static int sru_enum_frame_size(struct v4l2_subdev *subdev,
226 return 0; 230 return 0;
227} 231}
228 232
229static int sru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 233static int sru_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
230 struct v4l2_subdev_format *fmt) 234 struct v4l2_subdev_format *fmt)
231{ 235{
232 struct vsp1_sru *sru = to_sru(subdev); 236 struct vsp1_sru *sru = to_sru(subdev);
233 237
234 fmt->format = *vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad, 238 fmt->format = *vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad,
235 fmt->which); 239 fmt->which);
236 240
237 return 0; 241 return 0;
238} 242}
239 243
240static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh, 244static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_pad_config *cfg,
241 unsigned int pad, struct v4l2_mbus_framefmt *fmt, 245 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
242 enum v4l2_subdev_format_whence which) 246 enum v4l2_subdev_format_whence which)
243{ 247{
@@ -258,7 +262,7 @@ static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh,
258 262
259 case SRU_PAD_SOURCE: 263 case SRU_PAD_SOURCE:
260 /* The SRU can't perform format conversion. */ 264 /* The SRU can't perform format conversion. */
261 format = vsp1_entity_get_pad_format(&sru->entity, fh, 265 format = vsp1_entity_get_pad_format(&sru->entity, cfg,
262 SRU_PAD_SINK, which); 266 SRU_PAD_SINK, which);
263 fmt->code = format->code; 267 fmt->code = format->code;
264 268
@@ -288,25 +292,25 @@ static void sru_try_format(struct vsp1_sru *sru, struct v4l2_subdev_fh *fh,
288 fmt->colorspace = V4L2_COLORSPACE_SRGB; 292 fmt->colorspace = V4L2_COLORSPACE_SRGB;
289} 293}
290 294
291static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 295static int sru_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
292 struct v4l2_subdev_format *fmt) 296 struct v4l2_subdev_format *fmt)
293{ 297{
294 struct vsp1_sru *sru = to_sru(subdev); 298 struct vsp1_sru *sru = to_sru(subdev);
295 struct v4l2_mbus_framefmt *format; 299 struct v4l2_mbus_framefmt *format;
296 300
297 sru_try_format(sru, fh, fmt->pad, &fmt->format, fmt->which); 301 sru_try_format(sru, cfg, fmt->pad, &fmt->format, fmt->which);
298 302
299 format = vsp1_entity_get_pad_format(&sru->entity, fh, fmt->pad, 303 format = vsp1_entity_get_pad_format(&sru->entity, cfg, fmt->pad,
300 fmt->which); 304 fmt->which);
301 *format = fmt->format; 305 *format = fmt->format;
302 306
303 if (fmt->pad == SRU_PAD_SINK) { 307 if (fmt->pad == SRU_PAD_SINK) {
304 /* Propagate the format to the source pad. */ 308 /* Propagate the format to the source pad. */
305 format = vsp1_entity_get_pad_format(&sru->entity, fh, 309 format = vsp1_entity_get_pad_format(&sru->entity, cfg,
306 SRU_PAD_SOURCE, fmt->which); 310 SRU_PAD_SOURCE, fmt->which);
307 *format = fmt->format; 311 *format = fmt->format;
308 312
309 sru_try_format(sru, fh, SRU_PAD_SOURCE, format, fmt->which); 313 sru_try_format(sru, cfg, SRU_PAD_SOURCE, format, fmt->which);
310 } 314 }
311 315
312 return 0; 316 return 0;
diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c
index a4afec133800..ccc8243e3493 100644
--- a/drivers/media/platform/vsp1/vsp1_uds.c
+++ b/drivers/media/platform/vsp1/vsp1_uds.c
@@ -169,13 +169,14 @@ static int uds_s_stream(struct v4l2_subdev *subdev, int enable)
169 */ 169 */
170 170
171static int uds_enum_mbus_code(struct v4l2_subdev *subdev, 171static int uds_enum_mbus_code(struct v4l2_subdev *subdev,
172 struct v4l2_subdev_fh *fh, 172 struct v4l2_subdev_pad_config *cfg,
173 struct v4l2_subdev_mbus_code_enum *code) 173 struct v4l2_subdev_mbus_code_enum *code)
174{ 174{
175 static const unsigned int codes[] = { 175 static const unsigned int codes[] = {
176 MEDIA_BUS_FMT_ARGB8888_1X32, 176 MEDIA_BUS_FMT_ARGB8888_1X32,
177 MEDIA_BUS_FMT_AYUV8_1X32, 177 MEDIA_BUS_FMT_AYUV8_1X32,
178 }; 178 };
179 struct vsp1_uds *uds = to_uds(subdev);
179 180
180 if (code->pad == UDS_PAD_SINK) { 181 if (code->pad == UDS_PAD_SINK) {
181 if (code->index >= ARRAY_SIZE(codes)) 182 if (code->index >= ARRAY_SIZE(codes))
@@ -191,7 +192,8 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev,
191 if (code->index) 192 if (code->index)
192 return -EINVAL; 193 return -EINVAL;
193 194
194 format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); 195 format = vsp1_entity_get_pad_format(&uds->entity, cfg,
196 UDS_PAD_SINK, code->which);
195 code->code = format->code; 197 code->code = format->code;
196 } 198 }
197 199
@@ -199,12 +201,14 @@ static int uds_enum_mbus_code(struct v4l2_subdev *subdev,
199} 201}
200 202
201static int uds_enum_frame_size(struct v4l2_subdev *subdev, 203static int uds_enum_frame_size(struct v4l2_subdev *subdev,
202 struct v4l2_subdev_fh *fh, 204 struct v4l2_subdev_pad_config *cfg,
203 struct v4l2_subdev_frame_size_enum *fse) 205 struct v4l2_subdev_frame_size_enum *fse)
204{ 206{
207 struct vsp1_uds *uds = to_uds(subdev);
205 struct v4l2_mbus_framefmt *format; 208 struct v4l2_mbus_framefmt *format;
206 209
207 format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); 210 format = vsp1_entity_get_pad_format(&uds->entity, cfg,
211 UDS_PAD_SINK, fse->which);
208 212
209 if (fse->index || fse->code != format->code) 213 if (fse->index || fse->code != format->code)
210 return -EINVAL; 214 return -EINVAL;
@@ -224,18 +228,18 @@ static int uds_enum_frame_size(struct v4l2_subdev *subdev,
224 return 0; 228 return 0;
225} 229}
226 230
227static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 231static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
228 struct v4l2_subdev_format *fmt) 232 struct v4l2_subdev_format *fmt)
229{ 233{
230 struct vsp1_uds *uds = to_uds(subdev); 234 struct vsp1_uds *uds = to_uds(subdev);
231 235
232 fmt->format = *vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, 236 fmt->format = *vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
233 fmt->which); 237 fmt->which);
234 238
235 return 0; 239 return 0;
236} 240}
237 241
238static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, 242static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_pad_config *cfg,
239 unsigned int pad, struct v4l2_mbus_framefmt *fmt, 243 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
240 enum v4l2_subdev_format_whence which) 244 enum v4l2_subdev_format_whence which)
241{ 245{
@@ -256,7 +260,7 @@ static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh,
256 260
257 case UDS_PAD_SOURCE: 261 case UDS_PAD_SOURCE:
258 /* The UDS scales but can't perform format conversion. */ 262 /* The UDS scales but can't perform format conversion. */
259 format = vsp1_entity_get_pad_format(&uds->entity, fh, 263 format = vsp1_entity_get_pad_format(&uds->entity, cfg,
260 UDS_PAD_SINK, which); 264 UDS_PAD_SINK, which);
261 fmt->code = format->code; 265 fmt->code = format->code;
262 266
@@ -271,25 +275,25 @@ static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh,
271 fmt->colorspace = V4L2_COLORSPACE_SRGB; 275 fmt->colorspace = V4L2_COLORSPACE_SRGB;
272} 276}
273 277
274static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, 278static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_pad_config *cfg,
275 struct v4l2_subdev_format *fmt) 279 struct v4l2_subdev_format *fmt)
276{ 280{
277 struct vsp1_uds *uds = to_uds(subdev); 281 struct vsp1_uds *uds = to_uds(subdev);
278 struct v4l2_mbus_framefmt *format; 282 struct v4l2_mbus_framefmt *format;
279 283
280 uds_try_format(uds, fh, fmt->pad, &fmt->format, fmt->which); 284 uds_try_format(uds, cfg, fmt->pad, &fmt->format, fmt->which);
281 285
282 format = vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, 286 format = vsp1_entity_get_pad_format(&uds->entity, cfg, fmt->pad,
283 fmt->which); 287 fmt->which);
284 *format = fmt->format; 288 *format = fmt->format;
285 289
286 if (fmt->pad == UDS_PAD_SINK) { 290 if (fmt->pad == UDS_PAD_SINK) {
287 /* Propagate the format to the source pad. */ 291 /* Propagate the format to the source pad. */
288 format = vsp1_entity_get_pad_format(&uds->entity, fh, 292 format = vsp1_entity_get_pad_format(&uds->entity, cfg,
289 UDS_PAD_SOURCE, fmt->which); 293 UDS_PAD_SOURCE, fmt->which);
290 *format = fmt->format; 294 *format = fmt->format;
291 295
292 uds_try_format(uds, fh, UDS_PAD_SOURCE, format, fmt->which); 296 uds_try_format(uds, cfg, UDS_PAD_SOURCE, format, fmt->which);
293 } 297 }
294 298
295 return 0; 299 return 0;
diff --git a/drivers/media/platform/xilinx/Kconfig b/drivers/media/platform/xilinx/Kconfig
new file mode 100644
index 000000000000..d7324c726fc2
--- /dev/null
+++ b/drivers/media/platform/xilinx/Kconfig
@@ -0,0 +1,23 @@
1config VIDEO_XILINX
2 tristate "Xilinx Video IP (EXPERIMENTAL)"
3 depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && OF
4 select VIDEOBUF2_DMA_CONTIG
5 ---help---
6 Driver for Xilinx Video IP Pipelines
7
8if VIDEO_XILINX
9
10config VIDEO_XILINX_TPG
11 tristate "Xilinx Video Test Pattern Generator"
12 depends on VIDEO_XILINX
13 select VIDEO_XILINX_VTC
14 ---help---
15 Driver for the Xilinx Video Test Pattern Generator
16
17config VIDEO_XILINX_VTC
18 tristate "Xilinx Video Timing Controller"
19 depends on VIDEO_XILINX
20 ---help---
21 Driver for the Xilinx Video Timing Controller
22
23endif #VIDEO_XILINX
diff --git a/drivers/media/platform/xilinx/Makefile b/drivers/media/platform/xilinx/Makefile
new file mode 100644
index 000000000000..e8a0f2a9f733
--- /dev/null
+++ b/drivers/media/platform/xilinx/Makefile
@@ -0,0 +1,5 @@
1xilinx-video-objs += xilinx-dma.o xilinx-vip.o xilinx-vipp.o
2
3obj-$(CONFIG_VIDEO_XILINX) += xilinx-video.o
4obj-$(CONFIG_VIDEO_XILINX_TPG) += xilinx-tpg.o
5obj-$(CONFIG_VIDEO_XILINX_VTC) += xilinx-vtc.o
diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c
new file mode 100644
index 000000000000..10209c294168
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-dma.c
@@ -0,0 +1,766 @@
1/*
2 * Xilinx Video DMA
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/amba/xilinx_dma.h>
16#include <linux/lcm.h>
17#include <linux/list.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/slab.h>
21
22#include <media/v4l2-dev.h>
23#include <media/v4l2-fh.h>
24#include <media/v4l2-ioctl.h>
25#include <media/videobuf2-core.h>
26#include <media/videobuf2-dma-contig.h>
27
28#include "xilinx-dma.h"
29#include "xilinx-vip.h"
30#include "xilinx-vipp.h"
31
32#define XVIP_DMA_DEF_FORMAT V4L2_PIX_FMT_YUYV
33#define XVIP_DMA_DEF_WIDTH 1920
34#define XVIP_DMA_DEF_HEIGHT 1080
35
36/* Minimum and maximum widths are expressed in bytes */
37#define XVIP_DMA_MIN_WIDTH 1U
38#define XVIP_DMA_MAX_WIDTH 65535U
39#define XVIP_DMA_MIN_HEIGHT 1U
40#define XVIP_DMA_MAX_HEIGHT 8191U
41
42/* -----------------------------------------------------------------------------
43 * Helper functions
44 */
45
46static struct v4l2_subdev *
47xvip_dma_remote_subdev(struct media_pad *local, u32 *pad)
48{
49 struct media_pad *remote;
50
51 remote = media_entity_remote_pad(local);
52 if (remote == NULL ||
53 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
54 return NULL;
55
56 if (pad)
57 *pad = remote->index;
58
59 return media_entity_to_v4l2_subdev(remote->entity);
60}
61
62static int xvip_dma_verify_format(struct xvip_dma *dma)
63{
64 struct v4l2_subdev_format fmt;
65 struct v4l2_subdev *subdev;
66 int ret;
67
68 subdev = xvip_dma_remote_subdev(&dma->pad, &fmt.pad);
69 if (subdev == NULL)
70 return -EPIPE;
71
72 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
73 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
74 if (ret < 0)
75 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
76
77 if (dma->fmtinfo->code != fmt.format.code ||
78 dma->format.height != fmt.format.height ||
79 dma->format.width != fmt.format.width ||
80 dma->format.colorspace != fmt.format.colorspace)
81 return -EINVAL;
82
83 return 0;
84}
85
86/* -----------------------------------------------------------------------------
87 * Pipeline Stream Management
88 */
89
90/**
91 * xvip_pipeline_start_stop - Start ot stop streaming on a pipeline
92 * @pipe: The pipeline
93 * @start: Start (when true) or stop (when false) the pipeline
94 *
95 * Walk the entities chain starting at the pipeline output video node and start
96 * or stop all of them.
97 *
98 * Return: 0 if successful, or the return value of the failed video::s_stream
99 * operation otherwise.
100 */
101static int xvip_pipeline_start_stop(struct xvip_pipeline *pipe, bool start)
102{
103 struct xvip_dma *dma = pipe->output;
104 struct media_entity *entity;
105 struct media_pad *pad;
106 struct v4l2_subdev *subdev;
107 int ret;
108
109 entity = &dma->video.entity;
110 while (1) {
111 pad = &entity->pads[0];
112 if (!(pad->flags & MEDIA_PAD_FL_SINK))
113 break;
114
115 pad = media_entity_remote_pad(pad);
116 if (pad == NULL ||
117 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
118 break;
119
120 entity = pad->entity;
121 subdev = media_entity_to_v4l2_subdev(entity);
122
123 ret = v4l2_subdev_call(subdev, video, s_stream, start);
124 if (start && ret < 0 && ret != -ENOIOCTLCMD)
125 return ret;
126 }
127
128 return 0;
129}
130
131/**
132 * xvip_pipeline_set_stream - Enable/disable streaming on a pipeline
133 * @pipe: The pipeline
134 * @on: Turn the stream on when true or off when false
135 *
136 * The pipeline is shared between all DMA engines connect at its input and
137 * output. While the stream state of DMA engines can be controlled
138 * independently, pipelines have a shared stream state that enable or disable
139 * all entities in the pipeline. For this reason the pipeline uses a streaming
140 * counter that tracks the number of DMA engines that have requested the stream
141 * to be enabled.
142 *
143 * When called with the @on argument set to true, this function will increment
144 * the pipeline streaming count. If the streaming count reaches the number of
145 * DMA engines in the pipeline it will enable all entities that belong to the
146 * pipeline.
147 *
148 * Similarly, when called with the @on argument set to false, this function will
149 * decrement the pipeline streaming count and disable all entities in the
150 * pipeline when the streaming count reaches zero.
151 *
152 * Return: 0 if successful, or the return value of the failed video::s_stream
153 * operation otherwise. Stopping the pipeline never fails. The pipeline state is
154 * not updated when the operation fails.
155 */
156static int xvip_pipeline_set_stream(struct xvip_pipeline *pipe, bool on)
157{
158 int ret = 0;
159
160 mutex_lock(&pipe->lock);
161
162 if (on) {
163 if (pipe->stream_count == pipe->num_dmas - 1) {
164 ret = xvip_pipeline_start_stop(pipe, true);
165 if (ret < 0)
166 goto done;
167 }
168 pipe->stream_count++;
169 } else {
170 if (--pipe->stream_count == 0)
171 xvip_pipeline_start_stop(pipe, false);
172 }
173
174done:
175 mutex_unlock(&pipe->lock);
176 return ret;
177}
178
179static int xvip_pipeline_validate(struct xvip_pipeline *pipe,
180 struct xvip_dma *start)
181{
182 struct media_entity_graph graph;
183 struct media_entity *entity = &start->video.entity;
184 struct media_device *mdev = entity->parent;
185 unsigned int num_inputs = 0;
186 unsigned int num_outputs = 0;
187
188 mutex_lock(&mdev->graph_mutex);
189
190 /* Walk the graph to locate the video nodes. */
191 media_entity_graph_walk_start(&graph, entity);
192
193 while ((entity = media_entity_graph_walk_next(&graph))) {
194 struct xvip_dma *dma;
195
196 if (entity->type != MEDIA_ENT_T_DEVNODE_V4L)
197 continue;
198
199 dma = to_xvip_dma(media_entity_to_video_device(entity));
200
201 if (dma->pad.flags & MEDIA_PAD_FL_SINK) {
202 pipe->output = dma;
203 num_outputs++;
204 } else {
205 num_inputs++;
206 }
207 }
208
209 mutex_unlock(&mdev->graph_mutex);
210
211 /* We need exactly one output and zero or one input. */
212 if (num_outputs != 1 || num_inputs > 1)
213 return -EPIPE;
214
215 pipe->num_dmas = num_inputs + num_outputs;
216
217 return 0;
218}
219
220static void __xvip_pipeline_cleanup(struct xvip_pipeline *pipe)
221{
222 pipe->num_dmas = 0;
223 pipe->output = NULL;
224}
225
226/**
227 * xvip_pipeline_cleanup - Cleanup the pipeline after streaming
228 * @pipe: the pipeline
229 *
230 * Decrease the pipeline use count and clean it up if we were the last user.
231 */
232static void xvip_pipeline_cleanup(struct xvip_pipeline *pipe)
233{
234 mutex_lock(&pipe->lock);
235
236 /* If we're the last user clean up the pipeline. */
237 if (--pipe->use_count == 0)
238 __xvip_pipeline_cleanup(pipe);
239
240 mutex_unlock(&pipe->lock);
241}
242
243/**
244 * xvip_pipeline_prepare - Prepare the pipeline for streaming
245 * @pipe: the pipeline
246 * @dma: DMA engine at one end of the pipeline
247 *
248 * Validate the pipeline if no user exists yet, otherwise just increase the use
249 * count.
250 *
251 * Return: 0 if successful or -EPIPE if the pipeline is not valid.
252 */
253static int xvip_pipeline_prepare(struct xvip_pipeline *pipe,
254 struct xvip_dma *dma)
255{
256 int ret;
257
258 mutex_lock(&pipe->lock);
259
260 /* If we're the first user validate and initialize the pipeline. */
261 if (pipe->use_count == 0) {
262 ret = xvip_pipeline_validate(pipe, dma);
263 if (ret < 0) {
264 __xvip_pipeline_cleanup(pipe);
265 goto done;
266 }
267 }
268
269 pipe->use_count++;
270 ret = 0;
271
272done:
273 mutex_unlock(&pipe->lock);
274 return ret;
275}
276
277/* -----------------------------------------------------------------------------
278 * videobuf2 queue operations
279 */
280
281/**
282 * struct xvip_dma_buffer - Video DMA buffer
283 * @buf: vb2 buffer base object
284 * @queue: buffer list entry in the DMA engine queued buffers list
285 * @dma: DMA channel that uses the buffer
286 */
287struct xvip_dma_buffer {
288 struct vb2_buffer buf;
289 struct list_head queue;
290 struct xvip_dma *dma;
291};
292
293#define to_xvip_dma_buffer(vb) container_of(vb, struct xvip_dma_buffer, buf)
294
295static void xvip_dma_complete(void *param)
296{
297 struct xvip_dma_buffer *buf = param;
298 struct xvip_dma *dma = buf->dma;
299
300 spin_lock(&dma->queued_lock);
301 list_del(&buf->queue);
302 spin_unlock(&dma->queued_lock);
303
304 buf->buf.v4l2_buf.field = V4L2_FIELD_NONE;
305 buf->buf.v4l2_buf.sequence = dma->sequence++;
306 v4l2_get_timestamp(&buf->buf.v4l2_buf.timestamp);
307 vb2_set_plane_payload(&buf->buf, 0, dma->format.sizeimage);
308 vb2_buffer_done(&buf->buf, VB2_BUF_STATE_DONE);
309}
310
311static int
312xvip_dma_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
313 unsigned int *nbuffers, unsigned int *nplanes,
314 unsigned int sizes[], void *alloc_ctxs[])
315{
316 struct xvip_dma *dma = vb2_get_drv_priv(vq);
317
318 /* Make sure the image size is large enough. */
319 if (fmt && fmt->fmt.pix.sizeimage < dma->format.sizeimage)
320 return -EINVAL;
321
322 *nplanes = 1;
323
324 sizes[0] = fmt ? fmt->fmt.pix.sizeimage : dma->format.sizeimage;
325 alloc_ctxs[0] = dma->alloc_ctx;
326
327 return 0;
328}
329
330static int xvip_dma_buffer_prepare(struct vb2_buffer *vb)
331{
332 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
333 struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
334
335 buf->dma = dma;
336
337 return 0;
338}
339
340static void xvip_dma_buffer_queue(struct vb2_buffer *vb)
341{
342 struct xvip_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
343 struct xvip_dma_buffer *buf = to_xvip_dma_buffer(vb);
344 struct dma_async_tx_descriptor *desc;
345 dma_addr_t addr = vb2_dma_contig_plane_dma_addr(vb, 0);
346 u32 flags;
347
348 if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
349 flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
350 dma->xt.dir = DMA_DEV_TO_MEM;
351 dma->xt.src_sgl = false;
352 dma->xt.dst_sgl = true;
353 dma->xt.dst_start = addr;
354 } else {
355 flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
356 dma->xt.dir = DMA_MEM_TO_DEV;
357 dma->xt.src_sgl = true;
358 dma->xt.dst_sgl = false;
359 dma->xt.src_start = addr;
360 }
361
362 dma->xt.frame_size = 1;
363 dma->sgl[0].size = dma->format.width * dma->fmtinfo->bpp;
364 dma->sgl[0].icg = dma->format.bytesperline - dma->sgl[0].size;
365 dma->xt.numf = dma->format.height;
366
367 desc = dmaengine_prep_interleaved_dma(dma->dma, &dma->xt, flags);
368 if (!desc) {
369 dev_err(dma->xdev->dev, "Failed to prepare DMA transfer\n");
370 vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
371 return;
372 }
373 desc->callback = xvip_dma_complete;
374 desc->callback_param = buf;
375
376 spin_lock_irq(&dma->queued_lock);
377 list_add_tail(&buf->queue, &dma->queued_bufs);
378 spin_unlock_irq(&dma->queued_lock);
379
380 dmaengine_submit(desc);
381
382 if (vb2_is_streaming(&dma->queue))
383 dma_async_issue_pending(dma->dma);
384}
385
386static int xvip_dma_start_streaming(struct vb2_queue *vq, unsigned int count)
387{
388 struct xvip_dma *dma = vb2_get_drv_priv(vq);
389 struct xvip_dma_buffer *buf, *nbuf;
390 struct xvip_pipeline *pipe;
391 int ret;
392
393 dma->sequence = 0;
394
395 /*
396 * Start streaming on the pipeline. No link touching an entity in the
397 * pipeline can be activated or deactivated once streaming is started.
398 *
399 * Use the pipeline object embedded in the first DMA object that starts
400 * streaming.
401 */
402 pipe = dma->video.entity.pipe
403 ? to_xvip_pipeline(&dma->video.entity) : &dma->pipe;
404
405 ret = media_entity_pipeline_start(&dma->video.entity, &pipe->pipe);
406 if (ret < 0)
407 goto error;
408
409 /* Verify that the configured format matches the output of the
410 * connected subdev.
411 */
412 ret = xvip_dma_verify_format(dma);
413 if (ret < 0)
414 goto error_stop;
415
416 ret = xvip_pipeline_prepare(pipe, dma);
417 if (ret < 0)
418 goto error_stop;
419
420 /* Start the DMA engine. This must be done before starting the blocks
421 * in the pipeline to avoid DMA synchronization issues.
422 */
423 dma_async_issue_pending(dma->dma);
424
425 /* Start the pipeline. */
426 xvip_pipeline_set_stream(pipe, true);
427
428 return 0;
429
430error_stop:
431 media_entity_pipeline_stop(&dma->video.entity);
432
433error:
434 /* Give back all queued buffers to videobuf2. */
435 spin_lock_irq(&dma->queued_lock);
436 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
437 vb2_buffer_done(&buf->buf, VB2_BUF_STATE_QUEUED);
438 list_del(&buf->queue);
439 }
440 spin_unlock_irq(&dma->queued_lock);
441
442 return ret;
443}
444
445static void xvip_dma_stop_streaming(struct vb2_queue *vq)
446{
447 struct xvip_dma *dma = vb2_get_drv_priv(vq);
448 struct xvip_pipeline *pipe = to_xvip_pipeline(&dma->video.entity);
449 struct xvip_dma_buffer *buf, *nbuf;
450
451 /* Stop the pipeline. */
452 xvip_pipeline_set_stream(pipe, false);
453
454 /* Stop and reset the DMA engine. */
455 dmaengine_terminate_all(dma->dma);
456
457 /* Cleanup the pipeline and mark it as being stopped. */
458 xvip_pipeline_cleanup(pipe);
459 media_entity_pipeline_stop(&dma->video.entity);
460
461 /* Give back all queued buffers to videobuf2. */
462 spin_lock_irq(&dma->queued_lock);
463 list_for_each_entry_safe(buf, nbuf, &dma->queued_bufs, queue) {
464 vb2_buffer_done(&buf->buf, VB2_BUF_STATE_ERROR);
465 list_del(&buf->queue);
466 }
467 spin_unlock_irq(&dma->queued_lock);
468}
469
470static struct vb2_ops xvip_dma_queue_qops = {
471 .queue_setup = xvip_dma_queue_setup,
472 .buf_prepare = xvip_dma_buffer_prepare,
473 .buf_queue = xvip_dma_buffer_queue,
474 .wait_prepare = vb2_ops_wait_prepare,
475 .wait_finish = vb2_ops_wait_finish,
476 .start_streaming = xvip_dma_start_streaming,
477 .stop_streaming = xvip_dma_stop_streaming,
478};
479
480/* -----------------------------------------------------------------------------
481 * V4L2 ioctls
482 */
483
484static int
485xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
486{
487 struct v4l2_fh *vfh = file->private_data;
488 struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
489
490 cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING
491 | dma->xdev->v4l2_caps;
492
493 if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
494 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
495 else
496 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
497
498 strlcpy(cap->driver, "xilinx-vipp", sizeof(cap->driver));
499 strlcpy(cap->card, dma->video.name, sizeof(cap->card));
500 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s:%u",
501 dma->xdev->dev->of_node->name, dma->port);
502
503 return 0;
504}
505
506/* FIXME: without this callback function, some applications are not configured
507 * with correct formats, and it results in frames in wrong format. Whether this
508 * callback needs to be required is not clearly defined, so it should be
509 * clarified through the mailing list.
510 */
511static int
512xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
513{
514 struct v4l2_fh *vfh = file->private_data;
515 struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
516
517 if (f->index > 0)
518 return -EINVAL;
519
520 f->pixelformat = dma->format.pixelformat;
521 strlcpy(f->description, dma->fmtinfo->description,
522 sizeof(f->description));
523
524 return 0;
525}
526
527static int
528xvip_dma_get_format(struct file *file, void *fh, struct v4l2_format *format)
529{
530 struct v4l2_fh *vfh = file->private_data;
531 struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
532
533 format->fmt.pix = dma->format;
534
535 return 0;
536}
537
538static void
539__xvip_dma_try_format(struct xvip_dma *dma, struct v4l2_pix_format *pix,
540 const struct xvip_video_format **fmtinfo)
541{
542 const struct xvip_video_format *info;
543 unsigned int min_width;
544 unsigned int max_width;
545 unsigned int min_bpl;
546 unsigned int max_bpl;
547 unsigned int width;
548 unsigned int align;
549 unsigned int bpl;
550
551 /* Retrieve format information and select the default format if the
552 * requested format isn't supported.
553 */
554 info = xvip_get_format_by_fourcc(pix->pixelformat);
555 if (IS_ERR(info))
556 info = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
557
558 pix->pixelformat = info->fourcc;
559 pix->field = V4L2_FIELD_NONE;
560
561 /* The transfer alignment requirements are expressed in bytes. Compute
562 * the minimum and maximum values, clamp the requested width and convert
563 * it back to pixels.
564 */
565 align = lcm(dma->align, info->bpp);
566 min_width = roundup(XVIP_DMA_MIN_WIDTH, align);
567 max_width = rounddown(XVIP_DMA_MAX_WIDTH, align);
568 width = rounddown(pix->width * info->bpp, align);
569
570 pix->width = clamp(width, min_width, max_width) / info->bpp;
571 pix->height = clamp(pix->height, XVIP_DMA_MIN_HEIGHT,
572 XVIP_DMA_MAX_HEIGHT);
573
574 /* Clamp the requested bytes per line value. If the maximum bytes per
575 * line value is zero, the module doesn't support user configurable line
576 * sizes. Override the requested value with the minimum in that case.
577 */
578 min_bpl = pix->width * info->bpp;
579 max_bpl = rounddown(XVIP_DMA_MAX_WIDTH, dma->align);
580 bpl = rounddown(pix->bytesperline, dma->align);
581
582 pix->bytesperline = clamp(bpl, min_bpl, max_bpl);
583 pix->sizeimage = pix->bytesperline * pix->height;
584
585 if (fmtinfo)
586 *fmtinfo = info;
587}
588
589static int
590xvip_dma_try_format(struct file *file, void *fh, struct v4l2_format *format)
591{
592 struct v4l2_fh *vfh = file->private_data;
593 struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
594
595 __xvip_dma_try_format(dma, &format->fmt.pix, NULL);
596 return 0;
597}
598
599static int
600xvip_dma_set_format(struct file *file, void *fh, struct v4l2_format *format)
601{
602 struct v4l2_fh *vfh = file->private_data;
603 struct xvip_dma *dma = to_xvip_dma(vfh->vdev);
604 const struct xvip_video_format *info;
605
606 __xvip_dma_try_format(dma, &format->fmt.pix, &info);
607
608 if (vb2_is_busy(&dma->queue))
609 return -EBUSY;
610
611 dma->format = format->fmt.pix;
612 dma->fmtinfo = info;
613
614 return 0;
615}
616
617static const struct v4l2_ioctl_ops xvip_dma_ioctl_ops = {
618 .vidioc_querycap = xvip_dma_querycap,
619 .vidioc_enum_fmt_vid_cap = xvip_dma_enum_format,
620 .vidioc_g_fmt_vid_cap = xvip_dma_get_format,
621 .vidioc_g_fmt_vid_out = xvip_dma_get_format,
622 .vidioc_s_fmt_vid_cap = xvip_dma_set_format,
623 .vidioc_s_fmt_vid_out = xvip_dma_set_format,
624 .vidioc_try_fmt_vid_cap = xvip_dma_try_format,
625 .vidioc_try_fmt_vid_out = xvip_dma_try_format,
626 .vidioc_reqbufs = vb2_ioctl_reqbufs,
627 .vidioc_querybuf = vb2_ioctl_querybuf,
628 .vidioc_qbuf = vb2_ioctl_qbuf,
629 .vidioc_dqbuf = vb2_ioctl_dqbuf,
630 .vidioc_create_bufs = vb2_ioctl_create_bufs,
631 .vidioc_expbuf = vb2_ioctl_expbuf,
632 .vidioc_streamon = vb2_ioctl_streamon,
633 .vidioc_streamoff = vb2_ioctl_streamoff,
634};
635
636/* -----------------------------------------------------------------------------
637 * V4L2 file operations
638 */
639
640static const struct v4l2_file_operations xvip_dma_fops = {
641 .owner = THIS_MODULE,
642 .unlocked_ioctl = video_ioctl2,
643 .open = v4l2_fh_open,
644 .release = vb2_fop_release,
645 .poll = vb2_fop_poll,
646 .mmap = vb2_fop_mmap,
647};
648
649/* -----------------------------------------------------------------------------
650 * Xilinx Video DMA Core
651 */
652
653int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
654 enum v4l2_buf_type type, unsigned int port)
655{
656 char name[14];
657 int ret;
658
659 dma->xdev = xdev;
660 dma->port = port;
661 mutex_init(&dma->lock);
662 mutex_init(&dma->pipe.lock);
663 INIT_LIST_HEAD(&dma->queued_bufs);
664 spin_lock_init(&dma->queued_lock);
665
666 dma->fmtinfo = xvip_get_format_by_fourcc(XVIP_DMA_DEF_FORMAT);
667 dma->format.pixelformat = dma->fmtinfo->fourcc;
668 dma->format.colorspace = V4L2_COLORSPACE_SRGB;
669 dma->format.field = V4L2_FIELD_NONE;
670 dma->format.width = XVIP_DMA_DEF_WIDTH;
671 dma->format.height = XVIP_DMA_DEF_HEIGHT;
672 dma->format.bytesperline = dma->format.width * dma->fmtinfo->bpp;
673 dma->format.sizeimage = dma->format.bytesperline * dma->format.height;
674
675 /* Initialize the media entity... */
676 dma->pad.flags = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
677 ? MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
678
679 ret = media_entity_init(&dma->video.entity, 1, &dma->pad, 0);
680 if (ret < 0)
681 goto error;
682
683 /* ... and the video node... */
684 dma->video.fops = &xvip_dma_fops;
685 dma->video.v4l2_dev = &xdev->v4l2_dev;
686 dma->video.queue = &dma->queue;
687 snprintf(dma->video.name, sizeof(dma->video.name), "%s %s %u",
688 xdev->dev->of_node->name,
689 type == V4L2_BUF_TYPE_VIDEO_CAPTURE ? "output" : "input",
690 port);
691 dma->video.vfl_type = VFL_TYPE_GRABBER;
692 dma->video.vfl_dir = type == V4L2_BUF_TYPE_VIDEO_CAPTURE
693 ? VFL_DIR_RX : VFL_DIR_TX;
694 dma->video.release = video_device_release_empty;
695 dma->video.ioctl_ops = &xvip_dma_ioctl_ops;
696 dma->video.lock = &dma->lock;
697
698 video_set_drvdata(&dma->video, dma);
699
700 /* ... and the buffers queue... */
701 dma->alloc_ctx = vb2_dma_contig_init_ctx(dma->xdev->dev);
702 if (IS_ERR(dma->alloc_ctx))
703 goto error;
704
705 /* Don't enable VB2_READ and VB2_WRITE, as using the read() and write()
706 * V4L2 APIs would be inefficient. Testing on the command line with a
707 * 'cat /dev/video?' thus won't be possible, but given that the driver
708 * anyway requires a test tool to setup the pipeline before any video
709 * stream can be started, requiring a specific V4L2 test tool as well
710 * instead of 'cat' isn't really a drawback.
711 */
712 dma->queue.type = type;
713 dma->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
714 dma->queue.lock = &dma->lock;
715 dma->queue.drv_priv = dma;
716 dma->queue.buf_struct_size = sizeof(struct xvip_dma_buffer);
717 dma->queue.ops = &xvip_dma_queue_qops;
718 dma->queue.mem_ops = &vb2_dma_contig_memops;
719 dma->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
720 | V4L2_BUF_FLAG_TSTAMP_SRC_EOF;
721 ret = vb2_queue_init(&dma->queue);
722 if (ret < 0) {
723 dev_err(dma->xdev->dev, "failed to initialize VB2 queue\n");
724 goto error;
725 }
726
727 /* ... and the DMA channel. */
728 sprintf(name, "port%u", port);
729 dma->dma = dma_request_slave_channel(dma->xdev->dev, name);
730 if (dma->dma == NULL) {
731 dev_err(dma->xdev->dev, "no VDMA channel found\n");
732 ret = -ENODEV;
733 goto error;
734 }
735
736 dma->align = 1 << dma->dma->device->copy_align;
737
738 ret = video_register_device(&dma->video, VFL_TYPE_GRABBER, -1);
739 if (ret < 0) {
740 dev_err(dma->xdev->dev, "failed to register video device\n");
741 goto error;
742 }
743
744 return 0;
745
746error:
747 xvip_dma_cleanup(dma);
748 return ret;
749}
750
751void xvip_dma_cleanup(struct xvip_dma *dma)
752{
753 if (video_is_registered(&dma->video))
754 video_unregister_device(&dma->video);
755
756 if (dma->dma)
757 dma_release_channel(dma->dma);
758
759 if (!IS_ERR_OR_NULL(dma->alloc_ctx))
760 vb2_dma_contig_cleanup_ctx(dma->alloc_ctx);
761
762 media_entity_cleanup(&dma->video.entity);
763
764 mutex_destroy(&dma->lock);
765 mutex_destroy(&dma->pipe.lock);
766}
diff --git a/drivers/media/platform/xilinx/xilinx-dma.h b/drivers/media/platform/xilinx/xilinx-dma.h
new file mode 100644
index 000000000000..a540111f8d3d
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-dma.h
@@ -0,0 +1,109 @@
1/*
2 * Xilinx Video DMA
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __XILINX_VIP_DMA_H__
16#define __XILINX_VIP_DMA_H__
17
18#include <linux/dmaengine.h>
19#include <linux/mutex.h>
20#include <linux/spinlock.h>
21#include <linux/videodev2.h>
22
23#include <media/media-entity.h>
24#include <media/v4l2-dev.h>
25#include <media/videobuf2-core.h>
26
27struct dma_chan;
28struct xvip_composite_device;
29struct xvip_video_format;
30
31/**
32 * struct xvip_pipeline - Xilinx Video IP pipeline structure
33 * @pipe: media pipeline
34 * @lock: protects the pipeline @stream_count
35 * @use_count: number of DMA engines using the pipeline
36 * @stream_count: number of DMA engines currently streaming
37 * @num_dmas: number of DMA engines in the pipeline
38 * @output: DMA engine at the output of the pipeline
39 */
40struct xvip_pipeline {
41 struct media_pipeline pipe;
42
43 struct mutex lock;
44 unsigned int use_count;
45 unsigned int stream_count;
46
47 unsigned int num_dmas;
48 struct xvip_dma *output;
49};
50
51static inline struct xvip_pipeline *to_xvip_pipeline(struct media_entity *e)
52{
53 return container_of(e->pipe, struct xvip_pipeline, pipe);
54}
55
56/**
57 * struct xvip_dma - Video DMA channel
58 * @list: list entry in a composite device dmas list
59 * @video: V4L2 video device associated with the DMA channel
60 * @pad: media pad for the video device entity
61 * @xdev: composite device the DMA channel belongs to
62 * @pipe: pipeline belonging to the DMA channel
63 * @port: composite device DT node port number for the DMA channel
64 * @lock: protects the @format, @fmtinfo and @queue fields
65 * @format: active V4L2 pixel format
66 * @fmtinfo: format information corresponding to the active @format
67 * @queue: vb2 buffers queue
68 * @alloc_ctx: allocation context for the vb2 @queue
69 * @sequence: V4L2 buffers sequence number
70 * @queued_bufs: list of queued buffers
71 * @queued_lock: protects the buf_queued list
72 * @dma: DMA engine channel
73 * @align: transfer alignment required by the DMA channel (in bytes)
74 * @xt: dma interleaved template for dma configuration
75 * @sgl: data chunk structure for dma_interleaved_template
76 */
77struct xvip_dma {
78 struct list_head list;
79 struct video_device video;
80 struct media_pad pad;
81
82 struct xvip_composite_device *xdev;
83 struct xvip_pipeline pipe;
84 unsigned int port;
85
86 struct mutex lock;
87 struct v4l2_pix_format format;
88 const struct xvip_video_format *fmtinfo;
89
90 struct vb2_queue queue;
91 void *alloc_ctx;
92 unsigned int sequence;
93
94 struct list_head queued_bufs;
95 spinlock_t queued_lock;
96
97 struct dma_chan *dma;
98 unsigned int align;
99 struct dma_interleaved_template xt;
100 struct data_chunk sgl[1];
101};
102
103#define to_xvip_dma(vdev) container_of(vdev, struct xvip_dma, video)
104
105int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma,
106 enum v4l2_buf_type type, unsigned int port);
107void xvip_dma_cleanup(struct xvip_dma *dma);
108
109#endif /* __XILINX_VIP_DMA_H__ */
diff --git a/drivers/media/platform/xilinx/xilinx-tpg.c b/drivers/media/platform/xilinx/xilinx-tpg.c
new file mode 100644
index 000000000000..b5f7d5ecb7f6
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-tpg.c
@@ -0,0 +1,931 @@
1/*
2 * Xilinx Test Pattern Generator
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/device.h>
16#include <linux/gpio/consumer.h>
17#include <linux/module.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20#include <linux/xilinx-v4l2-controls.h>
21
22#include <media/v4l2-async.h>
23#include <media/v4l2-ctrls.h>
24#include <media/v4l2-subdev.h>
25
26#include "xilinx-vip.h"
27#include "xilinx-vtc.h"
28
29#define XTPG_CTRL_STATUS_SLAVE_ERROR (1 << 16)
30#define XTPG_CTRL_IRQ_SLAVE_ERROR (1 << 16)
31
32#define XTPG_PATTERN_CONTROL 0x0100
33#define XTPG_PATTERN_MASK (0xf << 0)
34#define XTPG_PATTERN_CONTROL_CROSS_HAIRS (1 << 4)
35#define XTPG_PATTERN_CONTROL_MOVING_BOX (1 << 5)
36#define XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT 6
37#define XTPG_PATTERN_CONTROL_COLOR_MASK_MASK (0xf << 6)
38#define XTPG_PATTERN_CONTROL_STUCK_PIXEL (1 << 9)
39#define XTPG_PATTERN_CONTROL_NOISE (1 << 10)
40#define XTPG_PATTERN_CONTROL_MOTION (1 << 12)
41#define XTPG_MOTION_SPEED 0x0104
42#define XTPG_CROSS_HAIRS 0x0108
43#define XTPG_CROSS_HAIRS_ROW_SHIFT 0
44#define XTPG_CROSS_HAIRS_ROW_MASK (0xfff << 0)
45#define XTPG_CROSS_HAIRS_COLUMN_SHIFT 16
46#define XTPG_CROSS_HAIRS_COLUMN_MASK (0xfff << 16)
47#define XTPG_ZPLATE_HOR_CONTROL 0x010c
48#define XTPG_ZPLATE_VER_CONTROL 0x0110
49#define XTPG_ZPLATE_START_SHIFT 0
50#define XTPG_ZPLATE_START_MASK (0xffff << 0)
51#define XTPG_ZPLATE_SPEED_SHIFT 16
52#define XTPG_ZPLATE_SPEED_MASK (0xffff << 16)
53#define XTPG_BOX_SIZE 0x0114
54#define XTPG_BOX_COLOR 0x0118
55#define XTPG_STUCK_PIXEL_THRESH 0x011c
56#define XTPG_NOISE_GAIN 0x0120
57#define XTPG_BAYER_PHASE 0x0124
58#define XTPG_BAYER_PHASE_RGGB 0
59#define XTPG_BAYER_PHASE_GRBG 1
60#define XTPG_BAYER_PHASE_GBRG 2
61#define XTPG_BAYER_PHASE_BGGR 3
62#define XTPG_BAYER_PHASE_OFF 4
63
64/*
65 * The minimum blanking value is one clock cycle for the front porch, one clock
66 * cycle for the sync pulse and one clock cycle for the back porch.
67 */
68#define XTPG_MIN_HBLANK 3
69#define XTPG_MAX_HBLANK (XVTC_MAX_HSIZE - XVIP_MIN_WIDTH)
70#define XTPG_MIN_VBLANK 3
71#define XTPG_MAX_VBLANK (XVTC_MAX_VSIZE - XVIP_MIN_HEIGHT)
72
73/**
74 * struct xtpg_device - Xilinx Test Pattern Generator device structure
75 * @xvip: Xilinx Video IP device
76 * @pads: media pads
77 * @npads: number of pads (1 or 2)
78 * @has_input: whether an input is connected to the sink pad
79 * @formats: active V4L2 media bus format for each pad
80 * @default_format: default V4L2 media bus format
81 * @vip_format: format information corresponding to the active format
82 * @bayer: boolean flag if TPG is set to any bayer format
83 * @ctrl_handler: control handler
84 * @hblank: horizontal blanking control
85 * @vblank: vertical blanking control
86 * @pattern: test pattern control
87 * @streaming: is the video stream active
88 * @vtc: video timing controller
89 * @vtmux_gpio: video timing mux GPIO
90 */
91struct xtpg_device {
92 struct xvip_device xvip;
93
94 struct media_pad pads[2];
95 unsigned int npads;
96 bool has_input;
97
98 struct v4l2_mbus_framefmt formats[2];
99 struct v4l2_mbus_framefmt default_format;
100 const struct xvip_video_format *vip_format;
101 bool bayer;
102
103 struct v4l2_ctrl_handler ctrl_handler;
104 struct v4l2_ctrl *hblank;
105 struct v4l2_ctrl *vblank;
106 struct v4l2_ctrl *pattern;
107 bool streaming;
108
109 struct xvtc_device *vtc;
110 struct gpio_desc *vtmux_gpio;
111};
112
113static inline struct xtpg_device *to_tpg(struct v4l2_subdev *subdev)
114{
115 return container_of(subdev, struct xtpg_device, xvip.subdev);
116}
117
118static u32 xtpg_get_bayer_phase(unsigned int code)
119{
120 switch (code) {
121 case MEDIA_BUS_FMT_SRGGB8_1X8:
122 return XTPG_BAYER_PHASE_RGGB;
123 case MEDIA_BUS_FMT_SGRBG8_1X8:
124 return XTPG_BAYER_PHASE_GRBG;
125 case MEDIA_BUS_FMT_SGBRG8_1X8:
126 return XTPG_BAYER_PHASE_GBRG;
127 case MEDIA_BUS_FMT_SBGGR8_1X8:
128 return XTPG_BAYER_PHASE_BGGR;
129 default:
130 return XTPG_BAYER_PHASE_OFF;
131 }
132}
133
134static void __xtpg_update_pattern_control(struct xtpg_device *xtpg,
135 bool passthrough, bool pattern)
136{
137 u32 pattern_mask = (1 << (xtpg->pattern->maximum + 1)) - 1;
138
139 /*
140 * If the TPG has no sink pad or no input connected to its sink pad
141 * passthrough mode can't be enabled.
142 */
143 if (xtpg->npads == 1 || !xtpg->has_input)
144 passthrough = false;
145
146 /* If passthrough mode is allowed unmask bit 0. */
147 if (passthrough)
148 pattern_mask &= ~1;
149
150 /* If test pattern mode is allowed unmask all other bits. */
151 if (pattern)
152 pattern_mask &= 1;
153
154 __v4l2_ctrl_modify_range(xtpg->pattern, 0, xtpg->pattern->maximum,
155 pattern_mask, pattern ? 9 : 0);
156}
157
158static void xtpg_update_pattern_control(struct xtpg_device *xtpg,
159 bool passthrough, bool pattern)
160{
161 mutex_lock(xtpg->ctrl_handler.lock);
162 __xtpg_update_pattern_control(xtpg, passthrough, pattern);
163 mutex_unlock(xtpg->ctrl_handler.lock);
164}
165
166/* -----------------------------------------------------------------------------
167 * V4L2 Subdevice Video Operations
168 */
169
170static int xtpg_s_stream(struct v4l2_subdev *subdev, int enable)
171{
172 struct xtpg_device *xtpg = to_tpg(subdev);
173 unsigned int width = xtpg->formats[0].width;
174 unsigned int height = xtpg->formats[0].height;
175 bool passthrough;
176 u32 bayer_phase;
177
178 if (!enable) {
179 xvip_stop(&xtpg->xvip);
180 if (xtpg->vtc)
181 xvtc_generator_stop(xtpg->vtc);
182
183 xtpg_update_pattern_control(xtpg, true, true);
184 xtpg->streaming = false;
185 return 0;
186 }
187
188 xvip_set_frame_size(&xtpg->xvip, &xtpg->formats[0]);
189
190 if (xtpg->vtc) {
191 struct xvtc_config config = {
192 .hblank_start = width,
193 .hsync_start = width + 1,
194 .vblank_start = height,
195 .vsync_start = height + 1,
196 };
197 unsigned int htotal;
198 unsigned int vtotal;
199
200 htotal = min_t(unsigned int, XVTC_MAX_HSIZE,
201 v4l2_ctrl_g_ctrl(xtpg->hblank) + width);
202 vtotal = min_t(unsigned int, XVTC_MAX_VSIZE,
203 v4l2_ctrl_g_ctrl(xtpg->vblank) + height);
204
205 config.hsync_end = htotal - 1;
206 config.hsize = htotal;
207 config.vsync_end = vtotal - 1;
208 config.vsize = vtotal;
209
210 xvtc_generator_start(xtpg->vtc, &config);
211 }
212
213 /*
214 * Configure the bayer phase and video timing mux based on the
215 * operation mode (passthrough or test pattern generation). The test
216 * pattern can be modified by the control set handler, we thus need to
217 * take the control lock here to avoid races.
218 */
219 mutex_lock(xtpg->ctrl_handler.lock);
220
221 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
222 XTPG_PATTERN_MASK, xtpg->pattern->cur.val);
223
224 /*
225 * Switching between passthrough and test pattern generation modes isn't
226 * allowed during streaming, update the control range accordingly.
227 */
228 passthrough = xtpg->pattern->cur.val == 0;
229 __xtpg_update_pattern_control(xtpg, passthrough, !passthrough);
230
231 xtpg->streaming = true;
232
233 mutex_unlock(xtpg->ctrl_handler.lock);
234
235 /*
236 * For TPG v5.0, the bayer phase needs to be off for the pass through
237 * mode, otherwise the external input would be subsampled.
238 */
239 bayer_phase = passthrough ? XTPG_BAYER_PHASE_OFF
240 : xtpg_get_bayer_phase(xtpg->formats[0].code);
241 xvip_write(&xtpg->xvip, XTPG_BAYER_PHASE, bayer_phase);
242
243 if (xtpg->vtmux_gpio)
244 gpiod_set_value_cansleep(xtpg->vtmux_gpio, !passthrough);
245
246 xvip_start(&xtpg->xvip);
247
248 return 0;
249}
250
251/* -----------------------------------------------------------------------------
252 * V4L2 Subdevice Pad Operations
253 */
254
255static struct v4l2_mbus_framefmt *
256__xtpg_get_pad_format(struct xtpg_device *xtpg,
257 struct v4l2_subdev_pad_config *cfg,
258 unsigned int pad, u32 which)
259{
260 switch (which) {
261 case V4L2_SUBDEV_FORMAT_TRY:
262 return v4l2_subdev_get_try_format(&xtpg->xvip.subdev, cfg, pad);
263 case V4L2_SUBDEV_FORMAT_ACTIVE:
264 return &xtpg->formats[pad];
265 default:
266 return NULL;
267 }
268}
269
270static int xtpg_get_format(struct v4l2_subdev *subdev,
271 struct v4l2_subdev_pad_config *cfg,
272 struct v4l2_subdev_format *fmt)
273{
274 struct xtpg_device *xtpg = to_tpg(subdev);
275
276 fmt->format = *__xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which);
277
278 return 0;
279}
280
281static int xtpg_set_format(struct v4l2_subdev *subdev,
282 struct v4l2_subdev_pad_config *cfg,
283 struct v4l2_subdev_format *fmt)
284{
285 struct xtpg_device *xtpg = to_tpg(subdev);
286 struct v4l2_mbus_framefmt *__format;
287 u32 bayer_phase;
288
289 __format = __xtpg_get_pad_format(xtpg, cfg, fmt->pad, fmt->which);
290
291 /* In two pads mode the source pad format is always identical to the
292 * sink pad format.
293 */
294 if (xtpg->npads == 2 && fmt->pad == 1) {
295 fmt->format = *__format;
296 return 0;
297 }
298
299 /* Bayer phase is configurable at runtime */
300 if (xtpg->bayer) {
301 bayer_phase = xtpg_get_bayer_phase(fmt->format.code);
302 if (bayer_phase != XTPG_BAYER_PHASE_OFF)
303 __format->code = fmt->format.code;
304 }
305
306 xvip_set_format_size(__format, fmt);
307
308 fmt->format = *__format;
309
310 /* Propagate the format to the source pad. */
311 if (xtpg->npads == 2) {
312 __format = __xtpg_get_pad_format(xtpg, cfg, 1, fmt->which);
313 *__format = fmt->format;
314 }
315
316 return 0;
317}
318
319/* -----------------------------------------------------------------------------
320 * V4L2 Subdevice Operations
321 */
322
323static int xtpg_enum_frame_size(struct v4l2_subdev *subdev,
324 struct v4l2_subdev_pad_config *cfg,
325 struct v4l2_subdev_frame_size_enum *fse)
326{
327 struct v4l2_mbus_framefmt *format;
328
329 format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad);
330
331 if (fse->index || fse->code != format->code)
332 return -EINVAL;
333
334 /* Min / max values for pad 0 is always fixed in both one and two pads
335 * modes. In two pads mode, the source pad(= 1) size is identical to
336 * the sink pad size */
337 if (fse->pad == 0) {
338 fse->min_width = XVIP_MIN_WIDTH;
339 fse->max_width = XVIP_MAX_WIDTH;
340 fse->min_height = XVIP_MIN_HEIGHT;
341 fse->max_height = XVIP_MAX_HEIGHT;
342 } else {
343 fse->min_width = format->width;
344 fse->max_width = format->width;
345 fse->min_height = format->height;
346 fse->max_height = format->height;
347 }
348
349 return 0;
350}
351
352static int xtpg_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
353{
354 struct xtpg_device *xtpg = to_tpg(subdev);
355 struct v4l2_mbus_framefmt *format;
356
357 format = v4l2_subdev_get_try_format(subdev, fh->pad, 0);
358 *format = xtpg->default_format;
359
360 if (xtpg->npads == 2) {
361 format = v4l2_subdev_get_try_format(subdev, fh->pad, 1);
362 *format = xtpg->default_format;
363 }
364
365 return 0;
366}
367
368static int xtpg_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
369{
370 return 0;
371}
372
373static int xtpg_s_ctrl(struct v4l2_ctrl *ctrl)
374{
375 struct xtpg_device *xtpg = container_of(ctrl->handler,
376 struct xtpg_device,
377 ctrl_handler);
378 switch (ctrl->id) {
379 case V4L2_CID_TEST_PATTERN:
380 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
381 XTPG_PATTERN_MASK, ctrl->val);
382 return 0;
383 case V4L2_CID_XILINX_TPG_CROSS_HAIRS:
384 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
385 XTPG_PATTERN_CONTROL_CROSS_HAIRS, ctrl->val);
386 return 0;
387 case V4L2_CID_XILINX_TPG_MOVING_BOX:
388 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
389 XTPG_PATTERN_CONTROL_MOVING_BOX, ctrl->val);
390 return 0;
391 case V4L2_CID_XILINX_TPG_COLOR_MASK:
392 xvip_clr_and_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
393 XTPG_PATTERN_CONTROL_COLOR_MASK_MASK,
394 ctrl->val <<
395 XTPG_PATTERN_CONTROL_COLOR_MASK_SHIFT);
396 return 0;
397 case V4L2_CID_XILINX_TPG_STUCK_PIXEL:
398 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
399 XTPG_PATTERN_CONTROL_STUCK_PIXEL, ctrl->val);
400 return 0;
401 case V4L2_CID_XILINX_TPG_NOISE:
402 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
403 XTPG_PATTERN_CONTROL_NOISE, ctrl->val);
404 return 0;
405 case V4L2_CID_XILINX_TPG_MOTION:
406 xvip_clr_or_set(&xtpg->xvip, XTPG_PATTERN_CONTROL,
407 XTPG_PATTERN_CONTROL_MOTION, ctrl->val);
408 return 0;
409 case V4L2_CID_XILINX_TPG_MOTION_SPEED:
410 xvip_write(&xtpg->xvip, XTPG_MOTION_SPEED, ctrl->val);
411 return 0;
412 case V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW:
413 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
414 XTPG_CROSS_HAIRS_ROW_MASK,
415 ctrl->val << XTPG_CROSS_HAIRS_ROW_SHIFT);
416 return 0;
417 case V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN:
418 xvip_clr_and_set(&xtpg->xvip, XTPG_CROSS_HAIRS,
419 XTPG_CROSS_HAIRS_COLUMN_MASK,
420 ctrl->val << XTPG_CROSS_HAIRS_COLUMN_SHIFT);
421 return 0;
422 case V4L2_CID_XILINX_TPG_ZPLATE_HOR_START:
423 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
424 XTPG_ZPLATE_START_MASK,
425 ctrl->val << XTPG_ZPLATE_START_SHIFT);
426 return 0;
427 case V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED:
428 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_HOR_CONTROL,
429 XTPG_ZPLATE_SPEED_MASK,
430 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
431 return 0;
432 case V4L2_CID_XILINX_TPG_ZPLATE_VER_START:
433 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
434 XTPG_ZPLATE_START_MASK,
435 ctrl->val << XTPG_ZPLATE_START_SHIFT);
436 return 0;
437 case V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED:
438 xvip_clr_and_set(&xtpg->xvip, XTPG_ZPLATE_VER_CONTROL,
439 XTPG_ZPLATE_SPEED_MASK,
440 ctrl->val << XTPG_ZPLATE_SPEED_SHIFT);
441 return 0;
442 case V4L2_CID_XILINX_TPG_BOX_SIZE:
443 xvip_write(&xtpg->xvip, XTPG_BOX_SIZE, ctrl->val);
444 return 0;
445 case V4L2_CID_XILINX_TPG_BOX_COLOR:
446 xvip_write(&xtpg->xvip, XTPG_BOX_COLOR, ctrl->val);
447 return 0;
448 case V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH:
449 xvip_write(&xtpg->xvip, XTPG_STUCK_PIXEL_THRESH, ctrl->val);
450 return 0;
451 case V4L2_CID_XILINX_TPG_NOISE_GAIN:
452 xvip_write(&xtpg->xvip, XTPG_NOISE_GAIN, ctrl->val);
453 return 0;
454 }
455
456 return 0;
457}
458
459static const struct v4l2_ctrl_ops xtpg_ctrl_ops = {
460 .s_ctrl = xtpg_s_ctrl,
461};
462
463static struct v4l2_subdev_core_ops xtpg_core_ops = {
464};
465
466static struct v4l2_subdev_video_ops xtpg_video_ops = {
467 .s_stream = xtpg_s_stream,
468};
469
470static struct v4l2_subdev_pad_ops xtpg_pad_ops = {
471 .enum_mbus_code = xvip_enum_mbus_code,
472 .enum_frame_size = xtpg_enum_frame_size,
473 .get_fmt = xtpg_get_format,
474 .set_fmt = xtpg_set_format,
475};
476
477static struct v4l2_subdev_ops xtpg_ops = {
478 .core = &xtpg_core_ops,
479 .video = &xtpg_video_ops,
480 .pad = &xtpg_pad_ops,
481};
482
483static const struct v4l2_subdev_internal_ops xtpg_internal_ops = {
484 .open = xtpg_open,
485 .close = xtpg_close,
486};
487
488/*
489 * Control Config
490 */
491
492static const char *const xtpg_pattern_strings[] = {
493 "Passthrough",
494 "Horizontal Ramp",
495 "Vertical Ramp",
496 "Temporal Ramp",
497 "Solid Red",
498 "Solid Green",
499 "Solid Blue",
500 "Solid Black",
501 "Solid White",
502 "Color Bars",
503 "Zone Plate",
504 "Tartan Color Bars",
505 "Cross Hatch",
506 "None",
507 "Vertical/Horizontal Ramps",
508 "Black/White Checker Board",
509};
510
511static struct v4l2_ctrl_config xtpg_ctrls[] = {
512 {
513 .ops = &xtpg_ctrl_ops,
514 .id = V4L2_CID_XILINX_TPG_CROSS_HAIRS,
515 .name = "Test Pattern: Cross Hairs",
516 .type = V4L2_CTRL_TYPE_BOOLEAN,
517 .min = false,
518 .max = true,
519 .step = 1,
520 .def = 0,
521 }, {
522 .ops = &xtpg_ctrl_ops,
523 .id = V4L2_CID_XILINX_TPG_MOVING_BOX,
524 .name = "Test Pattern: Moving Box",
525 .type = V4L2_CTRL_TYPE_BOOLEAN,
526 .min = false,
527 .max = true,
528 .step = 1,
529 .def = 0,
530 }, {
531 .ops = &xtpg_ctrl_ops,
532 .id = V4L2_CID_XILINX_TPG_COLOR_MASK,
533 .name = "Test Pattern: Color Mask",
534 .type = V4L2_CTRL_TYPE_BITMASK,
535 .min = 0,
536 .max = 0xf,
537 .def = 0,
538 }, {
539 .ops = &xtpg_ctrl_ops,
540 .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL,
541 .name = "Test Pattern: Stuck Pixel",
542 .type = V4L2_CTRL_TYPE_BOOLEAN,
543 .min = false,
544 .max = true,
545 .step = 1,
546 .def = 0,
547 }, {
548 .ops = &xtpg_ctrl_ops,
549 .id = V4L2_CID_XILINX_TPG_NOISE,
550 .name = "Test Pattern: Noise",
551 .type = V4L2_CTRL_TYPE_BOOLEAN,
552 .min = false,
553 .max = true,
554 .step = 1,
555 .def = 0,
556 }, {
557 .ops = &xtpg_ctrl_ops,
558 .id = V4L2_CID_XILINX_TPG_MOTION,
559 .name = "Test Pattern: Motion",
560 .type = V4L2_CTRL_TYPE_BOOLEAN,
561 .min = false,
562 .max = true,
563 .step = 1,
564 .def = 0,
565 }, {
566 .ops = &xtpg_ctrl_ops,
567 .id = V4L2_CID_XILINX_TPG_MOTION_SPEED,
568 .name = "Test Pattern: Motion Speed",
569 .type = V4L2_CTRL_TYPE_INTEGER,
570 .min = 0,
571 .max = (1 << 8) - 1,
572 .step = 1,
573 .def = 4,
574 .flags = V4L2_CTRL_FLAG_SLIDER,
575 }, {
576 .ops = &xtpg_ctrl_ops,
577 .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_ROW,
578 .name = "Test Pattern: Cross Hairs Row",
579 .type = V4L2_CTRL_TYPE_INTEGER,
580 .min = 0,
581 .max = (1 << 12) - 1,
582 .step = 1,
583 .def = 0x64,
584 .flags = V4L2_CTRL_FLAG_SLIDER,
585 }, {
586 .ops = &xtpg_ctrl_ops,
587 .id = V4L2_CID_XILINX_TPG_CROSS_HAIR_COLUMN,
588 .name = "Test Pattern: Cross Hairs Column",
589 .type = V4L2_CTRL_TYPE_INTEGER,
590 .min = 0,
591 .max = (1 << 12) - 1,
592 .step = 1,
593 .def = 0x64,
594 .flags = V4L2_CTRL_FLAG_SLIDER,
595 }, {
596 .ops = &xtpg_ctrl_ops,
597 .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_START,
598 .name = "Test Pattern: Zplate Horizontal Start Pos",
599 .type = V4L2_CTRL_TYPE_INTEGER,
600 .min = 0,
601 .max = (1 << 16) - 1,
602 .step = 1,
603 .def = 0x1e,
604 .flags = V4L2_CTRL_FLAG_SLIDER,
605 }, {
606 .ops = &xtpg_ctrl_ops,
607 .id = V4L2_CID_XILINX_TPG_ZPLATE_HOR_SPEED,
608 .name = "Test Pattern: Zplate Horizontal Speed",
609 .type = V4L2_CTRL_TYPE_INTEGER,
610 .min = 0,
611 .max = (1 << 16) - 1,
612 .step = 1,
613 .def = 0,
614 .flags = V4L2_CTRL_FLAG_SLIDER,
615 }, {
616 .ops = &xtpg_ctrl_ops,
617 .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_START,
618 .name = "Test Pattern: Zplate Vertical Start Pos",
619 .type = V4L2_CTRL_TYPE_INTEGER,
620 .min = 0,
621 .max = (1 << 16) - 1,
622 .step = 1,
623 .def = 1,
624 .flags = V4L2_CTRL_FLAG_SLIDER,
625 }, {
626 .ops = &xtpg_ctrl_ops,
627 .id = V4L2_CID_XILINX_TPG_ZPLATE_VER_SPEED,
628 .name = "Test Pattern: Zplate Vertical Speed",
629 .type = V4L2_CTRL_TYPE_INTEGER,
630 .min = 0,
631 .max = (1 << 16) - 1,
632 .step = 1,
633 .def = 0,
634 .flags = V4L2_CTRL_FLAG_SLIDER,
635 }, {
636 .ops = &xtpg_ctrl_ops,
637 .id = V4L2_CID_XILINX_TPG_BOX_SIZE,
638 .name = "Test Pattern: Box Size",
639 .type = V4L2_CTRL_TYPE_INTEGER,
640 .min = 0,
641 .max = (1 << 12) - 1,
642 .step = 1,
643 .def = 0x32,
644 .flags = V4L2_CTRL_FLAG_SLIDER,
645 }, {
646 .ops = &xtpg_ctrl_ops,
647 .id = V4L2_CID_XILINX_TPG_BOX_COLOR,
648 .name = "Test Pattern: Box Color(RGB)",
649 .type = V4L2_CTRL_TYPE_INTEGER,
650 .min = 0,
651 .max = (1 << 24) - 1,
652 .step = 1,
653 .def = 0,
654 }, {
655 .ops = &xtpg_ctrl_ops,
656 .id = V4L2_CID_XILINX_TPG_STUCK_PIXEL_THRESH,
657 .name = "Test Pattern: Stuck Pixel threshold",
658 .type = V4L2_CTRL_TYPE_INTEGER,
659 .min = 0,
660 .max = (1 << 16) - 1,
661 .step = 1,
662 .def = 0,
663 .flags = V4L2_CTRL_FLAG_SLIDER,
664 }, {
665 .ops = &xtpg_ctrl_ops,
666 .id = V4L2_CID_XILINX_TPG_NOISE_GAIN,
667 .name = "Test Pattern: Noise Gain",
668 .type = V4L2_CTRL_TYPE_INTEGER,
669 .min = 0,
670 .max = (1 << 8) - 1,
671 .step = 1,
672 .def = 0,
673 .flags = V4L2_CTRL_FLAG_SLIDER,
674 },
675};
676
677/* -----------------------------------------------------------------------------
678 * Media Operations
679 */
680
681static const struct media_entity_operations xtpg_media_ops = {
682 .link_validate = v4l2_subdev_link_validate,
683};
684
685/* -----------------------------------------------------------------------------
686 * Power Management
687 */
688
689static int __maybe_unused xtpg_pm_suspend(struct device *dev)
690{
691 struct xtpg_device *xtpg = dev_get_drvdata(dev);
692
693 xvip_suspend(&xtpg->xvip);
694
695 return 0;
696}
697
698static int __maybe_unused xtpg_pm_resume(struct device *dev)
699{
700 struct xtpg_device *xtpg = dev_get_drvdata(dev);
701
702 xvip_resume(&xtpg->xvip);
703
704 return 0;
705}
706
707/* -----------------------------------------------------------------------------
708 * Platform Device Driver
709 */
710
711static int xtpg_parse_of(struct xtpg_device *xtpg)
712{
713 struct device *dev = xtpg->xvip.dev;
714 struct device_node *node = xtpg->xvip.dev->of_node;
715 struct device_node *ports;
716 struct device_node *port;
717 unsigned int nports = 0;
718 bool has_endpoint = false;
719
720 ports = of_get_child_by_name(node, "ports");
721 if (ports == NULL)
722 ports = node;
723
724 for_each_child_of_node(ports, port) {
725 const struct xvip_video_format *format;
726 struct device_node *endpoint;
727
728 if (!port->name || of_node_cmp(port->name, "port"))
729 continue;
730
731 format = xvip_of_get_format(port);
732 if (IS_ERR(format)) {
733 dev_err(dev, "invalid format in DT");
734 return PTR_ERR(format);
735 }
736
737 /* Get and check the format description */
738 if (!xtpg->vip_format) {
739 xtpg->vip_format = format;
740 } else if (xtpg->vip_format != format) {
741 dev_err(dev, "in/out format mismatch in DT");
742 return -EINVAL;
743 }
744
745 if (nports == 0) {
746 endpoint = of_get_next_child(port, NULL);
747 if (endpoint)
748 has_endpoint = true;
749 of_node_put(endpoint);
750 }
751
752 /* Count the number of ports. */
753 nports++;
754 }
755
756 if (nports != 1 && nports != 2) {
757 dev_err(dev, "invalid number of ports %u\n", nports);
758 return -EINVAL;
759 }
760
761 xtpg->npads = nports;
762 if (nports == 2 && has_endpoint)
763 xtpg->has_input = true;
764
765 return 0;
766}
767
768static int xtpg_probe(struct platform_device *pdev)
769{
770 struct v4l2_subdev *subdev;
771 struct xtpg_device *xtpg;
772 u32 i, bayer_phase;
773 int ret;
774
775 xtpg = devm_kzalloc(&pdev->dev, sizeof(*xtpg), GFP_KERNEL);
776 if (!xtpg)
777 return -ENOMEM;
778
779 xtpg->xvip.dev = &pdev->dev;
780
781 ret = xtpg_parse_of(xtpg);
782 if (ret < 0)
783 return ret;
784
785 ret = xvip_init_resources(&xtpg->xvip);
786 if (ret < 0)
787 return ret;
788
789 xtpg->vtmux_gpio = devm_gpiod_get_optional(&pdev->dev, "timing",
790 GPIOD_OUT_HIGH);
791 if (IS_ERR(xtpg->vtmux_gpio)) {
792 ret = PTR_ERR(xtpg->vtmux_gpio);
793 goto error_resource;
794 }
795
796 xtpg->vtc = xvtc_of_get(pdev->dev.of_node);
797 if (IS_ERR(xtpg->vtc)) {
798 ret = PTR_ERR(xtpg->vtc);
799 goto error_resource;
800 }
801
802 /* Reset and initialize the core */
803 xvip_reset(&xtpg->xvip);
804
805 /* Initialize V4L2 subdevice and media entity. Pad numbers depend on the
806 * number of pads.
807 */
808 if (xtpg->npads == 2) {
809 xtpg->pads[0].flags = MEDIA_PAD_FL_SINK;
810 xtpg->pads[1].flags = MEDIA_PAD_FL_SOURCE;
811 } else {
812 xtpg->pads[0].flags = MEDIA_PAD_FL_SOURCE;
813 }
814
815 /* Initialize the default format */
816 xtpg->default_format.code = xtpg->vip_format->code;
817 xtpg->default_format.field = V4L2_FIELD_NONE;
818 xtpg->default_format.colorspace = V4L2_COLORSPACE_SRGB;
819 xvip_get_frame_size(&xtpg->xvip, &xtpg->default_format);
820
821 bayer_phase = xtpg_get_bayer_phase(xtpg->vip_format->code);
822 if (bayer_phase != XTPG_BAYER_PHASE_OFF)
823 xtpg->bayer = true;
824
825 xtpg->formats[0] = xtpg->default_format;
826 if (xtpg->npads == 2)
827 xtpg->formats[1] = xtpg->default_format;
828
829 /* Initialize V4L2 subdevice and media entity */
830 subdev = &xtpg->xvip.subdev;
831 v4l2_subdev_init(subdev, &xtpg_ops);
832 subdev->dev = &pdev->dev;
833 subdev->internal_ops = &xtpg_internal_ops;
834 strlcpy(subdev->name, dev_name(&pdev->dev), sizeof(subdev->name));
835 v4l2_set_subdevdata(subdev, xtpg);
836 subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
837 subdev->entity.ops = &xtpg_media_ops;
838
839 ret = media_entity_init(&subdev->entity, xtpg->npads, xtpg->pads, 0);
840 if (ret < 0)
841 goto error;
842
843 v4l2_ctrl_handler_init(&xtpg->ctrl_handler, 3 + ARRAY_SIZE(xtpg_ctrls));
844
845 xtpg->vblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
846 V4L2_CID_VBLANK, XTPG_MIN_VBLANK,
847 XTPG_MAX_VBLANK, 1, 100);
848 xtpg->hblank = v4l2_ctrl_new_std(&xtpg->ctrl_handler, &xtpg_ctrl_ops,
849 V4L2_CID_HBLANK, XTPG_MIN_HBLANK,
850 XTPG_MAX_HBLANK, 1, 100);
851 xtpg->pattern = v4l2_ctrl_new_std_menu_items(&xtpg->ctrl_handler,
852 &xtpg_ctrl_ops, V4L2_CID_TEST_PATTERN,
853 ARRAY_SIZE(xtpg_pattern_strings) - 1,
854 1, 9, xtpg_pattern_strings);
855
856 for (i = 0; i < ARRAY_SIZE(xtpg_ctrls); i++)
857 v4l2_ctrl_new_custom(&xtpg->ctrl_handler, &xtpg_ctrls[i], NULL);
858
859 if (xtpg->ctrl_handler.error) {
860 dev_err(&pdev->dev, "failed to add controls\n");
861 ret = xtpg->ctrl_handler.error;
862 goto error;
863 }
864 subdev->ctrl_handler = &xtpg->ctrl_handler;
865
866 xtpg_update_pattern_control(xtpg, true, true);
867
868 ret = v4l2_ctrl_handler_setup(&xtpg->ctrl_handler);
869 if (ret < 0) {
870 dev_err(&pdev->dev, "failed to set controls\n");
871 goto error;
872 }
873
874 platform_set_drvdata(pdev, xtpg);
875
876 xvip_print_version(&xtpg->xvip);
877
878 ret = v4l2_async_register_subdev(subdev);
879 if (ret < 0) {
880 dev_err(&pdev->dev, "failed to register subdev\n");
881 goto error;
882 }
883
884 return 0;
885
886error:
887 v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
888 media_entity_cleanup(&subdev->entity);
889 xvtc_put(xtpg->vtc);
890error_resource:
891 xvip_cleanup_resources(&xtpg->xvip);
892 return ret;
893}
894
895static int xtpg_remove(struct platform_device *pdev)
896{
897 struct xtpg_device *xtpg = platform_get_drvdata(pdev);
898 struct v4l2_subdev *subdev = &xtpg->xvip.subdev;
899
900 v4l2_async_unregister_subdev(subdev);
901 v4l2_ctrl_handler_free(&xtpg->ctrl_handler);
902 media_entity_cleanup(&subdev->entity);
903
904 xvip_cleanup_resources(&xtpg->xvip);
905
906 return 0;
907}
908
909static SIMPLE_DEV_PM_OPS(xtpg_pm_ops, xtpg_pm_suspend, xtpg_pm_resume);
910
911static const struct of_device_id xtpg_of_id_table[] = {
912 { .compatible = "xlnx,v-tpg-5.0" },
913 { }
914};
915MODULE_DEVICE_TABLE(of, xtpg_of_id_table);
916
917static struct platform_driver xtpg_driver = {
918 .driver = {
919 .name = "xilinx-tpg",
920 .pm = &xtpg_pm_ops,
921 .of_match_table = xtpg_of_id_table,
922 },
923 .probe = xtpg_probe,
924 .remove = xtpg_remove,
925};
926
927module_platform_driver(xtpg_driver);
928
929MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
930MODULE_DESCRIPTION("Xilinx Test Pattern Generator Driver");
931MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c
new file mode 100644
index 000000000000..311259129504
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vip.c
@@ -0,0 +1,323 @@
1/*
2 * Xilinx Video IP Core
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/clk.h>
16#include <linux/export.h>
17#include <linux/kernel.h>
18#include <linux/of.h>
19#include <linux/platform_device.h>
20
21#include <dt-bindings/media/xilinx-vip.h>
22
23#include "xilinx-vip.h"
24
25/* -----------------------------------------------------------------------------
26 * Helper functions
27 */
28
29static const struct xvip_video_format xvip_video_formats[] = {
30 { XVIP_VF_YUV_422, 8, NULL, MEDIA_BUS_FMT_UYVY8_1X16,
31 2, V4L2_PIX_FMT_YUYV, "4:2:2, packed, YUYV" },
32 { XVIP_VF_YUV_444, 8, NULL, MEDIA_BUS_FMT_VUY8_1X24,
33 3, V4L2_PIX_FMT_YUV444, "4:4:4, packed, YUYV" },
34 { XVIP_VF_RBG, 8, NULL, MEDIA_BUS_FMT_RBG888_1X24,
35 3, 0, NULL },
36 { XVIP_VF_MONO_SENSOR, 8, "mono", MEDIA_BUS_FMT_Y8_1X8,
37 1, V4L2_PIX_FMT_GREY, "Greyscale 8-bit" },
38 { XVIP_VF_MONO_SENSOR, 8, "rggb", MEDIA_BUS_FMT_SRGGB8_1X8,
39 1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit RGGB" },
40 { XVIP_VF_MONO_SENSOR, 8, "grbg", MEDIA_BUS_FMT_SGRBG8_1X8,
41 1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit GRBG" },
42 { XVIP_VF_MONO_SENSOR, 8, "gbrg", MEDIA_BUS_FMT_SGBRG8_1X8,
43 1, V4L2_PIX_FMT_SGBRG8, "Bayer 8-bit GBRG" },
44 { XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8,
45 1, V4L2_PIX_FMT_SBGGR8, "Bayer 8-bit BGGR" },
46};
47
48/**
49 * xvip_get_format_by_code - Retrieve format information for a media bus code
50 * @code: the format media bus code
51 *
52 * Return: a pointer to the format information structure corresponding to the
53 * given V4L2 media bus format @code, or ERR_PTR if no corresponding format can
54 * be found.
55 */
56const struct xvip_video_format *xvip_get_format_by_code(unsigned int code)
57{
58 unsigned int i;
59
60 for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
61 const struct xvip_video_format *format = &xvip_video_formats[i];
62
63 if (format->code == code)
64 return format;
65 }
66
67 return ERR_PTR(-EINVAL);
68}
69EXPORT_SYMBOL_GPL(xvip_get_format_by_code);
70
71/**
72 * xvip_get_format_by_fourcc - Retrieve format information for a 4CC
73 * @fourcc: the format 4CC
74 *
75 * Return: a pointer to the format information structure corresponding to the
76 * given V4L2 format @fourcc, or ERR_PTR if no corresponding format can be
77 * found.
78 */
79const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc)
80{
81 unsigned int i;
82
83 for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
84 const struct xvip_video_format *format = &xvip_video_formats[i];
85
86 if (format->fourcc == fourcc)
87 return format;
88 }
89
90 return ERR_PTR(-EINVAL);
91}
92EXPORT_SYMBOL_GPL(xvip_get_format_by_fourcc);
93
94/**
95 * xvip_of_get_format - Parse a device tree node and return format information
96 * @node: the device tree node
97 *
98 * Read the xlnx,video-format, xlnx,video-width and xlnx,cfa-pattern properties
99 * from the device tree @node passed as an argument and return the corresponding
100 * format information.
101 *
102 * Return: a pointer to the format information structure corresponding to the
103 * format name and width, or ERR_PTR if no corresponding format can be found.
104 */
105const struct xvip_video_format *xvip_of_get_format(struct device_node *node)
106{
107 const char *pattern = "mono";
108 unsigned int vf_code;
109 unsigned int i;
110 u32 width;
111 int ret;
112
113 ret = of_property_read_u32(node, "xlnx,video-format", &vf_code);
114 if (ret < 0)
115 return ERR_PTR(ret);
116
117 ret = of_property_read_u32(node, "xlnx,video-width", &width);
118 if (ret < 0)
119 return ERR_PTR(ret);
120
121 if (vf_code == XVIP_VF_MONO_SENSOR)
122 of_property_read_string(node, "xlnx,cfa-pattern", &pattern);
123
124 for (i = 0; i < ARRAY_SIZE(xvip_video_formats); ++i) {
125 const struct xvip_video_format *format = &xvip_video_formats[i];
126
127 if (format->vf_code != vf_code || format->width != width)
128 continue;
129
130 if (vf_code == XVIP_VF_MONO_SENSOR &&
131 strcmp(pattern, format->pattern))
132 continue;
133
134 return format;
135 }
136
137 return ERR_PTR(-EINVAL);
138}
139EXPORT_SYMBOL_GPL(xvip_of_get_format);
140
141/**
142 * xvip_set_format_size - Set the media bus frame format size
143 * @format: V4L2 frame format on media bus
144 * @fmt: media bus format
145 *
146 * Set the media bus frame format size. The width / height from the subdevice
147 * format are set to the given media bus format. The new format size is stored
148 * in @format. The width and height are clamped using default min / max values.
149 */
150void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
151 const struct v4l2_subdev_format *fmt)
152{
153 format->width = clamp_t(unsigned int, fmt->format.width,
154 XVIP_MIN_WIDTH, XVIP_MAX_WIDTH);
155 format->height = clamp_t(unsigned int, fmt->format.height,
156 XVIP_MIN_HEIGHT, XVIP_MAX_HEIGHT);
157}
158EXPORT_SYMBOL_GPL(xvip_set_format_size);
159
160/**
161 * xvip_clr_or_set - Clear or set the register with a bitmask
162 * @xvip: Xilinx Video IP device
163 * @addr: address of register
164 * @mask: bitmask to be set or cleared
165 * @set: boolean flag indicating whether to set or clear
166 *
167 * Clear or set the register at address @addr with a bitmask @mask depending on
168 * the boolean flag @set. When the flag @set is true, the bitmask is set in
169 * the register, otherwise the bitmask is cleared from the register
170 * when the flag @set is false.
171 *
172 * Fox eample, this function can be used to set a control with a boolean value
173 * requested by users. If the caller knows whether to set or clear in the first
174 * place, the caller should call xvip_clr() or xvip_set() directly instead of
175 * using this function.
176 */
177void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set)
178{
179 u32 reg;
180
181 reg = xvip_read(xvip, addr);
182 reg = set ? reg | mask : reg & ~mask;
183 xvip_write(xvip, addr, reg);
184}
185EXPORT_SYMBOL_GPL(xvip_clr_or_set);
186
187/**
188 * xvip_clr_and_set - Clear and set the register with a bitmask
189 * @xvip: Xilinx Video IP device
190 * @addr: address of register
191 * @clr: bitmask to be cleared
192 * @set: bitmask to be set
193 *
194 * Clear a bit(s) of mask @clr in the register at address @addr, then set
195 * a bit(s) of mask @set in the register after.
196 */
197void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set)
198{
199 u32 reg;
200
201 reg = xvip_read(xvip, addr);
202 reg &= ~clr;
203 reg |= set;
204 xvip_write(xvip, addr, reg);
205}
206EXPORT_SYMBOL_GPL(xvip_clr_and_set);
207
208int xvip_init_resources(struct xvip_device *xvip)
209{
210 struct platform_device *pdev = to_platform_device(xvip->dev);
211 struct resource *res;
212
213 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
214 xvip->iomem = devm_ioremap_resource(xvip->dev, res);
215 if (IS_ERR(xvip->iomem))
216 return PTR_ERR(xvip->iomem);
217
218 xvip->clk = devm_clk_get(xvip->dev, NULL);
219 if (IS_ERR(xvip->clk))
220 return PTR_ERR(xvip->clk);
221
222 clk_prepare_enable(xvip->clk);
223 return 0;
224}
225EXPORT_SYMBOL_GPL(xvip_init_resources);
226
227void xvip_cleanup_resources(struct xvip_device *xvip)
228{
229 clk_disable_unprepare(xvip->clk);
230}
231EXPORT_SYMBOL_GPL(xvip_cleanup_resources);
232
233/* -----------------------------------------------------------------------------
234 * Subdev operations handlers
235 */
236
237/**
238 * xvip_enum_mbus_code - Enumerate the media format code
239 * @subdev: V4L2 subdevice
240 * @cfg: V4L2 subdev pad configuration
241 * @code: returning media bus code
242 *
243 * Enumerate the media bus code of the subdevice. Return the corresponding
244 * pad format code. This function only works for subdevices with fixed format
245 * on all pads. Subdevices with multiple format should have their own
246 * function to enumerate mbus codes.
247 *
248 * Return: 0 if the media bus code is found, or -EINVAL if the format index
249 * is not valid.
250 */
251int xvip_enum_mbus_code(struct v4l2_subdev *subdev,
252 struct v4l2_subdev_pad_config *cfg,
253 struct v4l2_subdev_mbus_code_enum *code)
254{
255 struct v4l2_mbus_framefmt *format;
256
257 /* Enumerating frame sizes based on the active configuration isn't
258 * supported yet.
259 */
260 if (code->which == V4L2_SUBDEV_FORMAT_ACTIVE)
261 return -EINVAL;
262
263 if (code->index)
264 return -EINVAL;
265
266 format = v4l2_subdev_get_try_format(subdev, cfg, code->pad);
267
268 code->code = format->code;
269
270 return 0;
271}
272EXPORT_SYMBOL_GPL(xvip_enum_mbus_code);
273
274/**
275 * xvip_enum_frame_size - Enumerate the media bus frame size
276 * @subdev: V4L2 subdevice
277 * @cfg: V4L2 subdev pad configuration
278 * @fse: returning media bus frame size
279 *
280 * This function is a drop-in implementation of the subdev enum_frame_size pad
281 * operation. It assumes that the subdevice has one sink pad and one source
282 * pad, and that the format on the source pad is always identical to the
283 * format on the sink pad. Entities with different requirements need to
284 * implement their own enum_frame_size handlers.
285 *
286 * Return: 0 if the media bus frame size is found, or -EINVAL
287 * if the index or the code is not valid.
288 */
289int xvip_enum_frame_size(struct v4l2_subdev *subdev,
290 struct v4l2_subdev_pad_config *cfg,
291 struct v4l2_subdev_frame_size_enum *fse)
292{
293 struct v4l2_mbus_framefmt *format;
294
295 /* Enumerating frame sizes based on the active configuration isn't
296 * supported yet.
297 */
298 if (fse->which == V4L2_SUBDEV_FORMAT_ACTIVE)
299 return -EINVAL;
300
301 format = v4l2_subdev_get_try_format(subdev, cfg, fse->pad);
302
303 if (fse->index || fse->code != format->code)
304 return -EINVAL;
305
306 if (fse->pad == XVIP_PAD_SINK) {
307 fse->min_width = XVIP_MIN_WIDTH;
308 fse->max_width = XVIP_MAX_WIDTH;
309 fse->min_height = XVIP_MIN_HEIGHT;
310 fse->max_height = XVIP_MAX_HEIGHT;
311 } else {
312 /* The size on the source pad is fixed and always identical to
313 * the size on the sink pad.
314 */
315 fse->min_width = format->width;
316 fse->max_width = format->width;
317 fse->min_height = format->height;
318 fse->max_height = format->height;
319 }
320
321 return 0;
322}
323EXPORT_SYMBOL_GPL(xvip_enum_frame_size);
diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h
new file mode 100644
index 000000000000..42fee2026815
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vip.h
@@ -0,0 +1,238 @@
1/*
2 * Xilinx Video IP Core
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __XILINX_VIP_H__
16#define __XILINX_VIP_H__
17
18#include <linux/io.h>
19#include <media/v4l2-subdev.h>
20
21struct clk;
22
23/*
24 * Minimum and maximum width and height common to most video IP cores. IP
25 * cores with different requirements must define their own values.
26 */
27#define XVIP_MIN_WIDTH 32
28#define XVIP_MAX_WIDTH 7680
29#define XVIP_MIN_HEIGHT 32
30#define XVIP_MAX_HEIGHT 7680
31
32/*
33 * Pad IDs. IP cores with with multiple inputs or outputs should define
34 * their own values.
35 */
36#define XVIP_PAD_SINK 0
37#define XVIP_PAD_SOURCE 1
38
39/* Xilinx Video IP Control Registers */
40#define XVIP_CTRL_CONTROL 0x0000
41#define XVIP_CTRL_CONTROL_SW_ENABLE (1 << 0)
42#define XVIP_CTRL_CONTROL_REG_UPDATE (1 << 1)
43#define XVIP_CTRL_CONTROL_BYPASS (1 << 4)
44#define XVIP_CTRL_CONTROL_TEST_PATTERN (1 << 5)
45#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET (1 << 30)
46#define XVIP_CTRL_CONTROL_SW_RESET (1 << 31)
47#define XVIP_CTRL_STATUS 0x0004
48#define XVIP_CTRL_STATUS_PROC_STARTED (1 << 0)
49#define XVIP_CTRL_STATUS_EOF (1 << 1)
50#define XVIP_CTRL_ERROR 0x0008
51#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY (1 << 0)
52#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE (1 << 1)
53#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY (1 << 2)
54#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE (1 << 3)
55#define XVIP_CTRL_IRQ_ENABLE 0x000c
56#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED (1 << 0)
57#define XVIP_CTRL_IRQ_EOF (1 << 1)
58#define XVIP_CTRL_VERSION 0x0010
59#define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24)
60#define XVIP_CTRL_VERSION_MAJOR_SHIFT 24
61#define XVIP_CTRL_VERSION_MINOR_MASK (0xff << 16)
62#define XVIP_CTRL_VERSION_MINOR_SHIFT 16
63#define XVIP_CTRL_VERSION_REVISION_MASK (0xf << 12)
64#define XVIP_CTRL_VERSION_REVISION_SHIFT 12
65#define XVIP_CTRL_VERSION_PATCH_MASK (0xf << 8)
66#define XVIP_CTRL_VERSION_PATCH_SHIFT 8
67#define XVIP_CTRL_VERSION_INTERNAL_MASK (0xff << 0)
68#define XVIP_CTRL_VERSION_INTERNAL_SHIFT 0
69
70/* Xilinx Video IP Timing Registers */
71#define XVIP_ACTIVE_SIZE 0x0020
72#define XVIP_ACTIVE_VSIZE_MASK (0x7ff << 16)
73#define XVIP_ACTIVE_VSIZE_SHIFT 16
74#define XVIP_ACTIVE_HSIZE_MASK (0x7ff << 0)
75#define XVIP_ACTIVE_HSIZE_SHIFT 0
76#define XVIP_ENCODING 0x0028
77#define XVIP_ENCODING_NBITS_8 (0 << 4)
78#define XVIP_ENCODING_NBITS_10 (1 << 4)
79#define XVIP_ENCODING_NBITS_12 (2 << 4)
80#define XVIP_ENCODING_NBITS_16 (3 << 4)
81#define XVIP_ENCODING_NBITS_MASK (3 << 4)
82#define XVIP_ENCODING_NBITS_SHIFT 4
83#define XVIP_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0)
84#define XVIP_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0)
85#define XVIP_ENCODING_VIDEO_FORMAT_RGB (2 << 0)
86#define XVIP_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0)
87#define XVIP_ENCODING_VIDEO_FORMAT_MASK (3 << 0)
88#define XVIP_ENCODING_VIDEO_FORMAT_SHIFT 0
89
90/**
91 * struct xvip_device - Xilinx Video IP device structure
92 * @subdev: V4L2 subdevice
93 * @dev: (OF) device
94 * @iomem: device I/O register space remapped to kernel virtual memory
95 * @clk: video core clock
96 * @saved_ctrl: saved control register for resume / suspend
97 */
98struct xvip_device {
99 struct v4l2_subdev subdev;
100 struct device *dev;
101 void __iomem *iomem;
102 struct clk *clk;
103 u32 saved_ctrl;
104};
105
106/**
107 * struct xvip_video_format - Xilinx Video IP video format description
108 * @vf_code: AXI4 video format code
109 * @width: AXI4 format width in bits per component
110 * @pattern: CFA pattern for Mono/Sensor formats
111 * @code: media bus format code
112 * @bpp: bytes per pixel (when stored in memory)
113 * @fourcc: V4L2 pixel format FCC identifier
114 * @description: format description, suitable for userspace
115 */
116struct xvip_video_format {
117 unsigned int vf_code;
118 unsigned int width;
119 const char *pattern;
120 unsigned int code;
121 unsigned int bpp;
122 u32 fourcc;
123 const char *description;
124};
125
126const struct xvip_video_format *xvip_get_format_by_code(unsigned int code);
127const struct xvip_video_format *xvip_get_format_by_fourcc(u32 fourcc);
128const struct xvip_video_format *xvip_of_get_format(struct device_node *node);
129void xvip_set_format_size(struct v4l2_mbus_framefmt *format,
130 const struct v4l2_subdev_format *fmt);
131int xvip_enum_mbus_code(struct v4l2_subdev *subdev,
132 struct v4l2_subdev_pad_config *cfg,
133 struct v4l2_subdev_mbus_code_enum *code);
134int xvip_enum_frame_size(struct v4l2_subdev *subdev,
135 struct v4l2_subdev_pad_config *cfg,
136 struct v4l2_subdev_frame_size_enum *fse);
137
138static inline u32 xvip_read(struct xvip_device *xvip, u32 addr)
139{
140 return ioread32(xvip->iomem + addr);
141}
142
143static inline void xvip_write(struct xvip_device *xvip, u32 addr, u32 value)
144{
145 iowrite32(value, xvip->iomem + addr);
146}
147
148static inline void xvip_clr(struct xvip_device *xvip, u32 addr, u32 clr)
149{
150 xvip_write(xvip, addr, xvip_read(xvip, addr) & ~clr);
151}
152
153static inline void xvip_set(struct xvip_device *xvip, u32 addr, u32 set)
154{
155 xvip_write(xvip, addr, xvip_read(xvip, addr) | set);
156}
157
158void xvip_clr_or_set(struct xvip_device *xvip, u32 addr, u32 mask, bool set);
159void xvip_clr_and_set(struct xvip_device *xvip, u32 addr, u32 clr, u32 set);
160
161int xvip_init_resources(struct xvip_device *xvip);
162void xvip_cleanup_resources(struct xvip_device *xvip);
163
164static inline void xvip_reset(struct xvip_device *xvip)
165{
166 xvip_write(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_RESET);
167}
168
169static inline void xvip_start(struct xvip_device *xvip)
170{
171 xvip_set(xvip, XVIP_CTRL_CONTROL,
172 XVIP_CTRL_CONTROL_SW_ENABLE | XVIP_CTRL_CONTROL_REG_UPDATE);
173}
174
175static inline void xvip_stop(struct xvip_device *xvip)
176{
177 xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_SW_ENABLE);
178}
179
180static inline void xvip_resume(struct xvip_device *xvip)
181{
182 xvip_write(xvip, XVIP_CTRL_CONTROL,
183 xvip->saved_ctrl | XVIP_CTRL_CONTROL_SW_ENABLE);
184}
185
186static inline void xvip_suspend(struct xvip_device *xvip)
187{
188 xvip->saved_ctrl = xvip_read(xvip, XVIP_CTRL_CONTROL);
189 xvip_write(xvip, XVIP_CTRL_CONTROL,
190 xvip->saved_ctrl & ~XVIP_CTRL_CONTROL_SW_ENABLE);
191}
192
193static inline void xvip_set_frame_size(struct xvip_device *xvip,
194 const struct v4l2_mbus_framefmt *format)
195{
196 xvip_write(xvip, XVIP_ACTIVE_SIZE,
197 (format->height << XVIP_ACTIVE_VSIZE_SHIFT) |
198 (format->width << XVIP_ACTIVE_HSIZE_SHIFT));
199}
200
201static inline void xvip_get_frame_size(struct xvip_device *xvip,
202 struct v4l2_mbus_framefmt *format)
203{
204 u32 reg;
205
206 reg = xvip_read(xvip, XVIP_ACTIVE_SIZE);
207 format->width = (reg & XVIP_ACTIVE_HSIZE_MASK) >>
208 XVIP_ACTIVE_HSIZE_SHIFT;
209 format->height = (reg & XVIP_ACTIVE_VSIZE_MASK) >>
210 XVIP_ACTIVE_VSIZE_SHIFT;
211}
212
213static inline void xvip_enable_reg_update(struct xvip_device *xvip)
214{
215 xvip_set(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
216}
217
218static inline void xvip_disable_reg_update(struct xvip_device *xvip)
219{
220 xvip_clr(xvip, XVIP_CTRL_CONTROL, XVIP_CTRL_CONTROL_REG_UPDATE);
221}
222
223static inline void xvip_print_version(struct xvip_device *xvip)
224{
225 u32 version;
226
227 version = xvip_read(xvip, XVIP_CTRL_VERSION);
228
229 dev_info(xvip->dev, "device found, version %u.%02x%x\n",
230 ((version & XVIP_CTRL_VERSION_MAJOR_MASK) >>
231 XVIP_CTRL_VERSION_MAJOR_SHIFT),
232 ((version & XVIP_CTRL_VERSION_MINOR_MASK) >>
233 XVIP_CTRL_VERSION_MINOR_SHIFT),
234 ((version & XVIP_CTRL_VERSION_REVISION_MASK) >>
235 XVIP_CTRL_VERSION_REVISION_SHIFT));
236}
237
238#endif /* __XILINX_VIP_H__ */
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c
new file mode 100644
index 000000000000..7b7cb9c28d2c
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vipp.c
@@ -0,0 +1,669 @@
1/*
2 * Xilinx Video IP Composite Device
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/list.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/of_graph.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21
22#include <media/v4l2-async.h>
23#include <media/v4l2-common.h>
24#include <media/v4l2-device.h>
25#include <media/v4l2-of.h>
26
27#include "xilinx-dma.h"
28#include "xilinx-vipp.h"
29
30#define XVIPP_DMA_S2MM 0
31#define XVIPP_DMA_MM2S 1
32
33/**
34 * struct xvip_graph_entity - Entity in the video graph
35 * @list: list entry in a graph entities list
36 * @node: the entity's DT node
37 * @entity: media entity, from the corresponding V4L2 subdev
38 * @asd: subdev asynchronous registration information
39 * @subdev: V4L2 subdev
40 */
41struct xvip_graph_entity {
42 struct list_head list;
43 struct device_node *node;
44 struct media_entity *entity;
45
46 struct v4l2_async_subdev asd;
47 struct v4l2_subdev *subdev;
48};
49
50/* -----------------------------------------------------------------------------
51 * Graph Management
52 */
53
54static struct xvip_graph_entity *
55xvip_graph_find_entity(struct xvip_composite_device *xdev,
56 const struct device_node *node)
57{
58 struct xvip_graph_entity *entity;
59
60 list_for_each_entry(entity, &xdev->entities, list) {
61 if (entity->node == node)
62 return entity;
63 }
64
65 return NULL;
66}
67
68static int xvip_graph_build_one(struct xvip_composite_device *xdev,
69 struct xvip_graph_entity *entity)
70{
71 u32 link_flags = MEDIA_LNK_FL_ENABLED;
72 struct media_entity *local = entity->entity;
73 struct media_entity *remote;
74 struct media_pad *local_pad;
75 struct media_pad *remote_pad;
76 struct xvip_graph_entity *ent;
77 struct v4l2_of_link link;
78 struct device_node *ep = NULL;
79 struct device_node *next;
80 int ret = 0;
81
82 dev_dbg(xdev->dev, "creating links for entity %s\n", local->name);
83
84 while (1) {
85 /* Get the next endpoint and parse its link. */
86 next = of_graph_get_next_endpoint(entity->node, ep);
87 if (next == NULL)
88 break;
89
90 of_node_put(ep);
91 ep = next;
92
93 dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
94
95 ret = v4l2_of_parse_link(ep, &link);
96 if (ret < 0) {
97 dev_err(xdev->dev, "failed to parse link for %s\n",
98 ep->full_name);
99 continue;
100 }
101
102 /* Skip sink ports, they will be processed from the other end of
103 * the link.
104 */
105 if (link.local_port >= local->num_pads) {
106 dev_err(xdev->dev, "invalid port number %u on %s\n",
107 link.local_port, link.local_node->full_name);
108 v4l2_of_put_link(&link);
109 ret = -EINVAL;
110 break;
111 }
112
113 local_pad = &local->pads[link.local_port];
114
115 if (local_pad->flags & MEDIA_PAD_FL_SINK) {
116 dev_dbg(xdev->dev, "skipping sink port %s:%u\n",
117 link.local_node->full_name, link.local_port);
118 v4l2_of_put_link(&link);
119 continue;
120 }
121
122 /* Skip DMA engines, they will be processed separately. */
123 if (link.remote_node == xdev->dev->of_node) {
124 dev_dbg(xdev->dev, "skipping DMA port %s:%u\n",
125 link.local_node->full_name, link.local_port);
126 v4l2_of_put_link(&link);
127 continue;
128 }
129
130 /* Find the remote entity. */
131 ent = xvip_graph_find_entity(xdev, link.remote_node);
132 if (ent == NULL) {
133 dev_err(xdev->dev, "no entity found for %s\n",
134 link.remote_node->full_name);
135 v4l2_of_put_link(&link);
136 ret = -ENODEV;
137 break;
138 }
139
140 remote = ent->entity;
141
142 if (link.remote_port >= remote->num_pads) {
143 dev_err(xdev->dev, "invalid port number %u on %s\n",
144 link.remote_port, link.remote_node->full_name);
145 v4l2_of_put_link(&link);
146 ret = -EINVAL;
147 break;
148 }
149
150 remote_pad = &remote->pads[link.remote_port];
151
152 v4l2_of_put_link(&link);
153
154 /* Create the media link. */
155 dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
156 local->name, local_pad->index,
157 remote->name, remote_pad->index);
158
159 ret = media_entity_create_link(local, local_pad->index,
160 remote, remote_pad->index,
161 link_flags);
162 if (ret < 0) {
163 dev_err(xdev->dev,
164 "failed to create %s:%u -> %s:%u link\n",
165 local->name, local_pad->index,
166 remote->name, remote_pad->index);
167 break;
168 }
169 }
170
171 of_node_put(ep);
172 return ret;
173}
174
175static struct xvip_dma *
176xvip_graph_find_dma(struct xvip_composite_device *xdev, unsigned int port)
177{
178 struct xvip_dma *dma;
179
180 list_for_each_entry(dma, &xdev->dmas, list) {
181 if (dma->port == port)
182 return dma;
183 }
184
185 return NULL;
186}
187
188static int xvip_graph_build_dma(struct xvip_composite_device *xdev)
189{
190 u32 link_flags = MEDIA_LNK_FL_ENABLED;
191 struct device_node *node = xdev->dev->of_node;
192 struct media_entity *source;
193 struct media_entity *sink;
194 struct media_pad *source_pad;
195 struct media_pad *sink_pad;
196 struct xvip_graph_entity *ent;
197 struct v4l2_of_link link;
198 struct device_node *ep = NULL;
199 struct device_node *next;
200 struct xvip_dma *dma;
201 int ret = 0;
202
203 dev_dbg(xdev->dev, "creating links for DMA engines\n");
204
205 while (1) {
206 /* Get the next endpoint and parse its link. */
207 next = of_graph_get_next_endpoint(node, ep);
208 if (next == NULL)
209 break;
210
211 of_node_put(ep);
212 ep = next;
213
214 dev_dbg(xdev->dev, "processing endpoint %s\n", ep->full_name);
215
216 ret = v4l2_of_parse_link(ep, &link);
217 if (ret < 0) {
218 dev_err(xdev->dev, "failed to parse link for %s\n",
219 ep->full_name);
220 continue;
221 }
222
223 /* Find the DMA engine. */
224 dma = xvip_graph_find_dma(xdev, link.local_port);
225 if (dma == NULL) {
226 dev_err(xdev->dev, "no DMA engine found for port %u\n",
227 link.local_port);
228 v4l2_of_put_link(&link);
229 ret = -EINVAL;
230 break;
231 }
232
233 dev_dbg(xdev->dev, "creating link for DMA engine %s\n",
234 dma->video.name);
235
236 /* Find the remote entity. */
237 ent = xvip_graph_find_entity(xdev, link.remote_node);
238 if (ent == NULL) {
239 dev_err(xdev->dev, "no entity found for %s\n",
240 link.remote_node->full_name);
241 v4l2_of_put_link(&link);
242 ret = -ENODEV;
243 break;
244 }
245
246 if (link.remote_port >= ent->entity->num_pads) {
247 dev_err(xdev->dev, "invalid port number %u on %s\n",
248 link.remote_port, link.remote_node->full_name);
249 v4l2_of_put_link(&link);
250 ret = -EINVAL;
251 break;
252 }
253
254 if (dma->pad.flags & MEDIA_PAD_FL_SOURCE) {
255 source = &dma->video.entity;
256 source_pad = &dma->pad;
257 sink = ent->entity;
258 sink_pad = &sink->pads[link.remote_port];
259 } else {
260 source = ent->entity;
261 source_pad = &source->pads[link.remote_port];
262 sink = &dma->video.entity;
263 sink_pad = &dma->pad;
264 }
265
266 v4l2_of_put_link(&link);
267
268 /* Create the media link. */
269 dev_dbg(xdev->dev, "creating %s:%u -> %s:%u link\n",
270 source->name, source_pad->index,
271 sink->name, sink_pad->index);
272
273 ret = media_entity_create_link(source, source_pad->index,
274 sink, sink_pad->index,
275 link_flags);
276 if (ret < 0) {
277 dev_err(xdev->dev,
278 "failed to create %s:%u -> %s:%u link\n",
279 source->name, source_pad->index,
280 sink->name, sink_pad->index);
281 break;
282 }
283 }
284
285 of_node_put(ep);
286 return ret;
287}
288
289static int xvip_graph_notify_complete(struct v4l2_async_notifier *notifier)
290{
291 struct xvip_composite_device *xdev =
292 container_of(notifier, struct xvip_composite_device, notifier);
293 struct xvip_graph_entity *entity;
294 int ret;
295
296 dev_dbg(xdev->dev, "notify complete, all subdevs registered\n");
297
298 /* Create links for every entity. */
299 list_for_each_entry(entity, &xdev->entities, list) {
300 ret = xvip_graph_build_one(xdev, entity);
301 if (ret < 0)
302 return ret;
303 }
304
305 /* Create links for DMA channels. */
306 ret = xvip_graph_build_dma(xdev);
307 if (ret < 0)
308 return ret;
309
310 ret = v4l2_device_register_subdev_nodes(&xdev->v4l2_dev);
311 if (ret < 0)
312 dev_err(xdev->dev, "failed to register subdev nodes\n");
313
314 return ret;
315}
316
317static int xvip_graph_notify_bound(struct v4l2_async_notifier *notifier,
318 struct v4l2_subdev *subdev,
319 struct v4l2_async_subdev *asd)
320{
321 struct xvip_composite_device *xdev =
322 container_of(notifier, struct xvip_composite_device, notifier);
323 struct xvip_graph_entity *entity;
324
325 /* Locate the entity corresponding to the bound subdev and store the
326 * subdev pointer.
327 */
328 list_for_each_entry(entity, &xdev->entities, list) {
329 if (entity->node != subdev->dev->of_node)
330 continue;
331
332 if (entity->subdev) {
333 dev_err(xdev->dev, "duplicate subdev for node %s\n",
334 entity->node->full_name);
335 return -EINVAL;
336 }
337
338 dev_dbg(xdev->dev, "subdev %s bound\n", subdev->name);
339 entity->entity = &subdev->entity;
340 entity->subdev = subdev;
341 return 0;
342 }
343
344 dev_err(xdev->dev, "no entity for subdev %s\n", subdev->name);
345 return -EINVAL;
346}
347
348static int xvip_graph_parse_one(struct xvip_composite_device *xdev,
349 struct device_node *node)
350{
351 struct xvip_graph_entity *entity;
352 struct device_node *remote;
353 struct device_node *ep = NULL;
354 struct device_node *next;
355 int ret = 0;
356
357 dev_dbg(xdev->dev, "parsing node %s\n", node->full_name);
358
359 while (1) {
360 next = of_graph_get_next_endpoint(node, ep);
361 if (next == NULL)
362 break;
363
364 of_node_put(ep);
365 ep = next;
366
367 dev_dbg(xdev->dev, "handling endpoint %s\n", ep->full_name);
368
369 remote = of_graph_get_remote_port_parent(ep);
370 if (remote == NULL) {
371 ret = -EINVAL;
372 break;
373 }
374
375 /* Skip entities that we have already processed. */
376 if (remote == xdev->dev->of_node ||
377 xvip_graph_find_entity(xdev, remote)) {
378 of_node_put(remote);
379 continue;
380 }
381
382 entity = devm_kzalloc(xdev->dev, sizeof(*entity), GFP_KERNEL);
383 if (entity == NULL) {
384 of_node_put(remote);
385 ret = -ENOMEM;
386 break;
387 }
388
389 entity->node = remote;
390 entity->asd.match_type = V4L2_ASYNC_MATCH_OF;
391 entity->asd.match.of.node = remote;
392 list_add_tail(&entity->list, &xdev->entities);
393 xdev->num_subdevs++;
394 }
395
396 of_node_put(ep);
397 return ret;
398}
399
400static int xvip_graph_parse(struct xvip_composite_device *xdev)
401{
402 struct xvip_graph_entity *entity;
403 int ret;
404
405 /*
406 * Walk the links to parse the full graph. Start by parsing the
407 * composite node and then parse entities in turn. The list_for_each
408 * loop will handle entities added at the end of the list while walking
409 * the links.
410 */
411 ret = xvip_graph_parse_one(xdev, xdev->dev->of_node);
412 if (ret < 0)
413 return 0;
414
415 list_for_each_entry(entity, &xdev->entities, list) {
416 ret = xvip_graph_parse_one(xdev, entity->node);
417 if (ret < 0)
418 break;
419 }
420
421 return ret;
422}
423
424static int xvip_graph_dma_init_one(struct xvip_composite_device *xdev,
425 struct device_node *node)
426{
427 struct xvip_dma *dma;
428 enum v4l2_buf_type type;
429 const char *direction;
430 unsigned int index;
431 int ret;
432
433 ret = of_property_read_string(node, "direction", &direction);
434 if (ret < 0)
435 return ret;
436
437 if (strcmp(direction, "input") == 0)
438 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
439 else if (strcmp(direction, "output") == 0)
440 type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
441 else
442 return -EINVAL;
443
444 of_property_read_u32(node, "reg", &index);
445
446 dma = devm_kzalloc(xdev->dev, sizeof(*dma), GFP_KERNEL);
447 if (dma == NULL)
448 return -ENOMEM;
449
450 ret = xvip_dma_init(xdev, dma, type, index);
451 if (ret < 0) {
452 dev_err(xdev->dev, "%s initialization failed\n",
453 node->full_name);
454 return ret;
455 }
456
457 list_add_tail(&dma->list, &xdev->dmas);
458
459 xdev->v4l2_caps |= type == V4L2_BUF_TYPE_VIDEO_CAPTURE
460 ? V4L2_CAP_VIDEO_CAPTURE : V4L2_CAP_VIDEO_OUTPUT;
461
462 return 0;
463}
464
465static int xvip_graph_dma_init(struct xvip_composite_device *xdev)
466{
467 struct device_node *ports;
468 struct device_node *port;
469 int ret;
470
471 ports = of_get_child_by_name(xdev->dev->of_node, "ports");
472 if (ports == NULL) {
473 dev_err(xdev->dev, "ports node not present\n");
474 return -EINVAL;
475 }
476
477 for_each_child_of_node(ports, port) {
478 ret = xvip_graph_dma_init_one(xdev, port);
479 if (ret < 0)
480 return ret;
481 }
482
483 return 0;
484}
485
486static void xvip_graph_cleanup(struct xvip_composite_device *xdev)
487{
488 struct xvip_graph_entity *entityp;
489 struct xvip_graph_entity *entity;
490 struct xvip_dma *dmap;
491 struct xvip_dma *dma;
492
493 v4l2_async_notifier_unregister(&xdev->notifier);
494
495 list_for_each_entry_safe(entity, entityp, &xdev->entities, list) {
496 of_node_put(entity->node);
497 list_del(&entity->list);
498 }
499
500 list_for_each_entry_safe(dma, dmap, &xdev->dmas, list) {
501 xvip_dma_cleanup(dma);
502 list_del(&dma->list);
503 }
504}
505
506static int xvip_graph_init(struct xvip_composite_device *xdev)
507{
508 struct xvip_graph_entity *entity;
509 struct v4l2_async_subdev **subdevs = NULL;
510 unsigned int num_subdevs;
511 unsigned int i;
512 int ret;
513
514 /* Init the DMA channels. */
515 ret = xvip_graph_dma_init(xdev);
516 if (ret < 0) {
517 dev_err(xdev->dev, "DMA initialization failed\n");
518 goto done;
519 }
520
521 /* Parse the graph to extract a list of subdevice DT nodes. */
522 ret = xvip_graph_parse(xdev);
523 if (ret < 0) {
524 dev_err(xdev->dev, "graph parsing failed\n");
525 goto done;
526 }
527
528 if (!xdev->num_subdevs) {
529 dev_err(xdev->dev, "no subdev found in graph\n");
530 goto done;
531 }
532
533 /* Register the subdevices notifier. */
534 num_subdevs = xdev->num_subdevs;
535 subdevs = devm_kzalloc(xdev->dev, sizeof(*subdevs) * num_subdevs,
536 GFP_KERNEL);
537 if (subdevs == NULL) {
538 ret = -ENOMEM;
539 goto done;
540 }
541
542 i = 0;
543 list_for_each_entry(entity, &xdev->entities, list)
544 subdevs[i++] = &entity->asd;
545
546 xdev->notifier.subdevs = subdevs;
547 xdev->notifier.num_subdevs = num_subdevs;
548 xdev->notifier.bound = xvip_graph_notify_bound;
549 xdev->notifier.complete = xvip_graph_notify_complete;
550
551 ret = v4l2_async_notifier_register(&xdev->v4l2_dev, &xdev->notifier);
552 if (ret < 0) {
553 dev_err(xdev->dev, "notifier registration failed\n");
554 goto done;
555 }
556
557 ret = 0;
558
559done:
560 if (ret < 0)
561 xvip_graph_cleanup(xdev);
562
563 return ret;
564}
565
566/* -----------------------------------------------------------------------------
567 * Media Controller and V4L2
568 */
569
570static void xvip_composite_v4l2_cleanup(struct xvip_composite_device *xdev)
571{
572 v4l2_device_unregister(&xdev->v4l2_dev);
573 media_device_unregister(&xdev->media_dev);
574}
575
576static int xvip_composite_v4l2_init(struct xvip_composite_device *xdev)
577{
578 int ret;
579
580 xdev->media_dev.dev = xdev->dev;
581 strlcpy(xdev->media_dev.model, "Xilinx Video Composite Device",
582 sizeof(xdev->media_dev.model));
583 xdev->media_dev.hw_revision = 0;
584
585 ret = media_device_register(&xdev->media_dev);
586 if (ret < 0) {
587 dev_err(xdev->dev, "media device registration failed (%d)\n",
588 ret);
589 return ret;
590 }
591
592 xdev->v4l2_dev.mdev = &xdev->media_dev;
593 ret = v4l2_device_register(xdev->dev, &xdev->v4l2_dev);
594 if (ret < 0) {
595 dev_err(xdev->dev, "V4L2 device registration failed (%d)\n",
596 ret);
597 media_device_unregister(&xdev->media_dev);
598 return ret;
599 }
600
601 return 0;
602}
603
604/* -----------------------------------------------------------------------------
605 * Platform Device Driver
606 */
607
608static int xvip_composite_probe(struct platform_device *pdev)
609{
610 struct xvip_composite_device *xdev;
611 int ret;
612
613 xdev = devm_kzalloc(&pdev->dev, sizeof(*xdev), GFP_KERNEL);
614 if (!xdev)
615 return -ENOMEM;
616
617 xdev->dev = &pdev->dev;
618 INIT_LIST_HEAD(&xdev->entities);
619 INIT_LIST_HEAD(&xdev->dmas);
620
621 ret = xvip_composite_v4l2_init(xdev);
622 if (ret < 0)
623 return ret;
624
625 ret = xvip_graph_init(xdev);
626 if (ret < 0)
627 goto error;
628
629 platform_set_drvdata(pdev, xdev);
630
631 dev_info(xdev->dev, "device registered\n");
632
633 return 0;
634
635error:
636 xvip_composite_v4l2_cleanup(xdev);
637 return ret;
638}
639
640static int xvip_composite_remove(struct platform_device *pdev)
641{
642 struct xvip_composite_device *xdev = platform_get_drvdata(pdev);
643
644 xvip_graph_cleanup(xdev);
645 xvip_composite_v4l2_cleanup(xdev);
646
647 return 0;
648}
649
650static const struct of_device_id xvip_composite_of_id_table[] = {
651 { .compatible = "xlnx,video" },
652 { }
653};
654MODULE_DEVICE_TABLE(of, xvip_composite_of_id_table);
655
656static struct platform_driver xvip_composite_driver = {
657 .driver = {
658 .name = "xilinx-video",
659 .of_match_table = xvip_composite_of_id_table,
660 },
661 .probe = xvip_composite_probe,
662 .remove = xvip_composite_remove,
663};
664
665module_platform_driver(xvip_composite_driver);
666
667MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
668MODULE_DESCRIPTION("Xilinx Video IP Composite Driver");
669MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/xilinx/xilinx-vipp.h b/drivers/media/platform/xilinx/xilinx-vipp.h
new file mode 100644
index 000000000000..faf6b6e80b3b
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vipp.h
@@ -0,0 +1,49 @@
1/*
2 * Xilinx Video IP Composite Device
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __XILINX_VIPP_H__
16#define __XILINX_VIPP_H__
17
18#include <linux/list.h>
19#include <linux/mutex.h>
20#include <media/media-device.h>
21#include <media/v4l2-async.h>
22#include <media/v4l2-ctrls.h>
23#include <media/v4l2-device.h>
24
25/**
26 * struct xvip_composite_device - Xilinx Video IP device structure
27 * @v4l2_dev: V4L2 device
28 * @media_dev: media device
29 * @dev: (OF) device
30 * @notifier: V4L2 asynchronous subdevs notifier
31 * @entities: entities in the graph as a list of xvip_graph_entity
32 * @num_subdevs: number of subdevs in the pipeline
33 * @dmas: list of DMA channels at the pipeline output and input
34 * @v4l2_caps: V4L2 capabilities of the whole device (see VIDIOC_QUERYCAP)
35 */
36struct xvip_composite_device {
37 struct v4l2_device v4l2_dev;
38 struct media_device media_dev;
39 struct device *dev;
40
41 struct v4l2_async_notifier notifier;
42 struct list_head entities;
43 unsigned int num_subdevs;
44
45 struct list_head dmas;
46 u32 v4l2_caps;
47};
48
49#endif /* __XILINX_VIPP_H__ */
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.c b/drivers/media/platform/xilinx/xilinx-vtc.c
new file mode 100644
index 000000000000..01c750edcac5
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vtc.c
@@ -0,0 +1,380 @@
1/*
2 * Xilinx Video Timing Controller
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/clk.h>
16#include <linux/module.h>
17#include <linux/of.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20
21#include "xilinx-vip.h"
22#include "xilinx-vtc.h"
23
24#define XVTC_CONTROL_FIELD_ID_POL_SRC (1 << 26)
25#define XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC (1 << 25)
26#define XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC (1 << 24)
27#define XVTC_CONTROL_HSYNC_POL_SRC (1 << 23)
28#define XVTC_CONTROL_VSYNC_POL_SRC (1 << 22)
29#define XVTC_CONTROL_HBLANK_POL_SRC (1 << 21)
30#define XVTC_CONTROL_VBLANK_POL_SRC (1 << 20)
31#define XVTC_CONTROL_CHROMA_SRC (1 << 18)
32#define XVTC_CONTROL_VBLANK_HOFF_SRC (1 << 17)
33#define XVTC_CONTROL_VSYNC_END_SRC (1 << 16)
34#define XVTC_CONTROL_VSYNC_START_SRC (1 << 15)
35#define XVTC_CONTROL_ACTIVE_VSIZE_SRC (1 << 14)
36#define XVTC_CONTROL_FRAME_VSIZE_SRC (1 << 13)
37#define XVTC_CONTROL_HSYNC_END_SRC (1 << 11)
38#define XVTC_CONTROL_HSYNC_START_SRC (1 << 10)
39#define XVTC_CONTROL_ACTIVE_HSIZE_SRC (1 << 9)
40#define XVTC_CONTROL_FRAME_HSIZE_SRC (1 << 8)
41#define XVTC_CONTROL_SYNC_ENABLE (1 << 5)
42#define XVTC_CONTROL_DET_ENABLE (1 << 3)
43#define XVTC_CONTROL_GEN_ENABLE (1 << 2)
44
45#define XVTC_STATUS_FSYNC(n) ((n) << 16)
46#define XVTC_STATUS_GEN_ACTIVE_VIDEO (1 << 13)
47#define XVTC_STATUS_GEN_VBLANK (1 << 12)
48#define XVTC_STATUS_DET_ACTIVE_VIDEO (1 << 11)
49#define XVTC_STATUS_DET_VBLANK (1 << 10)
50#define XVTC_STATUS_LOCK_LOSS (1 << 9)
51#define XVTC_STATUS_LOCK (1 << 8)
52
53#define XVTC_ERROR_ACTIVE_CHROMA_LOCK (1 << 21)
54#define XVTC_ERROR_ACTIVE_VIDEO_LOCK (1 << 20)
55#define XVTC_ERROR_HSYNC_LOCK (1 << 19)
56#define XVTC_ERROR_VSYNC_LOCK (1 << 18)
57#define XVTC_ERROR_HBLANK_LOCK (1 << 17)
58#define XVTC_ERROR_VBLANK_LOCK (1 << 16)
59
60#define XVTC_IRQ_ENABLE_FSYNC(n) ((n) << 16)
61#define XVTC_IRQ_ENABLE_GEN_ACTIVE_VIDEO (1 << 13)
62#define XVTC_IRQ_ENABLE_GEN_VBLANK (1 << 12)
63#define XVTC_IRQ_ENABLE_DET_ACTIVE_VIDEO (1 << 11)
64#define XVTC_IRQ_ENABLE_DET_VBLANK (1 << 10)
65#define XVTC_IRQ_ENABLE_LOCK_LOSS (1 << 9)
66#define XVTC_IRQ_ENABLE_LOCK (1 << 8)
67
68/*
69 * The following registers exist in two blocks, one at 0x0020 for the detector
70 * and one at 0x0060 for the generator.
71 */
72
73#define XVTC_DETECTOR_OFFSET 0x0020
74#define XVTC_GENERATOR_OFFSET 0x0060
75
76#define XVTC_ACTIVE_SIZE 0x0000
77#define XVTC_ACTIVE_VSIZE_SHIFT 16
78#define XVTC_ACTIVE_VSIZE_MASK (0x1fff << 16)
79#define XVTC_ACTIVE_HSIZE_SHIFT 0
80#define XVTC_ACTIVE_HSIZE_MASK (0x1fff << 0)
81
82#define XVTC_TIMING_STATUS 0x0004
83#define XVTC_TIMING_STATUS_ACTIVE_VIDEO (1 << 2)
84#define XVTC_TIMING_STATUS_VBLANK (1 << 1)
85#define XVTC_TIMING_STATUS_LOCKED (1 << 0)
86
87#define XVTC_ENCODING 0x0008
88#define XVTC_ENCODING_CHROMA_PARITY_SHIFT 8
89#define XVTC_ENCODING_CHROMA_PARITY_MASK (3 << 8)
90#define XVTC_ENCODING_CHROMA_PARITY_EVEN_ALL (0 << 8)
91#define XVTC_ENCODING_CHROMA_PARITY_ODD_ALL (1 << 8)
92#define XVTC_ENCODING_CHROMA_PARITY_EVEN_EVEN (2 << 8)
93#define XVTC_ENCODING_CHROMA_PARITY_ODD_EVEN (3 << 8)
94#define XVTC_ENCODING_VIDEO_FORMAT_SHIFT 0
95#define XVTC_ENCODING_VIDEO_FORMAT_MASK (0xf << 0)
96#define XVTC_ENCODING_VIDEO_FORMAT_YUV422 (0 << 0)
97#define XVTC_ENCODING_VIDEO_FORMAT_YUV444 (1 << 0)
98#define XVTC_ENCODING_VIDEO_FORMAT_RGB (2 << 0)
99#define XVTC_ENCODING_VIDEO_FORMAT_YUV420 (3 << 0)
100
101#define XVTC_POLARITY 0x000c
102#define XVTC_POLARITY_ACTIVE_CHROMA_POL (1 << 5)
103#define XVTC_POLARITY_ACTIVE_VIDEO_POL (1 << 4)
104#define XVTC_POLARITY_HSYNC_POL (1 << 3)
105#define XVTC_POLARITY_VSYNC_POL (1 << 2)
106#define XVTC_POLARITY_HBLANK_POL (1 << 1)
107#define XVTC_POLARITY_VBLANK_POL (1 << 0)
108
109#define XVTC_HSIZE 0x0010
110#define XVTC_HSIZE_MASK (0x1fff << 0)
111
112#define XVTC_VSIZE 0x0014
113#define XVTC_VSIZE_MASK (0x1fff << 0)
114
115#define XVTC_HSYNC 0x0018
116#define XVTC_HSYNC_END_SHIFT 16
117#define XVTC_HSYNC_END_MASK (0x1fff << 16)
118#define XVTC_HSYNC_START_SHIFT 0
119#define XVTC_HSYNC_START_MASK (0x1fff << 0)
120
121#define XVTC_F0_VBLANK_H 0x001c
122#define XVTC_F0_VBLANK_HEND_SHIFT 16
123#define XVTC_F0_VBLANK_HEND_MASK (0x1fff << 16)
124#define XVTC_F0_VBLANK_HSTART_SHIFT 0
125#define XVTC_F0_VBLANK_HSTART_MASK (0x1fff << 0)
126
127#define XVTC_F0_VSYNC_V 0x0020
128#define XVTC_F0_VSYNC_VEND_SHIFT 16
129#define XVTC_F0_VSYNC_VEND_MASK (0x1fff << 16)
130#define XVTC_F0_VSYNC_VSTART_SHIFT 0
131#define XVTC_F0_VSYNC_VSTART_MASK (0x1fff << 0)
132
133#define XVTC_F0_VSYNC_H 0x0024
134#define XVTC_F0_VSYNC_HEND_SHIFT 16
135#define XVTC_F0_VSYNC_HEND_MASK (0x1fff << 16)
136#define XVTC_F0_VSYNC_HSTART_SHIFT 0
137#define XVTC_F0_VSYNC_HSTART_MASK (0x1fff << 0)
138
139#define XVTC_FRAME_SYNC_CONFIG(n) (0x0100 + 4 * (n))
140#define XVTC_FRAME_SYNC_V_START_SHIFT 16
141#define XVTC_FRAME_SYNC_V_START_MASK (0x1fff << 16)
142#define XVTC_FRAME_SYNC_H_START_SHIFT 0
143#define XVTC_FRAME_SYNC_H_START_MASK (0x1fff << 0)
144
145#define XVTC_GENERATOR_GLOBAL_DELAY 0x0104
146
147/**
148 * struct xvtc_device - Xilinx Video Timing Controller device structure
149 * @xvip: Xilinx Video IP device
150 * @list: entry in the global VTC list
151 * @has_detector: the VTC has a timing detector
152 * @has_generator: the VTC has a timing generator
153 * @config: generator timings configuration
154 */
155struct xvtc_device {
156 struct xvip_device xvip;
157 struct list_head list;
158
159 bool has_detector;
160 bool has_generator;
161
162 struct xvtc_config config;
163};
164
165static LIST_HEAD(xvtc_list);
166static DEFINE_MUTEX(xvtc_lock);
167
168static inline void xvtc_gen_write(struct xvtc_device *xvtc, u32 addr, u32 value)
169{
170 xvip_write(&xvtc->xvip, XVTC_GENERATOR_OFFSET + addr, value);
171}
172
173/* -----------------------------------------------------------------------------
174 * Generator Operations
175 */
176
177int xvtc_generator_start(struct xvtc_device *xvtc,
178 const struct xvtc_config *config)
179{
180 int ret;
181
182 if (!xvtc->has_generator)
183 return -ENXIO;
184
185 ret = clk_prepare_enable(xvtc->xvip.clk);
186 if (ret < 0)
187 return ret;
188
189 /* We don't care about the chroma active signal, encoding parameters are
190 * not important for now.
191 */
192 xvtc_gen_write(xvtc, XVTC_POLARITY,
193 XVTC_POLARITY_ACTIVE_CHROMA_POL |
194 XVTC_POLARITY_ACTIVE_VIDEO_POL |
195 XVTC_POLARITY_HSYNC_POL | XVTC_POLARITY_VSYNC_POL |
196 XVTC_POLARITY_HBLANK_POL | XVTC_POLARITY_VBLANK_POL);
197
198 /* Hardcode the polarity to active high, as required by the video in to
199 * AXI4-stream core.
200 */
201 xvtc_gen_write(xvtc, XVTC_ENCODING, 0);
202
203 /* Configure the timings. The VBLANK and VSYNC signals assertion and
204 * deassertion are hardcoded to the first pixel of the line.
205 */
206 xvtc_gen_write(xvtc, XVTC_ACTIVE_SIZE,
207 (config->vblank_start << XVTC_ACTIVE_VSIZE_SHIFT) |
208 (config->hblank_start << XVTC_ACTIVE_HSIZE_SHIFT));
209 xvtc_gen_write(xvtc, XVTC_HSIZE, config->hsize);
210 xvtc_gen_write(xvtc, XVTC_VSIZE, config->vsize);
211 xvtc_gen_write(xvtc, XVTC_HSYNC,
212 (config->hsync_end << XVTC_HSYNC_END_SHIFT) |
213 (config->hsync_start << XVTC_HSYNC_START_SHIFT));
214 xvtc_gen_write(xvtc, XVTC_F0_VBLANK_H, 0);
215 xvtc_gen_write(xvtc, XVTC_F0_VSYNC_V,
216 (config->vsync_end << XVTC_F0_VSYNC_VEND_SHIFT) |
217 (config->vsync_start << XVTC_F0_VSYNC_VSTART_SHIFT));
218 xvtc_gen_write(xvtc, XVTC_F0_VSYNC_H, 0);
219
220 /* Enable the generator. Set the source of all generator parameters to
221 * generator registers.
222 */
223 xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL,
224 XVTC_CONTROL_ACTIVE_CHROMA_POL_SRC |
225 XVTC_CONTROL_ACTIVE_VIDEO_POL_SRC |
226 XVTC_CONTROL_HSYNC_POL_SRC | XVTC_CONTROL_VSYNC_POL_SRC |
227 XVTC_CONTROL_HBLANK_POL_SRC | XVTC_CONTROL_VBLANK_POL_SRC |
228 XVTC_CONTROL_CHROMA_SRC | XVTC_CONTROL_VBLANK_HOFF_SRC |
229 XVTC_CONTROL_VSYNC_END_SRC | XVTC_CONTROL_VSYNC_START_SRC |
230 XVTC_CONTROL_ACTIVE_VSIZE_SRC |
231 XVTC_CONTROL_FRAME_VSIZE_SRC | XVTC_CONTROL_HSYNC_END_SRC |
232 XVTC_CONTROL_HSYNC_START_SRC |
233 XVTC_CONTROL_ACTIVE_HSIZE_SRC |
234 XVTC_CONTROL_FRAME_HSIZE_SRC | XVTC_CONTROL_GEN_ENABLE |
235 XVIP_CTRL_CONTROL_REG_UPDATE);
236
237 return 0;
238}
239EXPORT_SYMBOL_GPL(xvtc_generator_start);
240
241int xvtc_generator_stop(struct xvtc_device *xvtc)
242{
243 if (!xvtc->has_generator)
244 return -ENXIO;
245
246 xvip_write(&xvtc->xvip, XVIP_CTRL_CONTROL, 0);
247
248 clk_disable_unprepare(xvtc->xvip.clk);
249
250 return 0;
251}
252EXPORT_SYMBOL_GPL(xvtc_generator_stop);
253
254struct xvtc_device *xvtc_of_get(struct device_node *np)
255{
256 struct device_node *xvtc_node;
257 struct xvtc_device *found = NULL;
258 struct xvtc_device *xvtc;
259
260 if (!of_find_property(np, "xlnx,vtc", NULL))
261 return NULL;
262
263 xvtc_node = of_parse_phandle(np, "xlnx,vtc", 0);
264 if (xvtc_node == NULL)
265 return ERR_PTR(-EINVAL);
266
267 mutex_lock(&xvtc_lock);
268 list_for_each_entry(xvtc, &xvtc_list, list) {
269 if (xvtc->xvip.dev->of_node == xvtc_node) {
270 found = xvtc;
271 break;
272 }
273 }
274 mutex_unlock(&xvtc_lock);
275
276 of_node_put(xvtc_node);
277
278 if (!found)
279 return ERR_PTR(-EPROBE_DEFER);
280
281 return found;
282}
283EXPORT_SYMBOL_GPL(xvtc_of_get);
284
285void xvtc_put(struct xvtc_device *xvtc)
286{
287}
288EXPORT_SYMBOL_GPL(xvtc_put);
289
290/* -----------------------------------------------------------------------------
291 * Registration and Unregistration
292 */
293
294static void xvtc_register_device(struct xvtc_device *xvtc)
295{
296 mutex_lock(&xvtc_lock);
297 list_add_tail(&xvtc->list, &xvtc_list);
298 mutex_unlock(&xvtc_lock);
299}
300
301static void xvtc_unregister_device(struct xvtc_device *xvtc)
302{
303 mutex_lock(&xvtc_lock);
304 list_del(&xvtc->list);
305 mutex_unlock(&xvtc_lock);
306}
307
308/* -----------------------------------------------------------------------------
309 * Platform Device Driver
310 */
311
312static int xvtc_parse_of(struct xvtc_device *xvtc)
313{
314 struct device_node *node = xvtc->xvip.dev->of_node;
315
316 xvtc->has_detector = of_property_read_bool(node, "xlnx,detector");
317 xvtc->has_generator = of_property_read_bool(node, "xlnx,generator");
318
319 return 0;
320}
321
322static int xvtc_probe(struct platform_device *pdev)
323{
324 struct xvtc_device *xvtc;
325 int ret;
326
327 xvtc = devm_kzalloc(&pdev->dev, sizeof(*xvtc), GFP_KERNEL);
328 if (!xvtc)
329 return -ENOMEM;
330
331 xvtc->xvip.dev = &pdev->dev;
332
333 ret = xvtc_parse_of(xvtc);
334 if (ret < 0)
335 return ret;
336
337 ret = xvip_init_resources(&xvtc->xvip);
338 if (ret < 0)
339 return ret;
340
341 platform_set_drvdata(pdev, xvtc);
342
343 xvip_print_version(&xvtc->xvip);
344
345 xvtc_register_device(xvtc);
346
347 return 0;
348}
349
350static int xvtc_remove(struct platform_device *pdev)
351{
352 struct xvtc_device *xvtc = platform_get_drvdata(pdev);
353
354 xvtc_unregister_device(xvtc);
355
356 xvip_cleanup_resources(&xvtc->xvip);
357
358 return 0;
359}
360
361static const struct of_device_id xvtc_of_id_table[] = {
362 { .compatible = "xlnx,v-tc-6.1" },
363 { }
364};
365MODULE_DEVICE_TABLE(of, xvtc_of_id_table);
366
367static struct platform_driver xvtc_driver = {
368 .driver = {
369 .name = "xilinx-vtc",
370 .of_match_table = xvtc_of_id_table,
371 },
372 .probe = xvtc_probe,
373 .remove = xvtc_remove,
374};
375
376module_platform_driver(xvtc_driver);
377
378MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
379MODULE_DESCRIPTION("Xilinx Video Timing Controller Driver");
380MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/platform/xilinx/xilinx-vtc.h b/drivers/media/platform/xilinx/xilinx-vtc.h
new file mode 100644
index 000000000000..e1bb2cfcf428
--- /dev/null
+++ b/drivers/media/platform/xilinx/xilinx-vtc.h
@@ -0,0 +1,42 @@
1/*
2 * Xilinx Video Timing Controller
3 *
4 * Copyright (C) 2013-2015 Ideas on Board
5 * Copyright (C) 2013-2015 Xilinx, Inc.
6 *
7 * Contacts: Hyun Kwon <hyun.kwon@xilinx.com>
8 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __XILINX_VTC_H__
16#define __XILINX_VTC_H__
17
18struct device_node;
19struct xvtc_device;
20
21#define XVTC_MAX_HSIZE 8191
22#define XVTC_MAX_VSIZE 8191
23
24struct xvtc_config {
25 unsigned int hblank_start;
26 unsigned int hsync_start;
27 unsigned int hsync_end;
28 unsigned int hsize;
29 unsigned int vblank_start;
30 unsigned int vsync_start;
31 unsigned int vsync_end;
32 unsigned int vsize;
33};
34
35struct xvtc_device *xvtc_of_get(struct device_node *np);
36void xvtc_put(struct xvtc_device *xvtc);
37
38int xvtc_generator_start(struct xvtc_device *xvtc,
39 const struct xvtc_config *config);
40int xvtc_generator_stop(struct xvtc_device *xvtc);
41
42#endif /* __XILINX_VTC_H__ */