From: Svyatoslav Ryhel Date: Mon, 27 Mar 2023 08:11:42 +0000 (+0300) Subject: video: tegra-dc: get clocks from device tree X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=e114f507ece4f5f40bc0e40d7a61084bbc17555e;p=u-boot.git 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 # ASUS TF101 T20 Tested-by: Nicolas Chauvet # Paz00 Tested-by: Andreas Westman Dorcsak # ASUS TF T30 Tested-by: Svyatoslav Ryhel # HTC One X T30 Signed-off-by: Svyatoslav Ryhel --- diff --git a/drivers/video/tegra20/tegra-dc.c b/drivers/video/tegra20/tegra-dc.c index 5e3f6bf029..ff67cc8989 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",