|
| 1 | +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Paolo Sabatino < [email protected]> |
| 3 | +Date: Mon, 29 Apr 2024 16:18:46 +0200 |
| 4 | +Subject: clock entries to accomodate rk3228 HDMI features |
| 5 | + |
| 6 | +--- |
| 7 | + arch/arm/include/asm/arch-rockchip/cru_rk322x.h | 14 + |
| 8 | + drivers/clk/rockchip/clk_rk322x.c | 129 +++++++++- |
| 9 | + 2 files changed, 140 insertions(+), 3 deletions(-) |
| 10 | + |
| 11 | +diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h |
| 12 | +index 111111111111..222222222222 100644 |
| 13 | +--- a/arch/arm/include/asm/arch-rockchip/cru_rk322x.h |
| 14 | ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk322x.h |
| 15 | +@@ -193,6 +193,10 @@ enum { |
| 16 | + /* CRU_CLKSEL27_CON */ |
| 17 | + VOP_DCLK_DIV_SHIFT = 8, |
| 18 | + VOP_DCLK_DIV_MASK = 0xff << VOP_DCLK_DIV_SHIFT, |
| 19 | ++ VOP_DCLK_PLL_SEL_SHIFT = 0, |
| 20 | ++ VOP_DCLK_PLL_SEL_MASK = 1 << VOP_DCLK_PLL_SEL_SHIFT, |
| 21 | ++ VOP_DCLK_SEL_GPLL = 0, |
| 22 | ++ VOP_DCLK_SEL_CPLL = 1, |
| 23 | + VOP_PLL_SEL_SHIFT = 1, |
| 24 | + VOP_PLL_SEL_MASK = 1 << VOP_PLL_SEL_SHIFT, |
| 25 | + |
| 26 | +@@ -200,6 +204,16 @@ enum { |
| 27 | + GMAC_CLK_SRC_SHIFT = 12, |
| 28 | + GMAC_CLK_SRC_MASK = 1 << GMAC_CLK_SRC_SHIFT, |
| 29 | + |
| 30 | ++ /* CRU_CLKSEL33_CON */ |
| 31 | ++ VOP_ACLK_DIV_SHIFT = 0, |
| 32 | ++ VOP_ACLK_DIV_MASK = 0x1f << VOP_ACLK_DIV_SHIFT, |
| 33 | ++ VOP_ACLK_PLL_SEL_SHIFT = 5, |
| 34 | ++ VOP_ACLK_PLL_SEL_MASK = 3 << VOP_ACLK_PLL_SEL_SHIFT, |
| 35 | ++ VOP_ACLK_SEL_CPLL = 0, |
| 36 | ++ VOP_ACLK_SEL_GPLL = 1, |
| 37 | ++ VOP_ACLK_SEL_HDMIPHY = 2, |
| 38 | ++ VOP_ACLK_SEL_USBPHY = 3, |
| 39 | ++ |
| 40 | + /* CRU_SOFTRST5_CON */ |
| 41 | + DDRCTRL_PSRST_SHIFT = 11, |
| 42 | + DDRCTRL_SRST_SHIFT = 10, |
| 43 | +diff --git a/drivers/clk/rockchip/clk_rk322x.c b/drivers/clk/rockchip/clk_rk322x.c |
| 44 | +index 111111111111..222222222222 100644 |
| 45 | +--- a/drivers/clk/rockchip/clk_rk322x.c |
| 46 | ++++ b/drivers/clk/rockchip/clk_rk322x.c |
| 47 | +@@ -367,6 +367,14 @@ static ulong rk322x_clk_get_rate(struct clk *clk) |
| 48 | + case SCLK_SDMMC: |
| 49 | + rate = rockchip_mmc_get_clk(priv->cru, gclk_rate, clk->id); |
| 50 | + break; |
| 51 | ++ case SCLK_HDMI_PHY: |
| 52 | ++ case PCLK_HDMI_PHY: |
| 53 | ++ case DCLK_HDMI_PHY: |
| 54 | ++ case SCLK_HDMI_HDCP: |
| 55 | ++ case PCLK_HDMI_CTRL: |
| 56 | ++ case SCLK_HDMI_CEC: |
| 57 | ++ printf("Attempt to get clk id %ld\n", clk->id); |
| 58 | ++ return 0; |
| 59 | + default: |
| 60 | + return -ENOENT; |
| 61 | + } |
| 62 | +@@ -374,6 +382,68 @@ static ulong rk322x_clk_get_rate(struct clk *clk) |
| 63 | + return rate; |
| 64 | + } |
| 65 | + |
| 66 | ++#ifndef CONFIG_SPL_BUILD |
| 67 | ++static ulong rk3228_vop_get_clk(struct rk322x_cru *cru, ulong clk_id) |
| 68 | ++{ |
| 69 | ++ u32 div, con, parent; |
| 70 | ++ |
| 71 | ++ switch (clk_id) { |
| 72 | ++ case DCLK_VOP: |
| 73 | ++ con = readl(&cru->cru_clksel_con[27]); |
| 74 | ++ div = (con & VOP_DCLK_DIV_MASK) >> VOP_DCLK_DIV_SHIFT; |
| 75 | ++ parent = GPLL_HZ; |
| 76 | ++ break; |
| 77 | ++ case ACLK_VOP: |
| 78 | ++ con = readl(&cru->cru_clksel_con[33]); |
| 79 | ++ div = (con & VOP_ACLK_DIV_MASK) >> VOP_ACLK_DIV_SHIFT; |
| 80 | ++ parent = GPLL_HZ; |
| 81 | ++ break; |
| 82 | ++ default: |
| 83 | ++ debug("%s: Unsupported vop get clk#%ld\n", __func__, clk_id); |
| 84 | ++ return -ENOENT; |
| 85 | ++ } |
| 86 | ++ |
| 87 | ++ return DIV_TO_RATE(parent, div); |
| 88 | ++} |
| 89 | ++ |
| 90 | ++static ulong rk3228_vop_set_clk(struct rk322x_cru *cru, |
| 91 | ++ ulong clk_id, uint hz) |
| 92 | ++{ |
| 93 | ++ int src_clk_div; |
| 94 | ++ |
| 95 | ++ src_clk_div = DIV_ROUND_UP(GPLL_HZ, hz); |
| 96 | ++ assert(src_clk_div - 1 < 31); |
| 97 | ++ |
| 98 | ++ switch (clk_id) { |
| 99 | ++ case DCLK_VOP: |
| 100 | ++ |
| 101 | ++ /* |
| 102 | ++ * Set HDMI parent clock to HDMIPHY. Normally, this is done |
| 103 | ++ * by .set_parent, but u-boot does not seem to work well with |
| 104 | ++ * device tree references |
| 105 | ++ */ |
| 106 | ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), 0); |
| 107 | ++ |
| 108 | ++ rk_clrsetreg(&cru->cru_clksel_con[27], |
| 109 | ++ VOP_DCLK_DIV_MASK | VOP_DCLK_PLL_SEL_MASK, |
| 110 | ++ VOP_DCLK_SEL_GPLL << VOP_DCLK_PLL_SEL_SHIFT | |
| 111 | ++ (src_clk_div - 1) << VOP_DCLK_DIV_SHIFT); |
| 112 | ++ break; |
| 113 | ++ case ACLK_VOP: |
| 114 | ++ rk_clrsetreg(&cru->cru_clksel_con[33], |
| 115 | ++ VOP_ACLK_DIV_MASK | VOP_ACLK_PLL_SEL_MASK, |
| 116 | ++ VOP_ACLK_SEL_GPLL << VOP_ACLK_PLL_SEL_SHIFT | |
| 117 | ++ (src_clk_div - 1) << VOP_ACLK_DIV_SHIFT); |
| 118 | ++ break; |
| 119 | ++ default: |
| 120 | ++ printf("%s: Unable to set vop clk#%ld\n", __func__, clk_id); |
| 121 | ++ return -EINVAL; |
| 122 | ++ } |
| 123 | ++ |
| 124 | ++ return rk3228_vop_get_clk(cru, clk_id); |
| 125 | ++} |
| 126 | ++#endif |
| 127 | ++ |
| 128 | + static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) |
| 129 | + { |
| 130 | + struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); |
| 131 | +@@ -395,7 +465,29 @@ static ulong rk322x_clk_set_rate(struct clk *clk, ulong rate) |
| 132 | + new_rate = rk322x_mac_set_clk(priv->cru, rate); |
| 133 | + break; |
| 134 | + case PLL_GPLL: |
| 135 | +- return 0; |
| 136 | ++ case PLL_CPLL: |
| 137 | ++ case ACLK_PERI: |
| 138 | ++ case HCLK_PERI: |
| 139 | ++ case PCLK_PERI: |
| 140 | ++ case ACLK_CPU: |
| 141 | ++ case HCLK_CPU: |
| 142 | ++ case PCLK_CPU: |
| 143 | ++ case ARMCLK: |
| 144 | ++ case SCLK_HDMI_PHY: |
| 145 | ++ case PCLK_HDMI_PHY: |
| 146 | ++ case DCLK_HDMI_PHY: |
| 147 | ++ case SCLK_HDMI_HDCP: |
| 148 | ++ case PCLK_HDMI_CTRL: |
| 149 | ++ case SCLK_HDMI_CEC: |
| 150 | ++ debug("Attempt to set clkid %ld, rate=%ld\n", clk->id, rate); |
| 151 | ++ return rate; |
| 152 | ++#ifndef CONFIG_SPL_BUILD |
| 153 | ++ case ACLK_VOP: |
| 154 | ++ case DCLK_VOP: |
| 155 | ++ debug("VOP set rate clkid %ld, rate=%ld\n", clk->id, rate); |
| 156 | ++ rate = rk3228_vop_set_clk(priv->cru, clk->id, rate); |
| 157 | ++ break; |
| 158 | ++#endif |
| 159 | + default: |
| 160 | + return -ENOENT; |
| 161 | + } |
| 162 | +@@ -456,13 +548,44 @@ static int rk322x_gmac_extclk_set_parent(struct clk *clk, struct clk *parent) |
| 163 | + return -EINVAL; |
| 164 | + } |
| 165 | + |
| 166 | ++static int rk322x_hdmi_set_parent(struct clk *clk, struct clk *parent) |
| 167 | ++{ |
| 168 | ++ struct rk322x_clk_priv *priv = dev_get_priv(clk->dev); |
| 169 | ++ const char *clock_output_name; |
| 170 | ++ struct rk322x_cru *cru = priv->cru; |
| 171 | ++ int ret; |
| 172 | ++ |
| 173 | ++ ret = dev_read_string_index(parent->dev, "clock-output-names", |
| 174 | ++ parent->id, &clock_output_name); |
| 175 | ++ if (ret < 0) |
| 176 | ++ return -ENODATA; |
| 177 | ++ |
| 178 | ++ if (!strcmp(clock_output_name, "hdmiphy_phy")) { |
| 179 | ++ debug("%s: switching hdmi_sclk to hdmiphy_phy\n", __func__); |
| 180 | ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), 0); |
| 181 | ++ return 0; |
| 182 | ++ } else if (!strcmp(clock_output_name, "xin24m")) { |
| 183 | ++ debug("%s: switching hdmi_sclk to xin24m\n", __func__); |
| 184 | ++ rk_clrsetreg(&cru->cru_misc_con, BIT(13), BIT(13)); |
| 185 | ++ return 0; |
| 186 | ++ } |
| 187 | ++ |
| 188 | ++ return -EINVAL; |
| 189 | ++ |
| 190 | ++} |
| 191 | ++ |
| 192 | + static int rk322x_clk_set_parent(struct clk *clk, struct clk *parent) |
| 193 | + { |
| 194 | ++ |
| 195 | ++ debug("%s, clkid=%ld, parent=%ld\n", __func__, clk->id, parent->id); |
| 196 | ++ |
| 197 | + switch (clk->id) { |
| 198 | + case SCLK_MAC: |
| 199 | + return rk322x_gmac_set_parent(clk, parent); |
| 200 | + case SCLK_MAC_EXTCLK: |
| 201 | + return rk322x_gmac_extclk_set_parent(clk, parent); |
| 202 | ++ case SCLK_HDMI_PHY: |
| 203 | ++ return rk322x_hdmi_set_parent(clk, parent); |
| 204 | + } |
| 205 | + |
| 206 | + debug("%s: unsupported clk %ld\n", __func__, clk->id); |
| 207 | +@@ -520,7 +643,7 @@ static int rk322x_clk_bind(struct udevice *dev) |
| 208 | + debug("Warning: software reset driver bind failed\n"); |
| 209 | + #endif |
| 210 | + |
| 211 | +- return 0; |
| 212 | ++ return ret; |
| 213 | + } |
| 214 | + |
| 215 | + static const struct udevice_id rk322x_clk_ids[] = { |
| 216 | +@@ -529,7 +652,7 @@ static const struct udevice_id rk322x_clk_ids[] = { |
| 217 | + }; |
| 218 | + |
| 219 | + U_BOOT_DRIVER(rockchip_rk322x_cru) = { |
| 220 | +- .name = "clk_rk322x", |
| 221 | ++ .name = "rockchip_rk322x_cru", |
| 222 | + .id = UCLASS_CLK, |
| 223 | + .of_match = rk322x_clk_ids, |
| 224 | + .priv_auto = sizeof(struct rk322x_clk_priv), |
| 225 | +-- |
| 226 | +Armbian |
| 227 | + |
0 commit comments