@@ -153,6 +153,11 @@ struct imx708_reg {
153153 u8 val ;
154154};
155155
156+ struct imx708_pair {
157+ u64 two_lane ;
158+ u64 four_lane ;
159+ };
160+
156161struct imx708_reg_list {
157162 unsigned int num_of_regs ;
158163 const struct imx708_reg * regs ;
@@ -167,7 +172,7 @@ struct imx708_mode {
167172 unsigned int height ;
168173
169174 /* H-timing in pixels */
170- unsigned int line_length_pix ;
175+ struct imx708_pair line_length_pix ;
171176
172177 /* Analog crop rectangle. */
173178 struct v4l2_rect crop ;
@@ -182,7 +187,7 @@ struct imx708_mode {
182187 struct imx708_reg_list reg_list ;
183188
184189 /* Not all modes have the same pixel rate. */
185- u64 pixel_rate ;
190+ struct imx708_pair pixel_rates ;
186191
187192 /* Not all modes have the same minimum exposure. */
188193 u32 exposure_lines_min ;
@@ -273,8 +278,8 @@ static const struct imx708_reg mode_common_regs[] = {
273278 {0x0100 , 0x00 },
274279 {0x0136 , 0x18 }, //REG_EXCK_FREQ_MSB
275280 {0x0137 , 0x00 }, //REG_EXCK_FREQ_LSB
276- {0x33F0 , 0x02 }, //0x01, 0x02
277- {0x33F1 , 0x05 }, //0x01, 0x05
281+ {0x33F0 , 0x02 }, //REG_IOPSYCK_DIV 0x01, 0x02
282+ {0x33F1 , 0x05 }, //REG_IOPPXCK_DIV 0x01, 0x05
278283 {0x3062 , 0x00 },
279284 {0x3063 , 0x12 }, //0x30, 0x12
280285 {0x3068 , 0x00 },
@@ -319,10 +324,99 @@ static const struct imx708_reg mode_common_regs[] = {
319324 {0x0138 , 0x01 }, //REG_TEMP_SENS_CTL
320325};
321326
327+ /* Pixel rate setup */
328+ enum {
329+ IMX708_PIX_RATE_566Mhz ,
330+ IMX708_PIX_RATE_585Mhz ,
331+ IMX708_PIX_RATE_595Mhz ,
332+ IMX708_PIX_RATE_777Mhz ,
333+ IMX708_PIX_RATE_854Mhz ,
334+ };
335+
336+ static const s64 pixel_rates [] = {
337+ [IMX708_PIX_RATE_566Mhz ] = 566400000 ,
338+ [IMX708_PIX_RATE_585Mhz ] = 585600000 ,
339+ [IMX708_PIX_RATE_595Mhz ] = 595200000 ,
340+ [IMX708_PIX_RATE_777Mhz ] = 777600000 ,
341+ [IMX708_PIX_RATE_854Mhz ] = 854400000 ,
342+ };
343+
344+ static const struct imx708_reg pixel_rate_566Mhz_regs [] = {
345+ {0x0305 , 0x02 },
346+ {0x0306 , 0x00 },
347+ {0x0307 , 0x76 },
348+ };
349+
350+ static const struct imx708_reg pixel_rate_585Mhz_regs [] = {
351+ {0x0305 , 0x02 },
352+ {0x0306 , 0x00 },
353+ {0x0307 , 0x7A },
354+ };
355+
356+ static const struct imx708_reg pixel_rate_595Mhz_regs [] = {
357+ {0x0305 , 0x02 },
358+ {0x0306 , 0x00 },
359+ {0x0307 , 0x7C },
360+ };
361+
362+ static const struct imx708_reg pixel_rate_777Mhz_regs [] = {
363+ {0x0305 , 0x02 },
364+ {0x0306 , 0x00 },
365+ {0x0307 , 0xA2 },
366+ };
367+
368+ static const struct imx708_reg pixel_rate_854Mhz_regs [] = {
369+ {0x0305 , 0x03 },
370+ {0x0306 , 0x01 },
371+ {0x0307 , 0x0B },
372+ };
373+
374+ static const struct imx708_reg_list pixel_rate_regs [] = {
375+ [IMX708_PIX_RATE_566Mhz ] = {
376+ .regs = pixel_rate_566Mhz_regs ,
377+ .num_of_regs = ARRAY_SIZE (pixel_rate_566Mhz_regs )
378+ },
379+ [IMX708_PIX_RATE_585Mhz ] = {
380+ .regs = pixel_rate_585Mhz_regs ,
381+ .num_of_regs = ARRAY_SIZE (pixel_rate_585Mhz_regs )
382+ },
383+ [IMX708_PIX_RATE_595Mhz ] = {
384+ .regs = pixel_rate_595Mhz_regs ,
385+ .num_of_regs = ARRAY_SIZE (pixel_rate_595Mhz_regs )
386+ },
387+ [IMX708_PIX_RATE_777Mhz ] = {
388+ .regs = pixel_rate_777Mhz_regs ,
389+ .num_of_regs = ARRAY_SIZE (pixel_rate_777Mhz_regs )
390+ },
391+ [IMX708_PIX_RATE_854Mhz ] = {
392+ .regs = pixel_rate_854Mhz_regs ,
393+ .num_of_regs = ARRAY_SIZE (pixel_rate_854Mhz_regs )
394+ },
395+ };
396+
397+ /* Line Length setup */
398+ enum {
399+ IMX708_LINE_LENGTH_2608 ,
400+ IMX708_LINE_LENGTH_5216 ,
401+ IMX708_LINE_LENGTH_7824 ,
402+ IMX708_LINE_LENGTH_10432 ,
403+ IMX708_LINE_LENGTH_15648 ,
404+ IMX708_LINE_LENGTH_20864 ,
405+ };
406+
407+ static const s64 line_lengths [] = {
408+ [IMX708_LINE_LENGTH_2608 ] = 2608 ,
409+ [IMX708_LINE_LENGTH_5216 ] = 5216 ,
410+ [IMX708_LINE_LENGTH_7824 ] = 7824 ,
411+ [IMX708_LINE_LENGTH_10432 ] = 10432 ,
412+ [IMX708_LINE_LENGTH_15648 ] = 15648 ,
413+ [IMX708_LINE_LENGTH_20864 ] = 20864 ,
414+ };
415+
322416/* 10-bit. */
323417static const struct imx708_reg mode_4608x2592_regs [] = {
324418 {0x0340 , 0x0A }, //REG_FRAME_LEN_MSB
325- {0x0341 , 0xC4 }, //REG_FRAME_LEN_LSB (0xC4, 0x5A, 0x59)
419+ {0x0341 , 0x59 }, //REG_FRAME_LEN_LSB (0xC4, 0x5A, 0x59)
326420 {0x0344 , 0x00 }, //REG_X_ADD_STA_MSB
327421 {0x0345 , 0x00 }, //REG_X_ADD_STA_LSB
328422 {0x0346 , 0x00 }, //REG_Y_ADD_STA_MSB
@@ -358,10 +452,7 @@ static const struct imx708_reg mode_4608x2592_regs[] = {
358452 {0x034F , 0x20 }, //REG_Y_OUT_SIZE_LSB
359453 {0x0301 , 0x05 }, //REG_IVTPXCK_DIV
360454 {0x0303 , 0x02 }, //REG_IVTSYCK_DIV
361- {0x0305 , 0x03 }, //REG_IVT_PREPLLCK_DIV (0x03 , 0x02)
362- {0x0306 , 0x01 }, //REG_PLL_IVT_MPY_MSB (0x01 , 0x00)
363- {0x0307 , 0x0B }, //REG_PLL_IVT_MPY_LSB (0x0B , 0x01, 0x7C)
364- {0x030B , 0x02 }, //REG_IOPSYCK_DIV
455+ {0x030B , 0x02 },
365456 {0x030D , 0x04 }, //REG_IOP_PREPLLCK_DIV
366457 {0x0310 , 0x01 }, //REG_PLL_MULTI_DRV
367458 {0x3CA0 , 0x00 },
@@ -381,7 +472,7 @@ static const struct imx708_reg mode_4608x2592_regs[] = {
381472 {0x3CBE , 0x00 },
382473 {0x3CBF , 0x00 },
383474 {0x0202 , 0x0A }, //REG_COARSE_INTEGRATION_TIME_MSB
384- {0x0203 , 0x29 }, //REG_COARSE_INTEGRATION_TIME_LSB (0x94, 0x29)
475+ {0x0203 , 0x29 }, //REG_COARSE_INTEGRATION_TIME_LSB
385476 {0x0224 , 0x01 },
386477 {0x0225 , 0xF4 },
387478 {0x3116 , 0x01 },
@@ -452,9 +543,6 @@ static const struct imx708_reg mode_2x2binned_regs[] = {
452543 {0x034F , 0x10 },
453544 {0x0301 , 0x05 },
454545 {0x0303 , 0x02 },
455- {0x0305 , 0x02 },
456- {0x0306 , 0x00 },
457- {0x0307 , 0x7A },
458546 {0x030B , 0x02 },
459547 {0x030D , 0x04 },
460548 {0x0310 , 0x01 },
@@ -546,9 +634,6 @@ static const struct imx708_reg mode_2x2binned_720p_regs[] = {
546634 {0x034F , 0x60 },
547635 {0x0301 , 0x05 },
548636 {0x0303 , 0x02 },
549- {0x0305 , 0x02 },
550- {0x0306 , 0x00 },
551- {0x0307 , 0x76 },
552637 {0x030B , 0x02 },
553638 {0x030D , 0x04 },
554639 {0x0310 , 0x01 },
@@ -640,9 +725,6 @@ static const struct imx708_reg mode_hdr_regs[] = {
640725 {0x034F , 0x10 },
641726 {0x0301 , 0x05 },
642727 {0x0303 , 0x02 },
643- {0x0305 , 0x02 },
644- {0x0306 , 0x00 },
645- {0x0307 , 0xA2 },
646728 {0x030B , 0x02 },
647729 {0x030D , 0x04 },
648730 {0x0310 , 0x01 },
@@ -702,7 +784,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
702784 /* Full resolution. */
703785 .width = 4608 ,
704786 .height = 2592 ,
705- .line_length_pix = 10432 ,
787+ .line_length_pix = { 15648 , 10432 } ,
706788 .crop = {
707789 .left = IMX708_PIXEL_ARRAY_LEFT ,
708790 .top = IMX708_PIXEL_ARRAY_TOP ,
@@ -715,7 +797,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
715797 .num_of_regs = ARRAY_SIZE (mode_4608x2592_regs ),
716798 .regs = mode_4608x2592_regs ,
717799 },
718- .pixel_rate = 854400000 , //595200000 ,
800+ .pixel_rates = { 595200000 , 854400000 } ,
719801 .exposure_lines_min = 8 ,
720802 .exposure_lines_step = 1 ,
721803 .hdr = false,
@@ -725,7 +807,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
725807 /* regular 2x2 binned. */
726808 .width = 2304 ,
727809 .height = 1296 ,
728- .line_length_pix = 0x1e90 ,
810+ .line_length_pix = { 7824 , 5216 } ,
729811 .crop = {
730812 .left = IMX708_PIXEL_ARRAY_LEFT ,
731813 .top = IMX708_PIXEL_ARRAY_TOP ,
@@ -738,7 +820,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
738820 .num_of_regs = ARRAY_SIZE (mode_2x2binned_regs ),
739821 .regs = mode_2x2binned_regs ,
740822 },
741- .pixel_rate = 585600000 ,
823+ .pixel_rates = { 585600000 , 585600000 } ,
742824 .exposure_lines_min = 4 ,
743825 .exposure_lines_step = 2 ,
744826 .hdr = false,
@@ -748,7 +830,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
748830 /* 2x2 binned and cropped for 720p. */
749831 .width = 1536 ,
750832 .height = 864 ,
751- .line_length_pix = 0x1460 ,
833+ .line_length_pix = { 5216 , 5216 } ,
752834 .crop = {
753835 .left = IMX708_PIXEL_ARRAY_LEFT + 768 ,
754836 .top = IMX708_PIXEL_ARRAY_TOP + 432 ,
@@ -761,7 +843,7 @@ static const struct imx708_mode supported_modes_10bit_no_hdr[] = {
761843 .num_of_regs = ARRAY_SIZE (mode_2x2binned_720p_regs ),
762844 .regs = mode_2x2binned_720p_regs ,
763845 },
764- .pixel_rate = 566400000 ,
846+ .pixel_rates = { 566400000 , 566400000 } ,
765847 .exposure_lines_min = 4 ,
766848 .exposure_lines_step = 2 ,
767849 .hdr = false,
@@ -774,7 +856,7 @@ static const struct imx708_mode supported_modes_10bit_hdr[] = {
774856 /* There's only one HDR mode, which is 2x2 downscaled */
775857 .width = 2304 ,
776858 .height = 1296 ,
777- .line_length_pix = 0x1460 ,
859+ .line_length_pix = { 5216 , 5216 } ,
778860 .crop = {
779861 .left = IMX708_PIXEL_ARRAY_LEFT ,
780862 .top = IMX708_PIXEL_ARRAY_TOP ,
@@ -787,7 +869,7 @@ static const struct imx708_mode supported_modes_10bit_hdr[] = {
787869 .num_of_regs = ARRAY_SIZE (mode_hdr_regs ),
788870 .regs = mode_hdr_regs ,
789871 },
790- .pixel_rate = 777600000 ,
872+ .pixel_rates = { 777600000 , 777600000 } ,
791873 .exposure_lines_min = 8 * IMX708_HDR_EXPOSURE_RATIO * IMX708_HDR_EXPOSURE_RATIO ,
792874 .exposure_lines_step = 2 * IMX708_HDR_EXPOSURE_RATIO * IMX708_HDR_EXPOSURE_RATIO ,
793875 .hdr = true,
@@ -892,6 +974,8 @@ struct imx708 {
892974 unsigned int long_exp_shift ;
893975
894976 unsigned int link_freq_idx ;
977+ unsigned int pix_rate_idx ;
978+ unsigned int line_length_idx ;
895979
896980 /* Two or Four lanes */
897981 u8 lanes ;
@@ -1137,20 +1221,32 @@ static int imx708_set_frame_length(struct imx708 *imx708, unsigned int val)
11371221static void imx708_set_framing_limits (struct imx708 * imx708 )
11381222{
11391223 const struct imx708_mode * mode = imx708 -> mode ;
1140- unsigned int hblank ;
1141-
1142- __v4l2_ctrl_modify_range (imx708 -> pixel_rate ,
1143- mode -> pixel_rate , mode -> pixel_rate ,
1144- 1 , mode -> pixel_rate );
1145-
1146- /* Update limits and set FPS to default */
1147- __v4l2_ctrl_modify_range (imx708 -> vblank , mode -> vblank_min ,
1148- ((1 << IMX708_LONG_EXP_SHIFT_MAX ) *
1149- IMX708_FRAME_LENGTH_MAX ) - mode -> height ,
1150- 1 , mode -> vblank_default );
1224+ unsigned int hblank , pix_rate ;
1225+ int i ;
11511226
1152- hblank = mode -> line_length_pix - mode -> width ;
1227+ /* Get the line lenth */
1228+ for (i = 0 ; i < ARRAY_SIZE (line_lengths ); i ++ ) {
1229+ if (line_lengths [i ] == (imx708 -> lanes == 2 ?
1230+ imx708 -> mode -> line_length_pix .two_lane :
1231+ imx708 -> mode -> line_length_pix .four_lane )) {
1232+ imx708 -> line_length_idx = i ;
1233+ break ;
1234+ }
1235+ }
1236+ hblank = line_lengths [imx708 -> line_length_idx ] - mode -> width ;
11531237 __v4l2_ctrl_modify_range (imx708 -> hblank , hblank , hblank , 1 , hblank );
1238+
1239+ /* Get the pixel rate */
1240+ for (i = 0 ; i < ARRAY_SIZE (pixel_rates ); i ++ ) {
1241+ if (pixel_rates [i ] == (imx708 -> lanes == 2 ?
1242+ imx708 -> mode -> pixel_rates .two_lane :
1243+ imx708 -> mode -> pixel_rates .four_lane )) {
1244+ imx708 -> pix_rate_idx = i ;
1245+ break ;
1246+ }
1247+ }
1248+ pix_rate = pixel_rates [imx708 -> pix_rate_idx ];
1249+ __v4l2_ctrl_modify_range (imx708 -> pixel_rate , pix_rate , pix_rate , 1 , pix_rate );
11541250}
11551251
11561252static int imx708_set_ctrl (struct v4l2_ctrl * ctrl )
@@ -1513,7 +1609,7 @@ static int imx708_configure_lanes(struct imx708 *imx708)
15131609static int imx708_start_streaming (struct imx708 * imx708 )
15141610{
15151611 struct i2c_client * client = v4l2_get_subdevdata (& imx708 -> sd );
1516- const struct imx708_reg_list * reg_list , * freq_regs ;
1612+ const struct imx708_reg_list * reg_list , * freq_regs , * pix_rate_regs ;
15171613 int i , ret ;
15181614 u32 val ;
15191615
@@ -1569,6 +1665,23 @@ static int imx708_start_streaming(struct imx708 *imx708)
15691665 return ret ;
15701666 }
15711667
1668+ // /* Set the pixel rate */
1669+ // for (i = 0; i < ARRAY_SIZE(pixel_rates); i++) {
1670+ // if (pixel_rates[i] == (imx708->lanes == 2 ?
1671+ // imx708->mode->pixel_rates.two_lane :
1672+ // imx708->mode->pixel_rates.four_lane)) {
1673+ // imx708->pix_rate_idx = i;
1674+ // break;
1675+ // }
1676+ // }
1677+ pix_rate_regs = & pixel_rate_regs [imx708 -> pix_rate_idx ];
1678+ ret = imx708_write_regs (imx708 , pix_rate_regs -> regs ,
1679+ pix_rate_regs -> num_of_regs );
1680+ if (ret ) {
1681+ dev_err (& client -> dev , "%s failed to set pixel rate\n" , __func__ );
1682+ return ret ;
1683+ }
1684+
15721685 /* Update the link frequency registers */
15731686 freq_regs = & link_freq_regs [imx708 -> link_freq_idx ];
15741687 ret = imx708_write_regs (imx708 , freq_regs -> regs ,
0 commit comments