aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 18:04:33 +0100
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 23:42:32 +0100
commitf07e572f6447465d8938679533d604e402b0f066 (patch)
treecb333bd2a67e59e7c07659514850a0fd55fc825e /target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
parent5d3a6fd970619dfc55f8259035c3027d7613a2a6 (diff)
downloadupstream-f07e572f6447465d8938679533d604e402b0f066.tar.gz
upstream-f07e572f6447465d8938679533d604e402b0f066.tar.bz2
upstream-f07e572f6447465d8938679533d604e402b0f066.zip
bcm27xx: import latest patches from the RPi foundation
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch285
1 files changed, 285 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
new file mode 100644
index 0000000000..d682cf842f
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0798-media-pxa_camera-Use-the-new-set_mbus_config-op.patch
@@ -0,0 +1,285 @@
+From 63f4970ce038e60455a6225b317d0b259e046c94 Mon Sep 17 00:00:00 2001
+From: Jacopo Mondi <jacopo+renesas@jmondi.org>
+Date: Tue, 16 Jun 2020 16:12:39 +0200
+Subject: [PATCH] media: pxa_camera: Use the new set_mbus_config op
+
+Upstream https://patchwork.linuxtv.org/patch/64671/
+
+Move the PXA camera driver to use the new set_mbus_config pad operation.
+For this platform the change is not only cosmetic, as the pxa driver is
+currently the only driver in mainline to make use of the g_mbus_config
+and s_mbus_config video operations.
+
+The existing driver semantic is the following:
+- Collect all supported mbus config flags from the remote end
+- Match them with the supported PXA mbus configuration flags
+- If the remote subdevice allows multiple options for for VSYNC, HSYNC
+ and PCLK polarity, use platform data requested settings
+
+The semantic of the new get_mbus_config and set_mbus_config differs from
+the corresponding video ops, particularly in the fact get_mbus_config
+reports the current mbus configuration and not the set of supported
+configuration options, with set_mbus_config always reporting the actual
+mbus configuration applied to the remote subdevice.
+
+Adapt the driver to perform the following
+- Set the remote subdevice mbus configuration according to the PXA
+ platform data preferences.
+- If the applied configuration differs from the requested one (i.e. the
+ remote subdevice does not allow changing one setting) make sure that
+ - The remote end does not claim for DATA_ACTIVE_LOW, which seems not
+ supported by the platform
+ - The bus mastering roles match
+
+While at there remove a few checks performed on the media bus
+configuration at get_format() time as they do not belong there.
+
+Compile-tested only.
+
+Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
+---
+ drivers/media/platform/pxa_camera.c | 189 ++++++++--------------------
+ 1 file changed, 51 insertions(+), 138 deletions(-)
+
+--- a/drivers/media/platform/pxa_camera.c
++++ b/drivers/media/platform/pxa_camera.c
+@@ -605,42 +605,6 @@ static const struct pxa_mbus_pixelfmt *p
+ return pxa_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
+ }
+
+-static unsigned int pxa_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
+- unsigned int flags)
+-{
+- unsigned long common_flags;
+- bool hsync = true, vsync = true, pclk, data, mode;
+- bool mipi_lanes, mipi_clock;
+-
+- common_flags = cfg->flags & flags;
+-
+- switch (cfg->type) {
+- case V4L2_MBUS_PARALLEL:
+- hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_HSYNC_ACTIVE_LOW);
+- vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_VSYNC_ACTIVE_LOW);
+- /* fall through */
+- case V4L2_MBUS_BT656:
+- pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
+- V4L2_MBUS_PCLK_SAMPLE_FALLING);
+- data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
+- V4L2_MBUS_DATA_ACTIVE_LOW);
+- mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
+- return (!hsync || !vsync || !pclk || !data || !mode) ?
+- 0 : common_flags;
+- case V4L2_MBUS_CSI2_DPHY:
+- mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
+- mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
+- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
+- return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
+- default:
+- WARN_ON(1);
+- return -EINVAL;
+- }
+- return 0;
+-}
+-
+ /**
+ * struct pxa_camera_format_xlate - match between host and sensor formats
+ * @code: code of a sensor provided format
+@@ -1231,31 +1195,6 @@ static irqreturn_t pxa_camera_irq(int ir
+ return IRQ_HANDLED;
+ }
+
+-static int test_platform_param(struct pxa_camera_dev *pcdev,
+- unsigned char buswidth, unsigned long *flags)
+-{
+- /*
+- * Platform specified synchronization and pixel clock polarities are
+- * only a recommendation and are only used during probing. The PXA270
+- * quick capture interface supports both.
+- */
+- *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
+- V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
+- V4L2_MBUS_HSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_HSYNC_ACTIVE_LOW |
+- V4L2_MBUS_VSYNC_ACTIVE_HIGH |
+- V4L2_MBUS_VSYNC_ACTIVE_LOW |
+- V4L2_MBUS_DATA_ACTIVE_HIGH |
+- V4L2_MBUS_PCLK_SAMPLE_RISING |
+- V4L2_MBUS_PCLK_SAMPLE_FALLING;
+-
+- /* If requested data width is supported by the platform, use it */
+- if ((1 << (buswidth - 1)) & pcdev->width_flags)
+- return 0;
+-
+- return -EINVAL;
+-}
+-
+ static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev,
+ unsigned long flags, __u32 pixfmt)
+ {
+@@ -1598,99 +1537,78 @@ static int pxa_camera_init_videobuf2(str
+ */
+ static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev)
+ {
++ unsigned int bus_width = pcdev->current_fmt->host_fmt->bits_per_sample;
+ struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+ u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc;
+- unsigned long bus_flags, common_flags;
++ int mbus_config;
+ int ret;
+
+- ret = test_platform_param(pcdev,
+- pcdev->current_fmt->host_fmt->bits_per_sample,
+- &bus_flags);
+- if (ret < 0)
+- return ret;
+-
+- ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
+- if (!ret) {
+- common_flags = pxa_mbus_config_compatible(&cfg,
+- bus_flags);
+- if (!common_flags) {
+- dev_warn(pcdev_to_dev(pcdev),
+- "Flags incompatible: camera 0x%x, host 0x%lx\n",
+- cfg.flags, bus_flags);
+- return -EINVAL;
+- }
+- } else if (ret != -ENOIOCTLCMD) {
+- return ret;
+- } else {
+- common_flags = bus_flags;
++ if (!((1 << (bus_width - 1)) & pcdev->width_flags)) {
++ dev_err(pcdev_to_dev(pcdev), "Unsupported bus width %u",
++ bus_width);
++ return -EINVAL;
+ }
+
+ pcdev->channels = 1;
+
+ /* Make choices, based on platform preferences */
+- if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
+- (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
+- if (pcdev->platform_flags & PXA_CAMERA_HSP)
+- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
+- else
+- common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
+- }
+-
+- if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
+- (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
+- if (pcdev->platform_flags & PXA_CAMERA_VSP)
+- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
+- else
+- common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
+- }
+-
+- if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
+- (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
+- if (pcdev->platform_flags & PXA_CAMERA_PCP)
+- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
+- else
+- common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
+- }
+-
+- cfg.flags = common_flags;
+- ret = sensor_call(pcdev, video, s_mbus_config, &cfg);
+- if (ret < 0 && ret != -ENOIOCTLCMD) {
+- dev_dbg(pcdev_to_dev(pcdev),
+- "camera s_mbus_config(0x%lx) returned %d\n",
+- common_flags, ret);
+- return ret;
+- }
++ mbus_config = 0;
++ if (pcdev->platform_flags & PXA_CAMERA_MASTER)
++ mbus_config |= V4L2_MBUS_MASTER;
++ else
++ mbus_config |= V4L2_MBUS_SLAVE;
+
+- pxa_camera_setup_cicr(pcdev, common_flags, pixfmt);
++ if (pcdev->platform_flags & PXA_CAMERA_HSP)
++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH;
++ else
++ mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW;
+
+- return 0;
+-}
++ if (pcdev->platform_flags & PXA_CAMERA_VSP)
++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH;
++ else
++ mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW;
+
+-static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev,
+- unsigned char buswidth)
+-{
+- struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
+- unsigned long bus_flags, common_flags;
+- int ret = test_platform_param(pcdev, buswidth, &bus_flags);
++ if (pcdev->platform_flags & PXA_CAMERA_PCP)
++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING;
++ else
++ mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING;
++ mbus_config |= V4L2_MBUS_DATA_ACTIVE_HIGH;
+
+- if (ret < 0)
++ cfg.flags = mbus_config;
++ ret = sensor_call(pcdev, pad, set_mbus_config, 0, &cfg);
++ if (ret < 0 && ret != -ENOIOCTLCMD) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Failed to call set_mbus_config: %d\n", ret);
+ return ret;
++ }
++
++ /*
++ * If the requested media bus configuration has not been fully applied
++ * make sure it is supported by the platform.
++ *
++ * PXA does not support V4L2_MBUS_DATA_ACTIVE_LOW and the bus mastering
++ * roles should match.
++ */
++ if (cfg.flags != mbus_config) {
++ unsigned int pxa_mbus_role = mbus_config & (V4L2_MBUS_MASTER |
++ V4L2_MBUS_SLAVE);
++ if (pxa_mbus_role != (cfg.flags & (V4L2_MBUS_MASTER |
++ V4L2_MBUS_SLAVE))) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Unsupported mbus configuration: bus mastering\n");
++ return -EINVAL;
++ }
+
+- ret = sensor_call(pcdev, video, g_mbus_config, &cfg);
+- if (!ret) {
+- common_flags = pxa_mbus_config_compatible(&cfg,
+- bus_flags);
+- if (!common_flags) {
+- dev_warn(pcdev_to_dev(pcdev),
+- "Flags incompatible: camera 0x%x, host 0x%lx\n",
+- cfg.flags, bus_flags);
++ if (cfg.flags & V4L2_MBUS_DATA_ACTIVE_LOW) {
++ dev_err(pcdev_to_dev(pcdev),
++ "Unsupported mbus configuration: DATA_ACTIVE_LOW\n");
+ return -EINVAL;
+ }
+- } else if (ret == -ENOIOCTLCMD) {
+- ret = 0;
+ }
+
+- return ret;
++ pxa_camera_setup_cicr(pcdev, cfg.flags, pixfmt);
++
++ return 0;
+ }
+
+ static const struct pxa_mbus_pixelfmt pxa_camera_formats[] = {
+@@ -1738,11 +1656,6 @@ static int pxa_camera_get_formats(struct
+ return 0;
+ }
+
+- /* This also checks support for the requested bits-per-sample */
+- ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample);
+- if (ret < 0)
+- return 0;
+-
+ switch (code.code) {
+ case MEDIA_BUS_FMT_UYVY8_2X8:
+ formats++;