aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSvyatoslav Ryhel2023-03-27 11:11:42 +0300
committerAnatolij Gustschin2023-04-07 18:34:19 +0200
commite114f507ece4f5f40bc0e40d7a61084bbc17555e (patch)
tree6be87adcdc759e1bdda3c12b37952bb10c378b86 /drivers
parentcf291babc7669013fb4efbceda98977bb2720635 (diff)
video: tegra-dc: get clocks from device tree
DISP1 clock may use PLLP, PLLC and PLLD as parents. Instead of hardcoding, lets pass clock and its parent from device tree. Default parent is PLLP. Tested-by: Robert Eckelmann <longnoserob@gmail.com> # ASUS TF101 T20 Tested-by: Nicolas Chauvet <kwizart@gmail.com> # Paz00 Tested-by: Andreas Westman Dorcsak <hedmoo@yahoo.com> # ASUS TF T30 Tested-by: Svyatoslav Ryhel <clamor95@gmail.com> # HTC One X T30 Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/tegra20/tegra-dc.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/video/tegra20/tegra-dc.c b/drivers/video/tegra20/tegra-dc.c
index 5e3f6bf029a..ff67cc89892 100644
--- a/drivers/video/tegra20/tegra-dc.c
+++ b/drivers/video/tegra20/tegra-dc.c
@@ -36,6 +36,7 @@ struct tegra_lcd_priv {
struct disp_ctlr *disp; /* Display controller to use */
fdt_addr_t frame_buffer; /* Address of frame buffer */
unsigned pixel_clock; /* Pixel clock in Hz */
+ int dc_clk[2]; /* Contains clk and its parent */
};
enum {
@@ -134,7 +135,7 @@ static int update_display_mode(struct dc_disp_reg *disp,
* the display clock (typically 600MHz) to the pixel clock. We round
* up or down as requried.
*/
- rate = clock_get_periph_rate(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL);
+ rate = clock_get_periph_rate(priv->dc_clk[0], priv->dc_clk[1]);
div = ((rate * 2 + priv->pixel_clock / 2) / priv->pixel_clock) - 2;
debug("Display clock %lu, divider %lu\n", rate, div);
@@ -269,20 +270,27 @@ static int tegra_display_probe(const void *blob, struct tegra_lcd_priv *priv,
{
struct disp_ctl_win window;
struct dc_ctlr *dc;
+ unsigned long rate = clock_get_rate(priv->dc_clk[1]);
priv->frame_buffer = (u32)default_lcd_base;
dc = (struct dc_ctlr *)priv->disp;
/*
- * A header file for clock constants was NAKed upstream.
- * TODO: Put this into the FDT and fdt_lcd struct when we have clock
- * support there
+ * We halve the rate if DISP1 paret is PLLD, since actual parent
+ * is plld_out0 which is PLLD divided by 2.
*/
- clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_PERIPH,
- 144 * 1000000);
- clock_start_periph_pll(PERIPH_ID_DISP1, CLOCK_ID_CGENERAL,
- 600 * 1000000);
+ if (priv->dc_clk[1] == CLOCK_ID_DISPLAY)
+ rate /= 2;
+
+ /*
+ * HOST1X is init by default at 150MHz with PLLC as parent
+ */
+ clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_CGENERAL,
+ 150 * 1000000);
+ clock_start_periph_pll(priv->dc_clk[0], priv->dc_clk[1],
+ rate);
+
basic_init(&dc->cmd);
basic_init_timer(&dc->disp);
rgb_enable(&dc->com);
@@ -358,6 +366,13 @@ static int tegra_lcd_of_to_plat(struct udevice *dev)
return -EINVAL;
}
+ ret = clock_decode_pair(dev, priv->dc_clk);
+ if (ret < 0) {
+ debug("%s: Cannot decode clocks for '%s' (ret = %d)\n",
+ __func__, dev->name, ret);
+ return -EINVAL;
+ }
+
rgb = fdt_subnode_offset(blob, node, "rgb");
if (rgb < 0) {
debug("%s: Cannot find rgb subnode for '%s' (ret=%d)\n",