diff options
| author | Tom Rini <[email protected]> | 2024-04-21 08:54:20 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2024-04-21 08:54:20 -0600 |
| commit | 1dd659fd626204bb6a6b4f330c27b11a7823bbb0 (patch) | |
| tree | 44a012a0d9503033a6eca2e158b7ad4273644013 /drivers/clk | |
| parent | c08685289171e68afd4bae2eb2e279cdc49a407d (diff) | |
| parent | efe1ceec7ef0c2ce2344dbe066fca0d389a0b4f3 (diff) | |
Merge tag 'video-20240421' of https://source.denx.de/u-boot/custodians/u-boot-video
CI: https://source.denx.de/u-boot/custodians/u-boot-video/-/pipelines/20466
- simple_panel: support timing parsing from EDID
- dw_hdmi: fix gcc-14 compiler warnings
- dw_hdmi: support vendor PHY for HDMI
- rockchip: add Rockchip INNO HDMI PHY driver
- rockchip: RK3328 HDMI and VOP support
- evb-rk3328: enable vidconsole support
- Tegra DC and DSI improvements and Tegra 114 support
- add LG LG070WX3 MIPI DSI panel driver
- add Samsung LTL106HL02 MIPI DSI panel driver
- add Toshiba TC358768 RGB to DSI bridge support
- add basic support for the Parade DP501 transmitter
- Tegra 3 panel and bridge driver improvements
- simplefb: modernise DT parsing
- fdt_simplefb: Enumerate framebuffer info from video handoff
- preserve framebuffer if SPL is passing video hand-off
- fdt_support: allow reserving FB region without simplefb
Diffstat (limited to 'drivers/clk')
| -rw-r--r-- | drivers/clk/rockchip/clk_rk3328.c | 105 |
1 files changed, 103 insertions, 2 deletions
diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c index cfec1d974ac..87075ec7134 100644 --- a/drivers/clk/rockchip/clk_rk3328.c +++ b/drivers/clk/rockchip/clk_rk3328.c @@ -178,6 +178,10 @@ enum { CLK_I2C3_DIV_CON_SHIFT = 8, CLK_I2C2_PLL_SEL_SHIFT = 7, CLK_I2C2_DIV_CON_SHIFT = 0, + + /* CLKSEL_CON40 */ + CLK_HDMIPHY_DIV_CON_SHIFT = 3, + CLK_HDMIPHY_DIV_CON_MASK = 0x7 << CLK_HDMIPHY_DIV_CON_SHIFT, }; #define VCO_MAX_KHZ (3200 * (MHz / KHz)) @@ -580,6 +584,96 @@ static ulong rk3328_spi_set_clk(struct rk3328_cru *cru, uint hz) return rk3328_spi_get_clk(cru); } +#ifndef CONFIG_SPL_BUILD +static ulong rk3328_vop_get_clk(struct rk3328_clk_priv *priv, ulong clk_id) +{ + struct rk3328_cru *cru = priv->cru; + u32 div, con, parent; + + switch (clk_id) { + case ACLK_VOP_PRE: + con = readl(&cru->clksel_con[39]); + div = (con & ACLK_VOP_DIV_CON_MASK) >> ACLK_VOP_DIV_CON_SHIFT; + parent = GPLL_HZ; + break; + case ACLK_VIO_PRE: + con = readl(&cru->clksel_con[37]); + div = (con & ACLK_VIO_DIV_CON_MASK) >> ACLK_VIO_DIV_CON_SHIFT; + parent = GPLL_HZ; + break; + case DCLK_LCDC: + con = readl(&cru->clksel_con[40]); + div = (con & DCLK_LCDC_DIV_CON_MASK) >> DCLK_LCDC_DIV_CON_SHIFT; + parent = GPLL_HZ; + break; + default: + printf("%s: Unsupported vop get clk#%ld\n", __func__, clk_id); + return -ENOENT; + } + + return DIV_TO_RATE(parent, div); +} + +static ulong rk3328_vop_set_clk(struct rk3328_clk_priv *priv, + ulong clk_id, uint hz) +{ + struct rk3328_cru *cru = priv->cru; + int src_clk_div; + u32 con, parent; + + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); + assert(src_clk_div - 1 < 31); + + switch (clk_id) { + case ACLK_VOP_PRE: + rk_clrsetreg(&cru->clksel_con[39], + ACLK_VOP_PLL_SEL_MASK | ACLK_VOP_DIV_CON_MASK, + ACLK_VOP_PLL_SEL_CPLL << ACLK_VOP_PLL_SEL_SHIFT | + (src_clk_div - 1) << ACLK_VOP_DIV_CON_SHIFT); + break; + case ACLK_VIO_PRE: + rk_clrsetreg(&cru->clksel_con[37], + ACLK_VIO_PLL_SEL_MASK | ACLK_VIO_DIV_CON_MASK, + ACLK_VIO_PLL_SEL_CPLL << ACLK_VIO_PLL_SEL_SHIFT | + (src_clk_div - 1) << ACLK_VIO_DIV_CON_SHIFT); + break; + case DCLK_LCDC: + con = readl(&cru->clksel_con[40]); + con = (con & DCLK_LCDC_SEL_MASK) >> DCLK_LCDC_SEL_SHIFT; + if (con) { + parent = readl(&cru->clksel_con[40]); + parent = (parent & DCLK_LCDC_PLL_SEL_MASK) >> + DCLK_LCDC_PLL_SEL_SHIFT; + if (parent) + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); + else + src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); + + rk_clrsetreg(&cru->clksel_con[40], + DCLK_LCDC_DIV_CON_MASK, + (src_clk_div - 1) << + DCLK_LCDC_DIV_CON_SHIFT); + } + break; + default: + printf("%s: Unable to set vop clk#%ld\n", __func__, clk_id); + return -EINVAL; + } + + return rk3328_vop_get_clk(priv, clk_id); +} +#endif + +static ulong rk3328_hdmiphy_get_clk(struct rk3328_cru *cru) +{ + u32 div, con; + + con = readl(&cru->clksel_con[40]); + div = (con & CLK_HDMIPHY_DIV_CON_MASK) >> CLK_HDMIPHY_DIV_CON_SHIFT; + + return DIV_TO_RATE(GPLL_HZ, div); +} + static ulong rk3328_clk_get_rate(struct clk *clk) { struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); @@ -609,6 +703,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk) case SCLK_SPI: rate = rk3328_spi_get_clk(priv->cru); break; + case PCLK_HDMIPHY: + rate = rk3328_hdmiphy_get_clk(priv->cru); + break; default: return -ENOENT; } @@ -648,7 +745,13 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) case SCLK_SPI: ret = rk3328_spi_set_clk(priv->cru, rate); break; +#ifndef CONFIG_SPL_BUILD case DCLK_LCDC: + case ACLK_VOP_PRE: + case ACLK_VIO_PRE: + rate = rk3328_vop_set_clk(priv, clk->id, rate); + break; +#endif case SCLK_PDM: case SCLK_RTC32K: case SCLK_UART0: @@ -663,11 +766,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) case ACLK_PERI_PRE: case HCLK_PERI: case PCLK_PERI: - case ACLK_VIO_PRE: case HCLK_VIO_PRE: case ACLK_RGA_PRE: case SCLK_RGA: - case ACLK_VOP_PRE: case ACLK_RKVDEC_PRE: case ACLK_RKVENC: case ACLK_VPU_PRE: |
