]> git.ipfire.org Git - thirdparty/openwrt.git/blob
227ada434c89a096594357feb6c4889f429bc818
[thirdparty/openwrt.git] /
1 From 5b958efc20d381ee103103df5df0c88dc02ada18 Mon Sep 17 00:00:00 2001
2 From: Dave Stevenson <dave.stevenson@raspberrypi.com>
3 Date: Thu, 16 Jan 2025 11:08:25 +0000
4 Subject: [PATCH] media: imx219: Adjust PLL settings based on the number of
5 MIPI lanes
6
7 Commit ceddfd4493b3 ("media: i2c: imx219: Support four-lane operation")
8 added support for device tree to allow configuration of the sensor to
9 use 4 lanes with a link frequency of 363MHz, and amended the advertised
10 pixel rate to 280.8MPix/s.
11
12 However it didn't change any of the PLL settings, so actually it would
13 have been running effectively overclocked in the MIPI block, and with
14 the frame rate and exposure calculations being wrong.
15
16 The pixel rate and link frequency advertised were taken from the "Clock
17 Setting Example" section of the datasheet. However those are based on an
18 external clock of 12MHz, and are unachievable with a clock of 24MHz (it
19 seems PREPLLCLK_VT_DIV and PREPLLCK_OP_DIV can ONLY be set via the
20 automatic configuration doumented in "9-1-2 EXCK_FREQ setting depend on
21 INCK frequency).
22
23 Dropping all support for the 363MHz link frequency would cause problems
24 for existing users, so allow it from device tree, but log a warning that
25 the requested value is not being truly applied.
26
27 Fixes: ceddfd4493b3 ("media: i2c: imx219: Support four-lane operation")
28 Co-developed-by: Peyton Howe <peyton.howe@bellsouth.net>
29 Signed-off-by: Peyton Howe <peyton.howe@bellsouth.net>
30 Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
31 ---
32 drivers/media/i2c/imx219.c | 83 +++++++++++++++++++++++++++++---------
33 1 file changed, 64 insertions(+), 19 deletions(-)
34
35 --- a/drivers/media/i2c/imx219.c
36 +++ b/drivers/media/i2c/imx219.c
37 @@ -148,10 +148,11 @@
38
39 /* Pixel rate is fixed for all the modes */
40 #define IMX219_PIXEL_RATE 182400000
41 -#define IMX219_PIXEL_RATE_4LANE 280800000
42 +#define IMX219_PIXEL_RATE_4LANE 281600000
43
44 #define IMX219_DEFAULT_LINK_FREQ 456000000
45 -#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000
46 +#define IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED 363000000
47 +#define IMX219_DEFAULT_LINK_FREQ_4LANE 364000000
48
49 /* IMX219 native and active pixel array size. */
50 #define IMX219_NATIVE_WIDTH 3296U
51 @@ -224,15 +225,6 @@ static const struct cci_reg_sequence imx
52 { CCI_REG8(0x30eb), 0x05 },
53 { CCI_REG8(0x30eb), 0x09 },
54
55 - /* PLL Clock Table */
56 - { IMX219_REG_VTPXCK_DIV, 5 },
57 - { IMX219_REG_VTSYCK_DIV, 1 },
58 - { IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
59 - { IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
60 - { IMX219_REG_PLL_VT_MPY, 57 },
61 - { IMX219_REG_OPSYCK_DIV, 1 },
62 - { IMX219_REG_PLL_OP_MPY, 114 },
63 -
64 /* Undocumented registers */
65 { CCI_REG8(0x455e), 0x00 },
66 { CCI_REG8(0x471e), 0x4b },
67 @@ -316,6 +308,34 @@ static const struct cci_reg_sequence raw
68 { IMX219_REG_OPPXCK_DIV, 10 },
69 };
70
71 +static const struct cci_reg_sequence imx219_2lane_regs[] = {
72 + /* PLL Clock Table */
73 + { IMX219_REG_VTPXCK_DIV, 5 },
74 + { IMX219_REG_VTSYCK_DIV, 1 },
75 + { IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
76 + { IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
77 + { IMX219_REG_PLL_VT_MPY, 57 },
78 + { IMX219_REG_OPSYCK_DIV, 1 },
79 + { IMX219_REG_PLL_OP_MPY, 114 },
80 +
81 + /* 2-Lane CSI Mode */
82 + { IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE },
83 +};
84 +
85 +static const struct cci_reg_sequence imx219_4lane_regs[] = {
86 + /* PLL Clock Table */
87 + { IMX219_REG_VTPXCK_DIV, 5 },
88 + { IMX219_REG_VTSYCK_DIV, 1 },
89 + { IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
90 + { IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
91 + { IMX219_REG_PLL_VT_MPY, 88 },
92 + { IMX219_REG_OPSYCK_DIV, 1 },
93 + { IMX219_REG_PLL_OP_MPY, 91 },
94 +
95 + /* 4-Lane CSI Mode */
96 + { IMX219_REG_CSI_LANE_MODE, IMX219_CSI_4_LANE_MODE },
97 +};
98 +
99 static const s64 imx219_link_freq_menu[] = {
100 IMX219_DEFAULT_LINK_FREQ,
101 };
102 @@ -941,9 +961,11 @@ static int imx219_get_selection(struct v
103
104 static int imx219_configure_lanes(struct imx219 *imx219)
105 {
106 - return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE,
107 - imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE :
108 - IMX219_CSI_4_LANE_MODE, NULL);
109 + /* Write the appropriate PLL settings for the number of MIPI lanes */
110 + return cci_multi_reg_write(imx219->regmap,
111 + imx219->lanes == 2 ? imx219_2lane_regs : imx219_4lane_regs,
112 + imx219->lanes == 2 ? ARRAY_SIZE(imx219_2lane_regs) :
113 + ARRAY_SIZE(imx219_4lane_regs), NULL);
114 };
115
116 static int imx219_start_streaming(struct imx219 *imx219,
117 @@ -1334,6 +1356,7 @@ static int imx219_check_hwcfg(struct dev
118 .bus_type = V4L2_MBUS_CSI2_DPHY
119 };
120 int ret = -EINVAL;
121 + bool link_frequency_valid = false;
122
123 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
124 if (!endpoint) {
125 @@ -1360,11 +1383,33 @@ static int imx219_check_hwcfg(struct dev
126 goto error_out;
127 }
128
129 - if (ep_cfg.nr_of_link_frequencies != 1 ||
130 - (ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ?
131 - IMX219_DEFAULT_LINK_FREQ : IMX219_DEFAULT_LINK_FREQ_4LANE))) {
132 - dev_err(dev, "Link frequency not supported: %lld\n",
133 - ep_cfg.link_frequencies[0]);
134 + if (ep_cfg.nr_of_link_frequencies == 1) {
135 + switch (imx219->lanes) {
136 + case 2:
137 + if (ep_cfg.link_frequencies[0] ==
138 + IMX219_DEFAULT_LINK_FREQ)
139 + link_frequency_valid = true;
140 + break;
141 + case 4:
142 + if (ep_cfg.link_frequencies[0] ==
143 + IMX219_DEFAULT_LINK_FREQ_4LANE)
144 + link_frequency_valid = true;
145 + else if (ep_cfg.link_frequencies[0] ==
146 + IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED) {
147 + dev_warn(dev, "Link frequency of %d not supported, but has been incorrectly advertised previously\n",
148 + IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED);
149 + dev_warn(dev, "Using link frequency of %d\n",
150 + IMX219_DEFAULT_LINK_FREQ_4LANE);
151 + link_frequency_valid = true;
152 + }
153 + break;
154 + }
155 + }
156 +
157 + if (!link_frequency_valid) {
158 + dev_err_probe(dev, -EINVAL,
159 + "Link frequency not supported: %lld\n",
160 + ep_cfg.link_frequencies[0]);
161 goto error_out;
162 }
163