aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/bridge/tc358767.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
index 166f9a3e9622..fe2b93546eae 100644
--- a/drivers/gpu/drm/bridge/tc358767.c
+++ b/drivers/gpu/drm/bridge/tc358767.c
@@ -382,6 +382,9 @@ struct tc_data {
/* HPD pin number (0 or 1) or -ENODEV */
int hpd_pin;
+
+ /* Number of pixels to subtract from a line due to pixel clock delta */
+ u32 line_pixel_subtract;
};
static inline struct tc_data *aux_to_tc(struct drm_dp_aux *a)
@@ -577,6 +580,11 @@ static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl)
return 0;
}
+static u32 div64_round_up(u64 v, u32 d)
+{
+ return div_u64(v + d - 1, d);
+}
+
static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
{
int ret;
@@ -658,8 +666,11 @@ static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
return -EINVAL;
}
- dev_dbg(tc->dev, "PLL: got %d, delta %d\n", best_pixelclock,
- best_delta);
+ tc->line_pixel_subtract = tc->mode.htotal -
+ div64_round_up(tc->mode.htotal * (u64)best_pixelclock, pixelclock);
+
+ dev_dbg(tc->dev, "PLL: got %d, delta %d (subtract %d px)\n", best_pixelclock,
+ best_delta, tc->line_pixel_subtract);
dev_dbg(tc->dev, "PLL: %d / %d / %d * %d / %d\n", refclk,
ext_div[best_pre], best_div, best_mul, ext_div[best_post]);
@@ -885,6 +896,12 @@ static int tc_set_common_video_mode(struct tc_data *tc,
upper_margin, lower_margin, vsync_len);
dev_dbg(tc->dev, "total: %dx%d\n", mode->htotal, mode->vtotal);
+ if (right_margin > tc->line_pixel_subtract) {
+ right_margin -= tc->line_pixel_subtract;
+ } else {
+ dev_err(tc->dev, "Bridge pixel clock too slow for mode\n");
+ right_margin = 0;
+ }
/*
* LCD Ctl Frame Size
@@ -894,7 +911,7 @@ static int tc_set_common_video_mode(struct tc_data *tc,
*/
ret = regmap_write(tc->regmap, VPCTRL0,
FIELD_PREP(VSDELAY, right_margin + 10) |
- OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED);
+ OPXLFMT_RGB888 | FRMSYNC_ENABLED | MSF_DISABLED);
if (ret)
return ret;