diff options
author | Vince Hsu <vinceh@nvidia.com> | 2014-06-11 17:14:05 +0800 |
---|---|---|
committer | Marc Jones <marc.jones@se-eng.com> | 2015-01-04 00:14:03 +0100 |
commit | 1e3679ddd0fd03fdc00b50a45fc652a539b9c9a7 (patch) | |
tree | 11020367ea7d724801654a7e3f7b017048b393ce /src/soc/nvidia/tegra124 | |
parent | c1f7cbe49f0023655f6f60b1d924ed5c61533806 (diff) | |
download | coreboot-1e3679ddd0fd03fdc00b50a45fc652a539b9c9a7.tar.xz |
tegra124: configure DP with correct pixel clock
For some panels, the plld can't provide the pixel clock that
the panels wants, so we give it a good enough one. And we
should calculate the dp/dc settings by the real pixel clock.
BRANCH=nyan
BUG=chrome-os-partner:29489
TEST=Verified the panels N116BGE-EA2(Nyan) and N133BGE-EAB(Big).
No screen flicker is observed. No sor dp fifo underflow found.
Original-Change-Id: I037b2bd5f5e9bb8b15ab6f47a84ac7ef2e207779
Original-Signed-off-by: Vince Hsu <vinceh@nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/203358
Original-Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
(cherry picked from commit d320f0c6b54ea8ca84206447b223da76ac5f771b)
Signed-off-by: Marc Jones <marc.jones@se-eng.com>
Change-Id: I772bb8e7a40cc462c72ba0fb9657c63ed2e0d0ac
Reviewed-on: http://review.coreboot.org/8044
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/nvidia/tegra124')
-rw-r--r-- | src/soc/nvidia/tegra124/clock.c | 23 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/display.c | 9 | ||||
-rw-r--r-- | src/soc/nvidia/tegra124/include/soc/clock.h | 2 |
3 files changed, 23 insertions, 11 deletions
diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c index c5b06f4557..af2f96a5db 100644 --- a/src/soc/nvidia/tegra124/clock.c +++ b/src/soc/nvidia/tegra124/clock.c @@ -295,8 +295,14 @@ static void graphics_pll(void) */ } -/* Init PLLD clock source. */ -int +/* + * Init PLLD clock source. + * + * @frequency: the requested plld frequency + * + * Return the plld frequency if success, otherwise return 0. + */ +u32 clock_display(u32 frequency) { /** @@ -314,7 +320,7 @@ clock_display(u32 frequency) */ struct pllpad_dividers plld = { 0 }; u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0; - u32 cf, vco; + u32 cf, vco, rounded_rate = frequency; u32 diff, best_diff; const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3, mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz, @@ -326,7 +332,7 @@ clock_display(u32 frequency) if (vco < min_vco || vco > max_vco) { printk(BIOS_ERR, "%s: Cannot find out a supported VCO" " for Frequency (%u).\n", __func__, frequency); - return -1; + return 0; } plld.p = p; @@ -367,18 +373,19 @@ clock_display(u32 frequency) plld.cpcon = 12; if (best_diff) { - printk(BIOS_ERR, "%s: Failed to match output frequency %u, " + printk(BIOS_WARNING, "%s: Failed to match output frequency %u, " "best difference is %u.\n", __func__, frequency, best_diff); + rounded_rate = (ref / plld.m * plld.n) >> plld.p; } printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n", - __func__, (ref / plld.m * plld.n) >> plld.p, ref, plld.m, plld.n, - plld.p, plld.cpcon); + __func__, rounded_rate, ref, plld.m, plld.n, plld.p, plld.cpcon); init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld, (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE)); - return 0; + + return rounded_rate; } /* Initialize the UART and put it on CLK_M so we can use it during clock_init(). diff --git a/src/soc/nvidia/tegra124/display.c b/src/soc/nvidia/tegra124/display.c index 9ad76f0ead..6f6790d56e 100644 --- a/src/soc/nvidia/tegra124/display.c +++ b/src/soc/nvidia/tegra124/display.c @@ -221,6 +221,7 @@ void display_startup(device_t dev) struct display_controller *disp_ctrl = (void *)config->display_controller; struct pwm_controller *pwm = (void *)TEGRA_PWM_BASE; struct tegra_dc *dc = &dc_data; + u32 plld_rate; /* init dc */ dc->base = (void *)TEGRA_ARM_DISPLAYA; @@ -282,10 +283,14 @@ void display_startup(device_t dev) * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the * update_display_mode() for detail. */ - if (clock_display(config->pixel_clock * 2)) { + plld_rate = clock_display(config->pixel_clock * 2); + if (plld_rate == 0) { printk(BIOS_ERR, "dc: clock init failed\n"); return; - }; + } else if (plld_rate != config->pixel_clock * 2) { + printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate); + config->pixel_clock = plld_rate / 2; + } /* Init dc */ if (tegra_dc_init(disp_ctrl)) { diff --git a/src/soc/nvidia/tegra124/include/soc/clock.h b/src/soc/nvidia/tegra124/include/soc/clock.h index 73274a5c71..ffe9a4eedb 100644 --- a/src/soc/nvidia/tegra124/include/soc/clock.h +++ b/src/soc/nvidia/tegra124/include/soc/clock.h @@ -279,7 +279,7 @@ enum clock_source { /* Careful: Not true for all sources, always check TRM! */ int clock_get_osc_khz(void); int clock_get_pll_input_khz(void); -int clock_display(u32 frequency); +u32 clock_display(u32 frequency); void clock_early_uart(void); void clock_external_output(int clk_id); void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90, |