[PATCH v3 03/11] video: tegra-dc: get clocks from device tree

Svyatoslav Ryhel clamor95 at gmail.com
Mon Mar 27 10:11:42 CEST 2023


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 at gmail.com> # ASUS TF101 T20
Tested-by: Nicolas Chauvet <kwizart at gmail.com> # Paz00
Tested-by: Andreas Westman Dorcsak <hedmoo at yahoo.com> # ASUS TF T30
Tested-by: Svyatoslav Ryhel <clamor95 at gmail.com> # HTC One X T30
Signed-off-by: Svyatoslav Ryhel <clamor95 at gmail.com>
---
 drivers/video/tegra20/tegra-dc.c | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

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",
-- 
2.37.2



More information about the U-Boot mailing list