summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/nvidia/tegra/dc.h2
-rw-r--r--src/soc/nvidia/tegra132/dc.c32
-rw-r--r--src/soc/nvidia/tegra132/dsi.c14
-rw-r--r--src/soc/nvidia/tegra132/include/soc/display.h2
4 files changed, 32 insertions, 18 deletions
diff --git a/src/soc/nvidia/tegra/dc.h b/src/soc/nvidia/tegra/dc.h
index a27fbc1fe1..88080082b2 100644
--- a/src/soc/nvidia/tegra/dc.h
+++ b/src/soc/nvidia/tegra/dc.h
@@ -450,7 +450,7 @@ enum {
PIXEL_CLK_DIVIDER_PCD24,
PIXEL_CLK_DIVIDER_PCD13,
};
-#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
+#define SHIFT_CLK_DIVIDER(x) (((x) - 1) * 2)
/* DC_WIN_WIN_OPTIONS 0x700 */
#define H_DIRECTION_DECREMENT(x) ((x) << 0)
diff --git a/src/soc/nvidia/tegra132/dc.c b/src/soc/nvidia/tegra132/dc.c
index e5ab23ad89..1b650ec23d 100644
--- a/src/soc/nvidia/tegra132/dc.c
+++ b/src/soc/nvidia/tegra132/dc.c
@@ -116,26 +116,24 @@ 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 1. In future these values
- * may be calculated by clock_configure_plld(), to allow wider
- * frequency range.
- *
- * Note ShiftClockDiv is a 7.1 format value.
+ * default: Set both shift_clk_div and pixel_clock_div to 1
*/
- const u32 shift_clock_div = 1;
+ update_display_shift_clock_divider(disp_ctrl, SHIFT_CLK_DIVIDER(1));
+
+ return 0;
+}
+
+void update_display_shift_clock_divider(struct display_controller *disp_ctrl,
+ u32 shift_clock_div)
+{
WRITEL((PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT) |
- ((shift_clock_div - 1) * 2 + 1) << SHIFT_CLK_DIVIDER_SHIFT,
+ (shift_clock_div & 0xff) << 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 0;
+ printk(BIOS_DEBUG, "%s: ShiftClockDiv=%u\n",
+ __func__, shift_clock_div);
}
/*
@@ -182,7 +180,9 @@ void update_window(const struct soc_nvidia_tegra132_config *config)
WRITEL(val, &disp_ctrl->cmd.disp_pow_ctrl);
val = GENERAL_UPDATE | WIN_A_UPDATE;
- val |= GENERAL_ACT_REQ | WIN_A_ACT_REQ;
+ WRITEL(val, &disp_ctrl->cmd.state_ctrl);
+
+ val = GENERAL_ACT_REQ | WIN_A_ACT_REQ;
WRITEL(val, &disp_ctrl->cmd.state_ctrl);
}
diff --git a/src/soc/nvidia/tegra132/dsi.c b/src/soc/nvidia/tegra132/dsi.c
index ad27b3d8b4..af2f592aa0 100644
--- a/src/soc/nvidia/tegra132/dsi.c
+++ b/src/soc/nvidia/tegra132/dsi.c
@@ -430,11 +430,14 @@ static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
static int tegra_output_dsi_setup_clock(struct tegra_dsi *dsi,
const struct soc_nvidia_tegra132_config *config)
{
- unsigned int mul, div, num_lanes; // , vrefresh, num_lanes;
+ unsigned int mul, div, num_lanes;
unsigned long bclk;
unsigned long pclk = config->pixel_clock;
int plld;
int err;
+ struct display_controller *disp_ctrl =
+ (void *)config->display_controller;
+ unsigned int shift_clk_div;
err = tegra_dsi_get_muldiv(dsi->format, &mul, &div);
if (err < 0)
@@ -471,6 +474,15 @@ static int tegra_output_dsi_setup_clock(struct tegra_dsi *dsi,
return -1;
}
+ /*
+ * Derive pixel clock from bit clock using the shift clock divider.
+ * Note that this is only half of what we would expect, but we need
+ * that to make up for the fact that we divided the bit clock by a
+ * factor of two above.
+ */
+ shift_clk_div = ((8 * mul) / (div * num_lanes)) - 2;
+ update_display_shift_clock_divider(disp_ctrl, shift_clk_div);
+
tegra_dsi_set_timeout(dsi, bclk, config->refresh);
return plld/1000000;
}
diff --git a/src/soc/nvidia/tegra132/include/soc/display.h b/src/soc/nvidia/tegra132/include/soc/display.h
index d7c172d71c..bb4a0f23c8 100644
--- a/src/soc/nvidia/tegra132/include/soc/display.h
+++ b/src/soc/nvidia/tegra132/include/soc/display.h
@@ -45,4 +45,6 @@ int tegra_dc_init(struct display_controller *disp_ctrl);
int update_display_mode(struct display_controller *disp_ctrl,
struct soc_nvidia_tegra132_config *config);
void update_window(const struct soc_nvidia_tegra132_config *config);
+void update_display_shift_clock_divider(struct display_controller *disp_ctrl,
+ u32 shift_clock_div);
#endif /* __SOC_NVIDIA_TEGRA132_INCLUDE_SOC_DISPLAY_H__ */