Skip to content

Commit 64fbedf

Browse files
committed
imx355: Rework to compute link frequency and pixel clock
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
1 parent fa11eff commit 64fbedf

1 file changed

Lines changed: 21 additions & 41 deletions

File tree

drivers/media/i2c/imx355.c

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#define IMX355_REG_PLL_OP_PREDIV CCI_REG8(0x030d)
3535
#define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e)
3636
#define IMX355_REG_PLL_IVT_SYSCK_DIV CCI_REG8(0x0303)
37+
#define IMX355_REG_PLL_IVT_PCK_DIV CCI_REG8(0x0301)
38+
#define IMX355_PLL_IVT_PCK_DIV 5
3739

3840
/* V_TIMING internal */
3941
#define IMX355_REG_FLL CCI_REG16(0x0340)
@@ -89,13 +91,6 @@
8991
/* Flip Control */
9092
#define IMX355_REG_ORIENTATION CCI_REG8(0x0101)
9193

92-
/* default link frequency and external clock */
93-
#define IMX355_LINK_FREQ_4LANE 360000000LL
94-
#define IMX355_LINK_FREQ_2LANE 444000000LL
95-
96-
#define IMX355_PIXEL_RATE_4LANE 288000000
97-
#define IMX355_PIXEL_RATE_2LANE 177600000
98-
9994
#define IMX355_PIXEL_ARRAY_TOP 0
10095
#define IMX355_PIXEL_ARRAY_LEFT 0
10196
#define IMX355_PIXEL_ARRAY_WIDTH 3280
@@ -142,7 +137,7 @@ static const struct imx355_clk_params imx355_clk_params[] = {
142137
{
143138
.ext_clk = 19200000,
144139
.extclk_freq = 0x1333,
145-
.pll_op_mpy = { 75, 93 },
140+
.pll_op_mpy = { 75, 92 },
146141
.pll_op_prediv = { 2, 2 }
147142
},
148143
{
@@ -154,6 +149,7 @@ static const struct imx355_clk_params imx355_clk_params[] = {
154149
};
155150

156151
struct imx355_hwcfg {
152+
s64 link_freq_menu;
157153
unsigned long link_freq_bitmap;
158154
unsigned int num_lanes;
159155
};
@@ -241,7 +237,7 @@ static const struct cci_reg_sequence imx355_global_regs[] = {
241237
{ CCI_REG8(0x305a), 0x00 },
242238
{ CCI_REG8(0x0112), 0x0a },
243239
{ CCI_REG8(0x0113), 0x0a },
244-
{ CCI_REG8(0x0301), 0x05 },
240+
{ IMX355_REG_PLL_IVT_PCK_DIV, IMX355_PLL_IVT_PCK_DIV },
245241
{ CCI_REG8(0x0305), 0x02 },
246242
{ CCI_REG8(0x0220), 0x00 },
247243
{ CCI_REG8(0x0222), 0x01 },
@@ -333,22 +329,6 @@ static const char * const imx355_test_pattern_menu[] = {
333329
"Pseudorandom Sequence (PN9)",
334330
};
335331

336-
/*
337-
* When adding more than the one below, make sure the disallowed ones will
338-
* actually be disabled in the LINK_FREQ control.
339-
*/
340-
static const s64 link_freq_menu_items_4lane[] = {
341-
IMX355_LINK_FREQ_4LANE,
342-
};
343-
344-
static const s64 link_freq_menu_items_2lane[] = {
345-
IMX355_LINK_FREQ_2LANE,
346-
};
347-
348-
/* Avoid the two arrays getting out of sync */
349-
static_assert(ARRAY_SIZE(link_freq_menu_items_4lane) ==
350-
ARRAY_SIZE(link_freq_menu_items_2lane));
351-
352332
/* Mode configs */
353333
static const struct imx355_mode supported_modes[] = {
354334
{
@@ -1032,33 +1012,30 @@ static int imx355_init_controls(struct imx355 *imx355)
10321012
{
10331013
struct v4l2_fwnode_device_properties props;
10341014
struct v4l2_ctrl_handler *ctrl_hdlr;
1015+
int lane_idx = imx355->hwcfg->num_lanes == 4 ? 0 : 1;
10351016
const struct imx355_mode *mode = &supported_modes[0];
1017+
const struct imx355_clk_params *clk = imx355->clk_params;
10361018
s64 exposure_max;
10371019
s64 vblank_def;
10381020
s64 hblank;
1039-
const s64 *link_freq_menu;
10401021
s64 pixel_rate;
1041-
u32 max;
10421022
int ret;
10431023

10441024
ctrl_hdlr = &imx355->ctrl_handler;
10451025
ret = v4l2_ctrl_handler_init(ctrl_hdlr, 12);
10461026
if (ret)
10471027
return ret;
10481028

1049-
link_freq_menu = imx355->hwcfg->num_lanes == 4 ?
1050-
link_freq_menu_items_4lane :
1051-
link_freq_menu_items_2lane;
1052-
max = ARRAY_SIZE(link_freq_menu_items_4lane) - 1;
10531029
imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
1054-
V4L2_CID_LINK_FREQ, max, 0,
1055-
link_freq_menu);
1030+
V4L2_CID_LINK_FREQ, 0, 0,
1031+
&imx355->hwcfg->link_freq_menu);
10561032
if (imx355->link_freq)
10571033
imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
10581034

10591035
/* By default, PIXEL_RATE is read only */
1060-
pixel_rate = imx355->hwcfg->num_lanes == 4 ? IMX355_PIXEL_RATE_4LANE :
1061-
IMX355_PIXEL_RATE_2LANE;
1036+
pixel_rate = ((s64)clk->ext_clk * clk->pll_op_mpy[lane_idx] * 2) /
1037+
(IMX355_PLL_IVT_PCK_DIV * clk->pll_op_prediv[lane_idx] *
1038+
(lane_idx + 1));
10621039
v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE,
10631040
pixel_rate, pixel_rate, 1, pixel_rate);
10641041

@@ -1130,14 +1107,17 @@ static int imx355_init_controls(struct imx355 *imx355)
11301107
return ret;
11311108
}
11321109

1133-
static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
1110+
static struct imx355_hwcfg *imx355_get_hwcfg(struct imx355 *imx355)
11341111
{
1112+
struct device *dev = imx355->dev;
11351113
struct imx355_hwcfg *cfg;
11361114
struct v4l2_fwnode_endpoint bus_cfg = {
11371115
.bus_type = V4L2_MBUS_CSI2_DPHY
11381116
};
11391117
struct fwnode_handle *ep;
11401118
struct fwnode_handle *fwnode = dev_fwnode(dev);
1119+
const struct imx355_clk_params *clk = imx355->clk_params;
1120+
int lane_idx;
11411121
int ret;
11421122

11431123
if (!fwnode)
@@ -1161,12 +1141,12 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
11611141

11621142
cfg->num_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
11631143

1144+
lane_idx = cfg->num_lanes == 4 ? 0 : 1;
1145+
cfg->link_freq_menu = (clk->ext_clk * clk->pll_op_mpy[lane_idx]) /
1146+
(clk->pll_op_prediv[lane_idx] * 2);
11641147
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
11651148
bus_cfg.nr_of_link_frequencies,
1166-
cfg->num_lanes == 4 ?
1167-
link_freq_menu_items_4lane :
1168-
link_freq_menu_items_2lane,
1169-
ARRAY_SIZE(link_freq_menu_items_4lane),
1149+
&cfg->link_freq_menu, 1,
11701150
&cfg->link_freq_bitmap);
11711151
if (ret)
11721152
goto out_err;
@@ -1236,7 +1216,7 @@ static int imx355_probe(struct i2c_client *client)
12361216
/* Initialize subdev */
12371217
v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
12381218

1239-
imx355->hwcfg = imx355_get_hwcfg(imx355->dev);
1219+
imx355->hwcfg = imx355_get_hwcfg(imx355);
12401220
if (!imx355->hwcfg) {
12411221
dev_err(imx355->dev, "failed to get hwcfg");
12421222
return -ENODEV;

0 commit comments

Comments
 (0)