@@ -170,9 +170,6 @@ struct imx477_mode {
170170 /* Frame height */
171171 unsigned int height ;
172172
173- /* H-timing in pixels */
174- unsigned int line_length_pix ;
175-
176173 /* Analog crop rectangle. */
177174 struct v4l2_rect crop ;
178175
@@ -873,7 +870,6 @@ static const struct imx477_mode supported_modes_12bit[] = {
873870 /* 12MPix 10fps mode */
874871 .width = 4056 ,
875872 .height = 3040 ,
876- .line_length_pix = 24000 ,
877873 .crop = {
878874 .left = IMX477_PIXEL_ARRAY_LEFT ,
879875 .top = IMX477_PIXEL_ARRAY_TOP ,
@@ -890,7 +886,6 @@ static const struct imx477_mode supported_modes_12bit[] = {
890886 /* 12MPix cropped 16:9 mode */
891887 .width = 4056 ,
892888 .height = 2160 ,
893- .line_length_pix = 24000 ,
894889 .crop = {
895890 .left = IMX477_PIXEL_ARRAY_LEFT ,
896891 .top = IMX477_PIXEL_ARRAY_TOP + 440 ,
@@ -907,7 +902,6 @@ static const struct imx477_mode supported_modes_12bit[] = {
907902 /* 2x2 binned 40fps mode */
908903 .width = 2028 ,
909904 .height = 1520 ,
910- .line_length_pix = 12740 ,
911905 .crop = {
912906 .left = IMX477_PIXEL_ARRAY_LEFT ,
913907 .top = IMX477_PIXEL_ARRAY_TOP ,
@@ -924,7 +918,6 @@ static const struct imx477_mode supported_modes_12bit[] = {
924918 /* 1080p 50fps cropped mode */
925919 .width = 2028 ,
926920 .height = 1080 ,
927- .line_length_pix = 12740 ,
928921 .crop = {
929922 .left = IMX477_PIXEL_ARRAY_LEFT ,
930923 .top = IMX477_PIXEL_ARRAY_TOP + 440 ,
@@ -944,7 +937,6 @@ static const struct imx477_mode supported_modes_10bit[] = {
944937 /* 120fps. 2x2 binned and cropped */
945938 .width = 1332 ,
946939 .height = 990 ,
947- .line_length_pix = 6664 ,
948940 .crop = {
949941 /*
950942 * FIXME: the analog crop rectangle is actually
@@ -1141,6 +1133,24 @@ static void imx477_set_default_format(struct imx477 *imx477)
11411133 imx477 -> fmt_code = MEDIA_BUS_FMT_SRGGB12_1X12 ;
11421134}
11431135
1136+ static int imx477_get_bpp (unsigned int code )
1137+ {
1138+ switch (code ) {
1139+ default :
1140+ case MEDIA_BUS_FMT_SRGGB12_1X12 :
1141+ case MEDIA_BUS_FMT_SGRBG12_1X12 :
1142+ case MEDIA_BUS_FMT_SGBRG12_1X12 :
1143+ case MEDIA_BUS_FMT_SBGGR12_1X12 :
1144+ return 12 ;
1145+
1146+ case MEDIA_BUS_FMT_SRGGB10_1X10 :
1147+ case MEDIA_BUS_FMT_SGRBG10_1X10 :
1148+ case MEDIA_BUS_FMT_SGBRG10_1X10 :
1149+ case MEDIA_BUS_FMT_SBGGR10_1X10 :
1150+ return 10 ;
1151+ }
1152+ }
1153+
11441154static int imx477_open (struct v4l2_subdev * sd , struct v4l2_subdev_fh * fh )
11451155{
11461156 struct imx477 * imx477 = to_imx477 (sd );
@@ -1428,6 +1438,8 @@ static int imx477_get_pad_format(struct v4l2_subdev *sd,
14281438static void imx477_set_framing_limits (struct imx477 * imx477 )
14291439{
14301440 unsigned int hblank_min ;
1441+ u64 line_length_min ;
1442+ int bpp ;
14311443 const struct imx477_mode * mode = imx477 -> mode ;
14321444
14331445 /* Default to no long exposure multiplier. */
@@ -1444,7 +1456,14 @@ static void imx477_set_framing_limits(struct imx477 *imx477)
14441456 __v4l2_ctrl_s_ctrl (imx477 -> vblank ,
14451457 mode -> frm_length_default - mode -> height );
14461458
1447- hblank_min = mode -> line_length_pix - mode -> width ;
1459+ bpp = imx477_get_bpp (imx477 -> fmt_code );
1460+
1461+ line_length_min = mode -> width * bpp * (u64 )IMX477_PIXEL_RATE ;
1462+ do_div (line_length_min , imx477 -> link_freq_value * 2 * 2 /*LANES*/ );
1463+ /* Allow 500pixel clocks for HS<>LP transitions (approx 0.6usecs) */
1464+ line_length_min += 500 ;
1465+
1466+ hblank_min = line_length_min - mode -> width ;
14481467 __v4l2_ctrl_modify_range (imx477 -> hblank , hblank_min ,
14491468 IMX477_LINE_LENGTH_MAX , 1 , hblank_min );
14501469 __v4l2_ctrl_s_ctrl (imx477 -> hblank , hblank_min );
0 commit comments