diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 22:22:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 22:22:22 -0500 |
commit | d8c532c40721f7507896d202b8cae3b3642d2b0d (patch) | |
tree | 42b1ce76671eb85324281ed93491432f4523f983 /drivers/media/platform/omap3isp | |
parent | e777d192ffb9f2929d547a2f8a5f65b7db7a9552 (diff) | |
parent | 77c53d0b56264a8fc5844e087ad15fffe20c299d (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- Missing MAINTAINERS entries were added for several drivers
- Adds V4L2 support for DMABUF handling, allowing zero-copy buffer
sharing between V4L2 devices and GPU
- Got rid of all warnings when compiling with W=1 on x86
- Add a new driver for Exynos hardware (s3c-camif)
- Several bug fixes, cleanups and driver improvements
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (243 commits)
[media] omap3isp: Replace cpu_is_omap3630() with ISP revision check
[media] omap3isp: Prepare/unprepare clocks before/after enable/disable
[media] omap3isp: preview: Add support for 8-bit formats at the sink pad
[media] omap3isp: Replace printk with dev_*
[media] omap3isp: Find source pad from external entity
[media] omap3isp: Configure CSI-2 phy based on platform data
[media] omap3isp: Add PHY routing configuration
[media] omap3isp: Add CSI configuration registers from control block to ISP resources
[media] omap3isp: Remove unneeded module memory address definitions
[media] omap3isp: Use monotonic timestamps for statistics buffers
[media] uvcvideo: Fix control value clamping for unsigned integer controls
[media] uvcvideo: Mark first output terminal as default video node
[media] uvcvideo: Add VIDIOC_[GS]_PRIORITY support
[media] uvcvideo: Return -ENOTTY for unsupported ioctls
[media] uvcvideo: Set device_caps in VIDIOC_QUERYCAP
[media] uvcvideo: Don't fail when an unsupported format is requested
[media] uvcvideo: Return -EACCES when trying to access a read/write-only control
[media] uvcvideo: Set error_idx properly for extended controls API failures
[media] rtl28xxu: add NOXON DAB/DAB+ USB dongle rev 2
[media] fc2580: write some registers conditionally
...
Diffstat (limited to 'drivers/media/platform/omap3isp')
-rw-r--r-- | drivers/media/platform/omap3isp/isp.c | 83 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/isp.h | 5 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispcsi2.c | 6 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispcsiphy.c | 227 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispcsiphy.h | 10 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/isphist.c | 8 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/isppreview.c | 41 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispreg.h | 99 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispstat.c | 5 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispstat.h | 2 | ||||
-rw-r--r-- | drivers/media/platform/omap3isp/ispvideo.c | 3 |
11 files changed, 284 insertions, 205 deletions
diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 7f182f0ff3da..a9f6de5b69d8 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c | |||
@@ -103,7 +103,8 @@ static const struct isp_res_mapping isp_res_maps[] = { | |||
103 | 1 << OMAP3_ISP_IOMEM_RESZ | | 103 | 1 << OMAP3_ISP_IOMEM_RESZ | |
104 | 1 << OMAP3_ISP_IOMEM_SBL | | 104 | 1 << OMAP3_ISP_IOMEM_SBL | |
105 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | | 105 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 | |
106 | 1 << OMAP3_ISP_IOMEM_CSIPHY2, | 106 | 1 << OMAP3_ISP_IOMEM_CSIPHY2 | |
107 | 1 << OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, | ||
107 | }, | 108 | }, |
108 | { | 109 | { |
109 | .isp_rev = ISP_REVISION_15_0, | 110 | .isp_rev = ISP_REVISION_15_0, |
@@ -120,7 +121,8 @@ static const struct isp_res_mapping isp_res_maps[] = { | |||
120 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 | | 121 | 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 | |
121 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 | | 122 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 | |
122 | 1 << OMAP3_ISP_IOMEM_CSIPHY1 | | 123 | 1 << OMAP3_ISP_IOMEM_CSIPHY1 | |
123 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2, | 124 | 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2 | |
125 | 1 << OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, | ||
124 | }, | 126 | }, |
125 | }; | 127 | }; |
126 | 128 | ||
@@ -1331,7 +1333,8 @@ void omap3isp_subclk_disable(struct isp_device *isp, | |||
1331 | * isp_enable_clocks - Enable ISP clocks | 1333 | * isp_enable_clocks - Enable ISP clocks |
1332 | * @isp: OMAP3 ISP device | 1334 | * @isp: OMAP3 ISP device |
1333 | * | 1335 | * |
1334 | * Return 0 if successful, or clk_enable return value if any of tthem fails. | 1336 | * Return 0 if successful, or clk_prepare_enable return value if any of them |
1337 | * fails. | ||
1335 | */ | 1338 | */ |
1336 | static int isp_enable_clocks(struct isp_device *isp) | 1339 | static int isp_enable_clocks(struct isp_device *isp) |
1337 | { | 1340 | { |
@@ -1348,14 +1351,11 @@ static int isp_enable_clocks(struct isp_device *isp) | |||
1348 | * has to be twice of what is set on OMAP3430 to get | 1351 | * has to be twice of what is set on OMAP3430 to get |
1349 | * the required value for cam_mclk | 1352 | * the required value for cam_mclk |
1350 | */ | 1353 | */ |
1351 | if (cpu_is_omap3630()) | 1354 | divisor = isp->revision == ISP_REVISION_15_0 ? 1 : 2; |
1352 | divisor = 1; | ||
1353 | else | ||
1354 | divisor = 2; | ||
1355 | 1355 | ||
1356 | r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]); | 1356 | r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_ICK]); |
1357 | if (r) { | 1357 | if (r) { |
1358 | dev_err(isp->dev, "clk_enable cam_ick failed\n"); | 1358 | dev_err(isp->dev, "failed to enable cam_ick clock\n"); |
1359 | goto out_clk_enable_ick; | 1359 | goto out_clk_enable_ick; |
1360 | } | 1360 | } |
1361 | r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK], | 1361 | r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK], |
@@ -1364,9 +1364,9 @@ static int isp_enable_clocks(struct isp_device *isp) | |||
1364 | dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n"); | 1364 | dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n"); |
1365 | goto out_clk_enable_mclk; | 1365 | goto out_clk_enable_mclk; |
1366 | } | 1366 | } |
1367 | r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]); | 1367 | r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_MCLK]); |
1368 | if (r) { | 1368 | if (r) { |
1369 | dev_err(isp->dev, "clk_enable cam_mclk failed\n"); | 1369 | dev_err(isp->dev, "failed to enable cam_mclk clock\n"); |
1370 | goto out_clk_enable_mclk; | 1370 | goto out_clk_enable_mclk; |
1371 | } | 1371 | } |
1372 | rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]); | 1372 | rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]); |
@@ -1374,17 +1374,17 @@ static int isp_enable_clocks(struct isp_device *isp) | |||
1374 | dev_warn(isp->dev, "unexpected cam_mclk rate:\n" | 1374 | dev_warn(isp->dev, "unexpected cam_mclk rate:\n" |
1375 | " expected : %d\n" | 1375 | " expected : %d\n" |
1376 | " actual : %ld\n", CM_CAM_MCLK_HZ, rate); | 1376 | " actual : %ld\n", CM_CAM_MCLK_HZ, rate); |
1377 | r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]); | 1377 | r = clk_prepare_enable(isp->clock[ISP_CLK_CSI2_FCK]); |
1378 | if (r) { | 1378 | if (r) { |
1379 | dev_err(isp->dev, "clk_enable csi2_fck failed\n"); | 1379 | dev_err(isp->dev, "failed to enable csi2_fck clock\n"); |
1380 | goto out_clk_enable_csi2_fclk; | 1380 | goto out_clk_enable_csi2_fclk; |
1381 | } | 1381 | } |
1382 | return 0; | 1382 | return 0; |
1383 | 1383 | ||
1384 | out_clk_enable_csi2_fclk: | 1384 | out_clk_enable_csi2_fclk: |
1385 | clk_disable(isp->clock[ISP_CLK_CAM_MCLK]); | 1385 | clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]); |
1386 | out_clk_enable_mclk: | 1386 | out_clk_enable_mclk: |
1387 | clk_disable(isp->clock[ISP_CLK_CAM_ICK]); | 1387 | clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]); |
1388 | out_clk_enable_ick: | 1388 | out_clk_enable_ick: |
1389 | return r; | 1389 | return r; |
1390 | } | 1390 | } |
@@ -1395,9 +1395,9 @@ out_clk_enable_ick: | |||
1395 | */ | 1395 | */ |
1396 | static void isp_disable_clocks(struct isp_device *isp) | 1396 | static void isp_disable_clocks(struct isp_device *isp) |
1397 | { | 1397 | { |
1398 | clk_disable(isp->clock[ISP_CLK_CAM_ICK]); | 1398 | clk_disable_unprepare(isp->clock[ISP_CLK_CAM_ICK]); |
1399 | clk_disable(isp->clock[ISP_CLK_CAM_MCLK]); | 1399 | clk_disable_unprepare(isp->clock[ISP_CLK_CAM_MCLK]); |
1400 | clk_disable(isp->clock[ISP_CLK_CSI2_FCK]); | 1400 | clk_disable_unprepare(isp->clock[ISP_CLK_CSI2_FCK]); |
1401 | } | 1401 | } |
1402 | 1402 | ||
1403 | static const char *isp_clocks[] = { | 1403 | static const char *isp_clocks[] = { |
@@ -1678,7 +1678,7 @@ isp_register_subdev_group(struct isp_device *isp, | |||
1678 | 1678 | ||
1679 | adapter = i2c_get_adapter(board_info->i2c_adapter_id); | 1679 | adapter = i2c_get_adapter(board_info->i2c_adapter_id); |
1680 | if (adapter == NULL) { | 1680 | if (adapter == NULL) { |
1681 | printk(KERN_ERR "%s: Unable to get I2C adapter %d for " | 1681 | dev_err(isp->dev, "%s: Unable to get I2C adapter %d for " |
1682 | "device %s\n", __func__, | 1682 | "device %s\n", __func__, |
1683 | board_info->i2c_adapter_id, | 1683 | board_info->i2c_adapter_id, |
1684 | board_info->board_info->type); | 1684 | board_info->board_info->type); |
@@ -1688,7 +1688,7 @@ isp_register_subdev_group(struct isp_device *isp, | |||
1688 | subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, | 1688 | subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, |
1689 | board_info->board_info, NULL); | 1689 | board_info->board_info, NULL); |
1690 | if (subdev == NULL) { | 1690 | if (subdev == NULL) { |
1691 | printk(KERN_ERR "%s: Unable to register subdev %s\n", | 1691 | dev_err(isp->dev, "%s: Unable to register subdev %s\n", |
1692 | __func__, board_info->board_info->type); | 1692 | __func__, board_info->board_info->type); |
1693 | continue; | 1693 | continue; |
1694 | } | 1694 | } |
@@ -1713,7 +1713,7 @@ static int isp_register_entities(struct isp_device *isp) | |||
1713 | isp->media_dev.link_notify = isp_pipeline_link_notify; | 1713 | isp->media_dev.link_notify = isp_pipeline_link_notify; |
1714 | ret = media_device_register(&isp->media_dev); | 1714 | ret = media_device_register(&isp->media_dev); |
1715 | if (ret < 0) { | 1715 | if (ret < 0) { |
1716 | printk(KERN_ERR "%s: Media device registration failed (%d)\n", | 1716 | dev_err(isp->dev, "%s: Media device registration failed (%d)\n", |
1717 | __func__, ret); | 1717 | __func__, ret); |
1718 | return ret; | 1718 | return ret; |
1719 | } | 1719 | } |
@@ -1721,7 +1721,7 @@ static int isp_register_entities(struct isp_device *isp) | |||
1721 | isp->v4l2_dev.mdev = &isp->media_dev; | 1721 | isp->v4l2_dev.mdev = &isp->media_dev; |
1722 | ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); | 1722 | ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); |
1723 | if (ret < 0) { | 1723 | if (ret < 0) { |
1724 | printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n", | 1724 | dev_err(isp->dev, "%s: V4L2 device registration failed (%d)\n", |
1725 | __func__, ret); | 1725 | __func__, ret); |
1726 | goto done; | 1726 | goto done; |
1727 | } | 1727 | } |
@@ -1766,6 +1766,7 @@ static int isp_register_entities(struct isp_device *isp) | |||
1766 | struct media_entity *input; | 1766 | struct media_entity *input; |
1767 | unsigned int flags; | 1767 | unsigned int flags; |
1768 | unsigned int pad; | 1768 | unsigned int pad; |
1769 | unsigned int i; | ||
1769 | 1770 | ||
1770 | sensor = isp_register_subdev_group(isp, subdevs->subdevs); | 1771 | sensor = isp_register_subdev_group(isp, subdevs->subdevs); |
1771 | if (sensor == NULL) | 1772 | if (sensor == NULL) |
@@ -1807,13 +1808,25 @@ static int isp_register_entities(struct isp_device *isp) | |||
1807 | break; | 1808 | break; |
1808 | 1809 | ||
1809 | default: | 1810 | default: |
1810 | printk(KERN_ERR "%s: invalid interface type %u\n", | 1811 | dev_err(isp->dev, "%s: invalid interface type %u\n", |
1811 | __func__, subdevs->interface); | 1812 | __func__, subdevs->interface); |
1813 | ret = -EINVAL; | ||
1814 | goto done; | ||
1815 | } | ||
1816 | |||
1817 | for (i = 0; i < sensor->entity.num_pads; i++) { | ||
1818 | if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE) | ||
1819 | break; | ||
1820 | } | ||
1821 | if (i == sensor->entity.num_pads) { | ||
1822 | dev_err(isp->dev, | ||
1823 | "%s: no source pad in external entity\n", | ||
1824 | __func__); | ||
1812 | ret = -EINVAL; | 1825 | ret = -EINVAL; |
1813 | goto done; | 1826 | goto done; |
1814 | } | 1827 | } |
1815 | 1828 | ||
1816 | ret = media_entity_create_link(&sensor->entity, 0, input, pad, | 1829 | ret = media_entity_create_link(&sensor->entity, i, input, pad, |
1817 | flags); | 1830 | flags); |
1818 | if (ret < 0) | 1831 | if (ret < 0) |
1819 | goto done; | 1832 | goto done; |
@@ -2096,7 +2109,11 @@ static int __devinit isp_probe(struct platform_device *pdev) | |||
2096 | isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1"); | 2109 | isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1"); |
2097 | isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2"); | 2110 | isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2"); |
2098 | 2111 | ||
2099 | /* Clocks */ | 2112 | /* Clocks |
2113 | * | ||
2114 | * The ISP clock tree is revision-dependent. We thus need to enable ICLK | ||
2115 | * manually to read the revision before calling __omap3isp_get(). | ||
2116 | */ | ||
2100 | ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN); | 2117 | ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN); |
2101 | if (ret < 0) | 2118 | if (ret < 0) |
2102 | goto error; | 2119 | goto error; |
@@ -2105,6 +2122,16 @@ static int __devinit isp_probe(struct platform_device *pdev) | |||
2105 | if (ret < 0) | 2122 | if (ret < 0) |
2106 | goto error; | 2123 | goto error; |
2107 | 2124 | ||
2125 | ret = clk_enable(isp->clock[ISP_CLK_CAM_ICK]); | ||
2126 | if (ret < 0) | ||
2127 | goto error; | ||
2128 | |||
2129 | isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION); | ||
2130 | dev_info(isp->dev, "Revision %d.%d found\n", | ||
2131 | (isp->revision & 0xf0) >> 4, isp->revision & 0x0f); | ||
2132 | |||
2133 | clk_disable(isp->clock[ISP_CLK_CAM_ICK]); | ||
2134 | |||
2108 | if (__omap3isp_get(isp, false) == NULL) { | 2135 | if (__omap3isp_get(isp, false) == NULL) { |
2109 | ret = -ENODEV; | 2136 | ret = -ENODEV; |
2110 | goto error; | 2137 | goto error; |
@@ -2115,10 +2142,6 @@ static int __devinit isp_probe(struct platform_device *pdev) | |||
2115 | goto error_isp; | 2142 | goto error_isp; |
2116 | 2143 | ||
2117 | /* Memory resources */ | 2144 | /* Memory resources */ |
2118 | isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION); | ||
2119 | dev_info(isp->dev, "Revision %d.%d found\n", | ||
2120 | (isp->revision & 0xf0) >> 4, isp->revision & 0x0f); | ||
2121 | |||
2122 | for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++) | 2145 | for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++) |
2123 | if (isp->revision == isp_res_maps[m].isp_rev) | 2146 | if (isp->revision == isp_res_maps[m].isp_rev) |
2124 | break; | 2147 | break; |
diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index 8d6866942b85..517d348ce32b 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h | |||
@@ -70,6 +70,8 @@ enum isp_mem_resources { | |||
70 | OMAP3_ISP_IOMEM_CSI2C_REGS1, | 70 | OMAP3_ISP_IOMEM_CSI2C_REGS1, |
71 | OMAP3_ISP_IOMEM_CSIPHY1, | 71 | OMAP3_ISP_IOMEM_CSIPHY1, |
72 | OMAP3_ISP_IOMEM_CSI2C_REGS2, | 72 | OMAP3_ISP_IOMEM_CSI2C_REGS2, |
73 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, | ||
74 | OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, | ||
73 | OMAP3_ISP_IOMEM_LAST | 75 | OMAP3_ISP_IOMEM_LAST |
74 | }; | 76 | }; |
75 | 77 | ||
@@ -125,9 +127,6 @@ struct isp_reg { | |||
125 | 127 | ||
126 | struct isp_platform_callback { | 128 | struct isp_platform_callback { |
127 | u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel); | 129 | u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel); |
128 | int (*csiphy_config)(struct isp_csiphy *phy, | ||
129 | struct isp_csiphy_dphy_cfg *dphy, | ||
130 | struct isp_csiphy_lanes_cfg *lanes); | ||
131 | }; | 130 | }; |
132 | 131 | ||
133 | /* | 132 | /* |
diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index 6a3ff792af7d..783f4b05b153 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c | |||
@@ -517,7 +517,7 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2) | |||
517 | } while (soft_reset_retries < 5); | 517 | } while (soft_reset_retries < 5); |
518 | 518 | ||
519 | if (soft_reset_retries == 5) { | 519 | if (soft_reset_retries == 5) { |
520 | printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n"); | 520 | dev_err(isp->dev, "CSI2: Soft reset try count exceeded!\n"); |
521 | return -EBUSY; | 521 | return -EBUSY; |
522 | } | 522 | } |
523 | 523 | ||
@@ -535,8 +535,8 @@ int omap3isp_csi2_reset(struct isp_csi2_device *csi2) | |||
535 | } while (--i > 0); | 535 | } while (--i > 0); |
536 | 536 | ||
537 | if (i == 0) { | 537 | if (i == 0) { |
538 | printk(KERN_ERR | 538 | dev_err(isp->dev, |
539 | "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n"); | 539 | "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n"); |
540 | return -EBUSY; | 540 | return -EBUSY; |
541 | } | 541 | } |
542 | 542 | ||
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.c b/drivers/media/platform/omap3isp/ispcsiphy.c index 348f67ebbbc9..3d56b33f85e8 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.c +++ b/drivers/media/platform/omap3isp/ispcsiphy.c | |||
@@ -32,34 +32,92 @@ | |||
32 | #include "ispreg.h" | 32 | #include "ispreg.h" |
33 | #include "ispcsiphy.h" | 33 | #include "ispcsiphy.h" |
34 | 34 | ||
35 | /* | 35 | static void csiphy_routing_cfg_3630(struct isp_csiphy *phy, u32 iface, |
36 | * csiphy_lanes_config - Configuration of CSIPHY lanes. | 36 | bool ccp2_strobe) |
37 | * | ||
38 | * Updates HW configuration. | ||
39 | * Called with phy->mutex taken. | ||
40 | */ | ||
41 | static void csiphy_lanes_config(struct isp_csiphy *phy) | ||
42 | { | 37 | { |
43 | unsigned int i; | 38 | u32 reg = isp_reg_readl( |
44 | u32 reg; | 39 | phy->isp, OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0); |
40 | u32 shift, mode; | ||
41 | |||
42 | switch (iface) { | ||
43 | case ISP_INTERFACE_CCP2B_PHY1: | ||
44 | reg &= ~OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2; | ||
45 | shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT; | ||
46 | break; | ||
47 | case ISP_INTERFACE_CSI2C_PHY1: | ||
48 | shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT; | ||
49 | mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY; | ||
50 | break; | ||
51 | case ISP_INTERFACE_CCP2B_PHY2: | ||
52 | reg |= OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2; | ||
53 | shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT; | ||
54 | break; | ||
55 | case ISP_INTERFACE_CSI2A_PHY2: | ||
56 | shift = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT; | ||
57 | mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY; | ||
58 | break; | ||
59 | } | ||
45 | 60 | ||
46 | reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG); | 61 | /* Select data/clock or data/strobe mode for CCP2 */ |
62 | switch (iface) { | ||
63 | case ISP_INTERFACE_CCP2B_PHY1: | ||
64 | case ISP_INTERFACE_CCP2B_PHY2: | ||
65 | if (ccp2_strobe) | ||
66 | mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_STROBE; | ||
67 | else | ||
68 | mode = OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_CLOCK; | ||
69 | } | ||
47 | 70 | ||
48 | for (i = 0; i < phy->num_data_lanes; i++) { | 71 | reg &= ~(OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK << shift); |
49 | reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) | | 72 | reg |= mode << shift; |
50 | ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1)); | 73 | |
51 | reg |= (phy->lanes.data[i].pol << | 74 | isp_reg_writel(phy->isp, reg, |
52 | ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1)); | 75 | OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL, 0); |
53 | reg |= (phy->lanes.data[i].pos << | 76 | } |
54 | ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1)); | 77 | |
78 | static void csiphy_routing_cfg_3430(struct isp_csiphy *phy, u32 iface, bool on, | ||
79 | bool ccp2_strobe) | ||
80 | { | ||
81 | u32 csirxfe = OMAP343X_CONTROL_CSIRXFE_PWRDNZ | ||
82 | | OMAP343X_CONTROL_CSIRXFE_RESET; | ||
83 | |||
84 | /* Only the CCP2B on PHY1 is configurable. */ | ||
85 | if (iface != ISP_INTERFACE_CCP2B_PHY1) | ||
86 | return; | ||
87 | |||
88 | if (!on) { | ||
89 | isp_reg_writel(phy->isp, 0, | ||
90 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0); | ||
91 | return; | ||
55 | } | 92 | } |
56 | 93 | ||
57 | reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK | | 94 | if (ccp2_strobe) |
58 | ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK); | 95 | csirxfe |= OMAP343X_CONTROL_CSIRXFE_SELFORM; |
59 | reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT; | ||
60 | reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT; | ||
61 | 96 | ||
62 | isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG); | 97 | isp_reg_writel(phy->isp, csirxfe, |
98 | OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE, 0); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Configure OMAP 3 CSI PHY routing. | ||
103 | * @phy: relevant phy device | ||
104 | * @iface: ISP_INTERFACE_* | ||
105 | * @on: power on or off | ||
106 | * @ccp2_strobe: false: data/clock, true: data/strobe | ||
107 | * | ||
108 | * Note that the underlying routing configuration registers are part of the | ||
109 | * control (SCM) register space and part of the CORE power domain on both 3430 | ||
110 | * and 3630, so they will not hold their contents in off-mode. This isn't an | ||
111 | * issue since the MPU power domain is forced on whilst the ISP is in use. | ||
112 | */ | ||
113 | static void csiphy_routing_cfg(struct isp_csiphy *phy, u32 iface, bool on, | ||
114 | bool ccp2_strobe) | ||
115 | { | ||
116 | if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_3630_CONTROL_CAMERA_PHY_CTRL] | ||
117 | && on) | ||
118 | return csiphy_routing_cfg_3630(phy, iface, ccp2_strobe); | ||
119 | if (phy->isp->mmio_base[OMAP3_ISP_IOMEM_343X_CONTROL_CSIRXFE]) | ||
120 | return csiphy_routing_cfg_3430(phy, iface, on, ccp2_strobe); | ||
63 | } | 121 | } |
64 | 122 | ||
65 | /* | 123 | /* |
@@ -99,7 +157,7 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power) | |||
99 | } while ((reg != power >> 2) && (retry_count < 100)); | 157 | } while ((reg != power >> 2) && (retry_count < 100)); |
100 | 158 | ||
101 | if (retry_count == 100) { | 159 | if (retry_count == 100) { |
102 | printk(KERN_ERR "CSI2 CIO set power failed!\n"); | 160 | dev_err(phy->isp->dev, "CSI2 CIO set power failed!\n"); |
103 | return -EBUSY; | 161 | return -EBUSY; |
104 | } | 162 | } |
105 | 163 | ||
@@ -107,43 +165,28 @@ static int csiphy_set_power(struct isp_csiphy *phy, u32 power) | |||
107 | } | 165 | } |
108 | 166 | ||
109 | /* | 167 | /* |
110 | * csiphy_dphy_config - Configure CSI2 D-PHY parameters. | 168 | * TCLK values are OK at their reset values |
111 | * | ||
112 | * Called with phy->mutex taken. | ||
113 | */ | 169 | */ |
114 | static void csiphy_dphy_config(struct isp_csiphy *phy) | 170 | #define TCLK_TERM 0 |
115 | { | 171 | #define TCLK_MISS 1 |
116 | u32 reg; | 172 | #define TCLK_SETTLE 14 |
117 | |||
118 | /* Set up ISPCSIPHY_REG0 */ | ||
119 | reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0); | ||
120 | |||
121 | reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK | | ||
122 | ISPCSIPHY_REG0_THS_SETTLE_MASK); | ||
123 | reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT; | ||
124 | reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT; | ||
125 | |||
126 | isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0); | ||
127 | |||
128 | /* Set up ISPCSIPHY_REG1 */ | ||
129 | reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1); | ||
130 | |||
131 | reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK | | ||
132 | ISPCSIPHY_REG1_TCLK_MISS_MASK | | ||
133 | ISPCSIPHY_REG1_TCLK_SETTLE_MASK); | ||
134 | reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT; | ||
135 | reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT; | ||
136 | reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT; | ||
137 | |||
138 | isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1); | ||
139 | } | ||
140 | 173 | ||
141 | static int csiphy_config(struct isp_csiphy *phy, | 174 | static int omap3isp_csiphy_config(struct isp_csiphy *phy) |
142 | struct isp_csiphy_dphy_cfg *dphy, | ||
143 | struct isp_csiphy_lanes_cfg *lanes) | ||
144 | { | 175 | { |
176 | struct isp_csi2_device *csi2 = phy->csi2; | ||
177 | struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity); | ||
178 | struct isp_v4l2_subdevs_group *subdevs = pipe->external->host_priv; | ||
179 | struct isp_csiphy_lanes_cfg *lanes; | ||
180 | int csi2_ddrclk_khz; | ||
145 | unsigned int used_lanes = 0; | 181 | unsigned int used_lanes = 0; |
146 | unsigned int i; | 182 | unsigned int i; |
183 | u32 reg; | ||
184 | |||
185 | if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1 | ||
186 | || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2) | ||
187 | lanes = &subdevs->bus.ccp2.lanecfg; | ||
188 | else | ||
189 | lanes = &subdevs->bus.csi2.lanecfg; | ||
147 | 190 | ||
148 | /* Clock and data lanes verification */ | 191 | /* Clock and data lanes verification */ |
149 | for (i = 0; i < phy->num_data_lanes; i++) { | 192 | for (i = 0; i < phy->num_data_lanes; i++) { |
@@ -162,10 +205,61 @@ static int csiphy_config(struct isp_csiphy *phy, | |||
162 | if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos)) | 205 | if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos)) |
163 | return -EINVAL; | 206 | return -EINVAL; |
164 | 207 | ||
165 | mutex_lock(&phy->mutex); | 208 | /* |
166 | phy->dphy = *dphy; | 209 | * The PHY configuration is lost in off mode, that's not an |
167 | phy->lanes = *lanes; | 210 | * issue since the MPU power domain is forced on whilst the |
168 | mutex_unlock(&phy->mutex); | 211 | * ISP is in use. |
212 | */ | ||
213 | csiphy_routing_cfg(phy, subdevs->interface, true, | ||
214 | subdevs->bus.ccp2.phy_layer); | ||
215 | |||
216 | /* DPHY timing configuration */ | ||
217 | /* CSI-2 is DDR and we only count used lanes. */ | ||
218 | csi2_ddrclk_khz = pipe->external_rate / 1000 | ||
219 | / (2 * hweight32(used_lanes)) * pipe->external_width; | ||
220 | |||
221 | reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG0); | ||
222 | |||
223 | reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK | | ||
224 | ISPCSIPHY_REG0_THS_SETTLE_MASK); | ||
225 | /* THS_TERM: Programmed value = ceil(12.5 ns/DDRClk period) - 1. */ | ||
226 | reg |= (DIV_ROUND_UP(25 * csi2_ddrclk_khz, 2000000) - 1) | ||
227 | << ISPCSIPHY_REG0_THS_TERM_SHIFT; | ||
228 | /* THS_SETTLE: Programmed value = ceil(90 ns/DDRClk period) + 3. */ | ||
229 | reg |= (DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3) | ||
230 | << ISPCSIPHY_REG0_THS_SETTLE_SHIFT; | ||
231 | |||
232 | isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG0); | ||
233 | |||
234 | reg = isp_reg_readl(csi2->isp, phy->phy_regs, ISPCSIPHY_REG1); | ||
235 | |||
236 | reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK | | ||
237 | ISPCSIPHY_REG1_TCLK_MISS_MASK | | ||
238 | ISPCSIPHY_REG1_TCLK_SETTLE_MASK); | ||
239 | reg |= TCLK_TERM << ISPCSIPHY_REG1_TCLK_TERM_SHIFT; | ||
240 | reg |= TCLK_MISS << ISPCSIPHY_REG1_TCLK_MISS_SHIFT; | ||
241 | reg |= TCLK_SETTLE << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT; | ||
242 | |||
243 | isp_reg_writel(csi2->isp, reg, phy->phy_regs, ISPCSIPHY_REG1); | ||
244 | |||
245 | /* DPHY lane configuration */ | ||
246 | reg = isp_reg_readl(csi2->isp, phy->cfg_regs, ISPCSI2_PHY_CFG); | ||
247 | |||
248 | for (i = 0; i < phy->num_data_lanes; i++) { | ||
249 | reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) | | ||
250 | ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1)); | ||
251 | reg |= (lanes->data[i].pol << | ||
252 | ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1)); | ||
253 | reg |= (lanes->data[i].pos << | ||
254 | ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1)); | ||
255 | } | ||
256 | |||
257 | reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK | | ||
258 | ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK); | ||
259 | reg |= lanes->clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT; | ||
260 | reg |= lanes->clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT; | ||
261 | |||
262 | isp_reg_writel(csi2->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG); | ||
169 | 263 | ||
170 | return 0; | 264 | return 0; |
171 | } | 265 | } |
@@ -190,8 +284,9 @@ int omap3isp_csiphy_acquire(struct isp_csiphy *phy) | |||
190 | if (rval < 0) | 284 | if (rval < 0) |
191 | goto done; | 285 | goto done; |
192 | 286 | ||
193 | csiphy_dphy_config(phy); | 287 | rval = omap3isp_csiphy_config(phy); |
194 | csiphy_lanes_config(phy); | 288 | if (rval < 0) |
289 | goto done; | ||
195 | 290 | ||
196 | rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON); | 291 | rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON); |
197 | if (rval) { | 292 | if (rval) { |
@@ -211,6 +306,14 @@ void omap3isp_csiphy_release(struct isp_csiphy *phy) | |||
211 | { | 306 | { |
212 | mutex_lock(&phy->mutex); | 307 | mutex_lock(&phy->mutex); |
213 | if (phy->phy_in_use) { | 308 | if (phy->phy_in_use) { |
309 | struct isp_csi2_device *csi2 = phy->csi2; | ||
310 | struct isp_pipeline *pipe = | ||
311 | to_isp_pipeline(&csi2->subdev.entity); | ||
312 | struct isp_v4l2_subdevs_group *subdevs = | ||
313 | pipe->external->host_priv; | ||
314 | |||
315 | csiphy_routing_cfg(phy, subdevs->interface, false, | ||
316 | subdevs->bus.ccp2.phy_layer); | ||
214 | csiphy_power_autoswitch_enable(phy, false); | 317 | csiphy_power_autoswitch_enable(phy, false); |
215 | csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); | 318 | csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF); |
216 | regulator_disable(phy->vdd); | 319 | regulator_disable(phy->vdd); |
@@ -227,8 +330,6 @@ int omap3isp_csiphy_init(struct isp_device *isp) | |||
227 | struct isp_csiphy *phy1 = &isp->isp_csiphy1; | 330 | struct isp_csiphy *phy1 = &isp->isp_csiphy1; |
228 | struct isp_csiphy *phy2 = &isp->isp_csiphy2; | 331 | struct isp_csiphy *phy2 = &isp->isp_csiphy2; |
229 | 332 | ||
230 | isp->platform_cb.csiphy_config = csiphy_config; | ||
231 | |||
232 | phy2->isp = isp; | 333 | phy2->isp = isp; |
233 | phy2->csi2 = &isp->isp_csi2a; | 334 | phy2->csi2 = &isp->isp_csi2a; |
234 | phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES; | 335 | phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES; |
diff --git a/drivers/media/platform/omap3isp/ispcsiphy.h b/drivers/media/platform/omap3isp/ispcsiphy.h index e93a661e65d9..14551fd77697 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.h +++ b/drivers/media/platform/omap3isp/ispcsiphy.h | |||
@@ -32,14 +32,6 @@ | |||
32 | struct isp_csi2_device; | 32 | struct isp_csi2_device; |
33 | struct regulator; | 33 | struct regulator; |
34 | 34 | ||
35 | struct isp_csiphy_dphy_cfg { | ||
36 | u8 ths_term; | ||
37 | u8 ths_settle; | ||
38 | u8 tclk_term; | ||
39 | unsigned tclk_miss:1; | ||
40 | u8 tclk_settle; | ||
41 | }; | ||
42 | |||
43 | struct isp_csiphy { | 35 | struct isp_csiphy { |
44 | struct isp_device *isp; | 36 | struct isp_device *isp; |
45 | struct mutex mutex; /* serialize csiphy configuration */ | 37 | struct mutex mutex; /* serialize csiphy configuration */ |
@@ -52,8 +44,6 @@ struct isp_csiphy { | |||
52 | unsigned int phy_regs; | 44 | unsigned int phy_regs; |
53 | 45 | ||
54 | u8 num_data_lanes; /* number of CSI2 Data Lanes supported */ | 46 | u8 num_data_lanes; /* number of CSI2 Data Lanes supported */ |
55 | struct isp_csiphy_lanes_cfg lanes; | ||
56 | struct isp_csiphy_dphy_cfg dphy; | ||
57 | }; | 47 | }; |
58 | 48 | ||
59 | int omap3isp_csiphy_acquire(struct isp_csiphy *phy); | 49 | int omap3isp_csiphy_acquire(struct isp_csiphy *phy); |
diff --git a/drivers/media/platform/omap3isp/isphist.c b/drivers/media/platform/omap3isp/isphist.c index e7f9c4292cc6..2d759c56f37c 100644 --- a/drivers/media/platform/omap3isp/isphist.c +++ b/drivers/media/platform/omap3isp/isphist.c | |||
@@ -74,11 +74,14 @@ static void hist_reset_mem(struct ispstat *hist) | |||
74 | 74 | ||
75 | static void hist_dma_config(struct ispstat *hist) | 75 | static void hist_dma_config(struct ispstat *hist) |
76 | { | 76 | { |
77 | struct isp_device *isp = hist->isp; | ||
78 | |||
77 | hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32; | 79 | hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32; |
78 | hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT; | 80 | hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT; |
79 | hist->dma_config.frame_count = 1; | 81 | hist->dma_config.frame_count = 1; |
80 | hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT; | 82 | hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT; |
81 | hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA; | 83 | hist->dma_config.src_start = isp->mmio_base_phys[OMAP3_ISP_IOMEM_HIST] |
84 | + ISPHIST_DATA; | ||
82 | hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC; | 85 | hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC; |
83 | hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC; | 86 | hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC; |
84 | } | 87 | } |
@@ -479,6 +482,8 @@ int omap3isp_hist_init(struct isp_device *isp) | |||
479 | return -ENOMEM; | 482 | return -ENOMEM; |
480 | 483 | ||
481 | memset(hist, 0, sizeof(*hist)); | 484 | memset(hist, 0, sizeof(*hist)); |
485 | hist->isp = isp; | ||
486 | |||
482 | if (HIST_CONFIG_DMA) | 487 | if (HIST_CONFIG_DMA) |
483 | ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST", | 488 | ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST", |
484 | hist_dma_cb, hist, &hist->dma_ch); | 489 | hist_dma_cb, hist, &hist->dma_ch); |
@@ -496,7 +501,6 @@ int omap3isp_hist_init(struct isp_device *isp) | |||
496 | hist->ops = &hist_ops; | 501 | hist->ops = &hist_ops; |
497 | hist->priv = hist_cfg; | 502 | hist->priv = hist_cfg; |
498 | hist->event_type = V4L2_EVENT_OMAP3ISP_HIST; | 503 | hist->event_type = V4L2_EVENT_OMAP3ISP_HIST; |
499 | hist->isp = isp; | ||
500 | 504 | ||
501 | ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops); | 505 | ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops); |
502 | if (ret) { | 506 | if (ret) { |
diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 1ae1c0909ed1..691b92a3c3e7 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c | |||
@@ -200,10 +200,10 @@ static void preview_enable_invalaw(struct isp_prev_device *prev, bool enable) | |||
200 | 200 | ||
201 | if (enable) | 201 | if (enable) |
202 | isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | 202 | isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, |
203 | ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW); | 203 | ISPPRV_PCR_INVALAW); |
204 | else | 204 | else |
205 | isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | 205 | isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, |
206 | ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW); | 206 | ISPPRV_PCR_INVALAW); |
207 | } | 207 | } |
208 | 208 | ||
209 | /* | 209 | /* |
@@ -1014,7 +1014,7 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average) | |||
1014 | /* | 1014 | /* |
1015 | * preview_config_input_format - Configure the input format | 1015 | * preview_config_input_format - Configure the input format |
1016 | * @prev: The preview engine | 1016 | * @prev: The preview engine |
1017 | * @format: Format on the preview engine sink pad | 1017 | * @info: Sink pad format information |
1018 | * | 1018 | * |
1019 | * Enable and configure CFA interpolation for Bayer formats and disable it for | 1019 | * Enable and configure CFA interpolation for Bayer formats and disable it for |
1020 | * greyscale formats. | 1020 | * greyscale formats. |
@@ -1025,22 +1025,29 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average) | |||
1025 | * reordered to support non-GRBG Bayer patterns. | 1025 | * reordered to support non-GRBG Bayer patterns. |
1026 | */ | 1026 | */ |
1027 | static void preview_config_input_format(struct isp_prev_device *prev, | 1027 | static void preview_config_input_format(struct isp_prev_device *prev, |
1028 | const struct v4l2_mbus_framefmt *format) | 1028 | const struct isp_format_info *info) |
1029 | { | 1029 | { |
1030 | struct isp_device *isp = to_isp_device(prev); | 1030 | struct isp_device *isp = to_isp_device(prev); |
1031 | struct prev_params *params; | 1031 | struct prev_params *params; |
1032 | 1032 | ||
1033 | switch (format->code) { | 1033 | if (info->width == 8) |
1034 | case V4L2_MBUS_FMT_SGRBG10_1X10: | 1034 | isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, |
1035 | ISPPRV_PCR_WIDTH); | ||
1036 | else | ||
1037 | isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR, | ||
1038 | ISPPRV_PCR_WIDTH); | ||
1039 | |||
1040 | switch (info->flavor) { | ||
1041 | case V4L2_MBUS_FMT_SGRBG8_1X8: | ||
1035 | prev->params.cfa_order = 0; | 1042 | prev->params.cfa_order = 0; |
1036 | break; | 1043 | break; |
1037 | case V4L2_MBUS_FMT_SRGGB10_1X10: | 1044 | case V4L2_MBUS_FMT_SRGGB8_1X8: |
1038 | prev->params.cfa_order = 1; | 1045 | prev->params.cfa_order = 1; |
1039 | break; | 1046 | break; |
1040 | case V4L2_MBUS_FMT_SBGGR10_1X10: | 1047 | case V4L2_MBUS_FMT_SBGGR8_1X8: |
1041 | prev->params.cfa_order = 2; | 1048 | prev->params.cfa_order = 2; |
1042 | break; | 1049 | break; |
1043 | case V4L2_MBUS_FMT_SGBRG10_1X10: | 1050 | case V4L2_MBUS_FMT_SGBRG8_1X8: |
1044 | prev->params.cfa_order = 3; | 1051 | prev->params.cfa_order = 3; |
1045 | break; | 1052 | break; |
1046 | default: | 1053 | default: |
@@ -1081,7 +1088,8 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) | |||
1081 | unsigned int elv = prev->crop.top + prev->crop.height - 1; | 1088 | unsigned int elv = prev->crop.top + prev->crop.height - 1; |
1082 | u32 features; | 1089 | u32 features; |
1083 | 1090 | ||
1084 | if (format->code != V4L2_MBUS_FMT_Y10_1X10) { | 1091 | if (format->code != V4L2_MBUS_FMT_Y8_1X8 && |
1092 | format->code != V4L2_MBUS_FMT_Y10_1X10) { | ||
1085 | sph -= 2; | 1093 | sph -= 2; |
1086 | eph += 2; | 1094 | eph += 2; |
1087 | slv -= 2; | 1095 | slv -= 2; |
@@ -1389,6 +1397,7 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev) | |||
1389 | static void preview_configure(struct isp_prev_device *prev) | 1397 | static void preview_configure(struct isp_prev_device *prev) |
1390 | { | 1398 | { |
1391 | struct isp_device *isp = to_isp_device(prev); | 1399 | struct isp_device *isp = to_isp_device(prev); |
1400 | const struct isp_format_info *info; | ||
1392 | struct v4l2_mbus_framefmt *format; | 1401 | struct v4l2_mbus_framefmt *format; |
1393 | unsigned long flags; | 1402 | unsigned long flags; |
1394 | u32 update; | 1403 | u32 update; |
@@ -1402,17 +1411,18 @@ static void preview_configure(struct isp_prev_device *prev) | |||
1402 | 1411 | ||
1403 | /* PREV_PAD_SINK */ | 1412 | /* PREV_PAD_SINK */ |
1404 | format = &prev->formats[PREV_PAD_SINK]; | 1413 | format = &prev->formats[PREV_PAD_SINK]; |
1414 | info = omap3isp_video_format_info(format->code); | ||
1405 | 1415 | ||
1406 | preview_adjust_bandwidth(prev); | 1416 | preview_adjust_bandwidth(prev); |
1407 | 1417 | ||
1408 | preview_config_input_format(prev, format); | 1418 | preview_config_input_format(prev, info); |
1409 | preview_config_input_size(prev, active); | 1419 | preview_config_input_size(prev, active); |
1410 | 1420 | ||
1411 | if (prev->input == PREVIEW_INPUT_CCDC) | 1421 | if (prev->input == PREVIEW_INPUT_CCDC) |
1412 | preview_config_inlineoffset(prev, 0); | 1422 | preview_config_inlineoffset(prev, 0); |
1413 | else | 1423 | else |
1414 | preview_config_inlineoffset(prev, | 1424 | preview_config_inlineoffset(prev, ALIGN(format->width, 0x20) * |
1415 | ALIGN(format->width, 0x20) * 2); | 1425 | info->bpp); |
1416 | 1426 | ||
1417 | preview_setup_hw(prev, update, active); | 1427 | preview_setup_hw(prev, update, active); |
1418 | 1428 | ||
@@ -1709,6 +1719,11 @@ __preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh, | |||
1709 | 1719 | ||
1710 | /* previewer format descriptions */ | 1720 | /* previewer format descriptions */ |
1711 | static const unsigned int preview_input_fmts[] = { | 1721 | static const unsigned int preview_input_fmts[] = { |
1722 | V4L2_MBUS_FMT_Y8_1X8, | ||
1723 | V4L2_MBUS_FMT_SGRBG8_1X8, | ||
1724 | V4L2_MBUS_FMT_SRGGB8_1X8, | ||
1725 | V4L2_MBUS_FMT_SBGGR8_1X8, | ||
1726 | V4L2_MBUS_FMT_SGBRG8_1X8, | ||
1712 | V4L2_MBUS_FMT_Y10_1X10, | 1727 | V4L2_MBUS_FMT_Y10_1X10, |
1713 | V4L2_MBUS_FMT_SGRBG10_1X10, | 1728 | V4L2_MBUS_FMT_SGRBG10_1X10, |
1714 | V4L2_MBUS_FMT_SRGGB10_1X10, | 1729 | V4L2_MBUS_FMT_SRGGB10_1X10, |
diff --git a/drivers/media/platform/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h index e2c57f334c5d..b7d90e6fb01d 100644 --- a/drivers/media/platform/omap3isp/ispreg.h +++ b/drivers/media/platform/omap3isp/ispreg.h | |||
@@ -29,83 +29,6 @@ | |||
29 | 29 | ||
30 | #define CM_CAM_MCLK_HZ 172800000 /* Hz */ | 30 | #define CM_CAM_MCLK_HZ 172800000 /* Hz */ |
31 | 31 | ||
32 | /* ISP Submodules offset */ | ||
33 | |||
34 | #define L4_34XX_BASE 0x48000000 | ||
35 | #define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000) | ||
36 | |||
37 | #define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE | ||
38 | #define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset)) | ||
39 | |||
40 | #define OMAP3ISP_CCP2_REG_OFFSET 0x0400 | ||
41 | #define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
42 | OMAP3ISP_CCP2_REG_OFFSET) | ||
43 | #define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset)) | ||
44 | |||
45 | #define OMAP3ISP_CCDC_REG_OFFSET 0x0600 | ||
46 | #define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
47 | OMAP3ISP_CCDC_REG_OFFSET) | ||
48 | #define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset)) | ||
49 | |||
50 | #define OMAP3ISP_HIST_REG_OFFSET 0x0A00 | ||
51 | #define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
52 | OMAP3ISP_HIST_REG_OFFSET) | ||
53 | #define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset)) | ||
54 | |||
55 | #define OMAP3ISP_H3A_REG_OFFSET 0x0C00 | ||
56 | #define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
57 | OMAP3ISP_H3A_REG_OFFSET) | ||
58 | #define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset)) | ||
59 | |||
60 | #define OMAP3ISP_PREV_REG_OFFSET 0x0E00 | ||
61 | #define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
62 | OMAP3ISP_PREV_REG_OFFSET) | ||
63 | #define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset)) | ||
64 | |||
65 | #define OMAP3ISP_RESZ_REG_OFFSET 0x1000 | ||
66 | #define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
67 | OMAP3ISP_RESZ_REG_OFFSET) | ||
68 | #define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset)) | ||
69 | |||
70 | #define OMAP3ISP_SBL_REG_OFFSET 0x1200 | ||
71 | #define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
72 | OMAP3ISP_SBL_REG_OFFSET) | ||
73 | #define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset)) | ||
74 | |||
75 | #define OMAP3ISP_CSI2A_REGS1_REG_OFFSET 0x1800 | ||
76 | #define OMAP3ISP_CSI2A_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
77 | OMAP3ISP_CSI2A_REGS1_REG_OFFSET) | ||
78 | #define OMAP3ISP_CSI2A_REGS1_REG(offset) \ | ||
79 | (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset)) | ||
80 | |||
81 | #define OMAP3ISP_CSIPHY2_REG_OFFSET 0x1970 | ||
82 | #define OMAP3ISP_CSIPHY2_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
83 | OMAP3ISP_CSIPHY2_REG_OFFSET) | ||
84 | #define OMAP3ISP_CSIPHY2_REG(offset) (OMAP3ISP_CSIPHY2_REG_BASE + (offset)) | ||
85 | |||
86 | #define OMAP3ISP_CSI2A_REGS2_REG_OFFSET 0x19C0 | ||
87 | #define OMAP3ISP_CSI2A_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
88 | OMAP3ISP_CSI2A_REGS2_REG_OFFSET) | ||
89 | #define OMAP3ISP_CSI2A_REGS2_REG(offset) \ | ||
90 | (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset)) | ||
91 | |||
92 | #define OMAP3ISP_CSI2C_REGS1_REG_OFFSET 0x1C00 | ||
93 | #define OMAP3ISP_CSI2C_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
94 | OMAP3ISP_CSI2C_REGS1_REG_OFFSET) | ||
95 | #define OMAP3ISP_CSI2C_REGS1_REG(offset) \ | ||
96 | (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset)) | ||
97 | |||
98 | #define OMAP3ISP_CSIPHY1_REG_OFFSET 0x1D70 | ||
99 | #define OMAP3ISP_CSIPHY1_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
100 | OMAP3ISP_CSIPHY1_REG_OFFSET) | ||
101 | #define OMAP3ISP_CSIPHY1_REG(offset) (OMAP3ISP_CSIPHY1_REG_BASE + (offset)) | ||
102 | |||
103 | #define OMAP3ISP_CSI2C_REGS2_REG_OFFSET 0x1DC0 | ||
104 | #define OMAP3ISP_CSI2C_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \ | ||
105 | OMAP3ISP_CSI2C_REGS2_REG_OFFSET) | ||
106 | #define OMAP3ISP_CSI2C_REGS2_REG(offset) \ | ||
107 | (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset)) | ||
108 | |||
109 | /* ISP module register offset */ | 32 | /* ISP module register offset */ |
110 | 33 | ||
111 | #define ISP_REVISION (0x000) | 34 | #define ISP_REVISION (0x000) |
@@ -1583,4 +1506,26 @@ | |||
1583 | #define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \ | 1506 | #define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \ |
1584 | (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT) | 1507 | (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT) |
1585 | 1508 | ||
1509 | /* ----------------------------------------------------------------------------- | ||
1510 | * CONTROL registers for CSI-2 phy routing | ||
1511 | */ | ||
1512 | |||
1513 | /* OMAP343X_CONTROL_CSIRXFE */ | ||
1514 | #define OMAP343X_CONTROL_CSIRXFE_CSIB_INV (1 << 7) | ||
1515 | #define OMAP343X_CONTROL_CSIRXFE_RESENABLE (1 << 8) | ||
1516 | #define OMAP343X_CONTROL_CSIRXFE_SELFORM (1 << 10) | ||
1517 | #define OMAP343X_CONTROL_CSIRXFE_PWRDNZ (1 << 12) | ||
1518 | #define OMAP343X_CONTROL_CSIRXFE_RESET (1 << 13) | ||
1519 | |||
1520 | /* OMAP3630_CONTROL_CAMERA_PHY_CTRL */ | ||
1521 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT 2 | ||
1522 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY2_SHIFT 0 | ||
1523 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_DPHY 0x0 | ||
1524 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_STROBE 0x1 | ||
1525 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_CCP2_DATA_CLOCK 0x2 | ||
1526 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_GPI 0x3 | ||
1527 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK 0x3 | ||
1528 | /* CCP2B: set to receive data from PHY2 instead of PHY1 */ | ||
1529 | #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2 (1 << 4) | ||
1530 | |||
1586 | #endif /* OMAP3_ISP_REG_H */ | 1531 | #endif /* OMAP3_ISP_REG_H */ |
diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index e7939869bda7..61e17f9bd8b9 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c | |||
@@ -257,7 +257,7 @@ static int isp_stat_buf_queue(struct ispstat *stat) | |||
257 | if (!stat->active_buf) | 257 | if (!stat->active_buf) |
258 | return STAT_NO_BUF; | 258 | return STAT_NO_BUF; |
259 | 259 | ||
260 | do_gettimeofday(&stat->active_buf->ts); | 260 | ktime_get_ts(&stat->active_buf->ts); |
261 | 261 | ||
262 | stat->active_buf->buf_size = stat->buf_size; | 262 | stat->active_buf->buf_size = stat->buf_size; |
263 | if (isp_stat_buf_check_magic(stat, stat->active_buf)) { | 263 | if (isp_stat_buf_check_magic(stat, stat->active_buf)) { |
@@ -537,7 +537,8 @@ int omap3isp_stat_request_statistics(struct ispstat *stat, | |||
537 | return PTR_ERR(buf); | 537 | return PTR_ERR(buf); |
538 | } | 538 | } |
539 | 539 | ||
540 | data->ts = buf->ts; | 540 | data->ts.tv_sec = buf->ts.tv_sec; |
541 | data->ts.tv_usec = buf->ts.tv_nsec / NSEC_PER_USEC; | ||
541 | data->config_counter = buf->config_counter; | 542 | data->config_counter = buf->config_counter; |
542 | data->frame_number = buf->frame_number; | 543 | data->frame_number = buf->frame_number; |
543 | data->buf_size = buf->buf_size; | 544 | data->buf_size = buf->buf_size; |
diff --git a/drivers/media/platform/omap3isp/ispstat.h b/drivers/media/platform/omap3isp/ispstat.h index fd15094de34a..9a047c929b9f 100644 --- a/drivers/media/platform/omap3isp/ispstat.h +++ b/drivers/media/platform/omap3isp/ispstat.h | |||
@@ -50,7 +50,7 @@ struct ispstat_buffer { | |||
50 | struct iovm_struct *iovm; | 50 | struct iovm_struct *iovm; |
51 | void *virt_addr; | 51 | void *virt_addr; |
52 | dma_addr_t dma_addr; | 52 | dma_addr_t dma_addr; |
53 | struct timeval ts; | 53 | struct timespec ts; |
54 | u32 buf_size; | 54 | u32 buf_size; |
55 | u32 frame_number; | 55 | u32 frame_number; |
56 | u16 config_counter; | 56 | u16 config_counter; |
diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 3311d6bb3456..e0d73a642186 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c | |||
@@ -1392,7 +1392,8 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev) | |||
1392 | 1392 | ||
1393 | ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1); | 1393 | ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1); |
1394 | if (ret < 0) | 1394 | if (ret < 0) |
1395 | printk(KERN_ERR "%s: could not register video device (%d)\n", | 1395 | dev_err(video->isp->dev, |
1396 | "%s: could not register video device (%d)\n", | ||
1396 | __func__, ret); | 1397 | __func__, ret); |
1397 | 1398 | ||
1398 | return ret; | 1399 | return ret; |