Skip to content

Commit 5494f70

Browse files
6by9popcornmix
authored andcommitted
media: imx219: Adjust PLL settings based on the number of MIPI lanes
Commit ceddfd4 ("media: i2c: imx219: Support four-lane operation") added support for device tree to allow configuration of the sensor to use 4 lanes with a link frequency of 363MHz, and amended the advertised pixel rate to 280.8MPix/s. However it didn't change any of the PLL settings, so actually it would have been running effectively overclocked in the MIPI block, and with the frame rate and exposure calculations being wrong. The pixel rate and link frequency advertised were taken from the "Clock Setting Example" section of the datasheet. However those are based on an external clock of 12MHz, and are unachievable with a clock of 24MHz (it seems PREPLLCLK_VT_DIV and PREPLLCK_OP_DIV can ONLY be set via the automatic configuration doumented in "9-1-2 EXCK_FREQ setting depend on INCK frequency). Dropping all support for the 363MHz link frequency would cause problems for existing users, so allow it from device tree, but log a warning that the requested value is not being truly applied. Fixes: ceddfd4 ("media: i2c: imx219: Support four-lane operation") Co-developed-by: Peyton Howe <peyton.howe@bellsouth.net> Signed-off-by: Peyton Howe <peyton.howe@bellsouth.net> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
1 parent c22f301 commit 5494f70

File tree

1 file changed

+61
-17
lines changed

1 file changed

+61
-17
lines changed

drivers/media/i2c/imx219.c

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,11 @@
134134

135135
/* Pixel rate is fixed for all the modes */
136136
#define IMX219_PIXEL_RATE 182400000
137-
#define IMX219_PIXEL_RATE_4LANE 280800000
137+
#define IMX219_PIXEL_RATE_4LANE 281600000
138138

139139
#define IMX219_DEFAULT_LINK_FREQ 456000000
140-
#define IMX219_DEFAULT_LINK_FREQ_4LANE 363000000
140+
#define IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED 363000000
141+
#define IMX219_DEFAULT_LINK_FREQ_4LANE 364000000
141142

