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)
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
156151struct 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 */
353333static 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