[PATCH v2 03/11] video: tegra-dc: get clocks from device tree
Svyatoslav Ryhel
clamor95 at gmail.com
Sun Feb 26 19:19:57 CET 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