diff options
-rw-r--r-- | drivers/gpu/drm/tegra/sor.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 4b554908be5e..ff025aa786e8 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c | |||
@@ -48,6 +48,9 @@ struct tegra_sor_config { | |||
48 | u32 tu_size; | 48 | u32 tu_size; |
49 | u32 active_frac; | 49 | u32 active_frac; |
50 | u32 watermark; | 50 | u32 watermark; |
51 | |||
52 | u32 hblank_symbols; | ||
53 | u32 vblank_symbols; | ||
51 | }; | 54 | }; |
52 | 55 | ||
53 | static inline struct tegra_sor * | 56 | static inline struct tegra_sor * |
@@ -393,8 +396,8 @@ static int tegra_sor_calc_config(struct tegra_sor *sor, | |||
393 | { | 396 | { |
394 | const u64 f = 100000, link_rate = link->rate * 1000; | 397 | const u64 f = 100000, link_rate = link->rate * 1000; |
395 | const u64 pclk = mode->clock * 1000; | 398 | const u64 pclk = mode->clock * 1000; |
399 | u64 input, output, watermark, num; | ||
396 | struct tegra_sor_params params; | 400 | struct tegra_sor_params params; |
397 | u64 input, output, watermark; | ||
398 | u32 num_syms_per_line; | 401 | u32 num_syms_per_line; |
399 | unsigned int i; | 402 | unsigned int i; |
400 | 403 | ||
@@ -458,6 +461,23 @@ static int tegra_sor_calc_config(struct tegra_sor *sor, | |||
458 | config->watermark); | 461 | config->watermark); |
459 | } | 462 | } |
460 | 463 | ||
464 | /* compute the number of symbols per horizontal blanking interval */ | ||
465 | num = ((mode->htotal - mode->hdisplay) - 7) * link_rate; | ||
466 | config->hblank_symbols = div_u64(num, pclk); | ||
467 | |||
468 | if (link->capabilities & DP_LINK_CAP_ENHANCED_FRAMING) | ||
469 | config->hblank_symbols -= 3; | ||
470 | |||
471 | config->hblank_symbols -= 12 / link->num_lanes; | ||
472 | |||
473 | /* compute the number of symbols per vertical blanking interval */ | ||
474 | num = (mode->hdisplay - 25) * link_rate; | ||
475 | config->vblank_symbols = div_u64(num, pclk); | ||
476 | config->vblank_symbols -= 36 / link->num_lanes + 4; | ||
477 | |||
478 | dev_dbg(sor->dev, "blank symbols: H:%u V:%u\n", config->hblank_symbols, | ||
479 | config->vblank_symbols); | ||
480 | |||
461 | return 0; | 481 | return 0; |
462 | } | 482 | } |
463 | 483 | ||
@@ -684,12 +704,12 @@ static int tegra_output_sor_enable(struct tegra_output *output) | |||
684 | 704 | ||
685 | value = tegra_sor_readl(sor, SOR_DP_AUDIO_HBLANK_SYMBOLS); | 705 | value = tegra_sor_readl(sor, SOR_DP_AUDIO_HBLANK_SYMBOLS); |
686 | value &= ~SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK; | 706 | value &= ~SOR_DP_AUDIO_HBLANK_SYMBOLS_MASK; |
687 | value |= 137; /* XXX: don't hardcode? */ | 707 | value |= config.hblank_symbols & 0xffff; |
688 | tegra_sor_writel(sor, value, SOR_DP_AUDIO_HBLANK_SYMBOLS); | 708 | tegra_sor_writel(sor, value, SOR_DP_AUDIO_HBLANK_SYMBOLS); |
689 | 709 | ||
690 | value = tegra_sor_readl(sor, SOR_DP_AUDIO_VBLANK_SYMBOLS); | 710 | value = tegra_sor_readl(sor, SOR_DP_AUDIO_VBLANK_SYMBOLS); |
691 | value &= ~SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK; | 711 | value &= ~SOR_DP_AUDIO_VBLANK_SYMBOLS_MASK; |
692 | value |= 2368; /* XXX: don't hardcode? */ | 712 | value |= config.vblank_symbols & 0xffff; |
693 | tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS); | 713 | tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS); |
694 | 714 | ||
695 | /* enable pad calibration logic */ | 715 | /* enable pad calibration logic */ |