142143
/* IMX219 native and active pixel array size. */
143144
#define IMX219_NATIVE_WIDTH 3296U
@@ -169,15 +170,6 @@ static const struct cci_reg_sequence imx219_common_regs[] = {
169170
{ CCI_REG8(0x30eb), 0x05 },
170171
{ CCI_REG8(0x30eb), 0x09 },
171172

172-
/* PLL Clock Table */
173-
{ IMX219_REG_VTPXCK_DIV, 5 },
174-
{ IMX219_REG_VTSYCK_DIV, 1 },
175-
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
176-
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
177-
{ IMX219_REG_PLL_VT_MPY, 57 },
178-
{ IMX219_REG_OPSYCK_DIV, 1 },
179-
{ IMX219_REG_PLL_OP_MPY, 114 },
180-
181173
/* Undocumented registers */
182174
{ CCI_REG8(0x455e), 0x00 },
183175
{ CCI_REG8(0x471e), 0x4b },
@@ -202,6 +194,34 @@ static const struct cci_reg_sequence imx219_common_regs[] = {
202194
{ IMX219_REG_EXCK_FREQ, IMX219_EXCK_FREQ(IMX219_XCLK_FREQ / 1000000) },
203195
};
204196

197+
static const struct cci_reg_sequence imx219_2lane_regs[] = {
198+
/* PLL Clock Table */
199+
{ IMX219_REG_VTPXCK_DIV, 5 },
200+
{ IMX219_REG_VTSYCK_DIV, 1 },
201+
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
202+
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
203+
{ IMX219_REG_PLL_VT_MPY, 57 },
204+
{ IMX219_REG_OPSYCK_DIV, 1 },
205+
{ IMX219_REG_PLL_OP_MPY, 114 },
206+
207+
/* 2-Lane CSI Mode */
208+
{ IMX219_REG_CSI_LANE_MODE, IMX219_CSI_2_LANE_MODE },
209+
};
210+
211+
static const struct cci_reg_sequence imx219_4lane_regs[] = {
212+
/* PLL Clock Table */
213+
{ IMX219_REG_VTPXCK_DIV, 5 },
214+
{ IMX219_REG_VTSYCK_DIV, 1 },
215+
{ IMX219_REG_PREPLLCK_VT_DIV, 3 }, /* 0x03 = AUTO set */
216+
{ IMX219_REG_PREPLLCK_OP_DIV, 3 }, /* 0x03 = AUTO set */
217+
{ IMX219_REG_PLL_VT_MPY, 88 },
218+
{ IMX219_REG_OPSYCK_DIV, 1 },
219+
{ IMX219_REG_PLL_OP_MPY, 91 },
220+
221+
/* 4-Lane CSI Mode */
222+
{ IMX219_REG_CSI_LANE_MODE, IMX219_CSI_4_LANE_MODE },
223+
};
224+
205225
static const s64 imx219_link_freq_menu[] = {
206226
IMX219_DEFAULT_LINK_FREQ,
207227
};
@@ -663,9 +683,11 @@ static int imx219_set_framefmt(struct imx219 *imx219,
663683

664684
static int imx219_configure_lanes(struct imx219 *imx219)
665685
{
666-
return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE,
667-
imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE :
668-
IMX219_CSI_4_LANE_MODE, NULL);
686+
/* Write the appropriate PLL settings for the number of MIPI lanes */
687+
return cci_multi_reg_write(imx219->regmap,
688+
imx219->lanes == 2 ? imx219_2lane_regs : imx219_4lane_regs,
689+
imx219->lanes == 2 ? ARRAY_SIZE(imx219_2lane_regs) :
690+
ARRAY_SIZE(imx219_4lane_regs), NULL);
669691
};
670692

671693
static int imx219_start_streaming(struct imx219 *imx219,
@@ -1043,6 +1065,7 @@ static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)
10431065
.bus_type = V4L2_MBUS_CSI2_DPHY
10441066
};
10451067
int ret = -EINVAL;
1068+
bool link_frequency_valid = false;
10461069

10471070
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL);
10481071
if (!endpoint)
@@ -1069,9 +1092,30 @@ static int imx219_check_hwcfg(struct device *dev, struct imx219 *imx219)
10691092
goto error_out;
10701093
}
10711094

1072-
if (ep_cfg.nr_of_link_frequencies != 1 ||
1073-
(ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ?
1074-
IMX219_DEFAULT_LINK_FREQ : IMX219_DEFAULT_LINK_FREQ_4LANE))) {
1095+
if (ep_cfg.nr_of_link_frequencies == 1) {
1096+
switch (imx219->lanes) {
1097+
case 2:
1098+
if (ep_cfg.link_frequencies[0] ==
1099+
IMX219_DEFAULT_LINK_FREQ)
1100+
link_frequency_valid = true;
1101+
break;
1102+
case 4:
1103+
if (ep_cfg.link_frequencies[0] ==
1104+
IMX219_DEFAULT_LINK_FREQ_4LANE)
1105+
link_frequency_valid = true;
1106+
else if (ep_cfg.link_frequencies[0] ==
1107+
IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED) {
1108+
dev_warn(dev, "Link frequency of %d not supported, but has been incorrectly advertised previously\n",
1109+
IMX219_DEFAULT_LINK_FREQ_4LANE_UNSUPPORTED);
1110+
dev_warn(dev, "Using link frequency of %d\n",
1111+
IMX219_DEFAULT_LINK_FREQ_4LANE);
1112+
link_frequency_valid = true;
1113+
}
1114+
break;
1115+
}
1116+
}
1117+
1118+
if (!link_frequency_valid) {
10751119
dev_err_probe(dev, -EINVAL,
10761120
"Link frequency not supported: %lld\n",
10771121
ep_cfg.link_frequencies[0]);

0 commit comments

Comments
 (0)