forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/media/v4l2-core/v4l2-dv-timings.c
....@@ -145,6 +145,8 @@
145145 const struct v4l2_bt_timings *bt = &t->bt;
146146 const struct v4l2_bt_timings_cap *cap = &dvcap->bt;
147147 u32 caps = cap->capabilities;
148
+ const u32 max_vert = 10240;
149
+ u32 max_hor = 3 * bt->width;
148150
149151 if (t->type != V4L2_DV_BT_656_1120)
150152 return false;
....@@ -160,6 +162,26 @@
160162 !(bt->standards & cap->standards)) ||
161163 (bt->interlaced && !(caps & V4L2_DV_BT_CAP_INTERLACED)) ||
162164 (!bt->interlaced && !(caps & V4L2_DV_BT_CAP_PROGRESSIVE)))
165
+ return false;
166
+
167
+ /* sanity checks for the blanking timings */
168
+ if (!bt->interlaced &&
169
+ (bt->il_vbackporch || bt->il_vsync || bt->il_vfrontporch))
170
+ return false;
171
+ /*
172
+ * Some video receivers cannot properly separate the frontporch,
173
+ * backporch and sync values, and instead they only have the total
174
+ * blanking. That can be assigned to any of these three fields.
175
+ * So just check that none of these are way out of range.
176
+ */
177
+ if (bt->hfrontporch > max_hor ||
178
+ bt->hsync > max_hor || bt->hbackporch > max_hor)
179
+ return false;
180
+ if (bt->vfrontporch > max_vert ||
181
+ bt->vsync > max_vert || bt->vbackporch > max_vert)
182
+ return false;
183
+ if (bt->interlaced && (bt->il_vfrontporch > max_vert ||
184
+ bt->il_vsync > max_vert || bt->il_vbackporch > max_vert))
163185 return false;
164186 return fnc == NULL || fnc(t, fnc_handle);
165187 }
....@@ -293,7 +315,7 @@
293315 if (prefix == NULL)
294316 prefix = "";
295317
296
- pr_info("%s: %s%ux%u%s%u.%u (%ux%u)\n", dev_prefix, prefix,
318
+ pr_info("%s: %s%ux%u%s%u.%02u (%ux%u)\n", dev_prefix, prefix,
297319 bt->width, bt->height, bt->interlaced ? "i" : "p",
298320 fps / 100, fps % 100, htot, vtot);
299321
....@@ -373,6 +395,45 @@
373395 return ratio;
374396 }
375397 EXPORT_SYMBOL_GPL(v4l2_dv_timings_aspect_ratio);
398
+
399
+/** v4l2_calc_timeperframe - helper function to calculate timeperframe based
400
+ * v4l2_dv_timings fields.
401
+ * @t - Timings for the video mode.
402
+ *
403
+ * Calculates the expected timeperframe using the pixel clock value and
404
+ * horizontal/vertical measures. This means that v4l2_dv_timings structure
405
+ * must be correctly and fully filled.
406
+ */
407
+struct v4l2_fract v4l2_calc_timeperframe(const struct v4l2_dv_timings *t)
408
+{
409
+ const struct v4l2_bt_timings *bt = &t->bt;
410
+ struct v4l2_fract fps_fract = { 1, 1 };
411
+ unsigned long n, d;
412
+ u32 htot, vtot, fps;
413
+ u64 pclk;
414
+
415
+ if (t->type != V4L2_DV_BT_656_1120)
416
+ return fps_fract;
417
+
418
+ htot = V4L2_DV_BT_FRAME_WIDTH(bt);
419
+ vtot = V4L2_DV_BT_FRAME_HEIGHT(bt);
420
+ pclk = bt->pixelclock;
421
+
422
+ if ((bt->flags & V4L2_DV_FL_CAN_DETECT_REDUCED_FPS) &&
423
+ (bt->flags & V4L2_DV_FL_REDUCED_FPS))
424
+ pclk = div_u64(pclk * 1000ULL, 1001);
425
+
426
+ fps = (htot * vtot) > 0 ? div_u64((100 * pclk), (htot * vtot)) : 0;
427
+ if (!fps)
428
+ return fps_fract;
429
+
430
+ rational_best_approximation(fps, 100, fps, 100, &n, &d);
431
+
432
+ fps_fract.numerator = d;
433
+ fps_fract.denominator = n;
434
+ return fps_fract;
435
+}
436
+EXPORT_SYMBOL_GPL(v4l2_calc_timeperframe);
376437
377438 /*
378439 * CVT defines
....@@ -718,7 +779,7 @@
718779 pix_clk = pix_clk / GTF_PXL_CLK_GRAN * GTF_PXL_CLK_GRAN;
719780
720781 hsync = (frame_width * 8 + 50) / 100;
721
- hsync = ((hsync + GTF_CELL_GRAN / 2) / GTF_CELL_GRAN) * GTF_CELL_GRAN;
782
+ hsync = DIV_ROUND_CLOSEST(hsync, GTF_CELL_GRAN) * GTF_CELL_GRAN;
722783
723784 h_fp = h_blank / 2 - hsync;
724785