* [PATCH v6 0/7] MT9M114 driver bugfix and improvements
@ 2025-05-22 14:35 Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 1/7] media: dt-bindings: mt9m114: Add slew-rate DT-binding Mathis Foerst
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
Hi,
this patch series contains the following bugfix and improvements
for the MT9M114 camera driver:
Changelog:
v5 -> v6:
- Add 'Reviewed-By:' tags. Sorry for forgetting this in the previous versions
v4 -> v5:
- Apply reformatings and small refactorings as suggested in review comments
- Split PATCH 4 into two parts: One for applying HFLIP / VFLIP while
streaming, one for applying set_selection while streaming.
- Add condition to apply set_selection immediately only if the size of the
cropping rectangle does not change in PATCH 5
- Use device_property_read_u32 instead of of_property_read_u32 in PATCH 7
v3 -> v4:
- Rename DT binding from "onnn,slew-rate" to "slew-rate" in PATCH 1 and 6 as
requested in the review comment.
v2 -> v3:
- Dropped PATCH 2 ("media: mt9m114: Add get_mbus_config").
Based on the comments, this issure won't be fixed in the MT9M114
driver but in "imx-media-csi.c" in a separate patch.
- Renumbered patches accordingly.
- Fix the incomplete renaming of the DT property from 'pad-slew-rate'
to 'onnn,slew-rate' in PATCH 1 and 6.
- Fix checkpatch formatting suggestions in PATCH 2 and 6.
v1 -> v2:
- Fix the subjects of the patches
- Dropped PATCH 1 ("Add bypass-pll DT-binding") as it can be automatically
detected if the PLL should be bypassed.
- Renumbered patches accordingly
- Switch to uint32, add default value and clarify documentation in PATCH 1
- Add 'Fixes' and 'Cc' tags as suggested in PATCH 6
Link to v1 discussion:
https://lore.kernel.org/linux-media/20250226153929.274562-1-mathis.foerst@mt.com/
Link to v2 discussion:
https://lore.kernel.org/linux-media/20250304103647.34235-1-mathis.foerst@mt.com/
Link to v3 discussion:
https://lore.kernel.org/linux-media/20250305101453.708270-1-mathis.foerst@mt.com/
Link to v4 discussion:
https://lore.kernel.org/linux-media/20250307093140.370061-1-mathis.foerst@mt.com/
Bugfixes:
- Fix a deadlock when using the V4L2 pad-ops get/set_frame_interval
New Features:
- Bypass the internal PLL if EXTCLK matches the configured link_frequency
- Make the slew-rate of the output pads configurable via DT
- Allow to change the cropping configuration and the horizontal/vertical
flipping while the sensor is in streaming state
Thanks,
Mathis
Mathis Foerst (7):
media: dt-bindings: mt9m114: Add slew-rate DT-binding
media: mt9m114: Bypass PLL if required
media: mt9m114: Factor out mt9m114_configure_pa
media: mt9m114: Apply horizontal / vertical flip while streaming
media: mt9m114: Allow set_selection while streaming
media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval
media: mt9m114: Set pad-slew-rate
.../bindings/media/i2c/onnn,mt9m114.yaml | 9 +
drivers/media/i2c/mt9m114.c | 264 ++++++++++++------
2 files changed, 185 insertions(+), 88 deletions(-)
base-commit: d608703fcdd9e9538f6c7a0fcf98bf79b1375b60
--
2.34.1
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v6 1/7] media: dt-bindings: mt9m114: Add slew-rate DT-binding
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 2/7] media: mt9m114: Bypass PLL if required Mathis Foerst
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst, Krzysztof Kozlowski
The MT9M114 supports the different slew rates (0 to 7) on the output pads.
At the moment, this is hardcoded to 7 (the fastest rate).
The user might want to change this values due to EMC requirements.
Add the 'slew-rate' property to the MT9M114 DT-bindings for selecting
the desired slew rate.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
---
.../devicetree/bindings/media/i2c/onnn,mt9m114.yaml | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml b/Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml
index f6b87892068a..a89f740214f7 100644
--- a/Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml
+++ b/Documentation/devicetree/bindings/media/i2c/onnn,mt9m114.yaml
@@ -70,6 +70,15 @@ properties:
- bus-type
- link-frequencies
+ slew-rate:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Slew rate ot the output pads DOUT[7:0], LINE_VALID, FRAME_VALID and
+ PIXCLK. Higher values imply steeper voltage-flanks on the pads.
+ minimum: 0
+ maximum: 7
+ default: 7
+
required:
- compatible
- reg
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 2/7] media: mt9m114: Bypass PLL if required
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 1/7] media: dt-bindings: mt9m114: Add slew-rate DT-binding Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 3/7] media: mt9m114: Factor out mt9m114_configure_pa Mathis Foerst
` (5 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
The MT9M114 sensor has an internal PLL that generates the required SYSCLK
from EXTCLK. It also has the option to bypass the PLL and use EXTCLK
directly as SYSCLK.
The current driver implementation uses a hardcoded PLL configuration that
requires a specific EXTCLK frequency. Depending on the available clocks,
it can be desirable to use a different PLL configuration or to bypass it.
The link-frequency of the output bus (Parallel or MIPI-CSI) is configured
in the device tree.
Check if EXTCLK can be used as SYSCLK to achieve this link-frequency. If
yes, bypass the PLL.
Otherwise, (as before) check if EXTCLK and the default PLL configuration
provide the required SYSCLK to achieve the link-frequency. If yes, use the
PLL. If no, throw an error.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/i2c/mt9m114.c | 68 +++++++++++++++++++++++++++----------
1 file changed, 50 insertions(+), 18 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index 5f0b0ad8f885..c3ec2eb0b134 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -261,6 +261,7 @@
#define MT9M114_CAM_PGA_PGA_CONTROL CCI_REG16(0xc95e)
#define MT9M114_CAM_SYSCTL_PLL_ENABLE CCI_REG8(0xc97e)
#define MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE BIT(0)
+#define MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE 0x00
#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N CCI_REG16(0xc980)
#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(m, n) (((n) << 8) | (m))
#define MT9M114_CAM_SYSCTL_PLL_DIVIDER_P CCI_REG16(0xc982)
@@ -377,6 +378,7 @@ struct mt9m114 {
struct gpio_desc *reset;
struct regulator_bulk_data supplies[3];
struct v4l2_fwnode_endpoint bus_cfg;
+ bool bypass_pll;
struct {
unsigned int m;
@@ -743,14 +745,21 @@ static int mt9m114_initialize(struct mt9m114 *sensor)
}
/* Configure the PLL. */
- cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
- MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);
- cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,
- MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m,
- sensor->pll.n),
- &ret);
- cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P,
- MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret);
+ if (sensor->bypass_pll) {
+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
+ MT9M114_CAM_SYSCTL_PLL_DISABLE_VALUE, &ret);
+ } else {
+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE,
+ MT9M114_CAM_SYSCTL_PLL_ENABLE_VALUE, &ret);
+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N,
+ MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m,
+ sensor->pll.n),
+ &ret);
+ cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P,
+ MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p),
+ &ret);
+ }
+
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK,
sensor->pixrate, &ret);
@@ -2235,9 +2244,22 @@ static const struct dev_pm_ops mt9m114_pm_ops = {
* Probe & Remove
*/
+static int mt9m114_verify_link_frequency(struct mt9m114 *sensor,
+ unsigned int pixrate)
+{
+ unsigned int link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY
+ ? pixrate * 8 : pixrate * 2;
+
+ if (sensor->bus_cfg.nr_of_link_frequencies != 1 ||
+ sensor->bus_cfg.link_frequencies[0] != link_freq)
+ return -EINVAL;
+
+ return 0;
+}
+
static int mt9m114_clk_init(struct mt9m114 *sensor)
{
- unsigned int link_freq;
+ unsigned int pixrate;
/* Hardcode the PLL multiplier and dividers to default settings. */
sensor->pll.m = 32;
@@ -2249,19 +2271,29 @@ static int mt9m114_clk_init(struct mt9m114 *sensor)
* for 16-bit per pixel, transmitted in DDR over a single lane. For
* parallel mode, the sensor ouputs one pixel in two PIXCLK cycles.
*/
- sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
- / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
- link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY
- ? sensor->pixrate * 8 : sensor->pixrate * 2;
+ /*
+ * Check if EXTCLK fits the configured link frequency. Bypass the PLL
+ * in this case.
+ */
+ pixrate = clk_get_rate(sensor->clk) / 2;
+ if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) {
+ sensor->pixrate = pixrate;
+ sensor->bypass_pll = true;
+ return 0;
+ }
- if (sensor->bus_cfg.nr_of_link_frequencies != 1 ||
- sensor->bus_cfg.link_frequencies[0] != link_freq) {
- dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");
- return -EINVAL;
+ /* Check if the PLL configuration fits the configured link frequency. */
+ pixrate = clk_get_rate(sensor->clk) * sensor->pll.m
+ / ((sensor->pll.n + 1) * (sensor->pll.p + 1));
+ if (mt9m114_verify_link_frequency(sensor, pixrate) == 0) {
+ sensor->pixrate = pixrate;
+ sensor->bypass_pll = false;
+ return 0;
}
- return 0;
+ dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n");
+ return -EINVAL;
}
static int mt9m114_identify(struct mt9m114 *sensor)
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 3/7] media: mt9m114: Factor out mt9m114_configure_pa
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 1/7] media: dt-bindings: mt9m114: Add slew-rate DT-binding Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 2/7] media: mt9m114: Bypass PLL if required Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming Mathis Foerst
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
The function mt9m114_configure writes the configuration registers of both,
the pixel array (pa) and the image flow processor (ifp).
This is undesirable if only the config of the pa should be changed without
affecting the ifp.
Factor out the function mt9m114_configure_pa() that just writes the
pa-configuration.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/i2c/mt9m114.c | 95 +++++++++++++++++++++----------------
1 file changed, 53 insertions(+), 42 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index c3ec2eb0b134..6c80c6926aef 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -790,41 +790,25 @@ static int mt9m114_initialize(struct mt9m114 *sensor)
return 0;
}
-static int mt9m114_configure(struct mt9m114 *sensor,
- struct v4l2_subdev_state *pa_state,
- struct v4l2_subdev_state *ifp_state)
+static int mt9m114_configure_pa(struct mt9m114 *sensor,
+ struct v4l2_subdev_state *state)
{
- const struct v4l2_mbus_framefmt *pa_format;
- const struct v4l2_rect *pa_crop;
- const struct mt9m114_format_info *ifp_info;
- const struct v4l2_mbus_framefmt *ifp_format;
- const struct v4l2_rect *ifp_crop;
- const struct v4l2_rect *ifp_compose;
+ const struct v4l2_mbus_framefmt *format;
+ const struct v4l2_rect *crop;
unsigned int hratio, vratio;
- u64 output_format;
u64 read_mode;
- int ret = 0;
-
- pa_format = v4l2_subdev_state_get_format(pa_state, 0);
- pa_crop = v4l2_subdev_state_get_crop(pa_state, 0);
+ int ret;
- ifp_format = v4l2_subdev_state_get_format(ifp_state, 1);
- ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code);
- ifp_crop = v4l2_subdev_state_get_crop(ifp_state, 0);
- ifp_compose = v4l2_subdev_state_get_compose(ifp_state, 0);
+ format = v4l2_subdev_state_get_format(state, 0);
+ crop = v4l2_subdev_state_get_crop(state, 0);
ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
&read_mode, NULL);
if (ret < 0)
return ret;
- ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
- &output_format, NULL);
- if (ret < 0)
- return ret;
-
- hratio = pa_crop->width / pa_format->width;
- vratio = pa_crop->height / pa_format->height;
+ hratio = crop->width / format->width;
+ vratio = crop->height / format->height;
/*
* Pixel array crop and binning. The CAM_SENSOR_CFG_CPIPE_LAST_ROW
@@ -833,15 +817,15 @@ static int mt9m114_configure(struct mt9m114 *sensor,
* example sensor modes.
*/
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START,
- pa_crop->left, &ret);
+ crop->left, &ret);
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START,
- pa_crop->top, &ret);
+ crop->top, &ret);
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END,
- pa_crop->width + pa_crop->left - 1, &ret);
+ crop->width + crop->left - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END,
- pa_crop->height + pa_crop->top - 1, &ret);
+ crop->height + crop->top - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW,
- (pa_crop->height - 4) / vratio - 1, &ret);
+ (crop->height - 4) / vratio - 1, &ret);
read_mode &= ~(MT9M114_CAM_SENSOR_CONTROL_X_READ_OUT_MASK |
MT9M114_CAM_SENSOR_CONTROL_Y_READ_OUT_MASK);
@@ -854,6 +838,29 @@ static int mt9m114_configure(struct mt9m114 *sensor,
cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
read_mode, &ret);
+ return ret;
+}
+
+static int mt9m114_configure_ifp(struct mt9m114 *sensor,
+ struct v4l2_subdev_state *state)
+{
+ const struct mt9m114_format_info *info;
+ const struct v4l2_mbus_framefmt *format;
+ const struct v4l2_rect *crop;
+ const struct v4l2_rect *compose;
+ u64 output_format;
+ int ret = 0;
+
+ format = v4l2_subdev_state_get_format(state, 1);
+ info = mt9m114_format_info(sensor, 1, format->code);
+ crop = v4l2_subdev_state_get_crop(state, 0);
+ compose = v4l2_subdev_state_get_compose(state, 0);
+
+ ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
+ &output_format, NULL);
+ if (ret < 0)
+ return ret;
+
/*
* Color pipeline (IFP) cropping and scaling. Subtract 4 from the left
* and top coordinates to compensate for the lines and columns removed
@@ -861,18 +868,18 @@ static int mt9m114_configure(struct mt9m114 *sensor,
* not in the hardware.
*/
cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET,
- ifp_crop->left - 4, &ret);
+ crop->left - 4, &ret);
cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET,
- ifp_crop->top - 4, &ret);
+ crop->top - 4, &ret);
cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH,
- ifp_crop->width, &ret);
+ crop->width, &ret);
cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT,
- ifp_crop->height, &ret);
+ crop->height, &ret);
cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH,
- ifp_compose->width, &ret);
+ compose->width, &ret);
cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT,
- ifp_compose->height, &ret);
+ compose->height, &ret);
/* AWB and AE windows, use the full frame. */
cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART,
@@ -880,18 +887,18 @@ static int mt9m114_configure(struct mt9m114 *sensor,
cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART,
0, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND,
- ifp_compose->width - 1, &ret);
+ compose->width - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND,
- ifp_compose->height - 1, &ret);
+ compose->height - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART,
0, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART,
0, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND,
- ifp_compose->width / 5 - 1, &ret);
+ compose->width / 5 - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND,
- ifp_compose->height / 5 - 1, &ret);
+ compose->height / 5 - 1, &ret);
cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE,
MT9M114_CAM_CROP_MODE_AWB_AUTO_CROP_EN |
@@ -903,7 +910,7 @@ static int mt9m114_configure(struct mt9m114 *sensor,
MT9M114_CAM_OUTPUT_FORMAT_FORMAT_MASK |
MT9M114_CAM_OUTPUT_FORMAT_SWAP_BYTES |
MT9M114_CAM_OUTPUT_FORMAT_SWAP_RED_BLUE);
- output_format |= ifp_info->output_format;
+ output_format |= info->output_format;
cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT,
output_format, &ret);
@@ -934,7 +941,11 @@ static int mt9m114_start_streaming(struct mt9m114 *sensor,
if (ret)
return ret;
- ret = mt9m114_configure(sensor, pa_state, ifp_state);
+ ret = mt9m114_configure_ifp(sensor, ifp_state);
+ if (ret)
+ goto error;
+
+ ret = mt9m114_configure_pa(sensor, pa_state);
if (ret)
goto error;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
` (2 preceding siblings ...)
2025-05-22 14:35 ` [PATCH v6 3/7] media: mt9m114: Factor out mt9m114_configure_pa Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-26 12:10 ` Laurent Pinchart
2025-05-22 14:35 ` [PATCH v6 5/7] media: mt9m114: Allow set_selection " Mathis Foerst
` (3 subsequent siblings)
7 siblings, 1 reply; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
The current implementation does not apply changes to the V4L2 controls
HFLIP & VFLIP of the sensor immediately if the sensor is in streaming
state. The user has to stop and restart the stream for the changes to be
applied.
Issue a CONFIG_CHANGE when the V4L2 controls HFLIP or VFLIP are set if the
sensor is in streaming state to apply the change immediately.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
---
drivers/media/i2c/mt9m114.c | 43 +++++++++++++++++++++++++------------
1 file changed, 29 insertions(+), 14 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index 6c80c6926aef..7d39978835fe 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -399,6 +399,11 @@ struct mt9m114 {
struct v4l2_ctrl *gain;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *vblank;
+ struct {
+ /* horizonal / vertical flip cluster */
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ };
} pa;
/* Image Flow Processor */
@@ -1059,6 +1064,7 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl)
struct v4l2_subdev_state *state;
int ret = 0;
u64 mask;
+ u64 val;
/* V4L2 controls values are applied only when power is up. */
if (!pm_runtime_get_if_in_use(&sensor->client->dev))
@@ -1095,17 +1101,25 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl)
break;
case V4L2_CID_HFLIP:
- mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN;
+ mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN |
+ MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN;
+ val = (sensor->pa.hflip->val ?
+ MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN : 0) &
+ (sensor->pa.vflip->val ?
+ MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN : 0);
ret = cci_update_bits(sensor->regmap,
MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
- mask, ctrl->val ? mask : 0, NULL);
- break;
+ mask, val, NULL);
+ /*
+ * A Config-Change needs to be issued for the change to take
+ * effect. If we're not streaming ignore this, the change will
+ * be applied when the stream is started.
+ */
+ if (ret || !sensor->streaming)
+ break;
- case V4L2_CID_VFLIP:
- mask = MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN;
- ret = cci_update_bits(sensor->regmap,
- MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
- mask, ctrl->val ? mask : 0, NULL);
+ ret = mt9m114_set_state(sensor,
+ MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
break;
default:
@@ -1406,12 +1420,13 @@ static int mt9m114_pa_init(struct mt9m114 *sensor)
sensor->pixrate, sensor->pixrate, 1,
sensor->pixrate);
- v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
- V4L2_CID_HFLIP,
- 0, 1, 1, 0);
- v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
- V4L2_CID_VFLIP,
- 0, 1, 1, 0);
+ sensor->pa.hflip = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
+ V4L2_CID_HFLIP,
+ 0, 1, 1, 0);
+ sensor->pa.vflip = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
+ V4L2_CID_VFLIP,
+ 0, 1, 1, 0);
+ v4l2_ctrl_cluster(2, &sensor->pa.hflip);
if (hdl->error) {
ret = hdl->error;
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 5/7] media: mt9m114: Allow set_selection while streaming
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
` (3 preceding siblings ...)
2025-05-22 14:35 ` [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-26 8:46 ` Sakari Ailus
2025-05-26 12:13 ` Laurent Pinchart
2025-05-22 14:35 ` [PATCH v6 6/7] media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval Mathis Foerst
` (2 subsequent siblings)
7 siblings, 2 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
The current implementation does not apply changes to the crop-
configuration of the sensor immediately if the sensor is in
streaming state. The user has to stop and restart the stream for
the changes to be applied.
This can be undesirable e.g. in a calibration usecase where the user
wants to see the impact of his changes in a live video stream.
Under the condition that the width & height of the cropped image area
does not change, the changed cropping configuration can be applied to
the pixel-array immediately without disturbing the IFP.
Call mt9m114_configure_pa() in mt9m114_pa_set_selection() if the sensor is
in streaming state and the size of the cropping rectangle didn't change,
issue a CONFIG_CHANGE to apply the changes immediately.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
---
drivers/media/i2c/mt9m114.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index 7d39978835fe..e909c1227e51 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -1301,11 +1301,14 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
struct mt9m114 *sensor = pa_to_mt9m114(sd);
struct v4l2_mbus_framefmt *format;
struct v4l2_rect *crop;
+ struct v4l2_rect old_crop;
+ int ret = 0;
if (sel->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
crop = v4l2_subdev_state_get_crop(state, sel->pad);
+ old_crop = *crop;
format = v4l2_subdev_state_get_format(state, sel->pad);
/*
@@ -1331,10 +1334,25 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
format->width = crop->width;
format->height = crop->height;
- if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
- mt9m114_pa_ctrl_update_blanking(sensor, format);
+ if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+ return ret;
- return 0;
+ mt9m114_pa_ctrl_update_blanking(sensor, format);
+
+ /*
+ * Apply values immediately if streaming and the selection size did not
+ * change.
+ */
+ if (sensor->streaming && old_crop.height == crop->height &&
+ old_crop.width == crop->width) {
+ ret = mt9m114_configure_pa(sensor, state);
+ if (ret)
+ return ret;
+ // Changing the cropping config requires a CONFIG_CHANGE
+ ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
+ }
+
+ return ret;
}
static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 6/7] media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
` (4 preceding siblings ...)
2025-05-22 14:35 ` [PATCH v6 5/7] media: mt9m114: Allow set_selection " Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate Mathis Foerst
2025-05-26 12:15 ` [PATCH v6 0/7] MT9M114 driver bugfix and improvements Laurent Pinchart
7 siblings, 0 replies; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst, stable
Getting / Setting the frame interval using the V4L2 subdev pad ops
get_frame_interval/set_frame_interval causes a deadlock, as the
subdev state is locked in the [1] but also in the driver itself.
In [2] it's described that the caller is responsible to acquire and
release the lock in this case. Therefore, acquiring the lock in the
driver is wrong.
Remove the lock acquisitions/releases from mt9m114_ifp_get_frame_interval()
and mt9m114_ifp_set_frame_interval().
[1] drivers/media/v4l2-core/v4l2-subdev.c - line 1129
[2] Documentation/driver-api/media/v4l2-subdev.rst
Fixes: 24d756e914fc ("media: i2c: Add driver for onsemi MT9M114 camera sensor")
Cc: stable@vger.kernel.org
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/i2c/mt9m114.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index e909c1227e51..9ff46c72dbc1 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -1652,13 +1652,9 @@ static int mt9m114_ifp_get_frame_interval(struct v4l2_subdev *sd,
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
- mutex_lock(sensor->ifp.hdl.lock);
-
ival->numerator = 1;
ival->denominator = sensor->ifp.frame_rate;
- mutex_unlock(sensor->ifp.hdl.lock);
-
return 0;
}
@@ -1677,8 +1673,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd,
if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
- mutex_lock(sensor->ifp.hdl.lock);
-
if (ival->numerator != 0 && ival->denominator != 0)
sensor->ifp.frame_rate = min_t(unsigned int,
ival->denominator / ival->numerator,
@@ -1692,8 +1686,6 @@ static int mt9m114_ifp_set_frame_interval(struct v4l2_subdev *sd,
if (sensor->streaming)
ret = mt9m114_set_frame_rate(sensor);
- mutex_unlock(sensor->ifp.hdl.lock);
-
return ret;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
` (5 preceding siblings ...)
2025-05-22 14:35 ` [PATCH v6 6/7] media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval Mathis Foerst
@ 2025-05-22 14:35 ` Mathis Foerst
2025-05-27 6:36 ` Sakari Ailus
2025-05-26 12:15 ` [PATCH v6 0/7] MT9M114 driver bugfix and improvements Laurent Pinchart
7 siblings, 1 reply; 14+ messages in thread
From: Mathis Foerst @ 2025-05-22 14:35 UTC (permalink / raw)
To: linux-kernel
Cc: Mathis Foerst, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Sakari Ailus,
Steve Longerbeam, Philipp Zabel, Greg Kroah-Hartman, Shawn Guo,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, linux-media,
devicetree, linux-staging, imx, linux-arm-kernel, manuel.traut,
mathis.foerst
The MT9M114 supports the different slew rates (0 to 7) on the output pads.
At the moment, this is hardcoded to 7 (the fastest rate).
The user might want to change this values due to EMC requirements.
Read the 'slew-rate' from the DT and configure the pad slew rates of
the output pads accordingly in mt9m114_initialize().
Remove the hardcoded slew rate setting from the mt9m114_init table.
Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
drivers/media/i2c/mt9m114.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
index 9ff46c72dbc1..f3f9ecc0866c 100644
--- a/drivers/media/i2c/mt9m114.c
+++ b/drivers/media/i2c/mt9m114.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
+#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
@@ -42,6 +43,9 @@
#define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a)
#define MT9M114_RESET_SOC BIT(0)
#define MT9M114_PAD_SLEW CCI_REG16(0x001e)
+#define MT9M114_PAD_SLEW_MIN 0
+#define MT9M114_PAD_SLEW_MAX 7
+#define MT9M114_PAD_SLEW_DEFAULT 7
#define MT9M114_PAD_CONTROL CCI_REG16(0x0032)
/* XDMA registers */
@@ -388,6 +392,7 @@ struct mt9m114 {
unsigned int pixrate;
bool streaming;
+ u32 pad_slew_rate;
/* Pixel Array */
struct {
@@ -650,9 +655,6 @@ static const struct cci_reg_sequence mt9m114_init[] = {
{ MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 1459 },
{ MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION, 96 },
{ MT9M114_CAM_SENSOR_CFG_REG_0_DATA, 32 },
-
- /* Miscellaneous settings */
- { MT9M114_PAD_SLEW, 0x0777 },
};
/* -----------------------------------------------------------------------------
@@ -784,6 +786,13 @@ static int mt9m114_initialize(struct mt9m114 *sensor)
if (ret < 0)
return ret;
+ value = (sensor->pad_slew_rate)
+ | (sensor->pad_slew_rate) << 4
+ | (sensor->pad_slew_rate) << 8;
+ cci_write(sensor->regmap, MT9M114_PAD_SLEW, value, &ret);
+ if (ret < 0)
+ return ret;
+
ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
if (ret < 0)
return ret;
@@ -2398,6 +2407,17 @@ static int mt9m114_parse_dt(struct mt9m114 *sensor)
goto error;
}
+ sensor->pad_slew_rate = MT9M114_PAD_SLEW_DEFAULT;
+ device_property_read_u32(&sensor->client->dev, "slew-rate",
+ &sensor->pad_slew_rate);
+
+ if (sensor->pad_slew_rate < MT9M114_PAD_SLEW_MIN ||
+ sensor->pad_slew_rate > MT9M114_PAD_SLEW_MAX) {
+ dev_err(&sensor->client->dev, "Invalid slew-rate %u\n",
+ sensor->pad_slew_rate);
+ return -EINVAL;
+ }
+
return 0;
error:
--
2.34.1
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v6 5/7] media: mt9m114: Allow set_selection while streaming
2025-05-22 14:35 ` [PATCH v6 5/7] media: mt9m114: Allow set_selection " Mathis Foerst
@ 2025-05-26 8:46 ` Sakari Ailus
2025-05-26 12:13 ` Laurent Pinchart
1 sibling, 0 replies; 14+ messages in thread
From: Sakari Ailus @ 2025-05-26 8:46 UTC (permalink / raw)
To: Mathis Foerst
Cc: linux-kernel, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Mathis,
On Thu, May 22, 2025 at 04:35:09PM +0200, Mathis Foerst wrote:
> The current implementation does not apply changes to the crop-
> configuration of the sensor immediately if the sensor is in
> streaming state. The user has to stop and restart the stream for
> the changes to be applied.
> This can be undesirable e.g. in a calibration usecase where the user
> wants to see the impact of his changes in a live video stream.
> Under the condition that the width & height of the cropped image area
> does not change, the changed cropping configuration can be applied to
> the pixel-array immediately without disturbing the IFP.
>
> Call mt9m114_configure_pa() in mt9m114_pa_set_selection() if the sensor is
> in streaming state and the size of the cropping rectangle didn't change,
> issue a CONFIG_CHANGE to apply the changes immediately.
>
> Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
> ---
> drivers/media/i2c/mt9m114.c | 24 +++++++++++++++++++++---
> 1 file changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
> index 7d39978835fe..e909c1227e51 100644
> --- a/drivers/media/i2c/mt9m114.c
> +++ b/drivers/media/i2c/mt9m114.c
> @@ -1301,11 +1301,14 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
> struct mt9m114 *sensor = pa_to_mt9m114(sd);
> struct v4l2_mbus_framefmt *format;
> struct v4l2_rect *crop;
> + struct v4l2_rect old_crop;
> + int ret = 0;
>
> if (sel->target != V4L2_SEL_TGT_CROP)
> return -EINVAL;
>
> crop = v4l2_subdev_state_get_crop(state, sel->pad);
> + old_crop = *crop;
> format = v4l2_subdev_state_get_format(state, sel->pad);
>
> /*
> @@ -1331,10 +1334,25 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
> format->width = crop->width;
> format->height = crop->height;
>
> - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
> - mt9m114_pa_ctrl_update_blanking(sensor, format);
> + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
> + return ret;
>
> - return 0;
> + mt9m114_pa_ctrl_update_blanking(sensor, format);
> +
> + /*
> + * Apply values immediately if streaming and the selection size did not
> + * change.
> + */
> + if (sensor->streaming && old_crop.height == crop->height &&
> + old_crop.width == crop->width) {
> + ret = mt9m114_configure_pa(sensor, state);
> + if (ret)
> + return ret;
> + // Changing the cropping config requires a CONFIG_CHANGE
/* C comments, please. */
> + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
Please run:
$ ./scripts/checkpatch.pl --strict --max-line-length=80
on this.
> + }
> +
> + return ret;
> }
>
> static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming
2025-05-22 14:35 ` [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming Mathis Foerst
@ 2025-05-26 12:10 ` Laurent Pinchart
0 siblings, 0 replies; 14+ messages in thread
From: Laurent Pinchart @ 2025-05-26 12:10 UTC (permalink / raw)
To: Mathis Foerst
Cc: linux-kernel, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Mathis,
Thank you for the patch.
On Thu, May 22, 2025 at 04:35:08PM +0200, Mathis Foerst wrote:
> The current implementation does not apply changes to the V4L2 controls
> HFLIP & VFLIP of the sensor immediately if the sensor is in streaming
> state. The user has to stop and restart the stream for the changes to be
> applied.
This is by design. Changing horizontal or vertical flip will cause a
shift in the bayer pattern, which would require reconfiguring the
downstream devices in the pipeline atomically. This affects raw data
capture.
> Issue a CONFIG_CHANGE when the V4L2 controls HFLIP or VFLIP are set if the
> sensor is in streaming state to apply the change immediately.
>
> Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
> ---
> drivers/media/i2c/mt9m114.c | 43 +++++++++++++++++++++++++------------
> 1 file changed, 29 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
> index 6c80c6926aef..7d39978835fe 100644
> --- a/drivers/media/i2c/mt9m114.c
> +++ b/drivers/media/i2c/mt9m114.c
> @@ -399,6 +399,11 @@ struct mt9m114 {
> struct v4l2_ctrl *gain;
> struct v4l2_ctrl *hblank;
> struct v4l2_ctrl *vblank;
> + struct {
> + /* horizonal / vertical flip cluster */
> + struct v4l2_ctrl *hflip;
> + struct v4l2_ctrl *vflip;
> + };
> } pa;
>
> /* Image Flow Processor */
> @@ -1059,6 +1064,7 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl)
> struct v4l2_subdev_state *state;
> int ret = 0;
> u64 mask;
> + u64 val;
>
> /* V4L2 controls values are applied only when power is up. */
> if (!pm_runtime_get_if_in_use(&sensor->client->dev))
> @@ -1095,17 +1101,25 @@ static int mt9m114_pa_s_ctrl(struct v4l2_ctrl *ctrl)
> break;
>
> case V4L2_CID_HFLIP:
> - mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN;
> + mask = MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN |
> + MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN;
> + val = (sensor->pa.hflip->val ?
> + MT9M114_CAM_SENSOR_CONTROL_HORZ_MIRROR_EN : 0) &
> + (sensor->pa.vflip->val ?
> + MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN : 0);
> ret = cci_update_bits(sensor->regmap,
> MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
> - mask, ctrl->val ? mask : 0, NULL);
> - break;
> + mask, val, NULL);
> + /*
> + * A Config-Change needs to be issued for the change to take
> + * effect. If we're not streaming ignore this, the change will
> + * be applied when the stream is started.
> + */
> + if (ret || !sensor->streaming)
> + break;
>
> - case V4L2_CID_VFLIP:
> - mask = MT9M114_CAM_SENSOR_CONTROL_VERT_FLIP_EN;
> - ret = cci_update_bits(sensor->regmap,
> - MT9M114_CAM_SENSOR_CONTROL_READ_MODE,
> - mask, ctrl->val ? mask : 0, NULL);
> + ret = mt9m114_set_state(sensor,
> + MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
> break;
>
> default:
> @@ -1406,12 +1420,13 @@ static int mt9m114_pa_init(struct mt9m114 *sensor)
> sensor->pixrate, sensor->pixrate, 1,
> sensor->pixrate);
>
> - v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
> - V4L2_CID_HFLIP,
> - 0, 1, 1, 0);
> - v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
> - V4L2_CID_VFLIP,
> - 0, 1, 1, 0);
> + sensor->pa.hflip = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
> + V4L2_CID_HFLIP,
> + 0, 1, 1, 0);
> + sensor->pa.vflip = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops,
> + V4L2_CID_VFLIP,
> + 0, 1, 1, 0);
> + v4l2_ctrl_cluster(2, &sensor->pa.hflip);
>
> if (hdl->error) {
> ret = hdl->error;
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v6 5/7] media: mt9m114: Allow set_selection while streaming
2025-05-22 14:35 ` [PATCH v6 5/7] media: mt9m114: Allow set_selection " Mathis Foerst
2025-05-26 8:46 ` Sakari Ailus
@ 2025-05-26 12:13 ` Laurent Pinchart
1 sibling, 0 replies; 14+ messages in thread
From: Laurent Pinchart @ 2025-05-26 12:13 UTC (permalink / raw)
To: Mathis Foerst
Cc: linux-kernel, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Mathis,
Thank you for the patch.
On Thu, May 22, 2025 at 04:35:09PM +0200, Mathis Foerst wrote:
> The current implementation does not apply changes to the crop-
> configuration of the sensor immediately if the sensor is in
> streaming state. The user has to stop and restart the stream for
> the changes to be applied.
> This can be undesirable e.g. in a calibration usecase where the user
> wants to see the impact of his changes in a live video stream.
> Under the condition that the width & height of the cropped image area
> does not change, the changed cropping configuration can be applied to
> the pixel-array immediately without disturbing the IFP.
>
> Call mt9m114_configure_pa() in mt9m114_pa_set_selection() if the sensor is
> in streaming state and the size of the cropping rectangle didn't change,
> issue a CONFIG_CHANGE to apply the changes immediately.
>
> Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
> ---
> drivers/media/i2c/mt9m114.c | 24 +++++++++++++++++++++---
> 1 file changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
> index 7d39978835fe..e909c1227e51 100644
> --- a/drivers/media/i2c/mt9m114.c
> +++ b/drivers/media/i2c/mt9m114.c
> @@ -1301,11 +1301,14 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
> struct mt9m114 *sensor = pa_to_mt9m114(sd);
> struct v4l2_mbus_framefmt *format;
> struct v4l2_rect *crop;
> + struct v4l2_rect old_crop;
> + int ret = 0;
>
> if (sel->target != V4L2_SEL_TGT_CROP)
> return -EINVAL;
>
> crop = v4l2_subdev_state_get_crop(state, sel->pad);
> + old_crop = *crop;
> format = v4l2_subdev_state_get_format(state, sel->pad);
>
> /*
> @@ -1331,10 +1334,25 @@ static int mt9m114_pa_set_selection(struct v4l2_subdev *sd,
> format->width = crop->width;
> format->height = crop->height;
>
> - if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE)
> - mt9m114_pa_ctrl_update_blanking(sensor, format);
> + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
> + return ret;
>
> - return 0;
> + mt9m114_pa_ctrl_update_blanking(sensor, format);
> +
> + /*
> + * Apply values immediately if streaming and the selection size did not
> + * change.
> + */
> + if (sensor->streaming && old_crop.height == crop->height &&
> + old_crop.width == crop->width) {
Changing the width or height of the active crop rectangle should be
disallowed completely during streaming. mt9m114_pa_set_selection().
should return -EBUSY in that case.
> + ret = mt9m114_configure_pa(sensor, state);
> + if (ret)
> + return ret;
> + // Changing the cropping config requires a CONFIG_CHANGE
> + ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
> + }
> +
> + return ret;
> }
>
> static const struct v4l2_subdev_pad_ops mt9m114_pa_pad_ops = {
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v6 0/7] MT9M114 driver bugfix and improvements
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
` (6 preceding siblings ...)
2025-05-22 14:35 ` [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate Mathis Foerst
@ 2025-05-26 12:15 ` Laurent Pinchart
2025-05-27 6:37 ` Sakari Ailus
7 siblings, 1 reply; 14+ messages in thread
From: Laurent Pinchart @ 2025-05-26 12:15 UTC (permalink / raw)
To: Mathis Foerst
Cc: linux-kernel, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Sakari Ailus, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Mathis, Sakari,
On Thu, May 22, 2025 at 04:35:04PM +0200, Mathis Foerst wrote:
> Hi,
>
> this patch series contains the following bugfix and improvements
> for the MT9M114 camera driver:
Review comments need to be addressed for patches 4/7 and 5/7, but the
rest of the series seems ready. Sakari, could you merge the other
patches, to reduce the size of the next version ?
> Changelog:
>
> v5 -> v6:
> - Add 'Reviewed-By:' tags. Sorry for forgetting this in the previous versions
>
> v4 -> v5:
> - Apply reformatings and small refactorings as suggested in review comments
> - Split PATCH 4 into two parts: One for applying HFLIP / VFLIP while
> streaming, one for applying set_selection while streaming.
> - Add condition to apply set_selection immediately only if the size of the
> cropping rectangle does not change in PATCH 5
> - Use device_property_read_u32 instead of of_property_read_u32 in PATCH 7
>
> v3 -> v4:
> - Rename DT binding from "onnn,slew-rate" to "slew-rate" in PATCH 1 and 6 as
> requested in the review comment.
>
> v2 -> v3:
> - Dropped PATCH 2 ("media: mt9m114: Add get_mbus_config").
> Based on the comments, this issure won't be fixed in the MT9M114
> driver but in "imx-media-csi.c" in a separate patch.
> - Renumbered patches accordingly.
> - Fix the incomplete renaming of the DT property from 'pad-slew-rate'
> to 'onnn,slew-rate' in PATCH 1 and 6.
> - Fix checkpatch formatting suggestions in PATCH 2 and 6.
>
> v1 -> v2:
> - Fix the subjects of the patches
> - Dropped PATCH 1 ("Add bypass-pll DT-binding") as it can be automatically
> detected if the PLL should be bypassed.
> - Renumbered patches accordingly
> - Switch to uint32, add default value and clarify documentation in PATCH 1
> - Add 'Fixes' and 'Cc' tags as suggested in PATCH 6
>
> Link to v1 discussion:
> https://lore.kernel.org/linux-media/20250226153929.274562-1-mathis.foerst@mt.com/
> Link to v2 discussion:
> https://lore.kernel.org/linux-media/20250304103647.34235-1-mathis.foerst@mt.com/
> Link to v3 discussion:
> https://lore.kernel.org/linux-media/20250305101453.708270-1-mathis.foerst@mt.com/
> Link to v4 discussion:
> https://lore.kernel.org/linux-media/20250307093140.370061-1-mathis.foerst@mt.com/
>
>
> Bugfixes:
> - Fix a deadlock when using the V4L2 pad-ops get/set_frame_interval
>
> New Features:
> - Bypass the internal PLL if EXTCLK matches the configured link_frequency
> - Make the slew-rate of the output pads configurable via DT
> - Allow to change the cropping configuration and the horizontal/vertical
> flipping while the sensor is in streaming state
>
> Thanks,
> Mathis
>
> Mathis Foerst (7):
> media: dt-bindings: mt9m114: Add slew-rate DT-binding
> media: mt9m114: Bypass PLL if required
> media: mt9m114: Factor out mt9m114_configure_pa
> media: mt9m114: Apply horizontal / vertical flip while streaming
> media: mt9m114: Allow set_selection while streaming
> media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval
> media: mt9m114: Set pad-slew-rate
>
> .../bindings/media/i2c/onnn,mt9m114.yaml | 9 +
> drivers/media/i2c/mt9m114.c | 264 ++++++++++++------
> 2 files changed, 185 insertions(+), 88 deletions(-)
>
> base-commit: d608703fcdd9e9538f6c7a0fcf98bf79b1375b60
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate
2025-05-22 14:35 ` [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate Mathis Foerst
@ 2025-05-27 6:36 ` Sakari Ailus
0 siblings, 0 replies; 14+ messages in thread
From: Sakari Ailus @ 2025-05-27 6:36 UTC (permalink / raw)
To: Mathis Foerst
Cc: linux-kernel, Laurent Pinchart, Mauro Carvalho Chehab,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Mathis,
On Thu, May 22, 2025 at 04:35:11PM +0200, Mathis Foerst wrote:
> The MT9M114 supports the different slew rates (0 to 7) on the output pads.
> At the moment, this is hardcoded to 7 (the fastest rate).
> The user might want to change this values due to EMC requirements.
>
> Read the 'slew-rate' from the DT and configure the pad slew rates of
> the output pads accordingly in mt9m114_initialize().
> Remove the hardcoded slew rate setting from the mt9m114_init table.
>
> Signed-off-by: Mathis Foerst <mathis.foerst@mt.com>
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/media/i2c/mt9m114.c | 26 +++++++++++++++++++++++---
> 1 file changed, 23 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/i2c/mt9m114.c b/drivers/media/i2c/mt9m114.c
> index 9ff46c72dbc1..f3f9ecc0866c 100644
> --- a/drivers/media/i2c/mt9m114.c
> +++ b/drivers/media/i2c/mt9m114.c
> @@ -18,6 +18,7 @@
> #include <linux/module.h>
> #include <linux/mutex.h>
> #include <linux/pm_runtime.h>
> +#include <linux/property.h>
> #include <linux/regmap.h>
> #include <linux/regulator/consumer.h>
> #include <linux/types.h>
> @@ -42,6 +43,9 @@
> #define MT9M114_RESET_AND_MISC_CONTROL CCI_REG16(0x001a)
> #define MT9M114_RESET_SOC BIT(0)
> #define MT9M114_PAD_SLEW CCI_REG16(0x001e)
> +#define MT9M114_PAD_SLEW_MIN 0
> +#define MT9M114_PAD_SLEW_MAX 7
> +#define MT9M114_PAD_SLEW_DEFAULT 7
> #define MT9M114_PAD_CONTROL CCI_REG16(0x0032)
>
> /* XDMA registers */
> @@ -388,6 +392,7 @@ struct mt9m114 {
>
> unsigned int pixrate;
> bool streaming;
> + u32 pad_slew_rate;
>
> /* Pixel Array */
> struct {
> @@ -650,9 +655,6 @@ static const struct cci_reg_sequence mt9m114_init[] = {
> { MT9M114_CAM_SENSOR_CFG_FINE_INTEG_TIME_MAX, 1459 },
> { MT9M114_CAM_SENSOR_CFG_FINE_CORRECTION, 96 },
> { MT9M114_CAM_SENSOR_CFG_REG_0_DATA, 32 },
> -
> - /* Miscellaneous settings */
> - { MT9M114_PAD_SLEW, 0x0777 },
> };
>
> /* -----------------------------------------------------------------------------
> @@ -784,6 +786,13 @@ static int mt9m114_initialize(struct mt9m114 *sensor)
> if (ret < 0)
> return ret;
>
> + value = (sensor->pad_slew_rate)
> + | (sensor->pad_slew_rate) << 4
> + | (sensor->pad_slew_rate) << 8;
Please drop the redundant parentheses.
> + cci_write(sensor->regmap, MT9M114_PAD_SLEW, value, &ret);
> + if (ret < 0)
> + return ret;
> +
> ret = mt9m114_set_state(sensor, MT9M114_SYS_STATE_ENTER_CONFIG_CHANGE);
> if (ret < 0)
> return ret;
> @@ -2398,6 +2407,17 @@ static int mt9m114_parse_dt(struct mt9m114 *sensor)
> goto error;
> }
>
> + sensor->pad_slew_rate = MT9M114_PAD_SLEW_DEFAULT;
> + device_property_read_u32(&sensor->client->dev, "slew-rate",
> + &sensor->pad_slew_rate);
> +
> + if (sensor->pad_slew_rate < MT9M114_PAD_SLEW_MIN ||
> + sensor->pad_slew_rate > MT9M114_PAD_SLEW_MAX) {
> + dev_err(&sensor->client->dev, "Invalid slew-rate %u\n",
> + sensor->pad_slew_rate);
> + return -EINVAL;
> + }
> +
> return 0;
>
> error:
--
Sakari Ailus
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v6 0/7] MT9M114 driver bugfix and improvements
2025-05-26 12:15 ` [PATCH v6 0/7] MT9M114 driver bugfix and improvements Laurent Pinchart
@ 2025-05-27 6:37 ` Sakari Ailus
0 siblings, 0 replies; 14+ messages in thread
From: Sakari Ailus @ 2025-05-27 6:37 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Mathis Foerst, linux-kernel, Mauro Carvalho Chehab, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Steve Longerbeam,
Philipp Zabel, Greg Kroah-Hartman, Shawn Guo, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, linux-media, devicetree,
linux-staging, imx, linux-arm-kernel, manuel.traut, mathis.foerst
Hi Laurent,
On Mon, May 26, 2025 at 02:15:20PM +0200, Laurent Pinchart wrote:
> Hi Mathis, Sakari,
>
> On Thu, May 22, 2025 at 04:35:04PM +0200, Mathis Foerst wrote:
> > Hi,
> >
> > this patch series contains the following bugfix and improvements
> > for the MT9M114 camera driver:
>
> Review comments need to be addressed for patches 4/7 and 5/7, but the
> rest of the series seems ready. Sakari, could you merge the other
> patches, to reduce the size of the next version ?
I've picked patches 1--3 and 6.
--
Sakari Ailus
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-05-27 6:43 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-22 14:35 [PATCH v6 0/7] MT9M114 driver bugfix and improvements Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 1/7] media: dt-bindings: mt9m114: Add slew-rate DT-binding Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 2/7] media: mt9m114: Bypass PLL if required Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 3/7] media: mt9m114: Factor out mt9m114_configure_pa Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 4/7] media: mt9m114: Apply horizontal / vertical flip while streaming Mathis Foerst
2025-05-26 12:10 ` Laurent Pinchart
2025-05-22 14:35 ` [PATCH v6 5/7] media: mt9m114: Allow set_selection " Mathis Foerst
2025-05-26 8:46 ` Sakari Ailus
2025-05-26 12:13 ` Laurent Pinchart
2025-05-22 14:35 ` [PATCH v6 6/7] media: mt9m114: Fix deadlock in get_frame_interval/set_frame_interval Mathis Foerst
2025-05-22 14:35 ` [PATCH v6 7/7] media: mt9m114: Set pad-slew-rate Mathis Foerst
2025-05-27 6:36 ` Sakari Ailus
2025-05-26 12:15 ` [PATCH v6 0/7] MT9M114 driver bugfix and improvements Laurent Pinchart
2025-05-27 6:37 ` Sakari Ailus
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).