aboutsummaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra124/display.c
diff options
context:
space:
mode:
authorHung-Te Lin <hungte@chromium.org>2014-04-08 20:03:40 +0800
committerMarc Jones <marc.jones@se-eng.com>2014-12-15 20:17:48 +0100
commit1a8e0af78b1886acc96d1e80be5871d287d148c5 (patch)
tree1019c994ddb15910833a59b5c11254105ce6e528 /src/soc/nvidia/tegra124/display.c
parent0c9cc5ee3be406901a52a8151408bb13253bf39b (diff)
tegra124: Setup clock PLLD by approximating display panel pixel clock.
PLLD, the clock for display, was previously hard-coded to 306MHz. To support more different panels, we should calcualte PLLD by panel pixel clock configuration. Note existing pixel clock configurations for nyan* boards won't work (they used to rely on hard-coded approximated values) so the device trees are also modified. BRANCH=none BUG=chrome-os-partner:25933 TEST=emerge-nyan_big coreboot chromeos-bootimage See panel correctly initialized and got DEV screen. Original-Change-Id: I8d592f0cc044e7c4e4803c45955642e791210ad3 Original-Signed-off-by: Hung-Te Lin <hungte@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/193565 (cherry picked from commit 4f9b793633ebb2d104b0544e3b72fa0d105951c4) Signed-off-by: Marc Jones <marc.jones@se-eng.com> Change-Id: Ib2cabbad60af010e872505e888eab485ba8c2916 Reviewed-on: http://review.coreboot.org/7762 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/nvidia/tegra124/display.c')
-rw-r--r--src/soc/nvidia/tegra124/display.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/soc/nvidia/tegra124/display.c b/src/soc/nvidia/tegra124/display.c
index 4a0f4501a2..c3117fdb01 100644
--- a/src/soc/nvidia/tegra124/display.c
+++ b/src/soc/nvidia/tegra124/display.c
@@ -98,8 +98,6 @@ static void print_mode(const struct soc_nvidia_tegra124_config *config)
static int update_display_mode(struct display_controller *disp_ctrl,
struct soc_nvidia_tegra124_config *config)
{
- unsigned long div = config->pll_div;
-
print_mode(config);
WRITEL(0x1, &disp_ctrl->disp.disp_timing_opt);
@@ -119,10 +117,25 @@ static int update_display_mode(struct display_controller *disp_ctrl,
WRITEL(config->xres | (config->yres << 16),
&disp_ctrl->disp.disp_active);
+ /**
+ * We want to use PLLD_out0, which is PLLD / 2:
+ * PixelClock = (PLLD / 2) / ShiftClockDiv / PixelClockDiv.
+ *
+ * Currently most panels work inside clock range 50MHz~100MHz, and PLLD
+ * has some requirements to have VCO in range 500MHz~1000MHz (see
+ * clock.c for more detail). To simplify calculation, we set
+ * PixelClockDiv to 1 and ShiftClockDiv to 5. In future these values
+ * may be calculated by clock_display, to allow wider frequency range.
+ *
+ * Note ShiftClockDiv is a 7.1 format value.
+ */
+ const u32 shift_clock_div = 5;
WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) |
- SHIFT_CLK_DIVIDER(div),
- &disp_ctrl->disp.disp_clk_ctrl);
- return 0;
+ ((shift_clock_div - 1) * 2) << SHIFT_CLK_DIVIDER_SHIFT,
+ &disp_ctrl->disp.disp_clk_ctrl);
+ printk(BIOS_DEBUG, "%s: PixelClock=%u, ShiftClockDiv=%u\n",
+ __func__, config->pixel_clock, shift_clock_div);
+ return clock_display(config->pixel_clock * shift_clock_div * 2);
}
static void update_window(struct display_controller *disp_ctrl,
@@ -285,7 +298,10 @@ void display_startup(device_t dev)
}
/* Configure dc mode */
- update_display_mode(disp_ctrl, config);
+ if (update_display_mode(disp_ctrl, config)) {
+ printk(BIOS_ERR, "dc: failed to configure display mode.\n");
+ return;
+ }
/* Enable dp */
dp_enable(dc->out);