* [PATCH v1 0/2] clk: rockchip: rk3568: add clock driver @ 2021-05-19 8:49 Elaine at denx.de 2021-05-19 8:49 ` [PATCH v1 1/2] rockchip: rk3568: add device tree file Elaine at denx.de 2021-05-19 8:49 ` [PATCH v1 2/2] rockchip: rk3568: add clock driver Elaine at denx.de 0 siblings, 2 replies; 5+ messages in thread From: Elaine at denx.de @ 2021-05-19 8:49 UTC (permalink / raw) To: u-boot From: Elaine Zhang <zhangqing@rock-chips.com> Add basic clock for rk3568 which including cpu, bus, mmc, i2c, pwm, gmac ...clocks init. Elaine Zhang (2): rockchip: rk3568: add device tree file rockchip: rk3568: add clock driver .../include/asm/arch-rockchip/cru_rk3568.h | 504 +++ drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk_rk3568.c | 2908 +++++++++++++++++ include/dt-bindings/clock/rk3568-cru.h | 925 ++++++ 4 files changed, 4338 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3568.h create mode 100644 drivers/clk/rockchip/clk_rk3568.c create mode 100644 include/dt-bindings/clock/rk3568-cru.h -- 2.17.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 1/2] rockchip: rk3568: add device tree file 2021-05-19 8:49 [PATCH v1 0/2] clk: rockchip: rk3568: add clock driver Elaine at denx.de @ 2021-05-19 8:49 ` Elaine at denx.de 2021-05-21 13:22 ` Kever Yang 2021-05-19 8:49 ` [PATCH v1 2/2] rockchip: rk3568: add clock driver Elaine at denx.de 1 sibling, 1 reply; 5+ messages in thread From: Elaine at denx.de @ 2021-05-19 8:49 UTC (permalink / raw) To: u-boot From: Elaine Zhang <zhangqing@rock-chips.com> Add dts binding header for rk3568, files origin from kernel. Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> --- include/dt-bindings/clock/rk3568-cru.h | 925 +++++++++++++++++++++++++ 1 file changed, 925 insertions(+) create mode 100644 include/dt-bindings/clock/rk3568-cru.h diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h new file mode 100644 index 000000000000..c1942422a438 --- /dev/null +++ b/include/dt-bindings/clock/rk3568-cru.h @@ -0,0 +1,925 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H + +/* pmucru-clocks indices */ + +/* pmucru plls */ +#define PLL_PPLL 1 +#define PLL_HPLL 2 + +/* pmucru clocks */ +#define XIN_OSC0_DIV 4 +#define CLK_RTC_32K 5 +#define CLK_PMU 6 +#define CLK_I2C0 7 +#define CLK_RTC32K_FRAC 8 +#define CLK_UART0_DIV 9 +#define CLK_UART0_FRAC 10 +#define SCLK_UART0 11 +#define DBCLK_GPIO0 12 +#define CLK_PWM0 13 +#define CLK_CAPTURE_PWM0_NDFT 14 +#define CLK_PMUPVTM 15 +#define CLK_CORE_PMUPVTM 16 +#define CLK_REF24M 17 +#define XIN_OSC0_USBPHY0_G 18 +#define CLK_USBPHY0_REF 19 +#define XIN_OSC0_USBPHY1_G 20 +#define CLK_USBPHY1_REF 21 +#define XIN_OSC0_MIPIDSIPHY0_G 22 +#define CLK_MIPIDSIPHY0_REF 23 +#define XIN_OSC0_MIPIDSIPHY1_G 24 +#define CLK_MIPIDSIPHY1_REF 25 +#define CLK_WIFI_DIV 26 +#define CLK_WIFI_OSC0 27 +#define CLK_WIFI 28 +#define CLK_PCIEPHY0_DIV 29 +#define CLK_PCIEPHY0_OSC0 30 +#define CLK_PCIEPHY0_REF 31 +#define CLK_PCIEPHY1_DIV 32 +#define CLK_PCIEPHY1_OSC0 33 +#define CLK_PCIEPHY1_REF 34 +#define CLK_PCIEPHY2_DIV 35 +#define CLK_PCIEPHY2_OSC0 36 +#define CLK_PCIEPHY2_REF 37 +#define CLK_PCIE30PHY_REF_M 38 +#define CLK_PCIE30PHY_REF_N 39 +#define CLK_HDMI_REF 40 +#define XIN_OSC0_EDPPHY_G 41 +#define PCLK_PDPMU 42 +#define PCLK_PMU 43 +#define PCLK_UART0 44 +#define PCLK_I2C0 45 +#define PCLK_GPIO0 46 +#define PCLK_PMUPVTM 47 +#define PCLK_PWM0 48 +#define CLK_PDPMU 49 +#define SCLK_32K_IOE 50 + +#define CLKPMU_NR_CLKS (SCLK_32K_IOE + 1) + +/* cru-clocks indices */ + +/* cru plls */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_GPLL 4 +#define PLL_VPLL 5 +#define PLL_NPLL 6 + +/* cru clocks */ +#define CPLL_333M 9 +#define ARMCLK 10 +#define USB480M 11 +#define ACLK_CORE_NIU2BUS 18 +#define CLK_CORE_PVTM 19 +#define CLK_CORE_PVTM_CORE 20 +#define CLK_CORE_PVTPLL 21 +#define CLK_GPU_SRC 22 +#define CLK_GPU_PRE_NDFT 23 +#define CLK_GPU_PRE_MUX 24 +#define ACLK_GPU_PRE 25 +#define PCLK_GPU_PRE 26 +#define CLK_GPU 27 +#define CLK_GPU_NP5 28 +#define PCLK_GPU_PVTM 29 +#define CLK_GPU_PVTM 30 +#define CLK_GPU_PVTM_CORE 31 +#define CLK_GPU_PVTPLL 32 +#define CLK_NPU_SRC 33 +#define CLK_NPU_PRE_NDFT 34 +#define CLK_NPU 35 +#define CLK_NPU_NP5 36 +#define HCLK_NPU_PRE 37 +#define PCLK_NPU_PRE 38 +#define ACLK_NPU_PRE 39 +#define ACLK_NPU 40 +#define HCLK_NPU 41 +#define PCLK_NPU_PVTM 42 +#define CLK_NPU_PVTM 43 +#define CLK_NPU_PVTM_CORE 44 +#define CLK_NPU_PVTPLL 45 +#define CLK_DDRPHY1X_SRC 46 +#define CLK_DDRPHY1X_HWFFC_SRC 47 +#define CLK_DDR1X 48 +#define CLK_MSCH 49 +#define CLK24_DDRMON 50 +#define ACLK_GIC_AUDIO 51 +#define HCLK_GIC_AUDIO 52 +#define HCLK_SDMMC_BUFFER 53 +#define DCLK_SDMMC_BUFFER 54 +#define ACLK_GIC600 55 +#define ACLK_SPINLOCK 56 +#define HCLK_I2S0_8CH 57 +#define HCLK_I2S1_8CH 58 +#define HCLK_I2S2_2CH 59 +#define HCLK_I2S3_2CH 60 +#define CLK_I2S0_8CH_TX_SRC 61 +#define CLK_I2S0_8CH_TX_FRAC 62 +#define MCLK_I2S0_8CH_TX 63 +#define I2S0_MCLKOUT_TX 64 +#define CLK_I2S0_8CH_RX_SRC 65 +#define CLK_I2S0_8CH_RX_FRAC 66 +#define MCLK_I2S0_8CH_RX 67 +#define I2S0_MCLKOUT_RX 68 +#define CLK_I2S1_8CH_TX_SRC 69 +#define CLK_I2S1_8CH_TX_FRAC 70 +#define MCLK_I2S1_8CH_TX 71 +#define I2S1_MCLKOUT_TX 72 +#define CLK_I2S1_8CH_RX_SRC 73 +#define CLK_I2S1_8CH_RX_FRAC 74 +#define MCLK_I2S1_8CH_RX 75 +#define I2S1_MCLKOUT_RX 76 +#define CLK_I2S2_2CH_SRC 77 +#define CLK_I2S2_2CH_FRAC 78 +#define MCLK_I2S2_2CH 79 +#define I2S2_MCLKOUT 80 +#define CLK_I2S3_2CH_TX_SRC 81 +#define CLK_I2S3_2CH_TX_FRAC 82 +#define MCLK_I2S3_2CH_TX 83 +#define I2S3_MCLKOUT_TX 84 +#define CLK_I2S3_2CH_RX_SRC 85 +#define CLK_I2S3_2CH_RX_FRAC 86 +#define MCLK_I2S3_2CH_RX 87 +#define I2S3_MCLKOUT_RX 88 +#define HCLK_PDM 89 +#define MCLK_PDM 90 +#define HCLK_VAD 91 +#define HCLK_SPDIF_8CH 92 +#define MCLK_SPDIF_8CH_SRC 93 +#define MCLK_SPDIF_8CH_FRAC 94 +#define MCLK_SPDIF_8CH 95 +#define HCLK_AUDPWM 96 +#define SCLK_AUDPWM_SRC 97 +#define SCLK_AUDPWM_FRAC 98 +#define SCLK_AUDPWM 99 +#define HCLK_ACDCDIG 100 +#define CLK_ACDCDIG_I2C 101 +#define CLK_ACDCDIG_DAC 102 +#define CLK_ACDCDIG_ADC 103 +#define ACLK_SECURE_FLASH 104 +#define HCLK_SECURE_FLASH 105 +#define ACLK_CRYPTO_NS 106 +#define HCLK_CRYPTO_NS 107 +#define CLK_CRYPTO_NS_CORE 108 +#define CLK_CRYPTO_NS_PKA 109 +#define CLK_CRYPTO_NS_RNG 110 +#define HCLK_TRNG_NS 111 +#define CLK_TRNG_NS 112 +#define PCLK_OTPC_NS 113 +#define CLK_OTPC_NS_SBPI 114 +#define CLK_OTPC_NS_USR 115 +#define HCLK_NANDC 116 +#define NCLK_NANDC 117 +#define HCLK_SFC 118 +#define HCLK_SFC_XIP 119 +#define SCLK_SFC 120 +#define ACLK_EMMC 121 +#define HCLK_EMMC 122 +#define BCLK_EMMC 123 +#define CCLK_EMMC 124 +#define TCLK_EMMC 125 +#define ACLK_PIPE 126 +#define PCLK_PIPE 127 +#define PCLK_PIPE_GRF 128 +#define ACLK_PCIE20_MST 129 +#define ACLK_PCIE20_SLV 130 +#define ACLK_PCIE20_DBI 131 +#define PCLK_PCIE20 132 +#define CLK_PCIE20_AUX_NDFT 133 +#define CLK_PCIE20_AUX_DFT 134 +#define CLK_PCIE20_PIPE_DFT 135 +#define ACLK_PCIE30X1_MST 136 +#define ACLK_PCIE30X1_SLV 137 +#define ACLK_PCIE30X1_DBI 138 +#define PCLK_PCIE30X1 139 +#define CLK_PCIE30X1_AUX_NDFT 140 +#define CLK_PCIE30X1_AUX_DFT 141 +#define CLK_PCIE30X1_PIPE_DFT 142 +#define ACLK_PCIE30X2_MST 143 +#define ACLK_PCIE30X2_SLV 144 +#define ACLK_PCIE30X2_DBI 145 +#define PCLK_PCIE30X2 146 +#define CLK_PCIE30X2_AUX_NDFT 147 +#define CLK_PCIE30X2_AUX_DFT 148 +#define CLK_PCIE30X2_PIPE_DFT 149 +#define ACLK_SATA0 150 +#define CLK_SATA0_PMALIVE 151 +#define CLK_SATA0_RXOOB 152 +#define CLK_SATA0_PIPE_NDFT 153 +#define CLK_SATA0_PIPE_DFT 154 +#define ACLK_SATA1 155 +#define CLK_SATA1_PMALIVE 156 +#define CLK_SATA1_RXOOB 157 +#define CLK_SATA1_PIPE_NDFT 158 +#define CLK_SATA1_PIPE_DFT 159 +#define ACLK_SATA2 160 +#define CLK_SATA2_PMALIVE 161 +#define CLK_SATA2_RXOOB 162 +#define CLK_SATA2_PIPE_NDFT 163 +#define CLK_SATA2_PIPE_DFT 164 +#define ACLK_USB3OTG0 165 +#define CLK_USB3OTG0_REF 166 +#define CLK_USB3OTG0_SUSPEND 167 +#define ACLK_USB3OTG1 168 +#define CLK_USB3OTG1_REF 169 +#define CLK_USB3OTG1_SUSPEND 170 +#define CLK_XPCS_EEE 171 +#define PCLK_XPCS 172 +#define ACLK_PHP 173 +#define HCLK_PHP 174 +#define PCLK_PHP 175 +#define HCLK_SDMMC0 176 +#define CLK_SDMMC0 177 +#define HCLK_SDMMC1 178 +#define CLK_SDMMC1 179 +#define ACLK_GMAC0 180 +#define PCLK_GMAC0 181 +#define CLK_MAC0_2TOP 182 +#define CLK_MAC0_OUT 183 +#define CLK_MAC0_REFOUT 184 +#define CLK_GMAC0_PTP_REF 185 +#define ACLK_USB 186 +#define HCLK_USB 187 +#define PCLK_USB 188 +#define HCLK_USB2HOST0 189 +#define HCLK_USB2HOST0_ARB 190 +#define HCLK_USB2HOST1 191 +#define HCLK_USB2HOST1_ARB 192 +#define HCLK_SDMMC2 193 +#define CLK_SDMMC2 194 +#define ACLK_GMAC1 195 +#define PCLK_GMAC1 196 +#define CLK_MAC1_2TOP 197 +#define CLK_MAC1_OUT 198 +#define CLK_MAC1_REFOUT 199 +#define CLK_GMAC1_PTP_REF 200 +#define ACLK_PERIMID 201 +#define HCLK_PERIMID 202 +#define ACLK_VI 203 +#define HCLK_VI 204 +#define PCLK_VI 205 +#define ACLK_VICAP 206 +#define HCLK_VICAP 207 +#define DCLK_VICAP 208 +#define ICLK_VICAP_G 209 +#define ACLK_ISP 210 +#define HCLK_ISP 211 +#define CLK_ISP 212 +#define PCLK_CSI2HOST1 213 +#define CLK_CIF_OUT 214 +#define CLK_CAM0_OUT 215 +#define CLK_CAM1_OUT 216 +#define ACLK_VO 217 +#define HCLK_VO 218 +#define PCLK_VO 219 +#define ACLK_VOP_PRE 220 +#define ACLK_VOP 221 +#define HCLK_VOP 222 +#define DCLK_VOP0 223 +#define DCLK_VOP1 224 +#define DCLK_VOP2 225 +#define CLK_VOP_PWM 226 +#define ACLK_HDCP 227 +#define HCLK_HDCP 228 +#define PCLK_HDCP 229 +#define PCLK_HDMI_HOST 230 +#define CLK_HDMI_SFR 231 +#define PCLK_DSITX_0 232 +#define PCLK_DSITX_1 233 +#define PCLK_EDP_CTRL 234 +#define CLK_EDP_200M 235 +#define ACLK_VPU_PRE 236 +#define HCLK_VPU_PRE 237 +#define ACLK_VPU 238 +#define HCLK_VPU 239 +#define ACLK_RGA_PRE 240 +#define HCLK_RGA_PRE 241 +#define PCLK_RGA_PRE 242 +#define ACLK_RGA 243 +#define HCLK_RGA 244 +#define CLK_RGA_CORE 245 +#define ACLK_IEP 246 +#define HCLK_IEP 247 +#define CLK_IEP_CORE 248 +#define HCLK_EBC 249 +#define DCLK_EBC 250 +#define ACLK_JDEC 251 +#define HCLK_JDEC 252 +#define ACLK_JENC 253 +#define HCLK_JENC 254 +#define PCLK_EINK 255 +#define HCLK_EINK 256 +#define ACLK_RKVENC_PRE 257 +#define HCLK_RKVENC_PRE 258 +#define ACLK_RKVENC 259 +#define HCLK_RKVENC 260 +#define CLK_RKVENC_CORE 261 +#define ACLK_RKVDEC_PRE 262 +#define HCLK_RKVDEC_PRE 263 +#define ACLK_RKVDEC 264 +#define HCLK_RKVDEC 265 +#define CLK_RKVDEC_CA 266 +#define CLK_RKVDEC_CORE 267 +#define CLK_RKVDEC_HEVC_CA 268 +#define ACLK_BUS 269 +#define PCLK_BUS 270 +#define PCLK_TSADC 271 +#define CLK_TSADC_TSEN 272 +#define CLK_TSADC 273 +#define PCLK_SARADC 274 +#define CLK_SARADC 275 +#define PCLK_SCR 276 +#define PCLK_WDT_NS 277 +#define TCLK_WDT_NS 278 +#define ACLK_DMAC0 279 +#define ACLK_DMAC1 280 +#define ACLK_MCU 281 +#define PCLK_INTMUX 282 +#define PCLK_MAILBOX 283 +#define PCLK_UART1 284 +#define CLK_UART1_SRC 285 +#define CLK_UART1_FRAC 286 +#define SCLK_UART1 287 +#define PCLK_UART2 288 +#define CLK_UART2_SRC 289 +#define CLK_UART2_FRAC 290 +#define SCLK_UART2 291 +#define PCLK_UART3 292 +#define CLK_UART3_SRC 293 +#define CLK_UART3_FRAC 294 +#define SCLK_UART3 295 +#define PCLK_UART4 296 +#define CLK_UART4_SRC 297 +#define CLK_UART4_FRAC 298 +#define SCLK_UART4 299 +#define PCLK_UART5 300 +#define CLK_UART5_SRC 301 +#define CLK_UART5_FRAC 302 +#define SCLK_UART5 303 +#define PCLK_UART6 304 +#define CLK_UART6_SRC 305 +#define CLK_UART6_FRAC 306 +#define SCLK_UART6 307 +#define PCLK_UART7 308 +#define CLK_UART7_SRC 309 +#define CLK_UART7_FRAC 310 +#define SCLK_UART7 311 +#define PCLK_UART8 312 +#define CLK_UART8_SRC 313 +#define CLK_UART8_FRAC 314 +#define SCLK_UART8 315 +#define PCLK_UART9 316 +#define CLK_UART9_SRC 317 +#define CLK_UART9_FRAC 318 +#define SCLK_UART9 319 +#define PCLK_CAN0 320 +#define CLK_CAN0 321 +#define PCLK_CAN1 322 +#define CLK_CAN1 323 +#define PCLK_CAN2 324 +#define CLK_CAN2 325 +#define CLK_I2C 326 +#define PCLK_I2C1 327 +#define CLK_I2C1 328 +#define PCLK_I2C2 329 +#define CLK_I2C2 330 +#define PCLK_I2C3 331 +#define CLK_I2C3 332 +#define PCLK_I2C4 333 +#define CLK_I2C4 334 +#define PCLK_I2C5 335 +#define CLK_I2C5 336 +#define PCLK_SPI0 337 +#define CLK_SPI0 338 +#define PCLK_SPI1 339 +#define CLK_SPI1 340 +#define PCLK_SPI2 341 +#define CLK_SPI2 342 +#define PCLK_SPI3 343 +#define CLK_SPI3 344 +#define PCLK_PWM1 345 +#define CLK_PWM1 346 +#define CLK_PWM1_CAPTURE 347 +#define PCLK_PWM2 348 +#define CLK_PWM2 349 +#define CLK_PWM2_CAPTURE 350 +#define PCLK_PWM3 351 +#define CLK_PWM3 352 +#define CLK_PWM3_CAPTURE 353 +#define DBCLK_GPIO 354 +#define PCLK_GPIO1 355 +#define DBCLK_GPIO1 356 +#define PCLK_GPIO2 357 +#define DBCLK_GPIO2 358 +#define PCLK_GPIO3 359 +#define DBCLK_GPIO3 360 +#define PCLK_GPIO4 361 +#define DBCLK_GPIO4 362 +#define OCC_SCAN_CLK_GPIO 363 +#define PCLK_TIMER 364 +#define CLK_TIMER0 365 +#define CLK_TIMER1 366 +#define CLK_TIMER2 367 +#define CLK_TIMER3 368 +#define CLK_TIMER4 369 +#define CLK_TIMER5 370 +#define ACLK_TOP_HIGH 371 +#define ACLK_TOP_LOW 372 +#define HCLK_TOP 373 +#define PCLK_TOP 374 +#define PCLK_PCIE30PHY 375 +#define CLK_OPTC_ARB 376 +#define PCLK_MIPICSIPHY 377 +#define PCLK_MIPIDSIPHY0 378 +#define PCLK_MIPIDSIPHY1 379 +#define PCLK_PIPEPHY0 380 +#define PCLK_PIPEPHY1 381 +#define PCLK_PIPEPHY2 382 +#define PCLK_CPU_BOOST 383 +#define CLK_CPU_BOOST 384 +#define PCLK_OTPPHY 385 +#define SCLK_GMAC0 386 +#define SCLK_GMAC0_RGMII_SPEED 387 +#define SCLK_GMAC0_RMII_SPEED 388 +#define SCLK_GMAC0_RX_TX 389 +#define SCLK_GMAC1 390 +#define SCLK_GMAC1_RGMII_SPEED 391 +#define SCLK_GMAC1_RMII_SPEED 392 +#define SCLK_GMAC1_RX_TX 393 +#define SCLK_SDMMC0_DRV 394 +#define SCLK_SDMMC0_SAMPLE 395 +#define SCLK_SDMMC1_DRV 396 +#define SCLK_SDMMC1_SAMPLE 397 +#define SCLK_SDMMC2_DRV 398 +#define SCLK_SDMMC2_SAMPLE 399 +#define SCLK_EMMC_DRV 400 +#define SCLK_EMMC_SAMPLE 401 +#define PCLK_EDPPHY_GRF 402 +#define CLK_HDMI_CEC 403 +#define CLK_I2S0_8CH_TX 404 +#define CLK_I2S0_8CH_RX 405 +#define CLK_I2S1_8CH_TX 406 +#define CLK_I2S1_8CH_RX 407 +#define CLK_I2S2_2CH 408 +#define CLK_I2S3_2CH_TX 409 +#define CLK_I2S3_2CH_RX 410 +#define CPLL_500M 411 +#define CPLL_250M 412 +#define CPLL_125M 413 +#define CPLL_62P5M 414 +#define CPLL_50M 415 +#define CPLL_25M 416 +#define CPLL_100M 417 + +#define PCLK_CORE_PVTM 450 + +#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1) + +/* pmu soft-reset indices */ +/* pmucru_softrst_con0 */ +#define SRST_P_PDPMU_NIU 0 +#define SRST_P_PMUCRU 1 +#define SRST_P_PMUGRF 2 +#define SRST_P_I2C0 3 +#define SRST_I2C0 4 +#define SRST_P_UART0 5 +#define SRST_S_UART0 6 +#define SRST_P_PWM0 7 +#define SRST_PWM0 8 +#define SRST_P_GPIO0 9 +#define SRST_GPIO0 10 +#define SRST_P_PMUPVTM 11 +#define SRST_PMUPVTM 12 + +/* soft-reset indices */ + +/* cru_softrst_con0 */ +#define SRST_NCORERESET0 0 +#define SRST_NCORERESET1 1 +#define SRST_NCORERESET2 2 +#define SRST_NCORERESET3 3 +#define SRST_NCPUPORESET0 4 +#define SRST_NCPUPORESET1 5 +#define SRST_NCPUPORESET2 6 +#define SRST_NCPUPORESET3 7 +#define SRST_NSRESET 8 +#define SRST_NSPORESET 9 +#define SRST_NATRESET 10 +#define SRST_NGICRESET 11 +#define SRST_NPRESET 12 +#define SRST_NPERIPHRESET 13 + +/* cru_softrst_con1 */ +#define SRST_A_CORE_NIU2DDR 16 +#define SRST_A_CORE_NIU2BUS 17 +#define SRST_P_DBG_NIU 18 +#define SRST_P_DBG 19 +#define SRST_P_DBG_DAPLITE 20 +#define SRST_DAP 21 +#define SRST_A_ADB400_CORE2GIC 22 +#define SRST_A_ADB400_GIC2CORE 23 +#define SRST_P_CORE_GRF 24 +#define SRST_P_CORE_PVTM 25 +#define SRST_CORE_PVTM 26 +#define SRST_CORE_PVTPLL 27 + +/* cru_softrst_con2 */ +#define SRST_GPU 32 +#define SRST_A_GPU_NIU 33 +#define SRST_P_GPU_NIU 34 +#define SRST_P_GPU_PVTM 35 +#define SRST_GPU_PVTM 36 +#define SRST_GPU_PVTPLL 37 +#define SRST_A_NPU_NIU 40 +#define SRST_H_NPU_NIU 41 +#define SRST_P_NPU_NIU 42 +#define SRST_A_NPU 43 +#define SRST_H_NPU 44 +#define SRST_P_NPU_PVTM 45 +#define SRST_NPU_PVTM 46 +#define SRST_NPU_PVTPLL 47 + +/* cru_softrst_con3 */ +#define SRST_A_MSCH 51 +#define SRST_HWFFC_CTRL 52 +#define SRST_DDR_ALWAYSON 53 +#define SRST_A_DDRSPLIT 54 +#define SRST_DDRDFI_CTL 55 +#define SRST_A_DMA2DDR 57 + +/* cru_softrst_con4 */ +#define SRST_A_PERIMID_NIU 64 +#define SRST_H_PERIMID_NIU 65 +#define SRST_A_GIC_AUDIO_NIU 66 +#define SRST_H_GIC_AUDIO_NIU 67 +#define SRST_A_GIC600 68 +#define SRST_A_GIC600_DEBUG 69 +#define SRST_A_GICADB_CORE2GIC 70 +#define SRST_A_GICADB_GIC2CORE 71 +#define SRST_A_SPINLOCK 72 +#define SRST_H_SDMMC_BUFFER 73 +#define SRST_D_SDMMC_BUFFER 74 +#define SRST_H_I2S0_8CH 75 +#define SRST_H_I2S1_8CH 76 +#define SRST_H_I2S2_2CH 77 +#define SRST_H_I2S3_2CH 78 + +/* cru_softrst_con5 */ +#define SRST_M_I2S0_8CH_TX 80 +#define SRST_M_I2S0_8CH_RX 81 +#define SRST_M_I2S1_8CH_TX 82 +#define SRST_M_I2S1_8CH_RX 83 +#define SRST_M_I2S2_2CH 84 +#define SRST_M_I2S3_2CH_TX 85 +#define SRST_M_I2S3_2CH_RX 86 +#define SRST_H_PDM 87 +#define SRST_M_PDM 88 +#define SRST_H_VAD 89 +#define SRST_H_SPDIF_8CH 90 +#define SRST_M_SPDIF_8CH 91 +#define SRST_H_AUDPWM 92 +#define SRST_S_AUDPWM 93 +#define SRST_H_ACDCDIG 94 +#define SRST_ACDCDIG 95 + +/* cru_softrst_con6 */ +#define SRST_A_SECURE_FLASH_NIU 96 +#define SRST_H_SECURE_FLASH_NIU 97 +#define SRST_A_CRYPTO_NS 103 +#define SRST_H_CRYPTO_NS 104 +#define SRST_CRYPTO_NS_CORE 105 +#define SRST_CRYPTO_NS_PKA 106 +#define SRST_CRYPTO_NS_RNG 107 +#define SRST_H_TRNG_NS 108 +#define SRST_TRNG_NS 109 + +/* cru_softrst_con7 */ +#define SRST_H_NANDC 112 +#define SRST_N_NANDC 113 +#define SRST_H_SFC 114 +#define SRST_H_SFC_XIP 115 +#define SRST_S_SFC 116 +#define SRST_A_EMMC 117 +#define SRST_H_EMMC 118 +#define SRST_B_EMMC 119 +#define SRST_C_EMMC 120 +#define SRST_T_EMMC 121 + +/* cru_softrst_con8 */ +#define SRST_A_PIPE_NIU 128 +#define SRST_P_PIPE_NIU 130 +#define SRST_P_PIPE_GRF 133 +#define SRST_A_SATA0 134 +#define SRST_SATA0_PIPE 135 +#define SRST_SATA0_PMALIVE 136 +#define SRST_SATA0_RXOOB 137 +#define SRST_A_SATA1 138 +#define SRST_SATA1_PIPE 139 +#define SRST_SATA1_PMALIVE 140 +#define SRST_SATA1_RXOOB 141 + +/* cru_softrst_con9 */ +#define SRST_A_SATA2 144 +#define SRST_SATA2_PIPE 145 +#define SRST_SATA2_PMALIVE 146 +#define SRST_SATA2_RXOOB 147 +#define SRST_USB3OTG0 148 +#define SRST_USB3OTG1 149 +#define SRST_XPCS 150 +#define SRST_XPCS_TX_DIV10 151 +#define SRST_XPCS_RX_DIV10 152 +#define SRST_XPCS_XGXS_RX 153 + +/* cru_softrst_con10 */ +#define SRST_P_PCIE20 160 +#define SRST_PCIE20_POWERUP 161 +#define SRST_MSTR_ARESET_PCIE20 162 +#define SRST_SLV_ARESET_PCIE20 163 +#define SRST_DBI_ARESET_PCIE20 164 +#define SRST_BRESET_PCIE20 165 +#define SRST_PERST_PCIE20 166 +#define SRST_CORE_RST_PCIE20 167 +#define SRST_NSTICKY_RST_PCIE20 168 +#define SRST_STICKY_RST_PCIE20 169 +#define SRST_PWR_RST_PCIE20 170 + +/* cru_softrst_con11 */ +#define SRST_P_PCIE30X1 176 +#define SRST_PCIE30X1_POWERUP 177 +#define SRST_M_ARESET_PCIE30X1 178 +#define SRST_S_ARESET_PCIE30X1 179 +#define SRST_D_ARESET_PCIE30X1 180 +#define SRST_BRESET_PCIE30X1 181 +#define SRST_PERST_PCIE30X1 182 +#define SRST_CORE_RST_PCIE30X1 183 +#define SRST_NSTC_RST_PCIE30X1 184 +#define SRST_STC_RST_PCIE30X1 185 +#define SRST_PWR_RST_PCIE30X1 186 + +/* cru_softrst_con12 */ +#define SRST_P_PCIE30X2 192 +#define SRST_PCIE30X2_POWERUP 193 +#define SRST_M_ARESET_PCIE30X2 194 +#define SRST_S_ARESET_PCIE30X2 195 +#define SRST_D_ARESET_PCIE30X2 196 +#define SRST_BRESET_PCIE30X2 197 +#define SRST_PERST_PCIE30X2 198 +#define SRST_CORE_RST_PCIE30X2 199 +#define SRST_NSTC_RST_PCIE30X2 200 +#define SRST_STC_RST_PCIE30X2 201 +#define SRST_PWR_RST_PCIE30X2 202 + +/* cru_softrst_con13 */ +#define SRST_A_PHP_NIU 208 +#define SRST_H_PHP_NIU 209 +#define SRST_P_PHP_NIU 210 +#define SRST_H_SDMMC0 211 +#define SRST_SDMMC0 212 +#define SRST_H_SDMMC1 213 +#define SRST_SDMMC1 214 +#define SRST_A_GMAC0 215 +#define SRST_GMAC0_TIMESTAMP 216 + +/* cru_softrst_con14 */ +#define SRST_A_USB_NIU 224 +#define SRST_H_USB_NIU 225 +#define SRST_P_USB_NIU 226 +#define SRST_P_USB_GRF 227 +#define SRST_H_USB2HOST0 228 +#define SRST_H_USB2HOST0_ARB 229 +#define SRST_USB2HOST0_UTMI 230 +#define SRST_H_USB2HOST1 231 +#define SRST_H_USB2HOST1_ARB 232 +#define SRST_USB2HOST1_UTMI 233 +#define SRST_H_SDMMC2 234 +#define SRST_SDMMC2 235 +#define SRST_A_GMAC1 236 +#define SRST_GMAC1_TIMESTAMP 237 + +/* cru_softrst_con15 */ +#define SRST_A_VI_NIU 240 +#define SRST_H_VI_NIU 241 +#define SRST_P_VI_NIU 242 +#define SRST_A_VICAP 247 +#define SRST_H_VICAP 248 +#define SRST_D_VICAP 249 +#define SRST_I_VICAP 250 +#define SRST_P_VICAP 251 +#define SRST_H_ISP 252 +#define SRST_ISP 253 +#define SRST_P_CSI2HOST1 255 + +/* cru_softrst_con16 */ +#define SRST_A_VO_NIU 256 +#define SRST_H_VO_NIU 257 +#define SRST_P_VO_NIU 258 +#define SRST_A_VOP_NIU 259 +#define SRST_A_VOP 260 +#define SRST_H_VOP 261 +#define SRST_VOP0 262 +#define SRST_VOP1 263 +#define SRST_VOP2 264 +#define SRST_VOP_PWM 265 +#define SRST_A_HDCP 266 +#define SRST_H_HDCP 267 +#define SRST_P_HDCP 268 +#define SRST_P_HDMI_HOST 270 +#define SRST_HDMI_HOST 271 + +/* cru_softrst_con17 */ +#define SRST_P_DSITX_0 272 +#define SRST_P_DSITX_1 273 +#define SRST_P_EDP_CTRL 274 +#define SRST_EDP_24M 275 +#define SRST_A_VPU_NIU 280 +#define SRST_H_VPU_NIU 281 +#define SRST_A_VPU 282 +#define SRST_H_VPU 283 +#define SRST_H_EINK 286 +#define SRST_P_EINK 287 + +/* cru_softrst_con18 */ +#define SRST_A_RGA_NIU 288 +#define SRST_H_RGA_NIU 289 +#define SRST_P_RGA_NIU 290 +#define SRST_A_RGA 292 +#define SRST_H_RGA 293 +#define SRST_RGA_CORE 294 +#define SRST_A_IEP 295 +#define SRST_H_IEP 296 +#define SRST_IEP_CORE 297 +#define SRST_H_EBC 298 +#define SRST_D_EBC 299 +#define SRST_A_JDEC 300 +#define SRST_H_JDEC 301 +#define SRST_A_JENC 302 +#define SRST_H_JENC 303 + +/* cru_softrst_con19 */ +#define SRST_A_VENC_NIU 304 +#define SRST_H_VENC_NIU 305 +#define SRST_A_RKVENC 307 +#define SRST_H_RKVENC 308 +#define SRST_RKVENC_CORE 309 + +/* cru_softrst_con20 */ +#define SRST_A_RKVDEC_NIU 320 +#define SRST_H_RKVDEC_NIU 321 +#define SRST_A_RKVDEC 322 +#define SRST_H_RKVDEC 323 +#define SRST_RKVDEC_CA 324 +#define SRST_RKVDEC_CORE 325 +#define SRST_RKVDEC_HEVC_CA 326 + +/* cru_softrst_con21 */ +#define SRST_A_BUS_NIU 336 +#define SRST_P_BUS_NIU 338 +#define SRST_P_CAN0 340 +#define SRST_CAN0 341 +#define SRST_P_CAN1 342 +#define SRST_CAN1 343 +#define SRST_P_CAN2 344 +#define SRST_CAN2 345 +#define SRST_P_GPIO1 346 +#define SRST_GPIO1 347 +#define SRST_P_GPIO2 348 +#define SRST_GPIO2 349 +#define SRST_P_GPIO3 350 +#define SRST_GPIO3 351 + +/* cru_softrst_con22 */ +#define SRST_P_GPIO4 352 +#define SRST_GPIO4 353 +#define SRST_P_I2C1 354 +#define SRST_I2C1 355 +#define SRST_P_I2C2 356 +#define SRST_I2C2 357 +#define SRST_P_I2C3 358 +#define SRST_I2C3 359 +#define SRST_P_I2C4 360 +#define SRST_I2C4 361 +#define SRST_P_I2C5 362 +#define SRST_I2C5 363 +#define SRST_P_OTPC_NS 364 +#define SRST_OTPC_NS_SBPI 365 +#define SRST_OTPC_NS_USR 366 + +/* cru_softrst_con23 */ +#define SRST_P_PWM1 368 +#define SRST_PWM1 369 +#define SRST_P_PWM2 370 +#define SRST_PWM2 371 +#define SRST_P_PWM3 372 +#define SRST_PWM3 373 +#define SRST_P_SPI0 374 +#define SRST_SPI0 375 +#define SRST_P_SPI1 376 +#define SRST_SPI1 377 +#define SRST_P_SPI2 378 +#define SRST_SPI2 379 +#define SRST_P_SPI3 380 +#define SRST_SPI3 381 + +/* cru_softrst_con24 */ +#define SRST_P_SARADC 384 +#define SRST_P_TSADC 385 +#define SRST_TSADC 386 +#define SRST_P_TIMER 387 +#define SRST_TIMER0 388 +#define SRST_TIMER1 389 +#define SRST_TIMER2 390 +#define SRST_TIMER3 391 +#define SRST_TIMER4 392 +#define SRST_TIMER5 393 +#define SRST_P_UART1 394 +#define SRST_S_UART1 395 + +/* cru_softrst_con25 */ +#define SRST_P_UART2 400 +#define SRST_S_UART2 401 +#define SRST_P_UART3 402 +#define SRST_S_UART3 403 +#define SRST_P_UART4 404 +#define SRST_S_UART4 405 +#define SRST_P_UART5 406 +#define SRST_S_UART5 407 +#define SRST_P_UART6 408 +#define SRST_S_UART6 409 +#define SRST_P_UART7 410 +#define SRST_S_UART7 411 +#define SRST_P_UART8 412 +#define SRST_S_UART8 413 +#define SRST_P_UART9 414 +#define SRST_S_UART9 415 + +/* cru_softrst_con26 */ +#define SRST_P_GRF 416 +#define SRST_P_GRF_VCCIO12 417 +#define SRST_P_GRF_VCCIO34 418 +#define SRST_P_GRF_VCCIO567 419 +#define SRST_P_SCR 420 +#define SRST_P_WDT_NS 421 +#define SRST_T_WDT_NS 422 +#define SRST_P_DFT2APB 423 +#define SRST_A_MCU 426 +#define SRST_P_INTMUX 427 +#define SRST_P_MAILBOX 428 + +/* cru_softrst_con27 */ +#define SRST_A_TOP_HIGH_NIU 432 +#define SRST_A_TOP_LOW_NIU 433 +#define SRST_H_TOP_NIU 434 +#define SRST_P_TOP_NIU 435 +#define SRST_P_TOP_CRU 438 +#define SRST_P_DDRPHY 439 +#define SRST_DDRPHY 440 +#define SRST_P_MIPICSIPHY 442 +#define SRST_P_MIPIDSIPHY0 443 +#define SRST_P_MIPIDSIPHY1 444 +#define SRST_P_PCIE30PHY 445 +#define SRST_PCIE30PHY 446 +#define SRST_P_PCIE30PHY_GRF 447 + +/* cru_softrst_con28 */ +#define SRST_P_APB2ASB_LEFT 448 +#define SRST_P_APB2ASB_BOTTOM 449 +#define SRST_P_ASB2APB_LEFT 450 +#define SRST_P_ASB2APB_BOTTOM 451 +#define SRST_P_PIPEPHY0 452 +#define SRST_PIPEPHY0 453 +#define SRST_P_PIPEPHY1 454 +#define SRST_PIPEPHY1 455 +#define SRST_P_PIPEPHY2 456 +#define SRST_PIPEPHY2 457 +#define SRST_P_USB2PHY0_GRF 458 +#define SRST_P_USB2PHY1_GRF 459 +#define SRST_P_CPU_BOOST 460 +#define SRST_CPU_BOOST 461 +#define SRST_P_OTPPHY 462 +#define SRST_OTPPHY 463 + +/* cru_softrst_con29 */ +#define SRST_USB2PHY0_POR 464 +#define SRST_USB2PHY0_USB3OTG0 465 +#define SRST_USB2PHY0_USB3OTG1 466 +#define SRST_USB2PHY1_POR 467 +#define SRST_USB2PHY1_USB2HOST0 468 +#define SRST_USB2PHY1_USB2HOST1 469 +#define SRST_P_EDPPHY_GRF 470 +#define SRST_TSADCPHY 471 +#define SRST_GMAC0_DELAYLINE 472 +#define SRST_GMAC1_DELAYLINE 473 +#define SRST_OTPC_ARB 474 +#define SRST_P_PIPEPHY0_GRF 475 +#define SRST_P_PIPEPHY1_GRF 476 +#define SRST_P_PIPEPHY2_GRF 477 + +#endif -- 2.17.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v1 1/2] rockchip: rk3568: add device tree file 2021-05-19 8:49 ` [PATCH v1 1/2] rockchip: rk3568: add device tree file Elaine at denx.de @ 2021-05-21 13:22 ` Kever Yang 0 siblings, 0 replies; 5+ messages in thread From: Kever Yang @ 2021-05-21 13:22 UTC (permalink / raw) To: Elaine Zhang, sjg, lukma; +Cc: u-boot, chenjh, Elaine Zhang On 2021/5/19 下午4:49, Elaine Zhang wrote: > From: Elaine Zhang <zhangqing@rock-chips.com> > > Add dts binding header for rk3568, files origin from kernel. > > Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> Reviewed-by: Kever Yang <kever.yang@rock-chips.com> Thanks, - Kever > --- > include/dt-bindings/clock/rk3568-cru.h | 925 +++++++++++++++++++++++++ > 1 file changed, 925 insertions(+) > create mode 100644 include/dt-bindings/clock/rk3568-cru.h > > diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h > new file mode 100644 > index 000000000000..c1942422a438 > --- /dev/null > +++ b/include/dt-bindings/clock/rk3568-cru.h > @@ -0,0 +1,925 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. > + * Author: Elaine Zhang <zhangqing@rock-chips.com> > + */ > + > +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H > +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H > + > +/* pmucru-clocks indices */ > + > +/* pmucru plls */ > +#define PLL_PPLL 1 > +#define PLL_HPLL 2 > + > +/* pmucru clocks */ > +#define XIN_OSC0_DIV 4 > +#define CLK_RTC_32K 5 > +#define CLK_PMU 6 > +#define CLK_I2C0 7 > +#define CLK_RTC32K_FRAC 8 > +#define CLK_UART0_DIV 9 > +#define CLK_UART0_FRAC 10 > +#define SCLK_UART0 11 > +#define DBCLK_GPIO0 12 > +#define CLK_PWM0 13 > +#define CLK_CAPTURE_PWM0_NDFT 14 > +#define CLK_PMUPVTM 15 > +#define CLK_CORE_PMUPVTM 16 > +#define CLK_REF24M 17 > +#define XIN_OSC0_USBPHY0_G 18 > +#define CLK_USBPHY0_REF 19 > +#define XIN_OSC0_USBPHY1_G 20 > +#define CLK_USBPHY1_REF 21 > +#define XIN_OSC0_MIPIDSIPHY0_G 22 > +#define CLK_MIPIDSIPHY0_REF 23 > +#define XIN_OSC0_MIPIDSIPHY1_G 24 > +#define CLK_MIPIDSIPHY1_REF 25 > +#define CLK_WIFI_DIV 26 > +#define CLK_WIFI_OSC0 27 > +#define CLK_WIFI 28 > +#define CLK_PCIEPHY0_DIV 29 > +#define CLK_PCIEPHY0_OSC0 30 > +#define CLK_PCIEPHY0_REF 31 > +#define CLK_PCIEPHY1_DIV 32 > +#define CLK_PCIEPHY1_OSC0 33 > +#define CLK_PCIEPHY1_REF 34 > +#define CLK_PCIEPHY2_DIV 35 > +#define CLK_PCIEPHY2_OSC0 36 > +#define CLK_PCIEPHY2_REF 37 > +#define CLK_PCIE30PHY_REF_M 38 > +#define CLK_PCIE30PHY_REF_N 39 > +#define CLK_HDMI_REF 40 > +#define XIN_OSC0_EDPPHY_G 41 > +#define PCLK_PDPMU 42 > +#define PCLK_PMU 43 > +#define PCLK_UART0 44 > +#define PCLK_I2C0 45 > +#define PCLK_GPIO0 46 > +#define PCLK_PMUPVTM 47 > +#define PCLK_PWM0 48 > +#define CLK_PDPMU 49 > +#define SCLK_32K_IOE 50 > + > +#define CLKPMU_NR_CLKS (SCLK_32K_IOE + 1) > + > +/* cru-clocks indices */ > + > +/* cru plls */ > +#define PLL_APLL 1 > +#define PLL_DPLL 2 > +#define PLL_CPLL 3 > +#define PLL_GPLL 4 > +#define PLL_VPLL 5 > +#define PLL_NPLL 6 > + > +/* cru clocks */ > +#define CPLL_333M 9 > +#define ARMCLK 10 > +#define USB480M 11 > +#define ACLK_CORE_NIU2BUS 18 > +#define CLK_CORE_PVTM 19 > +#define CLK_CORE_PVTM_CORE 20 > +#define CLK_CORE_PVTPLL 21 > +#define CLK_GPU_SRC 22 > +#define CLK_GPU_PRE_NDFT 23 > +#define CLK_GPU_PRE_MUX 24 > +#define ACLK_GPU_PRE 25 > +#define PCLK_GPU_PRE 26 > +#define CLK_GPU 27 > +#define CLK_GPU_NP5 28 > +#define PCLK_GPU_PVTM 29 > +#define CLK_GPU_PVTM 30 > +#define CLK_GPU_PVTM_CORE 31 > +#define CLK_GPU_PVTPLL 32 > +#define CLK_NPU_SRC 33 > +#define CLK_NPU_PRE_NDFT 34 > +#define CLK_NPU 35 > +#define CLK_NPU_NP5 36 > +#define HCLK_NPU_PRE 37 > +#define PCLK_NPU_PRE 38 > +#define ACLK_NPU_PRE 39 > +#define ACLK_NPU 40 > +#define HCLK_NPU 41 > +#define PCLK_NPU_PVTM 42 > +#define CLK_NPU_PVTM 43 > +#define CLK_NPU_PVTM_CORE 44 > +#define CLK_NPU_PVTPLL 45 > +#define CLK_DDRPHY1X_SRC 46 > +#define CLK_DDRPHY1X_HWFFC_SRC 47 > +#define CLK_DDR1X 48 > +#define CLK_MSCH 49 > +#define CLK24_DDRMON 50 > +#define ACLK_GIC_AUDIO 51 > +#define HCLK_GIC_AUDIO 52 > +#define HCLK_SDMMC_BUFFER 53 > +#define DCLK_SDMMC_BUFFER 54 > +#define ACLK_GIC600 55 > +#define ACLK_SPINLOCK 56 > +#define HCLK_I2S0_8CH 57 > +#define HCLK_I2S1_8CH 58 > +#define HCLK_I2S2_2CH 59 > +#define HCLK_I2S3_2CH 60 > +#define CLK_I2S0_8CH_TX_SRC 61 > +#define CLK_I2S0_8CH_TX_FRAC 62 > +#define MCLK_I2S0_8CH_TX 63 > +#define I2S0_MCLKOUT_TX 64 > +#define CLK_I2S0_8CH_RX_SRC 65 > +#define CLK_I2S0_8CH_RX_FRAC 66 > +#define MCLK_I2S0_8CH_RX 67 > +#define I2S0_MCLKOUT_RX 68 > +#define CLK_I2S1_8CH_TX_SRC 69 > +#define CLK_I2S1_8CH_TX_FRAC 70 > +#define MCLK_I2S1_8CH_TX 71 > +#define I2S1_MCLKOUT_TX 72 > +#define CLK_I2S1_8CH_RX_SRC 73 > +#define CLK_I2S1_8CH_RX_FRAC 74 > +#define MCLK_I2S1_8CH_RX 75 > +#define I2S1_MCLKOUT_RX 76 > +#define CLK_I2S2_2CH_SRC 77 > +#define CLK_I2S2_2CH_FRAC 78 > +#define MCLK_I2S2_2CH 79 > +#define I2S2_MCLKOUT 80 > +#define CLK_I2S3_2CH_TX_SRC 81 > +#define CLK_I2S3_2CH_TX_FRAC 82 > +#define MCLK_I2S3_2CH_TX 83 > +#define I2S3_MCLKOUT_TX 84 > +#define CLK_I2S3_2CH_RX_SRC 85 > +#define CLK_I2S3_2CH_RX_FRAC 86 > +#define MCLK_I2S3_2CH_RX 87 > +#define I2S3_MCLKOUT_RX 88 > +#define HCLK_PDM 89 > +#define MCLK_PDM 90 > +#define HCLK_VAD 91 > +#define HCLK_SPDIF_8CH 92 > +#define MCLK_SPDIF_8CH_SRC 93 > +#define MCLK_SPDIF_8CH_FRAC 94 > +#define MCLK_SPDIF_8CH 95 > +#define HCLK_AUDPWM 96 > +#define SCLK_AUDPWM_SRC 97 > +#define SCLK_AUDPWM_FRAC 98 > +#define SCLK_AUDPWM 99 > +#define HCLK_ACDCDIG 100 > +#define CLK_ACDCDIG_I2C 101 > +#define CLK_ACDCDIG_DAC 102 > +#define CLK_ACDCDIG_ADC 103 > +#define ACLK_SECURE_FLASH 104 > +#define HCLK_SECURE_FLASH 105 > +#define ACLK_CRYPTO_NS 106 > +#define HCLK_CRYPTO_NS 107 > +#define CLK_CRYPTO_NS_CORE 108 > +#define CLK_CRYPTO_NS_PKA 109 > +#define CLK_CRYPTO_NS_RNG 110 > +#define HCLK_TRNG_NS 111 > +#define CLK_TRNG_NS 112 > +#define PCLK_OTPC_NS 113 > +#define CLK_OTPC_NS_SBPI 114 > +#define CLK_OTPC_NS_USR 115 > +#define HCLK_NANDC 116 > +#define NCLK_NANDC 117 > +#define HCLK_SFC 118 > +#define HCLK_SFC_XIP 119 > +#define SCLK_SFC 120 > +#define ACLK_EMMC 121 > +#define HCLK_EMMC 122 > +#define BCLK_EMMC 123 > +#define CCLK_EMMC 124 > +#define TCLK_EMMC 125 > +#define ACLK_PIPE 126 > +#define PCLK_PIPE 127 > +#define PCLK_PIPE_GRF 128 > +#define ACLK_PCIE20_MST 129 > +#define ACLK_PCIE20_SLV 130 > +#define ACLK_PCIE20_DBI 131 > +#define PCLK_PCIE20 132 > +#define CLK_PCIE20_AUX_NDFT 133 > +#define CLK_PCIE20_AUX_DFT 134 > +#define CLK_PCIE20_PIPE_DFT 135 > +#define ACLK_PCIE30X1_MST 136 > +#define ACLK_PCIE30X1_SLV 137 > +#define ACLK_PCIE30X1_DBI 138 > +#define PCLK_PCIE30X1 139 > +#define CLK_PCIE30X1_AUX_NDFT 140 > +#define CLK_PCIE30X1_AUX_DFT 141 > +#define CLK_PCIE30X1_PIPE_DFT 142 > +#define ACLK_PCIE30X2_MST 143 > +#define ACLK_PCIE30X2_SLV 144 > +#define ACLK_PCIE30X2_DBI 145 > +#define PCLK_PCIE30X2 146 > +#define CLK_PCIE30X2_AUX_NDFT 147 > +#define CLK_PCIE30X2_AUX_DFT 148 > +#define CLK_PCIE30X2_PIPE_DFT 149 > +#define ACLK_SATA0 150 > +#define CLK_SATA0_PMALIVE 151 > +#define CLK_SATA0_RXOOB 152 > +#define CLK_SATA0_PIPE_NDFT 153 > +#define CLK_SATA0_PIPE_DFT 154 > +#define ACLK_SATA1 155 > +#define CLK_SATA1_PMALIVE 156 > +#define CLK_SATA1_RXOOB 157 > +#define CLK_SATA1_PIPE_NDFT 158 > +#define CLK_SATA1_PIPE_DFT 159 > +#define ACLK_SATA2 160 > +#define CLK_SATA2_PMALIVE 161 > +#define CLK_SATA2_RXOOB 162 > +#define CLK_SATA2_PIPE_NDFT 163 > +#define CLK_SATA2_PIPE_DFT 164 > +#define ACLK_USB3OTG0 165 > +#define CLK_USB3OTG0_REF 166 > +#define CLK_USB3OTG0_SUSPEND 167 > +#define ACLK_USB3OTG1 168 > +#define CLK_USB3OTG1_REF 169 > +#define CLK_USB3OTG1_SUSPEND 170 > +#define CLK_XPCS_EEE 171 > +#define PCLK_XPCS 172 > +#define ACLK_PHP 173 > +#define HCLK_PHP 174 > +#define PCLK_PHP 175 > +#define HCLK_SDMMC0 176 > +#define CLK_SDMMC0 177 > +#define HCLK_SDMMC1 178 > +#define CLK_SDMMC1 179 > +#define ACLK_GMAC0 180 > +#define PCLK_GMAC0 181 > +#define CLK_MAC0_2TOP 182 > +#define CLK_MAC0_OUT 183 > +#define CLK_MAC0_REFOUT 184 > +#define CLK_GMAC0_PTP_REF 185 > +#define ACLK_USB 186 > +#define HCLK_USB 187 > +#define PCLK_USB 188 > +#define HCLK_USB2HOST0 189 > +#define HCLK_USB2HOST0_ARB 190 > +#define HCLK_USB2HOST1 191 > +#define HCLK_USB2HOST1_ARB 192 > +#define HCLK_SDMMC2 193 > +#define CLK_SDMMC2 194 > +#define ACLK_GMAC1 195 > +#define PCLK_GMAC1 196 > +#define CLK_MAC1_2TOP 197 > +#define CLK_MAC1_OUT 198 > +#define CLK_MAC1_REFOUT 199 > +#define CLK_GMAC1_PTP_REF 200 > +#define ACLK_PERIMID 201 > +#define HCLK_PERIMID 202 > +#define ACLK_VI 203 > +#define HCLK_VI 204 > +#define PCLK_VI 205 > +#define ACLK_VICAP 206 > +#define HCLK_VICAP 207 > +#define DCLK_VICAP 208 > +#define ICLK_VICAP_G 209 > +#define ACLK_ISP 210 > +#define HCLK_ISP 211 > +#define CLK_ISP 212 > +#define PCLK_CSI2HOST1 213 > +#define CLK_CIF_OUT 214 > +#define CLK_CAM0_OUT 215 > +#define CLK_CAM1_OUT 216 > +#define ACLK_VO 217 > +#define HCLK_VO 218 > +#define PCLK_VO 219 > +#define ACLK_VOP_PRE 220 > +#define ACLK_VOP 221 > +#define HCLK_VOP 222 > +#define DCLK_VOP0 223 > +#define DCLK_VOP1 224 > +#define DCLK_VOP2 225 > +#define CLK_VOP_PWM 226 > +#define ACLK_HDCP 227 > +#define HCLK_HDCP 228 > +#define PCLK_HDCP 229 > +#define PCLK_HDMI_HOST 230 > +#define CLK_HDMI_SFR 231 > +#define PCLK_DSITX_0 232 > +#define PCLK_DSITX_1 233 > +#define PCLK_EDP_CTRL 234 > +#define CLK_EDP_200M 235 > +#define ACLK_VPU_PRE 236 > +#define HCLK_VPU_PRE 237 > +#define ACLK_VPU 238 > +#define HCLK_VPU 239 > +#define ACLK_RGA_PRE 240 > +#define HCLK_RGA_PRE 241 > +#define PCLK_RGA_PRE 242 > +#define ACLK_RGA 243 > +#define HCLK_RGA 244 > +#define CLK_RGA_CORE 245 > +#define ACLK_IEP 246 > +#define HCLK_IEP 247 > +#define CLK_IEP_CORE 248 > +#define HCLK_EBC 249 > +#define DCLK_EBC 250 > +#define ACLK_JDEC 251 > +#define HCLK_JDEC 252 > +#define ACLK_JENC 253 > +#define HCLK_JENC 254 > +#define PCLK_EINK 255 > +#define HCLK_EINK 256 > +#define ACLK_RKVENC_PRE 257 > +#define HCLK_RKVENC_PRE 258 > +#define ACLK_RKVENC 259 > +#define HCLK_RKVENC 260 > +#define CLK_RKVENC_CORE 261 > +#define ACLK_RKVDEC_PRE 262 > +#define HCLK_RKVDEC_PRE 263 > +#define ACLK_RKVDEC 264 > +#define HCLK_RKVDEC 265 > +#define CLK_RKVDEC_CA 266 > +#define CLK_RKVDEC_CORE 267 > +#define CLK_RKVDEC_HEVC_CA 268 > +#define ACLK_BUS 269 > +#define PCLK_BUS 270 > +#define PCLK_TSADC 271 > +#define CLK_TSADC_TSEN 272 > +#define CLK_TSADC 273 > +#define PCLK_SARADC 274 > +#define CLK_SARADC 275 > +#define PCLK_SCR 276 > +#define PCLK_WDT_NS 277 > +#define TCLK_WDT_NS 278 > +#define ACLK_DMAC0 279 > +#define ACLK_DMAC1 280 > +#define ACLK_MCU 281 > +#define PCLK_INTMUX 282 > +#define PCLK_MAILBOX 283 > +#define PCLK_UART1 284 > +#define CLK_UART1_SRC 285 > +#define CLK_UART1_FRAC 286 > +#define SCLK_UART1 287 > +#define PCLK_UART2 288 > +#define CLK_UART2_SRC 289 > +#define CLK_UART2_FRAC 290 > +#define SCLK_UART2 291 > +#define PCLK_UART3 292 > +#define CLK_UART3_SRC 293 > +#define CLK_UART3_FRAC 294 > +#define SCLK_UART3 295 > +#define PCLK_UART4 296 > +#define CLK_UART4_SRC 297 > +#define CLK_UART4_FRAC 298 > +#define SCLK_UART4 299 > +#define PCLK_UART5 300 > +#define CLK_UART5_SRC 301 > +#define CLK_UART5_FRAC 302 > +#define SCLK_UART5 303 > +#define PCLK_UART6 304 > +#define CLK_UART6_SRC 305 > +#define CLK_UART6_FRAC 306 > +#define SCLK_UART6 307 > +#define PCLK_UART7 308 > +#define CLK_UART7_SRC 309 > +#define CLK_UART7_FRAC 310 > +#define SCLK_UART7 311 > +#define PCLK_UART8 312 > +#define CLK_UART8_SRC 313 > +#define CLK_UART8_FRAC 314 > +#define SCLK_UART8 315 > +#define PCLK_UART9 316 > +#define CLK_UART9_SRC 317 > +#define CLK_UART9_FRAC 318 > +#define SCLK_UART9 319 > +#define PCLK_CAN0 320 > +#define CLK_CAN0 321 > +#define PCLK_CAN1 322 > +#define CLK_CAN1 323 > +#define PCLK_CAN2 324 > +#define CLK_CAN2 325 > +#define CLK_I2C 326 > +#define PCLK_I2C1 327 > +#define CLK_I2C1 328 > +#define PCLK_I2C2 329 > +#define CLK_I2C2 330 > +#define PCLK_I2C3 331 > +#define CLK_I2C3 332 > +#define PCLK_I2C4 333 > +#define CLK_I2C4 334 > +#define PCLK_I2C5 335 > +#define CLK_I2C5 336 > +#define PCLK_SPI0 337 > +#define CLK_SPI0 338 > +#define PCLK_SPI1 339 > +#define CLK_SPI1 340 > +#define PCLK_SPI2 341 > +#define CLK_SPI2 342 > +#define PCLK_SPI3 343 > +#define CLK_SPI3 344 > +#define PCLK_PWM1 345 > +#define CLK_PWM1 346 > +#define CLK_PWM1_CAPTURE 347 > +#define PCLK_PWM2 348 > +#define CLK_PWM2 349 > +#define CLK_PWM2_CAPTURE 350 > +#define PCLK_PWM3 351 > +#define CLK_PWM3 352 > +#define CLK_PWM3_CAPTURE 353 > +#define DBCLK_GPIO 354 > +#define PCLK_GPIO1 355 > +#define DBCLK_GPIO1 356 > +#define PCLK_GPIO2 357 > +#define DBCLK_GPIO2 358 > +#define PCLK_GPIO3 359 > +#define DBCLK_GPIO3 360 > +#define PCLK_GPIO4 361 > +#define DBCLK_GPIO4 362 > +#define OCC_SCAN_CLK_GPIO 363 > +#define PCLK_TIMER 364 > +#define CLK_TIMER0 365 > +#define CLK_TIMER1 366 > +#define CLK_TIMER2 367 > +#define CLK_TIMER3 368 > +#define CLK_TIMER4 369 > +#define CLK_TIMER5 370 > +#define ACLK_TOP_HIGH 371 > +#define ACLK_TOP_LOW 372 > +#define HCLK_TOP 373 > +#define PCLK_TOP 374 > +#define PCLK_PCIE30PHY 375 > +#define CLK_OPTC_ARB 376 > +#define PCLK_MIPICSIPHY 377 > +#define PCLK_MIPIDSIPHY0 378 > +#define PCLK_MIPIDSIPHY1 379 > +#define PCLK_PIPEPHY0 380 > +#define PCLK_PIPEPHY1 381 > +#define PCLK_PIPEPHY2 382 > +#define PCLK_CPU_BOOST 383 > +#define CLK_CPU_BOOST 384 > +#define PCLK_OTPPHY 385 > +#define SCLK_GMAC0 386 > +#define SCLK_GMAC0_RGMII_SPEED 387 > +#define SCLK_GMAC0_RMII_SPEED 388 > +#define SCLK_GMAC0_RX_TX 389 > +#define SCLK_GMAC1 390 > +#define SCLK_GMAC1_RGMII_SPEED 391 > +#define SCLK_GMAC1_RMII_SPEED 392 > +#define SCLK_GMAC1_RX_TX 393 > +#define SCLK_SDMMC0_DRV 394 > +#define SCLK_SDMMC0_SAMPLE 395 > +#define SCLK_SDMMC1_DRV 396 > +#define SCLK_SDMMC1_SAMPLE 397 > +#define SCLK_SDMMC2_DRV 398 > +#define SCLK_SDMMC2_SAMPLE 399 > +#define SCLK_EMMC_DRV 400 > +#define SCLK_EMMC_SAMPLE 401 > +#define PCLK_EDPPHY_GRF 402 > +#define CLK_HDMI_CEC 403 > +#define CLK_I2S0_8CH_TX 404 > +#define CLK_I2S0_8CH_RX 405 > +#define CLK_I2S1_8CH_TX 406 > +#define CLK_I2S1_8CH_RX 407 > +#define CLK_I2S2_2CH 408 > +#define CLK_I2S3_2CH_TX 409 > +#define CLK_I2S3_2CH_RX 410 > +#define CPLL_500M 411 > +#define CPLL_250M 412 > +#define CPLL_125M 413 > +#define CPLL_62P5M 414 > +#define CPLL_50M 415 > +#define CPLL_25M 416 > +#define CPLL_100M 417 > + > +#define PCLK_CORE_PVTM 450 > + > +#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1) > + > +/* pmu soft-reset indices */ > +/* pmucru_softrst_con0 */ > +#define SRST_P_PDPMU_NIU 0 > +#define SRST_P_PMUCRU 1 > +#define SRST_P_PMUGRF 2 > +#define SRST_P_I2C0 3 > +#define SRST_I2C0 4 > +#define SRST_P_UART0 5 > +#define SRST_S_UART0 6 > +#define SRST_P_PWM0 7 > +#define SRST_PWM0 8 > +#define SRST_P_GPIO0 9 > +#define SRST_GPIO0 10 > +#define SRST_P_PMUPVTM 11 > +#define SRST_PMUPVTM 12 > + > +/* soft-reset indices */ > + > +/* cru_softrst_con0 */ > +#define SRST_NCORERESET0 0 > +#define SRST_NCORERESET1 1 > +#define SRST_NCORERESET2 2 > +#define SRST_NCORERESET3 3 > +#define SRST_NCPUPORESET0 4 > +#define SRST_NCPUPORESET1 5 > +#define SRST_NCPUPORESET2 6 > +#define SRST_NCPUPORESET3 7 > +#define SRST_NSRESET 8 > +#define SRST_NSPORESET 9 > +#define SRST_NATRESET 10 > +#define SRST_NGICRESET 11 > +#define SRST_NPRESET 12 > +#define SRST_NPERIPHRESET 13 > + > +/* cru_softrst_con1 */ > +#define SRST_A_CORE_NIU2DDR 16 > +#define SRST_A_CORE_NIU2BUS 17 > +#define SRST_P_DBG_NIU 18 > +#define SRST_P_DBG 19 > +#define SRST_P_DBG_DAPLITE 20 > +#define SRST_DAP 21 > +#define SRST_A_ADB400_CORE2GIC 22 > +#define SRST_A_ADB400_GIC2CORE 23 > +#define SRST_P_CORE_GRF 24 > +#define SRST_P_CORE_PVTM 25 > +#define SRST_CORE_PVTM 26 > +#define SRST_CORE_PVTPLL 27 > + > +/* cru_softrst_con2 */ > +#define SRST_GPU 32 > +#define SRST_A_GPU_NIU 33 > +#define SRST_P_GPU_NIU 34 > +#define SRST_P_GPU_PVTM 35 > +#define SRST_GPU_PVTM 36 > +#define SRST_GPU_PVTPLL 37 > +#define SRST_A_NPU_NIU 40 > +#define SRST_H_NPU_NIU 41 > +#define SRST_P_NPU_NIU 42 > +#define SRST_A_NPU 43 > +#define SRST_H_NPU 44 > +#define SRST_P_NPU_PVTM 45 > +#define SRST_NPU_PVTM 46 > +#define SRST_NPU_PVTPLL 47 > + > +/* cru_softrst_con3 */ > +#define SRST_A_MSCH 51 > +#define SRST_HWFFC_CTRL 52 > +#define SRST_DDR_ALWAYSON 53 > +#define SRST_A_DDRSPLIT 54 > +#define SRST_DDRDFI_CTL 55 > +#define SRST_A_DMA2DDR 57 > + > +/* cru_softrst_con4 */ > +#define SRST_A_PERIMID_NIU 64 > +#define SRST_H_PERIMID_NIU 65 > +#define SRST_A_GIC_AUDIO_NIU 66 > +#define SRST_H_GIC_AUDIO_NIU 67 > +#define SRST_A_GIC600 68 > +#define SRST_A_GIC600_DEBUG 69 > +#define SRST_A_GICADB_CORE2GIC 70 > +#define SRST_A_GICADB_GIC2CORE 71 > +#define SRST_A_SPINLOCK 72 > +#define SRST_H_SDMMC_BUFFER 73 > +#define SRST_D_SDMMC_BUFFER 74 > +#define SRST_H_I2S0_8CH 75 > +#define SRST_H_I2S1_8CH 76 > +#define SRST_H_I2S2_2CH 77 > +#define SRST_H_I2S3_2CH 78 > + > +/* cru_softrst_con5 */ > +#define SRST_M_I2S0_8CH_TX 80 > +#define SRST_M_I2S0_8CH_RX 81 > +#define SRST_M_I2S1_8CH_TX 82 > +#define SRST_M_I2S1_8CH_RX 83 > +#define SRST_M_I2S2_2CH 84 > +#define SRST_M_I2S3_2CH_TX 85 > +#define SRST_M_I2S3_2CH_RX 86 > +#define SRST_H_PDM 87 > +#define SRST_M_PDM 88 > +#define SRST_H_VAD 89 > +#define SRST_H_SPDIF_8CH 90 > +#define SRST_M_SPDIF_8CH 91 > +#define SRST_H_AUDPWM 92 > +#define SRST_S_AUDPWM 93 > +#define SRST_H_ACDCDIG 94 > +#define SRST_ACDCDIG 95 > + > +/* cru_softrst_con6 */ > +#define SRST_A_SECURE_FLASH_NIU 96 > +#define SRST_H_SECURE_FLASH_NIU 97 > +#define SRST_A_CRYPTO_NS 103 > +#define SRST_H_CRYPTO_NS 104 > +#define SRST_CRYPTO_NS_CORE 105 > +#define SRST_CRYPTO_NS_PKA 106 > +#define SRST_CRYPTO_NS_RNG 107 > +#define SRST_H_TRNG_NS 108 > +#define SRST_TRNG_NS 109 > + > +/* cru_softrst_con7 */ > +#define SRST_H_NANDC 112 > +#define SRST_N_NANDC 113 > +#define SRST_H_SFC 114 > +#define SRST_H_SFC_XIP 115 > +#define SRST_S_SFC 116 > +#define SRST_A_EMMC 117 > +#define SRST_H_EMMC 118 > +#define SRST_B_EMMC 119 > +#define SRST_C_EMMC 120 > +#define SRST_T_EMMC 121 > + > +/* cru_softrst_con8 */ > +#define SRST_A_PIPE_NIU 128 > +#define SRST_P_PIPE_NIU 130 > +#define SRST_P_PIPE_GRF 133 > +#define SRST_A_SATA0 134 > +#define SRST_SATA0_PIPE 135 > +#define SRST_SATA0_PMALIVE 136 > +#define SRST_SATA0_RXOOB 137 > +#define SRST_A_SATA1 138 > +#define SRST_SATA1_PIPE 139 > +#define SRST_SATA1_PMALIVE 140 > +#define SRST_SATA1_RXOOB 141 > + > +/* cru_softrst_con9 */ > +#define SRST_A_SATA2 144 > +#define SRST_SATA2_PIPE 145 > +#define SRST_SATA2_PMALIVE 146 > +#define SRST_SATA2_RXOOB 147 > +#define SRST_USB3OTG0 148 > +#define SRST_USB3OTG1 149 > +#define SRST_XPCS 150 > +#define SRST_XPCS_TX_DIV10 151 > +#define SRST_XPCS_RX_DIV10 152 > +#define SRST_XPCS_XGXS_RX 153 > + > +/* cru_softrst_con10 */ > +#define SRST_P_PCIE20 160 > +#define SRST_PCIE20_POWERUP 161 > +#define SRST_MSTR_ARESET_PCIE20 162 > +#define SRST_SLV_ARESET_PCIE20 163 > +#define SRST_DBI_ARESET_PCIE20 164 > +#define SRST_BRESET_PCIE20 165 > +#define SRST_PERST_PCIE20 166 > +#define SRST_CORE_RST_PCIE20 167 > +#define SRST_NSTICKY_RST_PCIE20 168 > +#define SRST_STICKY_RST_PCIE20 169 > +#define SRST_PWR_RST_PCIE20 170 > + > +/* cru_softrst_con11 */ > +#define SRST_P_PCIE30X1 176 > +#define SRST_PCIE30X1_POWERUP 177 > +#define SRST_M_ARESET_PCIE30X1 178 > +#define SRST_S_ARESET_PCIE30X1 179 > +#define SRST_D_ARESET_PCIE30X1 180 > +#define SRST_BRESET_PCIE30X1 181 > +#define SRST_PERST_PCIE30X1 182 > +#define SRST_CORE_RST_PCIE30X1 183 > +#define SRST_NSTC_RST_PCIE30X1 184 > +#define SRST_STC_RST_PCIE30X1 185 > +#define SRST_PWR_RST_PCIE30X1 186 > + > +/* cru_softrst_con12 */ > +#define SRST_P_PCIE30X2 192 > +#define SRST_PCIE30X2_POWERUP 193 > +#define SRST_M_ARESET_PCIE30X2 194 > +#define SRST_S_ARESET_PCIE30X2 195 > +#define SRST_D_ARESET_PCIE30X2 196 > +#define SRST_BRESET_PCIE30X2 197 > +#define SRST_PERST_PCIE30X2 198 > +#define SRST_CORE_RST_PCIE30X2 199 > +#define SRST_NSTC_RST_PCIE30X2 200 > +#define SRST_STC_RST_PCIE30X2 201 > +#define SRST_PWR_RST_PCIE30X2 202 > + > +/* cru_softrst_con13 */ > +#define SRST_A_PHP_NIU 208 > +#define SRST_H_PHP_NIU 209 > +#define SRST_P_PHP_NIU 210 > +#define SRST_H_SDMMC0 211 > +#define SRST_SDMMC0 212 > +#define SRST_H_SDMMC1 213 > +#define SRST_SDMMC1 214 > +#define SRST_A_GMAC0 215 > +#define SRST_GMAC0_TIMESTAMP 216 > + > +/* cru_softrst_con14 */ > +#define SRST_A_USB_NIU 224 > +#define SRST_H_USB_NIU 225 > +#define SRST_P_USB_NIU 226 > +#define SRST_P_USB_GRF 227 > +#define SRST_H_USB2HOST0 228 > +#define SRST_H_USB2HOST0_ARB 229 > +#define SRST_USB2HOST0_UTMI 230 > +#define SRST_H_USB2HOST1 231 > +#define SRST_H_USB2HOST1_ARB 232 > +#define SRST_USB2HOST1_UTMI 233 > +#define SRST_H_SDMMC2 234 > +#define SRST_SDMMC2 235 > +#define SRST_A_GMAC1 236 > +#define SRST_GMAC1_TIMESTAMP 237 > + > +/* cru_softrst_con15 */ > +#define SRST_A_VI_NIU 240 > +#define SRST_H_VI_NIU 241 > +#define SRST_P_VI_NIU 242 > +#define SRST_A_VICAP 247 > +#define SRST_H_VICAP 248 > +#define SRST_D_VICAP 249 > +#define SRST_I_VICAP 250 > +#define SRST_P_VICAP 251 > +#define SRST_H_ISP 252 > +#define SRST_ISP 253 > +#define SRST_P_CSI2HOST1 255 > + > +/* cru_softrst_con16 */ > +#define SRST_A_VO_NIU 256 > +#define SRST_H_VO_NIU 257 > +#define SRST_P_VO_NIU 258 > +#define SRST_A_VOP_NIU 259 > +#define SRST_A_VOP 260 > +#define SRST_H_VOP 261 > +#define SRST_VOP0 262 > +#define SRST_VOP1 263 > +#define SRST_VOP2 264 > +#define SRST_VOP_PWM 265 > +#define SRST_A_HDCP 266 > +#define SRST_H_HDCP 267 > +#define SRST_P_HDCP 268 > +#define SRST_P_HDMI_HOST 270 > +#define SRST_HDMI_HOST 271 > + > +/* cru_softrst_con17 */ > +#define SRST_P_DSITX_0 272 > +#define SRST_P_DSITX_1 273 > +#define SRST_P_EDP_CTRL 274 > +#define SRST_EDP_24M 275 > +#define SRST_A_VPU_NIU 280 > +#define SRST_H_VPU_NIU 281 > +#define SRST_A_VPU 282 > +#define SRST_H_VPU 283 > +#define SRST_H_EINK 286 > +#define SRST_P_EINK 287 > + > +/* cru_softrst_con18 */ > +#define SRST_A_RGA_NIU 288 > +#define SRST_H_RGA_NIU 289 > +#define SRST_P_RGA_NIU 290 > +#define SRST_A_RGA 292 > +#define SRST_H_RGA 293 > +#define SRST_RGA_CORE 294 > +#define SRST_A_IEP 295 > +#define SRST_H_IEP 296 > +#define SRST_IEP_CORE 297 > +#define SRST_H_EBC 298 > +#define SRST_D_EBC 299 > +#define SRST_A_JDEC 300 > +#define SRST_H_JDEC 301 > +#define SRST_A_JENC 302 > +#define SRST_H_JENC 303 > + > +/* cru_softrst_con19 */ > +#define SRST_A_VENC_NIU 304 > +#define SRST_H_VENC_NIU 305 > +#define SRST_A_RKVENC 307 > +#define SRST_H_RKVENC 308 > +#define SRST_RKVENC_CORE 309 > + > +/* cru_softrst_con20 */ > +#define SRST_A_RKVDEC_NIU 320 > +#define SRST_H_RKVDEC_NIU 321 > +#define SRST_A_RKVDEC 322 > +#define SRST_H_RKVDEC 323 > +#define SRST_RKVDEC_CA 324 > +#define SRST_RKVDEC_CORE 325 > +#define SRST_RKVDEC_HEVC_CA 326 > + > +/* cru_softrst_con21 */ > +#define SRST_A_BUS_NIU 336 > +#define SRST_P_BUS_NIU 338 > +#define SRST_P_CAN0 340 > +#define SRST_CAN0 341 > +#define SRST_P_CAN1 342 > +#define SRST_CAN1 343 > +#define SRST_P_CAN2 344 > +#define SRST_CAN2 345 > +#define SRST_P_GPIO1 346 > +#define SRST_GPIO1 347 > +#define SRST_P_GPIO2 348 > +#define SRST_GPIO2 349 > +#define SRST_P_GPIO3 350 > +#define SRST_GPIO3 351 > + > +/* cru_softrst_con22 */ > +#define SRST_P_GPIO4 352 > +#define SRST_GPIO4 353 > +#define SRST_P_I2C1 354 > +#define SRST_I2C1 355 > +#define SRST_P_I2C2 356 > +#define SRST_I2C2 357 > +#define SRST_P_I2C3 358 > +#define SRST_I2C3 359 > +#define SRST_P_I2C4 360 > +#define SRST_I2C4 361 > +#define SRST_P_I2C5 362 > +#define SRST_I2C5 363 > +#define SRST_P_OTPC_NS 364 > +#define SRST_OTPC_NS_SBPI 365 > +#define SRST_OTPC_NS_USR 366 > + > +/* cru_softrst_con23 */ > +#define SRST_P_PWM1 368 > +#define SRST_PWM1 369 > +#define SRST_P_PWM2 370 > +#define SRST_PWM2 371 > +#define SRST_P_PWM3 372 > +#define SRST_PWM3 373 > +#define SRST_P_SPI0 374 > +#define SRST_SPI0 375 > +#define SRST_P_SPI1 376 > +#define SRST_SPI1 377 > +#define SRST_P_SPI2 378 > +#define SRST_SPI2 379 > +#define SRST_P_SPI3 380 > +#define SRST_SPI3 381 > + > +/* cru_softrst_con24 */ > +#define SRST_P_SARADC 384 > +#define SRST_P_TSADC 385 > +#define SRST_TSADC 386 > +#define SRST_P_TIMER 387 > +#define SRST_TIMER0 388 > +#define SRST_TIMER1 389 > +#define SRST_TIMER2 390 > +#define SRST_TIMER3 391 > +#define SRST_TIMER4 392 > +#define SRST_TIMER5 393 > +#define SRST_P_UART1 394 > +#define SRST_S_UART1 395 > + > +/* cru_softrst_con25 */ > +#define SRST_P_UART2 400 > +#define SRST_S_UART2 401 > +#define SRST_P_UART3 402 > +#define SRST_S_UART3 403 > +#define SRST_P_UART4 404 > +#define SRST_S_UART4 405 > +#define SRST_P_UART5 406 > +#define SRST_S_UART5 407 > +#define SRST_P_UART6 408 > +#define SRST_S_UART6 409 > +#define SRST_P_UART7 410 > +#define SRST_S_UART7 411 > +#define SRST_P_UART8 412 > +#define SRST_S_UART8 413 > +#define SRST_P_UART9 414 > +#define SRST_S_UART9 415 > + > +/* cru_softrst_con26 */ > +#define SRST_P_GRF 416 > +#define SRST_P_GRF_VCCIO12 417 > +#define SRST_P_GRF_VCCIO34 418 > +#define SRST_P_GRF_VCCIO567 419 > +#define SRST_P_SCR 420 > +#define SRST_P_WDT_NS 421 > +#define SRST_T_WDT_NS 422 > +#define SRST_P_DFT2APB 423 > +#define SRST_A_MCU 426 > +#define SRST_P_INTMUX 427 > +#define SRST_P_MAILBOX 428 > + > +/* cru_softrst_con27 */ > +#define SRST_A_TOP_HIGH_NIU 432 > +#define SRST_A_TOP_LOW_NIU 433 > +#define SRST_H_TOP_NIU 434 > +#define SRST_P_TOP_NIU 435 > +#define SRST_P_TOP_CRU 438 > +#define SRST_P_DDRPHY 439 > +#define SRST_DDRPHY 440 > +#define SRST_P_MIPICSIPHY 442 > +#define SRST_P_MIPIDSIPHY0 443 > +#define SRST_P_MIPIDSIPHY1 444 > +#define SRST_P_PCIE30PHY 445 > +#define SRST_PCIE30PHY 446 > +#define SRST_P_PCIE30PHY_GRF 447 > + > +/* cru_softrst_con28 */ > +#define SRST_P_APB2ASB_LEFT 448 > +#define SRST_P_APB2ASB_BOTTOM 449 > +#define SRST_P_ASB2APB_LEFT 450 > +#define SRST_P_ASB2APB_BOTTOM 451 > +#define SRST_P_PIPEPHY0 452 > +#define SRST_PIPEPHY0 453 > +#define SRST_P_PIPEPHY1 454 > +#define SRST_PIPEPHY1 455 > +#define SRST_P_PIPEPHY2 456 > +#define SRST_PIPEPHY2 457 > +#define SRST_P_USB2PHY0_GRF 458 > +#define SRST_P_USB2PHY1_GRF 459 > +#define SRST_P_CPU_BOOST 460 > +#define SRST_CPU_BOOST 461 > +#define SRST_P_OTPPHY 462 > +#define SRST_OTPPHY 463 > + > +/* cru_softrst_con29 */ > +#define SRST_USB2PHY0_POR 464 > +#define SRST_USB2PHY0_USB3OTG0 465 > +#define SRST_USB2PHY0_USB3OTG1 466 > +#define SRST_USB2PHY1_POR 467 > +#define SRST_USB2PHY1_USB2HOST0 468 > +#define SRST_USB2PHY1_USB2HOST1 469 > +#define SRST_P_EDPPHY_GRF 470 > +#define SRST_TSADCPHY 471 > +#define SRST_GMAC0_DELAYLINE 472 > +#define SRST_GMAC1_DELAYLINE 473 > +#define SRST_OTPC_ARB 474 > +#define SRST_P_PIPEPHY0_GRF 475 > +#define SRST_P_PIPEPHY1_GRF 476 > +#define SRST_P_PIPEPHY2_GRF 477 > + > +#endif ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v1 2/2] rockchip: rk3568: add clock driver 2021-05-19 8:49 [PATCH v1 0/2] clk: rockchip: rk3568: add clock driver Elaine at denx.de 2021-05-19 8:49 ` [PATCH v1 1/2] rockchip: rk3568: add device tree file Elaine at denx.de @ 2021-05-19 8:49 ` Elaine at denx.de 2021-05-21 13:33 ` Kever Yang 1 sibling, 1 reply; 5+ messages in thread From: Elaine at denx.de @ 2021-05-19 8:49 UTC (permalink / raw) To: u-boot From: Elaine Zhang <zhangqing@rock-chips.com> Add rk3568 clock driver and cru structure definition. Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> --- .../include/asm/arch-rockchip/cru_rk3568.h | 504 +++ drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk_rk3568.c | 2908 +++++++++++++++++ 3 files changed, 3413 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3568.h create mode 100644 drivers/clk/rockchip/clk_rk3568.c diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h new file mode 100644 index 000000000000..6c59033f03a6 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h @@ -0,0 +1,504 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#ifndef _ASM_ARCH_CRU_RK3568_H +#define _ASM_ARCH_CRU_RK3568_H + +#define MHz 1000000 +#define KHz 1000 +#define OSC_HZ (24 * MHz) + +#define APLL_HZ (816 * MHz) +#define GPLL_HZ (1188 * MHz) +#define CPLL_HZ (1000 * MHz) +#define PPLL_HZ (100 * MHz) + +/* RK3568 pll id */ +enum rk3568_pll_id { + APLL, + DPLL, + CPLL, + GPLL, + NPLL, + VPLL, + PPLL, + HPLL, + PLL_COUNT, +}; + +struct rk3568_clk_info { + unsigned long id; + char *name; + bool is_cru; +}; + +/* Private data for the clock driver - used by rockchip_get_cru() */ +struct rk3568_pmuclk_priv { + struct rk3568_pmucru *pmucru; + ulong ppll_hz; + ulong hpll_hz; +}; + +struct rk3568_clk_priv { + struct rk3568_cru *cru; + struct rk3568_grf *grf; + ulong ppll_hz; + ulong hpll_hz; + ulong gpll_hz; + ulong cpll_hz; + ulong npll_hz; + ulong vpll_hz; + ulong armclk_hz; + ulong armclk_enter_hz; + ulong armclk_init_hz; + bool sync_kernel; + bool set_armclk_rate; +}; + +struct rk3568_pll { + unsigned int con0; + unsigned int con1; + unsigned int con2; + unsigned int con3; + unsigned int con4; + unsigned int reserved0[3]; +}; + +struct rk3568_pmucru { + struct rk3568_pll pll[2];/* Address Offset: 0x0000 */ + unsigned int reserved0[16];/* Address Offset: 0x0040 */ + unsigned int mode_con00;/* Address Offset: 0x0080 */ + unsigned int reserved1[31];/* Address Offset: 0x0084 */ + unsigned int pmu_clksel_con[10];/* Address Offset: 0x0100 */ + unsigned int reserved2[22];/* Address Offset: 0x0128 */ + unsigned int pmu_clkgate_con[3];/* Address Offset: 0x0180 */ + unsigned int reserved3[29];/* Address Offset: 0x018C */ + unsigned int pmu_softrst_con[1];/* Address Offset: 0x0200 */ +}; + +check_member(rk3568_pmucru, mode_con00, 0x80); +check_member(rk3568_pmucru, pmu_softrst_con[0], 0x200); + +struct rk3568_cru { + struct rk3568_pll pll[6]; + unsigned int mode_con00;/* Address Offset: 0x00C0 */ + unsigned int misc_con[3];/* Address Offset: 0x00C4 */ + unsigned int glb_cnt_th;/* Address Offset: 0x00D0 */ + unsigned int glb_srst_fst;/* Address Offset: 0x00D4 */ + unsigned int glb_srsr_snd; /* Address Offset: 0x00D8 */ + unsigned int glb_rst_con;/* Address Offset: 0x00DC */ + unsigned int glb_rst_st;/* Address Offset: 0x00E0 */ + unsigned int reserved0[7];/* Address Offset: 0x00E4 */ + unsigned int clksel_con[85]; /* Address Offset: 0x0100 */ + unsigned int reserved1[43];/* Address Offset: 0x0254 */ + unsigned int clkgate_con[36];/* Address Offset: 0x0300 */ + unsigned int reserved2[28]; /* Address Offset: 0x0390 */ + unsigned int softrst_con[30];/* Address Offset: 0x0400 */ + unsigned int reserved3[2];/* Address Offset: 0x0478 */ + unsigned int ssgtbl[32];/* Address Offset: 0x0480 */ + unsigned int reserved4[32];/* Address Offset: 0x0500 */ + unsigned int sdmmc0_con[2];/* Address Offset: 0x0580 */ + unsigned int sdmmc1_con[2];/* Address Offset: 0x058C */ + unsigned int sdmmc2_con[2];/* Address Offset: 0x0590 */ + unsigned int emmc_con[2];/* Address Offset: 0x0598 */ +}; + +check_member(rk3568_cru, mode_con00, 0xc0); +check_member(rk3568_cru, softrst_con[0], 0x400); + +struct pll_rate_table { + unsigned long rate; + unsigned int fbdiv; + unsigned int postdiv1; + unsigned int refdiv; + unsigned int postdiv2; + unsigned int dsmpd; + unsigned int frac; +}; + +#define RK3568_PMU_MODE 0x80 +#define RK3568_PMU_PLL_CON(x) ((x) * 0x4) +#define RK3568_PLL_CON(x) ((x) * 0x4) +#define RK3568_MODE_CON 0xc0 + +enum { + /* CRU_PMU_CLK_SEL0_CON */ + RTC32K_SEL_SHIFT = 6, + RTC32K_SEL_MASK = 0x3 << RTC32K_SEL_SHIFT, + RTC32K_SEL_PMUPVTM = 0, + RTC32K_SEL_OSC1_32K, + RTC32K_SEL_OSC0_DIV32K, + + /* CRU_PMU_CLK_SEL1_CON */ + RTC32K_FRAC_NUMERATOR_SHIFT = 16, + RTC32K_FRAC_NUMERATOR_MASK = 0xffff << 16, + RTC32K_FRAC_DENOMINATOR_SHIFT = 0, + RTC32K_FRAC_DENOMINATOR_MASK = 0xffff, + + /* CRU_PMU_CLK_SEL2_CON */ + PCLK_PDPMU_SEL_SHIFT = 15, + PCLK_PDPMU_SEL_MASK = 1 << PCLK_PDPMU_SEL_SHIFT, + PCLK_PDPMU_SEL_PPLL = 0, + PCLK_PDPMU_SEL_GPLL, + PCLK_PDPMU_DIV_SHIFT = 0, + PCLK_PDPMU_DIV_MASK = 0x1f, + + /* CRU_PMU_CLK_SEL3_CON */ + CLK_I2C0_DIV_SHIFT = 0, + CLK_I2C0_DIV_MASK = 0x7f, + + /* CRU_PMU_CLK_SEL6_CON */ + CLK_PWM0_SEL_SHIFT = 7, + CLK_PWM0_SEL_MASK = 1 << CLK_PWM0_SEL_SHIFT, + CLK_PWM0_SEL_XIN24M = 0, + CLK_PWM0_SEL_PPLL, + CLK_PWM0_DIV_SHIFT = 0, + CLK_PWM0_DIV_MASK = 0x7f, + + /* CRU_CLK_SEL0_CON */ + CLK_CORE_PRE_SEL_SHIFT = 7, + CLK_CORE_PRE_SEL_MASK = 1 << CLK_CORE_PRE_SEL_SHIFT, + CLK_CORE_PRE_SEL_SRC = 0, + CLK_CORE_PRE_SEL_APLL, + + /* CRU_CLK_SEL2_CON */ + SCLK_CORE_PRE_SEL_SHIFT = 15, + SCLK_CORE_PRE_SEL_MASK = 1 << SCLK_CORE_PRE_SEL_SHIFT, + SCLK_CORE_PRE_SEL_SRC = 0, + SCLK_CORE_PRE_SEL_NPLL, + SCLK_CORE_SRC_SEL_SHIFT = 8, + SCLK_CORE_SRC_SEL_MASK = 3 << SCLK_CORE_SRC_SEL_SHIFT, + SCLK_CORE_SRC_SEL_APLL = 0, + SCLK_CORE_SRC_SEL_GPLL, + SCLK_CORE_SRC_SEL_NPLL, + SCLK_CORE_SRC_DIV_SHIFT = 0, + SCLK_CORE_SRC_DIV_MASK = 0x1f << SCLK_CORE_SRC_DIV_SHIFT, + + /* CRU_CLK_SEL3_CON */ + GICCLK_CORE_DIV_SHIFT = 8, + GICCLK_CORE_DIV_MASK = 0x1f << GICCLK_CORE_DIV_SHIFT, + ATCLK_CORE_DIV_SHIFT = 0, + ATCLK_CORE_DIV_MASK = 0x1f << ATCLK_CORE_DIV_SHIFT, + + /* CRU_CLK_SEL4_CON */ + PERIPHCLK_CORE_PRE_DIV_SHIFT = 8, + PERIPHCLK_CORE_PRE_DIV_MASK = 0x1f << PERIPHCLK_CORE_PRE_DIV_SHIFT, + PCLK_CORE_PRE_DIV_SHIFT = 0, + PCLK_CORE_PRE_DIV_MASK = 0x1f << PCLK_CORE_PRE_DIV_SHIFT, + + /* CRU_CLK_SEL5_CON */ + ACLK_CORE_NIU2BUS_SEL_SHIFT = 14, + ACLK_CORE_NIU2BUS_SEL_MASK = 0x3 << ACLK_CORE_NIU2BUS_SEL_SHIFT, + ACLK_CORE_NDFT_DIV_SHIFT = 8, + ACLK_CORE_NDFT_DIV_MASK = 0x1f << ACLK_CORE_NDFT_DIV_SHIFT, + + /* CRU_CLK_SEL10_CON */ + HCLK_PERIMID_SEL_SHIFT = 6, + HCLK_PERIMID_SEL_MASK = 3 << HCLK_PERIMID_SEL_SHIFT, + HCLK_PERIMID_SEL_150M = 0, + HCLK_PERIMID_SEL_100M, + HCLK_PERIMID_SEL_75M, + HCLK_PERIMID_SEL_24M, + ACLK_PERIMID_SEL_SHIFT = 4, + ACLK_PERIMID_SEL_MASK = 3 << ACLK_PERIMID_SEL_SHIFT, + ACLK_PERIMID_SEL_300M = 0, + ACLK_PERIMID_SEL_200M, + ACLK_PERIMID_SEL_100M, + ACLK_PERIMID_SEL_24M, + + /* CRU_CLK_SEL27_CON */ + CLK_CRYPTO_PKA_SEL_SHIFT = 6, + CLK_CRYPTO_PKA_SEL_MASK = 3 << CLK_CRYPTO_PKA_SEL_SHIFT, + CLK_CRYPTO_PKA_SEL_300M = 0, + CLK_CRYPTO_PKA_SEL_200M, + CLK_CRYPTO_PKA_SEL_100M, + CLK_CRYPTO_CORE_SEL_SHIFT = 4, + CLK_CRYPTO_CORE_SEL_MASK = 3 << CLK_CRYPTO_CORE_SEL_SHIFT, + CLK_CRYPTO_CORE_SEL_200M = 0, + CLK_CRYPTO_CORE_SEL_150M, + CLK_CRYPTO_CORE_SEL_100M, + HCLK_SECURE_FLASH_SEL_SHIFT = 2, + HCLK_SECURE_FLASH_SEL_MASK = 3 << HCLK_SECURE_FLASH_SEL_SHIFT, + HCLK_SECURE_FLASH_SEL_150M = 0, + HCLK_SECURE_FLASH_SEL_100M, + HCLK_SECURE_FLASH_SEL_75M, + HCLK_SECURE_FLASH_SEL_24M, + ACLK_SECURE_FLASH_SEL_SHIFT = 0, + ACLK_SECURE_FLASH_SEL_MASK = 3 << ACLK_SECURE_FLASH_SEL_SHIFT, + ACLK_SECURE_FLASH_SEL_200M = 0, + ACLK_SECURE_FLASH_SEL_150M, + ACLK_SECURE_FLASH_SEL_100M, + ACLK_SECURE_FLASH_SEL_24M, + + /* CRU_CLK_SEL28_CON */ + CCLK_EMMC_SEL_SHIFT = 12, + CCLK_EMMC_SEL_MASK = 7 << CCLK_EMMC_SEL_SHIFT, + CCLK_EMMC_SEL_24M = 0, + CCLK_EMMC_SEL_200M, + CCLK_EMMC_SEL_150M, + CCLK_EMMC_SEL_100M, + CCLK_EMMC_SEL_50M, + CCLK_EMMC_SEL_375K, + BCLK_EMMC_SEL_SHIFT = 8, + BCLK_EMMC_SEL_MASK = 3 << BCLK_EMMC_SEL_SHIFT, + BCLK_EMMC_SEL_200M = 0, + BCLK_EMMC_SEL_150M, + BCLK_EMMC_SEL_125M, + SCLK_SFC_SEL_SHIFT = 4, + SCLK_SFC_SEL_MASK = 7 << SCLK_SFC_SEL_SHIFT, + SCLK_SFC_SEL_24M = 0, + SCLK_SFC_SEL_50M, + SCLK_SFC_SEL_75M, + SCLK_SFC_SEL_100M, + SCLK_SFC_SEL_125M, + SCLK_SFC_SEL_150M, + NCLK_NANDC_SEL_SHIFT = 0, + NCLK_NANDC_SEL_MASK = 3 << NCLK_NANDC_SEL_SHIFT, + NCLK_NANDC_SEL_200M = 0, + NCLK_NANDC_SEL_150M, + NCLK_NANDC_SEL_100M, + NCLK_NANDC_SEL_24M, + + /* CRU_CLK_SEL30_CON */ + CLK_SDMMC1_SEL_SHIFT = 12, + CLK_SDMMC1_SEL_MASK = 7 << CLK_SDMMC1_SEL_SHIFT, + CLK_SDMMC0_SEL_SHIFT = 8, + CLK_SDMMC0_SEL_MASK = 7 << CLK_SDMMC0_SEL_SHIFT, + CLK_SDMMC_SEL_24M = 0, + CLK_SDMMC_SEL_400M, + CLK_SDMMC_SEL_300M, + CLK_SDMMC_SEL_100M, + CLK_SDMMC_SEL_50M, + CLK_SDMMC_SEL_750K, + + /* CRU_CLK_SEL31_CON */ + CLK_MAC0_OUT_SEL_SHIFT = 14, + CLK_MAC0_OUT_SEL_MASK = 3 << CLK_MAC0_OUT_SEL_SHIFT, + CLK_MAC0_OUT_SEL_125M = 0, + CLK_MAC0_OUT_SEL_50M, + CLK_MAC0_OUT_SEL_25M, + CLK_MAC0_OUT_SEL_24M, + CLK_GMAC0_PTP_REF_SEL_SHIFT = 12, + CLK_GMAC0_PTP_REF_SEL_MASK = 3 << CLK_GMAC0_PTP_REF_SEL_SHIFT, + CLK_GMAC0_PTP_REF_SEL_62_5M = 0, + CLK_GMAC0_PTP_REF_SEL_100M, + CLK_GMAC0_PTP_REF_SEL_50M, + CLK_GMAC0_PTP_REF_SEL_24M, + CLK_MAC0_2TOP_SEL_SHIFT = 8, + CLK_MAC0_2TOP_SEL_MASK = 3 << CLK_MAC0_2TOP_SEL_SHIFT, + CLK_MAC0_2TOP_SEL_125M = 0, + CLK_MAC0_2TOP_SEL_50M, + CLK_MAC0_2TOP_SEL_25M, + CLK_MAC0_2TOP_SEL_PPLL, + RGMII0_CLK_SEL_SHIFT = 4, + RGMII0_CLK_SEL_MASK = 3 << RGMII0_CLK_SEL_SHIFT, + RGMII0_CLK_SEL_125M = 0, + RGMII0_CLK_SEL_125M_1, + RGMII0_CLK_SEL_2_5M, + RGMII0_CLK_SEL_25M, + RMII0_CLK_SEL_SHIFT = 3, + RMII0_CLK_SEL_MASK = 1 << RMII0_CLK_SEL_SHIFT, + RMII0_CLK_SEL_2_5M = 0, + RMII0_CLK_SEL_25M, + RMII0_EXTCLK_SEL_SHIFT = 2, + RMII0_EXTCLK_SEL_MASK = 1 << RMII0_EXTCLK_SEL_SHIFT, + RMII0_EXTCLK_SEL_MAC0_TOP = 0, + RMII0_EXTCLK_SEL_IO, + RMII0_MODE_SHIFT = 0, + RMII0_MODE_MASK = 3 << RMII0_MODE_SHIFT, + RMII0_MODE_SEL_RGMII = 0, + RMII0_MODE_SEL_RMII, + RMII0_MODE_SEL_GMII, + + /* CRU_CLK_SEL32_CON */ + CLK_SDMMC2_SEL_SHIFT = 8, + CLK_SDMMC2_SEL_MASK = 7 << CLK_SDMMC2_SEL_SHIFT, + + /* CRU_CLK_SEL38_CON */ + ACLK_VOP_PRE_SEL_SHIFT = 6, + ACLK_VOP_PRE_SEL_MASK = 3 << ACLK_VOP_PRE_SEL_SHIFT, + ACLK_VOP_PRE_SEL_CPLL = 0, + ACLK_VOP_PRE_SEL_GPLL, + ACLK_VOP_PRE_SEL_HPLL, + ACLK_VOP_PRE_SEL_VPLL, + ACLK_VOP_PRE_DIV_SHIFT = 0, + ACLK_VOP_PRE_DIV_MASK = 0x1f << ACLK_VOP_PRE_DIV_SHIFT, + + /* CRU_CLK_SEL39_CON */ + DCLK0_VOP_SEL_SHIFT = 10, + DCLK0_VOP_SEL_MASK = 3 << DCLK0_VOP_SEL_SHIFT, + DCLK_VOP_SEL_HPLL = 0, + DCLK_VOP_SEL_VPLL, + DCLK_VOP_SEL_GPLL, + DCLK_VOP_SEL_CPLL, + DCLK0_VOP_DIV_SHIFT = 0, + DCLK0_VOP_DIV_MASK = 0xff << DCLK0_VOP_DIV_SHIFT, + + /* CRU_CLK_SEL40_CON */ + DCLK1_VOP_SEL_SHIFT = 10, + DCLK1_VOP_SEL_MASK = 3 << DCLK1_VOP_SEL_SHIFT, + DCLK1_VOP_DIV_SHIFT = 0, + DCLK1_VOP_DIV_MASK = 0xff << DCLK1_VOP_DIV_SHIFT, + + /* CRU_CLK_SEL41_CON */ + DCLK2_VOP_SEL_SHIFT = 10, + DCLK2_VOP_SEL_MASK = 3 << DCLK2_VOP_SEL_SHIFT, + DCLK2_VOP_DIV_SHIFT = 0, + DCLK2_VOP_DIV_MASK = 0xff << DCLK2_VOP_DIV_SHIFT, + + /* CRU_CLK_SEL43_CON */ + DCLK_EBC_SEL_SHIFT = 6, + DCLK_EBC_SEL_MASK = 3 << DCLK_EBC_SEL_SHIFT, + DCLK_EBC_SEL_GPLL_400M = 0, + DCLK_EBC_SEL_CPLL_333M, + DCLK_EBC_SEL_GPLL_200M, + + /* CRU_CLK_SEL47_CON */ + ACLK_RKVDEC_SEL_SHIFT = 7, + ACLK_RKVDEC_SEL_MASK = 1 << ACLK_RKVDEC_SEL_SHIFT, + ACLK_RKVDEC_SEL_GPLL = 0, + ACLK_RKVDEC_SEL_CPLL, + ACLK_RKVDEC_DIV_SHIFT = 0, + ACLK_RKVDEC_DIV_MASK = 0x1f << ACLK_RKVDEC_DIV_SHIFT, + + /* CRU_CLK_SEL49_CON */ + CLK_RKVDEC_CORE_SEL_SHIFT = 14, + CLK_RKVDEC_CORE_SEL_MASK = 0x3 << CLK_RKVDEC_CORE_SEL_SHIFT, + CLK_RKVDEC_CORE_SEL_GPLL = 0, + CLK_RKVDEC_CORE_SEL_CPLL, + CLK_RKVDEC_CORE_SEL_NPLL, + CLK_RKVDEC_CORE_SEL_VPLL, + CLK_RKVDEC_CORE_DIV_SHIFT = 8, + CLK_RKVDEC_CORE_DIV_MASK = 0x1f << CLK_RKVDEC_CORE_DIV_SHIFT, + + /* CRU_CLK_SEL50_CON */ + PCLK_BUS_SEL_SHIFT = 4, + PCLK_BUS_SEL_MASK = 3 << PCLK_BUS_SEL_SHIFT, + PCLK_BUS_SEL_100M = 0, + PCLK_BUS_SEL_75M, + PCLK_BUS_SEL_50M, + PCLK_BUS_SEL_24M, + ACLK_BUS_SEL_SHIFT = 0, + ACLK_BUS_SEL_MASK = 3 << ACLK_BUS_SEL_SHIFT, + ACLK_BUS_SEL_200M = 0, + ACLK_BUS_SEL_150M, + ACLK_BUS_SEL_100M, + ACLK_BUS_SEL_24M, + + /* CRU_CLK_SEL51_CON */ + CLK_TSADC_DIV_SHIFT = 8, + CLK_TSADC_DIV_MASK = 0x7f << CLK_TSADC_DIV_SHIFT, + CLK_TSADC_TSEN_SEL_SHIFT = 4, + CLK_TSADC_TSEN_SEL_MASK = 0x3 << CLK_TSADC_TSEN_SEL_SHIFT, + CLK_TSADC_TSEN_SEL_24M = 0, + CLK_TSADC_TSEN_SEL_100M, + CLK_TSADC_TSEN_SEL_CPLL_100M, + CLK_TSADC_TSEN_DIV_SHIFT = 0, + CLK_TSADC_TSEN_DIV_MASK = 0x7 << CLK_TSADC_TSEN_DIV_SHIFT, + + /* CRU_CLK_SEL52_CON */ + CLK_UART_SEL_SHIFT = 12, + CLK_UART_SEL_MASK = 0x3 << CLK_UART_SEL_SHIFT, + CLK_UART_SEL_SRC = 0, + CLK_UART_SEL_FRAC, + CLK_UART_SEL_XIN24M, + CLK_UART_SRC_SEL_SHIFT = 8, + CLK_UART_SRC_SEL_MASK = 0x3 << CLK_UART_SRC_SEL_SHIFT, + CLK_UART_SRC_SEL_GPLL = 0, + CLK_UART_SRC_SEL_CPLL, + CLK_UART_SRC_SEL_480M, + CLK_UART_SRC_DIV_SHIFT = 0, + CLK_UART_SRC_DIV_MASK = 0x3f << CLK_UART_SRC_DIV_SHIFT, + + /* CRU_CLK_SEL53_CON */ + CLK_UART_FRAC_NUMERATOR_SHIFT = 16, + CLK_UART_FRAC_NUMERATOR_MASK = 0xffff << 16, + CLK_UART_FRAC_DENOMINATOR_SHIFT = 0, + CLK_UART_FRAC_DENOMINATOR_MASK = 0xffff, + + /* CRU_CLK_SEL71_CON */ + CLK_I2C_SEL_SHIFT = 8, + CLK_I2C_SEL_MASK = 3 << CLK_I2C_SEL_SHIFT, + CLK_I2C_SEL_200M = 0, + CLK_I2C_SEL_100M, + CLK_I2C_SEL_24M, + CLK_I2C_SEL_CPLL_100M, + + /* CRU_CLK_SEL72_CON */ + CLK_PWM3_SEL_SHIFT = 12, + CLK_PWM3_SEL_MASK = 3 << CLK_PWM3_SEL_SHIFT, + CLK_PWM2_SEL_SHIFT = 10, + CLK_PWM2_SEL_MASK = 3 << CLK_PWM2_SEL_SHIFT, + CLK_PWM1_SEL_SHIFT = 8, + CLK_PWM1_SEL_MASK = 3 << CLK_PWM1_SEL_SHIFT, + CLK_PWM_SEL_100M = 0, + CLK_PWM_SEL_24M, + CLK_PWM_SEL_CPLL_100M, + CLK_SPI3_SEL_SHIFT = 6, + CLK_SPI3_SEL_MASK = 3 << CLK_SPI3_SEL_SHIFT, + CLK_SPI2_SEL_SHIFT = 4, + CLK_SPI2_SEL_MASK = 3 << CLK_SPI2_SEL_SHIFT, + CLK_SPI1_SEL_SHIFT = 2, + CLK_SPI1_SEL_MASK = 3 << CLK_SPI1_SEL_SHIFT, + CLK_SPI0_SEL_SHIFT = 0, + CLK_SPI0_SEL_MASK = 3 << CLK_SPI0_SEL_SHIFT, + CLK_SPI_SEL_200M = 0, + CLK_SPI_SEL_24M, + CLK_SPI_SEL_CPLL_100M, + + /* CRU_CLK_SEL73_CON */ + PCLK_TOP_SEL_SHIFT = 12, + PCLK_TOP_SEL_MASK = 3 << PCLK_TOP_SEL_SHIFT, + PCLK_TOP_SEL_100M = 0, + PCLK_TOP_SEL_75M, + PCLK_TOP_SEL_50M, + PCLK_TOP_SEL_24M, + HCLK_TOP_SEL_SHIFT = 8, + HCLK_TOP_SEL_MASK = 3 << HCLK_TOP_SEL_SHIFT, + HCLK_TOP_SEL_150M = 0, + HCLK_TOP_SEL_100M, + HCLK_TOP_SEL_75M, + HCLK_TOP_SEL_24M, + ACLK_TOP_LOW_SEL_SHIFT = 4, + ACLK_TOP_LOW_SEL_MASK = 3 << ACLK_TOP_LOW_SEL_SHIFT, + ACLK_TOP_LOW_SEL_400M = 0, + ACLK_TOP_LOW_SEL_300M, + ACLK_TOP_LOW_SEL_200M, + ACLK_TOP_LOW_SEL_24M, + ACLK_TOP_HIGH_SEL_SHIFT = 0, + ACLK_TOP_HIGH_SEL_MASK = 3 << ACLK_TOP_HIGH_SEL_SHIFT, + ACLK_TOP_HIGH_SEL_500M = 0, + ACLK_TOP_HIGH_SEL_400M, + ACLK_TOP_HIGH_SEL_300M, + ACLK_TOP_HIGH_SEL_24M, + + /* CRU_CLK_SEL78_CON */ + CPLL_500M_DIV_SHIFT = 8, + CPLL_500M_DIV_MASK = 0x1f << CPLL_500M_DIV_SHIFT, + + /* CRU_CLK_SEL79_CON */ + CPLL_250M_DIV_SHIFT = 8, + CPLL_250M_DIV_MASK = 0x1f << CPLL_250M_DIV_SHIFT, + CPLL_333M_DIV_SHIFT = 0, + CPLL_333M_DIV_MASK = 0x1f << CPLL_333M_DIV_SHIFT, + + /* CRU_CLK_SEL80_CON */ + CPLL_62P5M_DIV_SHIFT = 8, + CPLL_62P5M_DIV_MASK = 0x1f << CPLL_62P5M_DIV_SHIFT, + CPLL_125M_DIV_SHIFT = 0, + CPLL_125M_DIV_MASK = 0x1f << CPLL_125M_DIV_SHIFT, + + /* CRU_CLK_SEL81_CON */ + CPLL_25M_DIV_SHIFT = 8, + CPLL_25M_DIV_MASK = 0x1f << CPLL_25M_DIV_SHIFT, + CPLL_50M_DIV_SHIFT = 0, + CPLL_50M_DIV_MASK = 0x1f << CPLL_50M_DIV_SHIFT, + + /* CRU_CLK_SEL82_CON */ + CPLL_100M_DIV_SHIFT = 0, + CPLL_100M_DIV_MASK = 0x1f << CPLL_100M_DIV_SHIFT, +}; +#endif diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 4cfcf8330929..913f611a0ff8 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += clk_rk3308.o obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o +obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c new file mode 100644 index 000000000000..359aca358e0d --- /dev/null +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -0,0 +1,2908 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#include <common.h> +#include <bitfield.h> +#include <clk-uclass.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/arch-rockchip/cru_rk3568.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/hardware.h> +#include <asm/io.h> +#include <dm/lists.h> +#include <dt-bindings/clock/rk3568-cru.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(OF_PLATDATA) +struct rk3568_clk_plat { + struct dtd_rockchip_rk3568_cru dtd; +}; + +struct rk3568_pmuclk_plat { + struct dtd_rockchip_rk3568_pmucru dtd; +}; +#endif + +#define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ +{ \ + .rate = _rate##U, \ + .aclk_div = _aclk_div, \ + .pclk_div = _pclk_div, \ +} + +#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) + +static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = { + RK3568_CPUCLK_RATE(1416000000, 1, 5), + RK3568_CPUCLK_RATE(1296000000, 1, 5), + RK3568_CPUCLK_RATE(1200000000, 1, 3), + RK3568_CPUCLK_RATE(1104000000, 1, 3), + RK3568_CPUCLK_RATE(1008000000, 1, 3), + RK3568_CPUCLK_RATE(912000000, 1, 3), + RK3568_CPUCLK_RATE(816000000, 1, 3), + RK3568_CPUCLK_RATE(600000000, 1, 1), + RK3568_CPUCLK_RATE(408000000, 1, 1), + { /* sentinel */ }, +}; + +static struct rockchip_pll_rate_table rk3568_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), + RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0), + RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0), + RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), + { /* sentinel */ }, +}; + +static struct rockchip_pll_clock rk3568_pll_clks[] = { + [APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0), + RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates), + [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8), + RK3568_MODE_CON, 2, 10, 0, NULL), + [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24), + RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates), + [GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16), + RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates), + [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32), + RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates), + [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40), + RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates), + [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0), + RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates), + [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16), + RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates), +}; + +static ulong __maybe_unused +rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv, + ulong pll_id, ulong rate) +{ + struct udevice *pmucru_dev; + struct rk3568_pmuclk_priv *pmu_priv; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rk3568_pmucru), + &pmucru_dev); + if (ret) { + printf("%s: could not find pmucru device\n", __func__); + return ret; + } + pmu_priv = dev_get_priv(pmucru_dev); + + rockchip_pll_set_rate(&rk3568_pll_clks[pll_id], + pmu_priv->pmucru, pll_id, rate); + + return 0; +} + +static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv, + ulong pll_id) +{ + struct udevice *pmucru_dev; + struct rk3568_pmuclk_priv *pmu_priv; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rk3568_pmucru), + &pmucru_dev); + if (ret) { + printf("%s: could not find pmucru device\n", __func__); + return ret; + } + pmu_priv = dev_get_priv(pmucru_dev); + + return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id], + pmu_priv->pmucru, pll_id); +} + +/* + * + * rational_best_approximation(31415, 10000, + * (1 << 8) - 1, (1 << 5) - 1, &n, &d); + * + * you may look@given_numerator as a fixed point number, + * with the fractional part size described in given_denominator. + * + * for theoretical background, see: + * http://en.wikipedia.org/wiki/Continued_fraction + */ +static void rational_best_approximation(unsigned long given_numerator, + unsigned long given_denominator, + unsigned long max_numerator, + unsigned long max_denominator, + unsigned long *best_numerator, + unsigned long *best_denominator) +{ + unsigned long n, d, n0, d0, n1, d1; + + n = given_numerator; + d = given_denominator; + n0 = 0; + d1 = 0; + n1 = 1; + d0 = 1; + for (;;) { + unsigned long t, a; + + if (n1 > max_numerator || d1 > max_denominator) { + n1 = n0; + d1 = d0; + break; + } + if (d == 0) + break; + t = d; + a = n / d; + d = n % d; + n = t; + t = n0 + a * n1; + n0 = n1; + n1 = t; + t = d0 + a * d1; + d0 = d1; + d1 = t; + } + *best_numerator = n1; + *best_denominator = d1; +} + +static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + unsigned long m, n; + u32 fracdiv; + + fracdiv = readl(&pmucru->pmu_clksel_con[1]); + m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK; + m >>= RTC32K_FRAC_NUMERATOR_SHIFT; + n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK; + n >>= RTC32K_FRAC_DENOMINATOR_SHIFT; + + return OSC_HZ * m / n; +} + +static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong rate) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + unsigned long m, n, val; + + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); + + rational_best_approximation(rate, OSC_HZ, + GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), + &m, &n); + val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n; + writel(val, &pmucru->pmu_clksel_con[1]); + + return rk3568_rtc32k_get_pmuclk(priv); +} + +static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong clk_id) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + u32 div, con; + + switch (clk_id) { + case CLK_I2C0: + con = readl(&pmucru->pmu_clksel_con[3]); + div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(priv->ppll_hz, div); +} + +static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); + assert(src_clk_div - 1 <= 127); + + switch (clk_id) { + case CLK_I2C0: + rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK, + (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_i2c_get_pmuclk(priv, clk_id); +} + +static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong clk_id) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + u32 div, sel, con, parent; + + switch (clk_id) { + case CLK_PWM0: + con = readl(&pmucru->pmu_clksel_con[6]); + sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; + div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT; + if (sel == CLK_PWM0_SEL_XIN24M) + parent = OSC_HZ; + else + parent = priv->ppll_hz; + break; + default: + return -ENOENT; + } + + return DIV_TO_RATE(parent, div); +} + +static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + switch (clk_id) { + case CLK_PWM0: + if (rate == OSC_HZ) { + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK, + (CLK_PWM0_SEL_XIN24M << + CLK_PWM0_SEL_SHIFT) | + 0 << CLK_PWM0_SEL_SHIFT); + } else { + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); + assert(src_clk_div - 1 <= 127); + rk_clrsetreg(&pmucru->pmu_clksel_con[6], + CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK, + (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) | + (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT); + } + break; + default: + return -ENOENT; + } + + return rk3568_pwm_get_pmuclk(priv, clk_id); +} + +static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + u32 div, con, sel, parent; + + con = readl(&pmucru->pmu_clksel_con[2]); + sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT; + div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT; + if (sel) + parent = GPLL_HZ; + else + parent = priv->ppll_hz; + + return DIV_TO_RATE(parent, div); +} + +static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv, + ulong rate) +{ + struct rk3568_pmucru *pmucru = priv->pmucru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); + assert(src_clk_div - 1 <= 31); + + rk_clrsetreg(&pmucru->pmu_clksel_con[2], + PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK, + (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) | + ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT)); + + return rk3568_pmu_get_pmuclk(priv); +} + +static ulong rk3568_pmuclk_get_rate(struct clk *clk) +{ + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + if (!priv->ppll_hz) { + printf("%s ppll=%lu\n", __func__, priv->ppll_hz); + return -ENOENT; + } + + debug("%s %ld\n", __func__, clk->id); + switch (clk->id) { + case PLL_PPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], + priv->pmucru, PPLL); + break; + case PLL_HPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], + priv->pmucru, HPLL); + break; + case CLK_RTC_32K: + case CLK_RTC32K_FRAC: + rate = rk3568_rtc32k_get_pmuclk(priv); + break; + case CLK_I2C0: + rate = rk3568_i2c_get_pmuclk(priv, clk->id); + break; + case CLK_PWM0: + rate = rk3568_pwm_get_pmuclk(priv, clk->id); + break; + case PCLK_PMU: + rate = rk3568_pmu_get_pmuclk(priv); + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate) +{ + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + if (!priv->ppll_hz) { + printf("%s ppll=%lu\n", __func__, priv->ppll_hz); + return -ENOENT; + } + + debug("%s %ld %ld\n", __func__, clk->id, rate); + switch (clk->id) { + case PLL_PPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], + priv->pmucru, PPLL, rate); + priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], + priv->pmucru, PPLL); + break; + case PLL_HPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL], + priv->pmucru, HPLL, rate); + priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], + priv->pmucru, HPLL); + break; + case CLK_RTC_32K: + case CLK_RTC32K_FRAC: + ret = rk3568_rtc32k_set_pmuclk(priv, rate); + break; + case CLK_I2C0: + ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate); + break; + case CLK_PWM0: + ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate); + break; + case PCLK_PMU: + ret = rk3568_pmu_set_pmuclk(priv, rate); + break; + default: + return -ENOENT; + } + + return ret; +} + +static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent) +{ + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_pmucru *pmucru = priv->pmucru; + + if (parent->id == CLK_RTC32K_FRAC) + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); + else + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, + RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT); + + return 0; +} + +static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent) +{ + switch (clk->id) { + case CLK_RTC_32K: + return rk3568_rtc32k_set_parent(clk, parent); + default: + return -ENOENT; + } +} + +static struct clk_ops rk3568_pmuclk_ops = { + .get_rate = rk3568_pmuclk_get_rate, + .set_rate = rk3568_pmuclk_set_rate, + .set_parent = rk3568_pmuclk_set_parent, +}; + +static int rk3568_pmuclk_probe(struct udevice *dev) +{ + struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); + int ret = 0; + + if (priv->ppll_hz != PPLL_HZ) { + ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], + priv->pmucru, + PPLL, PPLL_HZ); + if (!ret) + priv->ppll_hz = PPLL_HZ; + } + + /* Ungate PCIe30phy refclk_m and refclk_n */ + rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13); + return 0; +} + +static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev) +{ + struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); + + priv->pmucru = dev_read_addr_ptr(dev); + + return 0; +} + +static int rk3568_pmuclk_bind(struct udevice *dev) +{ +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) + int ret = 0; + + ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]); + ret = rockchip_reset_bind(dev, ret, 1); + if (ret) + debug("Warning: pmucru software reset driver bind faile\n"); +#endif + + return 0; +} + +static const struct udevice_id rk3568_pmuclk_ids[] = { + { .compatible = "rockchip,rk3568-pmucru" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rk3568_pmucru) = { + .name = "rockchip_rk3568_pmucru", + .id = UCLASS_CLK, + .of_match = rk3568_pmuclk_ids, + .priv_auto = sizeof(struct rk3568_pmuclk_priv), + .of_to_plat = rk3568_pmuclk_ofdata_to_platdata, + .ops = &rk3568_pmuclk_ops, + .bind = rk3568_pmuclk_bind, + .probe = rk3568_pmuclk_probe, +#if CONFIG_IS_ENABLED(OF_PLATDATA) + .plat_auto = sizeof(struct rk3568_pmuclk_plat), +#endif + +}; + +static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz) +{ + struct rk3568_cru *cru = priv->cru; + const struct rockchip_cpu_rate_table *rate; + ulong old_rate; + + rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz); + if (!rate) { + printf("%s unsupported rate\n", __func__); + return -EINVAL; + } + + rk_clrsetreg(&cru->clksel_con[0], + CLK_CORE_PRE_SEL_MASK, + (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT)); + rk_clrsetreg(&cru->clksel_con[2], + SCLK_CORE_PRE_SEL_MASK | + SCLK_CORE_SRC_SEL_MASK | + SCLK_CORE_SRC_DIV_MASK, + (SCLK_CORE_PRE_SEL_SRC << + SCLK_CORE_PRE_SEL_SHIFT) | + (SCLK_CORE_SRC_SEL_APLL << + SCLK_CORE_SRC_SEL_SHIFT) | + (1 << SCLK_CORE_SRC_DIV_SHIFT)); + + /* + * set up dependent divisors for DBG and ACLK clocks. + */ + old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], + priv->cru, APLL); + if (old_rate > hz) { + if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], + priv->cru, APLL, hz)) + return -EINVAL; + rk_clrsetreg(&cru->clksel_con[3], + GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, + rate->pclk_div << GICCLK_CORE_DIV_SHIFT | + rate->pclk_div << ATCLK_CORE_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[4], + PERIPHCLK_CORE_PRE_DIV_MASK | + PCLK_CORE_PRE_DIV_MASK, + rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | + rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[5], + ACLK_CORE_NDFT_DIV_MASK, + rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); + } else if (old_rate < hz) { + rk_clrsetreg(&cru->clksel_con[3], + GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, + rate->pclk_div << GICCLK_CORE_DIV_SHIFT | + rate->pclk_div << ATCLK_CORE_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[4], + PERIPHCLK_CORE_PRE_DIV_MASK | + PCLK_CORE_PRE_DIV_MASK, + rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | + rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[5], + ACLK_CORE_NDFT_DIV_MASK, + rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); + if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], + priv->cru, APLL, hz)) + return -EINVAL; + } + + return 0; +} + +static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv, + ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + int div, mask, shift, con; + + switch (clk_id) { + case CPLL_500M: + con = 78; + mask = CPLL_500M_DIV_MASK; + shift = CPLL_500M_DIV_SHIFT; + break; + case CPLL_333M: + con = 79; + mask = CPLL_333M_DIV_MASK; + shift = CPLL_333M_DIV_SHIFT; + break; + case CPLL_250M: + con = 79; + mask = CPLL_250M_DIV_MASK; + shift = CPLL_250M_DIV_SHIFT; + break; + case CPLL_125M: + con = 80; + mask = CPLL_125M_DIV_MASK; + shift = CPLL_125M_DIV_SHIFT; + break; + case CPLL_100M: + con = 82; + mask = CPLL_100M_DIV_MASK; + shift = CPLL_100M_DIV_SHIFT; + break; + case CPLL_62P5M: + con = 80; + mask = CPLL_62P5M_DIV_MASK; + shift = CPLL_62P5M_DIV_SHIFT; + break; + case CPLL_50M: + con = 81; + mask = CPLL_50M_DIV_MASK; + shift = CPLL_50M_DIV_SHIFT; + break; + case CPLL_25M: + con = 81; + mask = CPLL_25M_DIV_MASK; + shift = CPLL_25M_DIV_SHIFT; + break; + default: + return -ENOENT; + } + + div = (readl(&cru->clksel_con[con]) & mask) >> shift; + return DIV_TO_RATE(priv->cpll_hz, div); +} + +static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int div, mask, shift, con; + + switch (clk_id) { + case CPLL_500M: + con = 78; + mask = CPLL_500M_DIV_MASK; + shift = CPLL_500M_DIV_SHIFT; + break; + case CPLL_333M: + con = 79; + mask = CPLL_333M_DIV_MASK; + shift = CPLL_333M_DIV_SHIFT; + break; + case CPLL_250M: + con = 79; + mask = CPLL_250M_DIV_MASK; + shift = CPLL_250M_DIV_SHIFT; + break; + case CPLL_125M: + con = 80; + mask = CPLL_125M_DIV_MASK; + shift = CPLL_125M_DIV_SHIFT; + break; + case CPLL_100M: + con = 82; + mask = CPLL_100M_DIV_MASK; + shift = CPLL_100M_DIV_SHIFT; + break; + case CPLL_62P5M: + con = 80; + mask = CPLL_62P5M_DIV_MASK; + shift = CPLL_62P5M_DIV_SHIFT; + break; + case CPLL_50M: + con = 81; + mask = CPLL_50M_DIV_MASK; + shift = CPLL_50M_DIV_SHIFT; + break; + case CPLL_25M: + con = 81; + mask = CPLL_25M_DIV_MASK; + shift = CPLL_25M_DIV_SHIFT; + break; + default: + return -ENOENT; + } + + div = DIV_ROUND_UP(priv->cpll_hz, rate); + assert(div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[con], + mask, (div - 1) << shift); + return rk3568_cpll_div_get_rate(priv, clk_id); +} + +static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, sel, rate; + + switch (clk_id) { + case ACLK_BUS: + con = readl(&cru->clksel_con[50]); + sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT; + if (sel == ACLK_BUS_SEL_200M) + rate = 200 * MHz; + else if (sel == ACLK_BUS_SEL_150M) + rate = 150 * MHz; + else if (sel == ACLK_BUS_SEL_100M) + rate = 100 * MHz; + else + rate = OSC_HZ; + break; + case PCLK_BUS: + case PCLK_WDT_NS: + con = readl(&cru->clksel_con[50]); + sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT; + if (sel == PCLK_BUS_SEL_100M) + rate = 100 * MHz; + else if (sel == PCLK_BUS_SEL_75M) + rate = 75 * MHz; + else if (sel == PCLK_BUS_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (clk_id) { + case ACLK_BUS: + if (rate == 200 * MHz) + src_clk = ACLK_BUS_SEL_200M; + else if (rate == 150 * MHz) + src_clk = ACLK_BUS_SEL_150M; + else if (rate == 100 * MHz) + src_clk = ACLK_BUS_SEL_100M; + else + src_clk = ACLK_BUS_SEL_24M; + rk_clrsetreg(&cru->clksel_con[50], + ACLK_BUS_SEL_MASK, + src_clk << ACLK_BUS_SEL_SHIFT); + break; + case PCLK_BUS: + case PCLK_WDT_NS: + if (rate == 100 * MHz) + src_clk = PCLK_BUS_SEL_100M; + else if (rate == 75 * MHz) + src_clk = PCLK_BUS_SEL_75M; + else if (rate == 50 * MHz) + src_clk = PCLK_BUS_SEL_50M; + else + src_clk = PCLK_BUS_SEL_24M; + rk_clrsetreg(&cru->clksel_con[50], + PCLK_BUS_SEL_MASK, + src_clk << PCLK_BUS_SEL_SHIFT); + break; + + default: + printf("do not support this bus freq\n"); + return -EINVAL; + } + + return rk3568_bus_get_clk(priv, clk_id); +} + +static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, sel, rate; + + switch (clk_id) { + case ACLK_PERIMID: + con = readl(&cru->clksel_con[10]); + sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT; + if (sel == ACLK_PERIMID_SEL_300M) + rate = 300 * MHz; + else if (sel == ACLK_PERIMID_SEL_200M) + rate = 200 * MHz; + else if (sel == ACLK_PERIMID_SEL_100M) + rate = 100 * MHz; + else + rate = OSC_HZ; + break; + case HCLK_PERIMID: + con = readl(&cru->clksel_con[10]); + sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT; + if (sel == HCLK_PERIMID_SEL_150M) + rate = 150 * MHz; + else if (sel == HCLK_PERIMID_SEL_100M) + rate = 100 * MHz; + else if (sel == HCLK_PERIMID_SEL_75M) + rate = 75 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (clk_id) { + case ACLK_PERIMID: + if (rate == 300 * MHz) + src_clk = ACLK_PERIMID_SEL_300M; + else if (rate == 200 * MHz) + src_clk = ACLK_PERIMID_SEL_200M; + else if (rate == 100 * MHz) + src_clk = ACLK_PERIMID_SEL_100M; + else + src_clk = ACLK_PERIMID_SEL_24M; + rk_clrsetreg(&cru->clksel_con[10], + ACLK_PERIMID_SEL_MASK, + src_clk << ACLK_PERIMID_SEL_SHIFT); + break; + case HCLK_PERIMID: + if (rate == 150 * MHz) + src_clk = HCLK_PERIMID_SEL_150M; + else if (rate == 100 * MHz) + src_clk = HCLK_PERIMID_SEL_100M; + else if (rate == 75 * MHz) + src_clk = HCLK_PERIMID_SEL_75M; + else + src_clk = HCLK_PERIMID_SEL_24M; + rk_clrsetreg(&cru->clksel_con[10], + HCLK_PERIMID_SEL_MASK, + src_clk << HCLK_PERIMID_SEL_SHIFT); + break; + + default: + printf("do not support this permid freq\n"); + return -EINVAL; + } + + return rk3568_perimid_get_clk(priv, clk_id); +} + +static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, sel, rate; + + switch (clk_id) { + case ACLK_TOP_HIGH: + con = readl(&cru->clksel_con[73]); + sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT; + if (sel == ACLK_TOP_HIGH_SEL_500M) + rate = 500 * MHz; + else if (sel == ACLK_TOP_HIGH_SEL_400M) + rate = 400 * MHz; + else if (sel == ACLK_TOP_HIGH_SEL_300M) + rate = 300 * MHz; + else + rate = OSC_HZ; + break; + case ACLK_TOP_LOW: + con = readl(&cru->clksel_con[73]); + sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT; + if (sel == ACLK_TOP_LOW_SEL_400M) + rate = 400 * MHz; + else if (sel == ACLK_TOP_LOW_SEL_300M) + rate = 300 * MHz; + else if (sel == ACLK_TOP_LOW_SEL_200M) + rate = 200 * MHz; + else + rate = OSC_HZ; + break; + case HCLK_TOP: + con = readl(&cru->clksel_con[73]); + sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT; + if (sel == HCLK_TOP_SEL_150M) + rate = 150 * MHz; + else if (sel == HCLK_TOP_SEL_100M) + rate = 100 * MHz; + else if (sel == HCLK_TOP_SEL_75M) + rate = 75 * MHz; + else + rate = OSC_HZ; + break; + case PCLK_TOP: + con = readl(&cru->clksel_con[73]); + sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; + if (sel == PCLK_TOP_SEL_100M) + rate = 100 * MHz; + else if (sel == PCLK_TOP_SEL_75M) + rate = 75 * MHz; + else if (sel == PCLK_TOP_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (clk_id) { + case ACLK_TOP_HIGH: + if (rate == 500 * MHz) + src_clk = ACLK_TOP_HIGH_SEL_500M; + else if (rate == 400 * MHz) + src_clk = ACLK_TOP_HIGH_SEL_400M; + else if (rate == 300 * MHz) + src_clk = ACLK_TOP_HIGH_SEL_300M; + else + src_clk = ACLK_TOP_HIGH_SEL_24M; + rk_clrsetreg(&cru->clksel_con[73], + ACLK_TOP_HIGH_SEL_MASK, + src_clk << ACLK_TOP_HIGH_SEL_SHIFT); + break; + case ACLK_TOP_LOW: + if (rate == 400 * MHz) + src_clk = ACLK_TOP_LOW_SEL_400M; + else if (rate == 300 * MHz) + src_clk = ACLK_TOP_LOW_SEL_300M; + else if (rate == 200 * MHz) + src_clk = ACLK_TOP_LOW_SEL_200M; + else + src_clk = ACLK_TOP_LOW_SEL_24M; + rk_clrsetreg(&cru->clksel_con[73], + ACLK_TOP_LOW_SEL_MASK, + src_clk << ACLK_TOP_LOW_SEL_SHIFT); + break; + case HCLK_TOP: + if (rate == 150 * MHz) + src_clk = HCLK_TOP_SEL_150M; + else if (rate == 100 * MHz) + src_clk = HCLK_TOP_SEL_100M; + else if (rate == 75 * MHz) + src_clk = HCLK_TOP_SEL_75M; + else + src_clk = HCLK_TOP_SEL_24M; + rk_clrsetreg(&cru->clksel_con[73], + HCLK_TOP_SEL_MASK, + src_clk << HCLK_TOP_SEL_SHIFT); + break; + case PCLK_TOP: + if (rate == 100 * MHz) + src_clk = PCLK_TOP_SEL_100M; + else if (rate == 75 * MHz) + src_clk = PCLK_TOP_SEL_75M; + else if (rate == 50 * MHz) + src_clk = PCLK_TOP_SEL_50M; + else + src_clk = PCLK_TOP_SEL_24M; + rk_clrsetreg(&cru->clksel_con[73], + PCLK_TOP_SEL_MASK, + src_clk << PCLK_TOP_SEL_SHIFT); + break; + + default: + printf("do not support this permid freq\n"); + return -EINVAL; + } + + return rk3568_top_get_clk(priv, clk_id); +} + +static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + ulong rate; + + switch (clk_id) { + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT; + if (sel == CLK_I2C_SEL_200M) + rate = 200 * MHz; + else if (sel == CLK_I2C_SEL_100M) + rate = 100 * MHz; + else if (sel == CLK_I2C_SEL_CPLL_100M) + rate = 100 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + if (rate == 200 * MHz) + src_clk = CLK_I2C_SEL_200M; + else if (rate == 100 * MHz) + src_clk = CLK_I2C_SEL_100M; + else + src_clk = CLK_I2C_SEL_24M; + + switch (clk_id) { + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK, + src_clk << CLK_I2C_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_i2c_get_clk(priv, clk_id); +} + +static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[72]); + + switch (clk_id) { + case CLK_SPI0: + sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; + break; + case CLK_SPI1: + sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; + break; + case CLK_SPI2: + sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; + break; + case CLK_SPI3: + sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + switch (sel) { + case CLK_SPI_SEL_200M: + return 200 * MHz; + case CLK_SPI_SEL_24M: + return OSC_HZ; + case CLK_SPI_SEL_CPLL_100M: + return 100 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + if (rate == 200 * MHz) + src_clk = CLK_SPI_SEL_200M; + else if (rate == 100 * MHz) + src_clk = CLK_SPI_SEL_CPLL_100M; + else + src_clk = CLK_SPI_SEL_24M; + + switch (clk_id) { + case CLK_SPI0: + rk_clrsetreg(&cru->clksel_con[72], + CLK_SPI0_SEL_MASK, + src_clk << CLK_SPI0_SEL_SHIFT); + break; + case CLK_SPI1: + rk_clrsetreg(&cru->clksel_con[72], + CLK_SPI1_SEL_MASK, + src_clk << CLK_SPI1_SEL_SHIFT); + break; + case CLK_SPI2: + rk_clrsetreg(&cru->clksel_con[72], + CLK_SPI2_SEL_MASK, + src_clk << CLK_SPI2_SEL_SHIFT); + break; + case CLK_SPI3: + rk_clrsetreg(&cru->clksel_con[72], + CLK_SPI3_SEL_MASK, + src_clk << CLK_SPI3_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_spi_get_clk(priv, clk_id); +} + +static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[72]); + + switch (clk_id) { + case CLK_PWM1: + sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; + break; + case CLK_PWM2: + sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; + break; + case CLK_PWM3: + sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + switch (sel) { + case CLK_PWM_SEL_100M: + return 100 * MHz; + case CLK_PWM_SEL_24M: + return OSC_HZ; + case CLK_PWM_SEL_CPLL_100M: + return 100 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + if (rate == 100 * MHz) + src_clk = CLK_PWM_SEL_100M; + else + src_clk = CLK_PWM_SEL_24M; + + switch (clk_id) { + case CLK_PWM1: + rk_clrsetreg(&cru->clksel_con[72], + CLK_PWM1_SEL_MASK, + src_clk << CLK_PWM1_SEL_SHIFT); + break; + case CLK_PWM2: + rk_clrsetreg(&cru->clksel_con[72], + CLK_PWM2_SEL_MASK, + src_clk << CLK_PWM2_SEL_SHIFT); + break; + case CLK_PWM3: + rk_clrsetreg(&cru->clksel_con[72], + CLK_PWM3_SEL_MASK, + src_clk << CLK_PWM3_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_pwm_get_clk(priv, clk_id); +} + +static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 div, sel, con, prate; + + switch (clk_id) { + case CLK_SARADC: + return OSC_HZ; + case CLK_TSADC_TSEN: + con = readl(&cru->clksel_con[51]); + div = (con & CLK_TSADC_TSEN_DIV_MASK) >> + CLK_TSADC_TSEN_DIV_SHIFT; + sel = (con & CLK_TSADC_TSEN_SEL_MASK) >> + CLK_TSADC_TSEN_SEL_SHIFT; + if (sel == CLK_TSADC_TSEN_SEL_24M) + prate = OSC_HZ; + else + prate = 100 * MHz; + return DIV_TO_RATE(prate, div); + case CLK_TSADC: + con = readl(&cru->clksel_con[51]); + div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT; + prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); + return DIV_TO_RATE(prate, div); + default: + return -ENOENT; + } +} + +static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk_div; + ulong prate = 0; + + switch (clk_id) { + case CLK_SARADC: + return OSC_HZ; + case CLK_TSADC_TSEN: + if (!(OSC_HZ % rate)) { + src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); + assert(src_clk_div - 1 <= 7); + rk_clrsetreg(&cru->clksel_con[51], + CLK_TSADC_TSEN_SEL_MASK | + CLK_TSADC_TSEN_DIV_MASK, + (CLK_TSADC_TSEN_SEL_24M << + CLK_TSADC_TSEN_SEL_SHIFT) | + (src_clk_div - 1) << + CLK_TSADC_TSEN_DIV_SHIFT); + } else { + src_clk_div = DIV_ROUND_UP(100 * MHz, rate); + assert(src_clk_div - 1 <= 7); + rk_clrsetreg(&cru->clksel_con[51], + CLK_TSADC_TSEN_SEL_MASK | + CLK_TSADC_TSEN_DIV_MASK, + (CLK_TSADC_TSEN_SEL_100M << + CLK_TSADC_TSEN_SEL_SHIFT) | + (src_clk_div - 1) << + CLK_TSADC_TSEN_DIV_SHIFT); + } + break; + case CLK_TSADC: + prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); + src_clk_div = DIV_ROUND_UP(prate, rate); + assert(src_clk_div - 1 <= 128); + rk_clrsetreg(&cru->clksel_con[51], + CLK_TSADC_DIV_MASK, + (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT); + break; + default: + return -ENOENT; + } + return rk3568_adc_get_clk(priv, clk_id); +} + +static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + switch (clk_id) { + case ACLK_SECURE_FLASH: + case ACLK_CRYPTO_NS: + con = readl(&cru->clksel_con[27]); + sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >> + ACLK_SECURE_FLASH_SEL_SHIFT; + if (sel == ACLK_SECURE_FLASH_SEL_200M) + return 200 * MHz; + else if (sel == ACLK_SECURE_FLASH_SEL_150M) + return 150 * MHz; + else if (sel == ACLK_SECURE_FLASH_SEL_100M) + return 100 * MHz; + else + return 24 * MHz; + case HCLK_SECURE_FLASH: + case HCLK_CRYPTO_NS: + case CLK_CRYPTO_NS_RNG: + con = readl(&cru->clksel_con[27]); + sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >> + HCLK_SECURE_FLASH_SEL_SHIFT; + if (sel == HCLK_SECURE_FLASH_SEL_150M) + return 150 * MHz; + else if (sel == HCLK_SECURE_FLASH_SEL_100M) + return 100 * MHz; + else if (sel == HCLK_SECURE_FLASH_SEL_75M) + return 75 * MHz; + else + return 24 * MHz; + case CLK_CRYPTO_NS_CORE: + con = readl(&cru->clksel_con[27]); + sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> + CLK_CRYPTO_CORE_SEL_SHIFT; + if (sel == CLK_CRYPTO_CORE_SEL_200M) + return 200 * MHz; + else if (sel == CLK_CRYPTO_CORE_SEL_150M) + return 150 * MHz; + else + return 100 * MHz; + case CLK_CRYPTO_NS_PKA: + con = readl(&cru->clksel_con[27]); + sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> + CLK_CRYPTO_PKA_SEL_SHIFT; + if (sel == CLK_CRYPTO_PKA_SEL_300M) + return 300 * MHz; + else if (sel == CLK_CRYPTO_PKA_SEL_200M) + return 200 * MHz; + else + return 100 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + u32 src_clk, mask, shift; + + switch (clk_id) { + case ACLK_SECURE_FLASH: + case ACLK_CRYPTO_NS: + mask = ACLK_SECURE_FLASH_SEL_MASK; + shift = ACLK_SECURE_FLASH_SEL_SHIFT; + if (rate == 200 * MHz) + src_clk = ACLK_SECURE_FLASH_SEL_200M; + else if (rate == 150 * MHz) + src_clk = ACLK_SECURE_FLASH_SEL_150M; + else if (rate == 100 * MHz) + src_clk = ACLK_SECURE_FLASH_SEL_100M; + else + src_clk = ACLK_SECURE_FLASH_SEL_24M; + break; + case HCLK_SECURE_FLASH: + case HCLK_CRYPTO_NS: + case CLK_CRYPTO_NS_RNG: + mask = HCLK_SECURE_FLASH_SEL_MASK; + shift = HCLK_SECURE_FLASH_SEL_SHIFT; + if (rate == 150 * MHz) + src_clk = HCLK_SECURE_FLASH_SEL_150M; + else if (rate == 100 * MHz) + src_clk = HCLK_SECURE_FLASH_SEL_100M; + else if (rate == 75 * MHz) + src_clk = HCLK_SECURE_FLASH_SEL_75M; + else + src_clk = HCLK_SECURE_FLASH_SEL_24M; + break; + case CLK_CRYPTO_NS_CORE: + mask = CLK_CRYPTO_CORE_SEL_MASK; + shift = CLK_CRYPTO_CORE_SEL_SHIFT; + if (rate == 200 * MHz) + src_clk = CLK_CRYPTO_CORE_SEL_200M; + else if (rate == 150 * MHz) + src_clk = CLK_CRYPTO_CORE_SEL_150M; + else + src_clk = CLK_CRYPTO_CORE_SEL_100M; + break; + case CLK_CRYPTO_NS_PKA: + mask = CLK_CRYPTO_PKA_SEL_MASK; + shift = CLK_CRYPTO_PKA_SEL_SHIFT; + if (rate == 300 * MHz) + src_clk = CLK_CRYPTO_PKA_SEL_300M; + else if (rate == 200 * MHz) + src_clk = CLK_CRYPTO_PKA_SEL_200M; + else + src_clk = CLK_CRYPTO_PKA_SEL_100M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift); + + return rk3568_crypto_get_rate(priv, clk_id); +} + +static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + switch (clk_id) { + case HCLK_SDMMC0: + case CLK_SDMMC0: + con = readl(&cru->clksel_con[30]); + sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT; + break; + case CLK_SDMMC1: + con = readl(&cru->clksel_con[30]); + sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT; + break; + case CLK_SDMMC2: + con = readl(&cru->clksel_con[32]); + sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + switch (sel) { + case CLK_SDMMC_SEL_24M: + return OSC_HZ; + case CLK_SDMMC_SEL_400M: + return 400 * MHz; + case CLK_SDMMC_SEL_300M: + return 300 * MHz; + case CLK_SDMMC_SEL_100M: + return 100 * MHz; + case CLK_SDMMC_SEL_50M: + return 50 * MHz; + case CLK_SDMMC_SEL_750K: + return 750 * KHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case OSC_HZ: + src_clk = CLK_SDMMC_SEL_24M; + break; + case 400 * MHz: + src_clk = CLK_SDMMC_SEL_400M; + break; + case 300 * MHz: + src_clk = CLK_SDMMC_SEL_300M; + break; + case 100 * MHz: + src_clk = CLK_SDMMC_SEL_100M; + break; + case 52 * MHz: + case 50 * MHz: + src_clk = CLK_SDMMC_SEL_50M; + break; + case 750 * KHz: + case 400 * KHz: + src_clk = CLK_SDMMC_SEL_750K; + break; + default: + return -ENOENT; + } + + switch (clk_id) { + case HCLK_SDMMC0: + case CLK_SDMMC0: + rk_clrsetreg(&cru->clksel_con[30], + CLK_SDMMC0_SEL_MASK, + src_clk << CLK_SDMMC0_SEL_SHIFT); + break; + case CLK_SDMMC1: + rk_clrsetreg(&cru->clksel_con[30], + CLK_SDMMC1_SEL_MASK, + src_clk << CLK_SDMMC1_SEL_SHIFT); + break; + case CLK_SDMMC2: + rk_clrsetreg(&cru->clksel_con[32], + CLK_SDMMC2_SEL_MASK, + src_clk << CLK_SDMMC2_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_sdmmc_get_clk(priv, clk_id); +} + +static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[28]); + sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; + switch (sel) { + case SCLK_SFC_SEL_24M: + return OSC_HZ; + case SCLK_SFC_SEL_50M: + return 50 * MHz; + case SCLK_SFC_SEL_75M: + return 75 * MHz; + case SCLK_SFC_SEL_100M: + return 100 * MHz; + case SCLK_SFC_SEL_125M: + return 125 * MHz; + case SCLK_SFC_SEL_150M: + return 150 * KHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case OSC_HZ: + src_clk = SCLK_SFC_SEL_24M; + break; + case 50 * MHz: + src_clk = SCLK_SFC_SEL_50M; + break; + case 75 * MHz: + src_clk = SCLK_SFC_SEL_75M; + break; + case 100 * MHz: + src_clk = SCLK_SFC_SEL_100M; + break; + case 125 * MHz: + src_clk = SCLK_SFC_SEL_125M; + break; + case 150 * KHz: + src_clk = SCLK_SFC_SEL_150M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[28], + SCLK_SFC_SEL_MASK, + src_clk << SCLK_SFC_SEL_SHIFT); + + return rk3568_sfc_get_clk(priv); +} + +static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[28]); + sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT; + switch (sel) { + case NCLK_NANDC_SEL_200M: + return 200 * MHz; + case NCLK_NANDC_SEL_150M: + return 150 * MHz; + case NCLK_NANDC_SEL_100M: + return 100 * MHz; + case NCLK_NANDC_SEL_24M: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case OSC_HZ: + src_clk = NCLK_NANDC_SEL_24M; + break; + case 100 * MHz: + src_clk = NCLK_NANDC_SEL_100M; + break; + case 150 * MHz: + src_clk = NCLK_NANDC_SEL_150M; + break; + case 200 * MHz: + src_clk = NCLK_NANDC_SEL_200M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[28], + NCLK_NANDC_SEL_MASK, + src_clk << NCLK_NANDC_SEL_SHIFT); + + return rk3568_nand_get_clk(priv); +} + +static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[28]); + sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT; + switch (sel) { + case CCLK_EMMC_SEL_200M: + return 200 * MHz; + case CCLK_EMMC_SEL_150M: + return 150 * MHz; + case CCLK_EMMC_SEL_100M: + return 100 * MHz; + case CCLK_EMMC_SEL_50M: + return 50 * MHz; + case CCLK_EMMC_SEL_375K: + return 375 * KHz; + case CCLK_EMMC_SEL_24M: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case OSC_HZ: + src_clk = CCLK_EMMC_SEL_24M; + break; + case 52 * MHz: + case 50 * MHz: + src_clk = CCLK_EMMC_SEL_50M; + break; + case 100 * MHz: + src_clk = CCLK_EMMC_SEL_100M; + break; + case 150 * MHz: + src_clk = CCLK_EMMC_SEL_150M; + break; + case 200 * MHz: + src_clk = CCLK_EMMC_SEL_200M; + break; + case 400 * KHz: + case 375 * KHz: + src_clk = CCLK_EMMC_SEL_375K; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[28], + CCLK_EMMC_SEL_MASK, + src_clk << CCLK_EMMC_SEL_SHIFT); + + return rk3568_emmc_get_clk(priv); +} + +#ifndef CONFIG_SPL_BUILD +static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 div, sel, con, parent; + + con = readl(&cru->clksel_con[38]); + div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT; + sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT; + if (sel == ACLK_VOP_PRE_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_VOP_PRE_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == ACLK_VOP_PRE_SEL_VPLL) + parent = priv->vpll_hz; + else + parent = priv->hpll_hz; + + return DIV_TO_RATE(parent, div); +} + +static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk_div, src_clk_mux; + + if ((priv->cpll_hz % rate) == 0) { + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + src_clk_mux = ACLK_VOP_PRE_SEL_CPLL; + } else { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + src_clk_mux = ACLK_VOP_PRE_SEL_GPLL; + } + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[38], + ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK, + src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT | + (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT); + + return rk3568_aclk_vop_get_clk(priv); +} + +static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 conid, div, sel, con, parent; + + switch (clk_id) { + case DCLK_VOP0: + conid = 39; + break; + case DCLK_VOP1: + conid = 40; + break; + case DCLK_VOP2: + conid = 41; + break; + default: + return -ENOENT; + } + + con = readl(&cru->clksel_con[conid]); + div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT; + sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; + if (sel == DCLK_VOP_SEL_HPLL) + parent = rk3568_pmu_pll_get_rate(priv, HPLL); + else if (sel == DCLK_VOP_SEL_VPLL) + parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], + priv->cru, VPLL); + else if (sel == DCLK_VOP_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == DCLK_VOP_SEL_CPLL) + parent = priv->cpll_hz; + else + return -ENOENT; + + return DIV_TO_RATE(parent, div); +} + +#define RK3568_VOP_PLL_LIMIT_FREQ 600000000 + +static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + ulong pll_rate, now, best_rate = 0; + u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; + + switch (clk_id) { + case DCLK_VOP0: + conid = 39; + break; + case DCLK_VOP1: + conid = 40; + break; + case DCLK_VOP2: + conid = 41; + break; + default: + return -ENOENT; + } + + con = readl(&cru->clksel_con[conid]); + sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; + + if (sel == DCLK_VOP_SEL_HPLL) { + div = 1; + rk_clrsetreg(&cru->clksel_con[conid], + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, + (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) | + ((div - 1) << DCLK0_VOP_DIV_SHIFT)); + rk3568_pmu_pll_set_rate(priv, HPLL, div * rate); + } else if (sel == DCLK_VOP_SEL_VPLL) { + div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate); + rk_clrsetreg(&cru->clksel_con[conid], + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, + (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) | + ((div - 1) << DCLK0_VOP_DIV_SHIFT)); + rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], + priv->cru, VPLL, div * rate); + } else { + for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) { + switch (i) { + case DCLK_VOP_SEL_GPLL: + pll_rate = priv->gpll_hz; + break; + case DCLK_VOP_SEL_CPLL: + pll_rate = priv->cpll_hz; + break; + default: + printf("do not support this vop pll sel\n"); + return -EINVAL; + } + + div = DIV_ROUND_UP(pll_rate, rate); + if (div > 255) + continue; + now = pll_rate / div; + if (abs(rate - now) < abs(rate - best_rate)) { + best_rate = now; + best_div = div; + best_sel = i; + } + debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", + pll_rate, best_rate, best_div, best_sel); + } + + if (best_rate) { + rk_clrsetreg(&cru->clksel_con[conid], + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, + best_sel << DCLK0_VOP_SEL_SHIFT | + (best_div - 1) << DCLK0_VOP_DIV_SHIFT); + } else { + printf("do not support this vop freq %lu\n", rate); + return -EINVAL; + } + } + return rk3568_dclk_vop_get_clk(priv, clk_id); +} + +static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv, + ulong mac_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[31 + mac_id * 2]); + sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT; + + switch (sel) { + case CLK_MAC0_2TOP_SEL_125M: + return 125 * MHz; + case CLK_MAC0_2TOP_SEL_50M: + return 50 * MHz; + case CLK_MAC0_2TOP_SEL_25M: + return 25 * MHz; + case CLK_MAC0_2TOP_SEL_PPLL: + return rk3568_pmu_pll_get_rate(priv, HPLL); + default: + return -ENOENT; + } +} + +static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv, + ulong mac_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case 125 * MHz: + src_clk = CLK_MAC0_2TOP_SEL_125M; + break; + case 50 * MHz: + src_clk = CLK_MAC0_2TOP_SEL_50M; + break; + case 25 * MHz: + src_clk = CLK_MAC0_2TOP_SEL_25M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], + CLK_MAC0_2TOP_SEL_MASK, + src_clk << CLK_MAC0_2TOP_SEL_SHIFT); + + return rk3568_gmac_src_get_clk(priv, mac_id); +} + +static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv, + ulong mac_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[31 + mac_id * 2]); + sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT; + + switch (sel) { + case CLK_MAC0_OUT_SEL_125M: + return 125 * MHz; + case CLK_MAC0_OUT_SEL_50M: + return 50 * MHz; + case CLK_MAC0_OUT_SEL_25M: + return 25 * MHz; + case CLK_MAC0_OUT_SEL_24M: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv, + ulong mac_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case 125 * MHz: + src_clk = CLK_MAC0_OUT_SEL_125M; + break; + case 50 * MHz: + src_clk = CLK_MAC0_OUT_SEL_50M; + break; + case 25 * MHz: + src_clk = CLK_MAC0_OUT_SEL_25M; + break; + case 24 * MHz: + src_clk = CLK_MAC0_OUT_SEL_24M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], + CLK_MAC0_OUT_SEL_MASK, + src_clk << CLK_MAC0_OUT_SEL_SHIFT); + + return rk3568_gmac_out_get_clk(priv, mac_id); +} + +static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv, + ulong mac_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[31 + mac_id * 2]); + sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT; + + switch (sel) { + case CLK_GMAC0_PTP_REF_SEL_62_5M: + return 62500 * KHz; + case CLK_GMAC0_PTP_REF_SEL_100M: + return 100 * MHz; + case CLK_GMAC0_PTP_REF_SEL_50M: + return 50 * MHz; + case CLK_GMAC0_PTP_REF_SEL_24M: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv, + ulong mac_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case 62500 * KHz: + src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M; + break; + case 100 * MHz: + src_clk = CLK_GMAC0_PTP_REF_SEL_100M; + break; + case 50 * MHz: + src_clk = CLK_GMAC0_PTP_REF_SEL_50M; + break; + case 24 * MHz: + src_clk = CLK_GMAC0_PTP_REF_SEL_24M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], + CLK_GMAC0_PTP_REF_SEL_MASK, + src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT); + + return rk3568_gmac_ptp_ref_get_clk(priv, mac_id); +} + +static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv, + ulong mac_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, sel, div_sel; + + con = readl(&cru->clksel_con[31 + mac_id * 2]); + sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT; + + if (sel == RMII0_MODE_SEL_RGMII) { + if (rate == 2500000) + div_sel = RGMII0_CLK_SEL_2_5M; + else if (rate == 25000000) + div_sel = RGMII0_CLK_SEL_25M; + else + div_sel = RGMII0_CLK_SEL_125M; + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], + RGMII0_CLK_SEL_MASK, + div_sel << RGMII0_CLK_SEL_SHIFT); + } else if (sel == RMII0_MODE_SEL_RMII) { + if (rate == 2500000) + div_sel = RMII0_CLK_SEL_2_5M; + else + div_sel = RMII0_CLK_SEL_25M; + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], + RMII0_CLK_SEL_MASK, + div_sel << RMII0_CLK_SEL_SHIFT); + } + + return 0; +} + +static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, div, p_rate; + + con = readl(&cru->clksel_con[79]); + div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT; + p_rate = DIV_TO_RATE(priv->cpll_hz, div); + + con = readl(&cru->clksel_con[43]); + div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; + switch (div) { + case DCLK_EBC_SEL_GPLL_400M: + return 400 * MHz; + case DCLK_EBC_SEL_CPLL_333M: + return p_rate; + case DCLK_EBC_SEL_GPLL_200M: + return 200 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[79], + CPLL_333M_DIV_MASK, + (src_clk_div - 1) << CPLL_333M_DIV_SHIFT); + rk_clrsetreg(&cru->clksel_con[43], + DCLK_EBC_SEL_MASK, + DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT); + + return rk3568_ebc_get_clk(priv); +} + +static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, div, src, p_rate; + + switch (clk_id) { + case ACLK_RKVDEC_PRE: + case ACLK_RKVDEC: + con = readl(&cru->clksel_con[47]); + src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT; + div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT; + if (src == ACLK_RKVDEC_SEL_CPLL) + p_rate = priv->cpll_hz; + else + p_rate = priv->gpll_hz; + return DIV_TO_RATE(p_rate, div); + case CLK_RKVDEC_CORE: + con = readl(&cru->clksel_con[49]); + src = (con & CLK_RKVDEC_CORE_SEL_MASK) + >> CLK_RKVDEC_CORE_SEL_SHIFT; + div = (con & CLK_RKVDEC_CORE_DIV_MASK) + >> CLK_RKVDEC_CORE_DIV_SHIFT; + if (src == CLK_RKVDEC_CORE_SEL_CPLL) + p_rate = priv->cpll_hz; + else if (src == CLK_RKVDEC_CORE_SEL_NPLL) + p_rate = priv->npll_hz; + else if (src == CLK_RKVDEC_CORE_SEL_VPLL) + p_rate = priv->vpll_hz; + else + p_rate = priv->gpll_hz; + return DIV_TO_RATE(p_rate, div); + default: + return -ENOENT; + } +} + +static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk_div, src, p_rate; + + switch (clk_id) { + case ACLK_RKVDEC_PRE: + case ACLK_RKVDEC: + src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK) + >> ACLK_RKVDEC_SEL_SHIFT; + if (src == ACLK_RKVDEC_SEL_CPLL) + p_rate = priv->cpll_hz; + else + p_rate = priv->gpll_hz; + src_clk_div = DIV_ROUND_UP(p_rate, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[47], + ACLK_RKVDEC_SEL_MASK | + ACLK_RKVDEC_DIV_MASK, + (src << ACLK_RKVDEC_SEL_SHIFT) | + (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT); + break; + case CLK_RKVDEC_CORE: + src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK) + >> CLK_RKVDEC_CORE_SEL_SHIFT; + if (src == CLK_RKVDEC_CORE_SEL_CPLL) + p_rate = priv->cpll_hz; + else if (src == CLK_RKVDEC_CORE_SEL_NPLL) + p_rate = priv->npll_hz; + else if (src == CLK_RKVDEC_CORE_SEL_VPLL) + p_rate = priv->vpll_hz; + else + p_rate = priv->gpll_hz; + src_clk_div = DIV_ROUND_UP(p_rate, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[49], + CLK_RKVDEC_CORE_SEL_MASK | + CLK_RKVDEC_CORE_DIV_MASK, + (src << CLK_RKVDEC_CORE_SEL_SHIFT) | + (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3568_rkvdec_get_clk(priv, clk_id); +} + +static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 reg, con, fracdiv, div, src, p_src, p_rate; + unsigned long m, n; + + switch (clk_id) { + case SCLK_UART1: + reg = 52; + break; + case SCLK_UART2: + reg = 54; + break; + case SCLK_UART3: + reg = 56; + break; + case SCLK_UART4: + reg = 58; + break; + case SCLK_UART5: + reg = 60; + break; + case SCLK_UART6: + reg = 62; + break; + case SCLK_UART7: + reg = 64; + break; + case SCLK_UART8: + reg = 66; + break; + case SCLK_UART9: + reg = 68; + break; + default: + return -ENOENT; + } + con = readl(&cru->clksel_con[reg]); + src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; + div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; + p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; + if (p_src == CLK_UART_SRC_SEL_GPLL) + p_rate = priv->gpll_hz; + else if (p_src == CLK_UART_SRC_SEL_CPLL) + p_rate = priv->cpll_hz; + else + p_rate = 480000000; + if (src == CLK_UART_SEL_SRC) { + return DIV_TO_RATE(p_rate, div); + } else if (src == CLK_UART_SEL_FRAC) { + fracdiv = readl(&cru->clksel_con[reg + 1]); + n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; + n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; + m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; + m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; + return DIV_TO_RATE(p_rate, div) * n / m; + } else { + return OSC_HZ; + } +} + +static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + u32 reg, clk_src, uart_src, div; + unsigned long m = 0, n = 0, val; + + if (priv->gpll_hz % rate == 0) { + clk_src = CLK_UART_SRC_SEL_GPLL; + uart_src = CLK_UART_SEL_SRC; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } else if (priv->cpll_hz % rate == 0) { + clk_src = CLK_UART_SRC_SEL_CPLL; + uart_src = CLK_UART_SEL_SRC; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } else if (rate == OSC_HZ) { + clk_src = CLK_UART_SRC_SEL_GPLL; + uart_src = CLK_UART_SEL_XIN24M; + div = 2; + } else { + clk_src = CLK_UART_SRC_SEL_GPLL; + uart_src = CLK_UART_SEL_FRAC; + div = 2; + rational_best_approximation(rate, priv->gpll_hz / div, + GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), + &m, &n); + } + + switch (clk_id) { + case SCLK_UART1: + reg = 52; + break; + case SCLK_UART2: + reg = 54; + break; + case SCLK_UART3: + reg = 56; + break; + case SCLK_UART4: + reg = 58; + break; + case SCLK_UART5: + reg = 60; + break; + case SCLK_UART6: + reg = 62; + break; + case SCLK_UART7: + reg = 64; + break; + case SCLK_UART8: + reg = 66; + break; + case SCLK_UART9: + reg = 68; + break; + default: + return -ENOENT; + } + rk_clrsetreg(&cru->clksel_con[reg], + CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK | + CLK_UART_SRC_DIV_MASK, + (clk_src << CLK_UART_SRC_SEL_SHIFT) | + (uart_src << CLK_UART_SEL_SHIFT) | + ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); + if (m && n) { + val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; + writel(val, &cru->clksel_con[reg + 1]); + } + + return rk3568_uart_get_rate(priv, clk_id); +} +#endif + +static ulong rk3568_clk_get_rate(struct clk *clk) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + switch (clk->id) { + case PLL_APLL: + case ARMCLK: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru, + APLL); + break; + case PLL_CPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru, + CPLL); + break; + case PLL_GPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru, + GPLL); + break; + case PLL_NPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru, + NPLL); + break; + case PLL_VPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru, + VPLL); + break; + case PLL_DPLL: + rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru, + DPLL); + break; + case ACLK_BUS: + case PCLK_BUS: + case PCLK_WDT_NS: + rate = rk3568_bus_get_clk(priv, clk->id); + break; + case ACLK_PERIMID: + case HCLK_PERIMID: + rate = rk3568_perimid_get_clk(priv, clk->id); + break; + case ACLK_TOP_HIGH: + case ACLK_TOP_LOW: + case HCLK_TOP: + case PCLK_TOP: + rate = rk3568_top_get_clk(priv, clk->id); + break; + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + rate = rk3568_i2c_get_clk(priv, clk->id); + break; + case CLK_SPI0: + case CLK_SPI1: + case CLK_SPI2: + case CLK_SPI3: + rate = rk3568_spi_get_clk(priv, clk->id); + break; + case CLK_PWM1: + case CLK_PWM2: + case CLK_PWM3: + rate = rk3568_pwm_get_clk(priv, clk->id); + break; + case CLK_SARADC: + case CLK_TSADC_TSEN: + case CLK_TSADC: + rate = rk3568_adc_get_clk(priv, clk->id); + break; + case HCLK_SDMMC0: + case CLK_SDMMC0: + case CLK_SDMMC1: + case CLK_SDMMC2: + rate = rk3568_sdmmc_get_clk(priv, clk->id); + break; + case SCLK_SFC: + rate = rk3568_sfc_get_clk(priv); + break; + case NCLK_NANDC: + rate = rk3568_nand_get_clk(priv); + break; + case CCLK_EMMC: + rate = rk3568_emmc_get_clk(priv); + break; +#ifndef CONFIG_SPL_BUILD + case ACLK_VOP: + rate = rk3568_aclk_vop_get_clk(priv); + break; + case DCLK_VOP0: + case DCLK_VOP1: + case DCLK_VOP2: + rate = rk3568_dclk_vop_get_clk(priv, clk->id); + break; + case SCLK_GMAC0: + case CLK_MAC0_2TOP: + case CLK_MAC0_REFOUT: + rate = rk3568_gmac_src_get_clk(priv, 0); + break; + case CLK_MAC0_OUT: + rate = rk3568_gmac_out_get_clk(priv, 0); + break; + case CLK_GMAC0_PTP_REF: + rate = rk3568_gmac_ptp_ref_get_clk(priv, 0); + break; + case SCLK_GMAC1: + case CLK_MAC1_2TOP: + case CLK_MAC1_REFOUT: + rate = rk3568_gmac_src_get_clk(priv, 1); + break; + case CLK_MAC1_OUT: + rate = rk3568_gmac_out_get_clk(priv, 1); + break; + case CLK_GMAC1_PTP_REF: + rate = rk3568_gmac_ptp_ref_get_clk(priv, 1); + break; + case DCLK_EBC: + rate = rk3568_ebc_get_clk(priv); + break; + case ACLK_RKVDEC_PRE: + case ACLK_RKVDEC: + case CLK_RKVDEC_CORE: + rate = rk3568_rkvdec_get_clk(priv, clk->id); + break; + case TCLK_WDT_NS: + rate = OSC_HZ; + break; + case SCLK_UART1: + case SCLK_UART2: + case SCLK_UART3: + case SCLK_UART4: + case SCLK_UART5: + case SCLK_UART6: + case SCLK_UART7: + case SCLK_UART8: + case SCLK_UART9: + rate = rk3568_uart_get_rate(priv, clk->id); + break; +#endif + case ACLK_SECURE_FLASH: + case ACLK_CRYPTO_NS: + case HCLK_SECURE_FLASH: + case HCLK_CRYPTO_NS: + case CLK_CRYPTO_NS_RNG: + case CLK_CRYPTO_NS_CORE: + case CLK_CRYPTO_NS_PKA: + rate = rk3568_crypto_get_rate(priv, clk->id); + break; + case CPLL_500M: + case CPLL_333M: + case CPLL_250M: + case CPLL_125M: + case CPLL_100M: + case CPLL_62P5M: + case CPLL_50M: + case CPLL_25M: + rate = rk3568_cpll_div_get_rate(priv, clk->id); + break; + default: + return -ENOENT; + } + + return rate; +}; + +static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + switch (clk->id) { + case PLL_APLL: + case ARMCLK: + if (priv->armclk_hz) + rk3568_armclk_set_clk(priv, rate); + priv->armclk_hz = rate; + break; + case PLL_CPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, + CPLL, rate); + priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], + priv->cru, CPLL); + break; + case PLL_GPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, + GPLL, rate); + priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], + priv->cru, GPLL); + break; + case PLL_NPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru, + NPLL, rate); + break; + case PLL_VPLL: + ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru, + VPLL, rate); + priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], + priv->cru, + VPLL); + break; + case ACLK_BUS: + case PCLK_BUS: + case PCLK_WDT_NS: + ret = rk3568_bus_set_clk(priv, clk->id, rate); + break; + case ACLK_PERIMID: + case HCLK_PERIMID: + ret = rk3568_perimid_set_clk(priv, clk->id, rate); + break; + case ACLK_TOP_HIGH: + case ACLK_TOP_LOW: + case HCLK_TOP: + case PCLK_TOP: + ret = rk3568_top_set_clk(priv, clk->id, rate); + break; + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + ret = rk3568_i2c_set_clk(priv, clk->id, rate); + break; + case CLK_SPI0: + case CLK_SPI1: + case CLK_SPI2: + case CLK_SPI3: + ret = rk3568_spi_set_clk(priv, clk->id, rate); + break; + case CLK_PWM1: + case CLK_PWM2: + case CLK_PWM3: + ret = rk3568_pwm_set_clk(priv, clk->id, rate); + break; + case CLK_SARADC: + case CLK_TSADC_TSEN: + case CLK_TSADC: + ret = rk3568_adc_set_clk(priv, clk->id, rate); + break; + case HCLK_SDMMC0: + case CLK_SDMMC0: + case CLK_SDMMC1: + case CLK_SDMMC2: + ret = rk3568_sdmmc_set_clk(priv, clk->id, rate); + break; + case SCLK_SFC: + ret = rk3568_sfc_set_clk(priv, rate); + break; + case NCLK_NANDC: + ret = rk3568_nand_set_clk(priv, rate); + break; + case CCLK_EMMC: + ret = rk3568_emmc_set_clk(priv, rate); + break; +#ifndef CONFIG_SPL_BUILD + case ACLK_VOP: + ret = rk3568_aclk_vop_set_clk(priv, rate); + break; + case DCLK_VOP0: + case DCLK_VOP1: + case DCLK_VOP2: + ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate); + break; + case SCLK_GMAC0: + case CLK_MAC0_2TOP: + case CLK_MAC0_REFOUT: + ret = rk3568_gmac_src_set_clk(priv, 0, rate); + break; + case CLK_MAC0_OUT: + ret = rk3568_gmac_out_set_clk(priv, 0, rate); + break; + case SCLK_GMAC0_RX_TX: + ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate); + break; + case CLK_GMAC0_PTP_REF: + ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate); + break; + case SCLK_GMAC1: + case CLK_MAC1_2TOP: + case CLK_MAC1_REFOUT: + ret = rk3568_gmac_src_set_clk(priv, 1, rate); + break; + case CLK_MAC1_OUT: + ret = rk3568_gmac_out_set_clk(priv, 1, rate); + break; + case SCLK_GMAC1_RX_TX: + ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate); + break; + case CLK_GMAC1_PTP_REF: + ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate); + break; + case DCLK_EBC: + ret = rk3568_ebc_set_clk(priv, rate); + break; + case ACLK_RKVDEC_PRE: + case ACLK_RKVDEC: + case CLK_RKVDEC_CORE: + ret = rk3568_rkvdec_set_clk(priv, clk->id, rate); + break; + case TCLK_WDT_NS: + ret = OSC_HZ; + break; + case SCLK_UART1: + case SCLK_UART2: + case SCLK_UART3: + case SCLK_UART4: + case SCLK_UART5: + case SCLK_UART6: + case SCLK_UART7: + case SCLK_UART8: + case SCLK_UART9: + ret = rk3568_uart_set_rate(priv, clk->id, rate); + break; +#endif + case ACLK_SECURE_FLASH: + case ACLK_CRYPTO_NS: + case HCLK_SECURE_FLASH: + case HCLK_CRYPTO_NS: + case CLK_CRYPTO_NS_RNG: + case CLK_CRYPTO_NS_CORE: + case CLK_CRYPTO_NS_PKA: + ret = rk3568_crypto_set_rate(priv, clk->id, rate); + break; + case CPLL_500M: + case CPLL_333M: + case CPLL_250M: + case CPLL_125M: + case CPLL_100M: + case CPLL_62P5M: + case CPLL_50M: + case CPLL_25M: + ret = rk3568_cpll_div_set_rate(priv, clk->id, rate); + break; + default: + return -ENOENT; + } + + return ret; +}; + +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) +static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + + if (parent->id == CLK_MAC0_2TOP) + rk_clrsetreg(&cru->clksel_con[31], + RMII0_EXTCLK_SEL_MASK, + RMII0_EXTCLK_SEL_MAC0_TOP << + RMII0_EXTCLK_SEL_SHIFT); + else + rk_clrsetreg(&cru->clksel_con[31], + RMII0_EXTCLK_SEL_MASK, + RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); + return 0; +} + +static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + + if (parent->id == CLK_MAC1_2TOP) + rk_clrsetreg(&cru->clksel_con[33], + RMII0_EXTCLK_SEL_MASK, + RMII0_EXTCLK_SEL_MAC0_TOP << + RMII0_EXTCLK_SEL_SHIFT); + else + rk_clrsetreg(&cru->clksel_con[33], + RMII0_EXTCLK_SEL_MASK, + RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); + return 0; +} + +static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + + if (parent->id == SCLK_GMAC0_RGMII_SPEED) + rk_clrsetreg(&cru->clksel_con[31], + RMII0_MODE_MASK, + RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); + else if (parent->id == SCLK_GMAC0_RMII_SPEED) + rk_clrsetreg(&cru->clksel_con[31], + RMII0_MODE_MASK, + RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); + else + rk_clrsetreg(&cru->clksel_con[31], + RMII0_MODE_MASK, + RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); + + return 0; +} + +static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + + if (parent->id == SCLK_GMAC1_RGMII_SPEED) + rk_clrsetreg(&cru->clksel_con[33], + RMII0_MODE_MASK, + RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); + else if (parent->id == SCLK_GMAC1_RMII_SPEED) + rk_clrsetreg(&cru->clksel_con[33], + RMII0_MODE_MASK, + RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); + else + rk_clrsetreg(&cru->clksel_con[33], + RMII0_MODE_MASK, + RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); + + return 0; +} + +static int __maybe_unused rk3568_dclk_vop_set_parent(struct clk *clk, + struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + u32 con_id; + + switch (clk->id) { + case DCLK_VOP0: + con_id = 39; + break; + case DCLK_VOP1: + con_id = 40; + break; + case DCLK_VOP2: + con_id = 41; + break; + default: + return -EINVAL; + } + if (parent->id == PLL_VPLL) { + rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, + DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT); + } else { + rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, + DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT); + } + + return 0; +} + +static int __maybe_unused rk3568_rkvdec_set_parent(struct clk *clk, + struct clk *parent) +{ + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3568_cru *cru = priv->cru; + u32 con_id, mask, shift; + + switch (clk->id) { + case ACLK_RKVDEC_PRE: + con_id = 47; + mask = ACLK_RKVDEC_SEL_MASK; + shift = ACLK_RKVDEC_SEL_SHIFT; + break; + case CLK_RKVDEC_CORE: + con_id = 49; + mask = CLK_RKVDEC_CORE_SEL_MASK; + shift = CLK_RKVDEC_CORE_SEL_SHIFT; + break; + default: + return -EINVAL; + } + if (parent->id == PLL_CPLL) { + rk_clrsetreg(&cru->clksel_con[con_id], mask, + ACLK_RKVDEC_SEL_CPLL << shift); + } else { + rk_clrsetreg(&cru->clksel_con[con_id], mask, + ACLK_RKVDEC_SEL_GPLL << shift); + } + + return 0; +} + +static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent) +{ + switch (clk->id) { + case SCLK_GMAC0: + return rk3568_gmac0_src_set_parent(clk, parent); + case SCLK_GMAC1: + return rk3568_gmac1_src_set_parent(clk, parent); + case SCLK_GMAC0_RX_TX: + return rk3568_gmac0_tx_rx_set_parent(clk, parent); + case SCLK_GMAC1_RX_TX: + return rk3568_gmac1_tx_rx_set_parent(clk, parent); + case DCLK_VOP0: + case DCLK_VOP1: + case DCLK_VOP2: + return rk3568_dclk_vop_set_parent(clk, parent); + case ACLK_RKVDEC_PRE: + case CLK_RKVDEC_CORE: + return rk3568_rkvdec_set_parent(clk, parent); + default: + return -ENOENT; + } + + return 0; +} +#endif + +static struct clk_ops rk3568_clk_ops = { + .get_rate = rk3568_clk_get_rate, + .set_rate = rk3568_clk_set_rate, +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) + .set_parent = rk3568_clk_set_parent, +#endif +}; + +static void rk3568_clk_init(struct rk3568_clk_priv *priv) +{ + int ret; + + priv->sync_kernel = false; + if (!priv->armclk_enter_hz) { + priv->armclk_enter_hz = + rockchip_pll_get_rate(&rk3568_pll_clks[APLL], + priv->cru, APLL); + priv->armclk_init_hz = priv->armclk_enter_hz; + } + + if (priv->armclk_init_hz != APLL_HZ) { + ret = rk3568_armclk_set_clk(priv, APLL_HZ); + if (!ret) + priv->armclk_init_hz = APLL_HZ; + } + if (priv->cpll_hz != CPLL_HZ) { + ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, + CPLL, CPLL_HZ); + if (!ret) + priv->cpll_hz = CPLL_HZ; + } + if (priv->gpll_hz != GPLL_HZ) { + ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, + GPLL, GPLL_HZ); + if (!ret) + priv->gpll_hz = GPLL_HZ; + } + +#ifdef CONFIG_SPL_BUILD + ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000); + if (ret < 0) + printf("Fail to set the ACLK_BUS clock.\n"); +#endif + + priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL); + priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL); +} + +static int rk3568_clk_probe(struct udevice *dev) +{ + struct rk3568_clk_priv *priv = dev_get_priv(dev); + int ret; + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(priv->grf)) + return PTR_ERR(priv->grf); + + rk3568_clk_init(priv); + + /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ + ret = clk_set_defaults(dev, 1); + if (ret) + debug("%s clk_set_defaults failed %d\n", __func__, ret); + else + priv->sync_kernel = true; + + return 0; +} + +static int rk3568_clk_ofdata_to_platdata(struct udevice *dev) +{ + struct rk3568_clk_priv *priv = dev_get_priv(dev); + + priv->cru = dev_read_addr_ptr(dev); + + return 0; +} + +static int rk3568_clk_bind(struct udevice *dev) +{ + int ret; + struct udevice *sys_child; + struct sysreset_reg *priv; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", + &sys_child); + if (ret) { + debug("Warning: No sysreset driver: ret=%d\n", ret); + } else { + priv = malloc(sizeof(struct sysreset_reg)); + priv->glb_srst_fst_value = offsetof(struct rk3568_cru, + glb_srst_fst); + priv->glb_srst_snd_value = offsetof(struct rk3568_cru, + glb_srsr_snd); + } + +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) + ret = offsetof(struct rk3568_cru, softrst_con[0]); + ret = rockchip_reset_bind(dev, ret, 30); + if (ret) + debug("Warning: software reset driver bind faile\n"); +#endif + + return 0; +} + +static const struct udevice_id rk3568_clk_ids[] = { + { .compatible = "rockchip,rk3568-cru" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rk3568_cru) = { + .name = "rockchip_rk3568_cru", + .id = UCLASS_CLK, + .of_match = rk3568_clk_ids, + .priv_auto = sizeof(struct rk3568_clk_priv), + .of_to_plat = rk3568_clk_ofdata_to_platdata, + .ops = &rk3568_clk_ops, + .bind = rk3568_clk_bind, + .probe = rk3568_clk_probe, +#if CONFIG_IS_ENABLED(OF_PLATDATA) + .plat_auto = sizeof(struct rk3568_clk_plat), +#endif +}; -- 2.17.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v1 2/2] rockchip: rk3568: add clock driver 2021-05-19 8:49 ` [PATCH v1 2/2] rockchip: rk3568: add clock driver Elaine at denx.de @ 2021-05-21 13:33 ` Kever Yang 0 siblings, 0 replies; 5+ messages in thread From: Kever Yang @ 2021-05-21 13:33 UTC (permalink / raw) To: Elaine Zhang, sjg, lukma; +Cc: u-boot, chenjh, Elaine Zhang Hi Elaine, Thanks for your patch, pls update the copyright info and remove unused clock set/get. On 2021/5/19 下午4:49, Elaine Zhang wrote: > From: Elaine Zhang <zhangqing@rock-chips.com> > > Add rk3568 clock driver and cru structure definition. > > Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> > --- > .../include/asm/arch-rockchip/cru_rk3568.h | 504 +++ > drivers/clk/rockchip/Makefile | 1 + > drivers/clk/rockchip/clk_rk3568.c | 2908 +++++++++++++++++ > 3 files changed, 3413 insertions(+) > create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3568.h > create mode 100644 drivers/clk/rockchip/clk_rk3568.c > > diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h > new file mode 100644 > index 000000000000..6c59033f03a6 > --- /dev/null > +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h > @@ -0,0 +1,504 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. > + * Author: Elaine Zhang <zhangqing@rock-chips.com> > + */ > + > +#ifndef _ASM_ARCH_CRU_RK3568_H > +#define _ASM_ARCH_CRU_RK3568_H > + > +#define MHz 1000000 > +#define KHz 1000 > +#define OSC_HZ (24 * MHz) > + > +#define APLL_HZ (816 * MHz) > +#define GPLL_HZ (1188 * MHz) > +#define CPLL_HZ (1000 * MHz) > +#define PPLL_HZ (100 * MHz) > + > +/* RK3568 pll id */ > +enum rk3568_pll_id { > + APLL, > + DPLL, > + CPLL, > + GPLL, > + NPLL, > + VPLL, > + PPLL, > + HPLL, > + PLL_COUNT, > +}; > + > +struct rk3568_clk_info { > + unsigned long id; > + char *name; > + bool is_cru; > +}; > + > +/* Private data for the clock driver - used by rockchip_get_cru() */ > +struct rk3568_pmuclk_priv { > + struct rk3568_pmucru *pmucru; > + ulong ppll_hz; > + ulong hpll_hz; > +}; > + > +struct rk3568_clk_priv { > + struct rk3568_cru *cru; > + struct rk3568_grf *grf; > + ulong ppll_hz; > + ulong hpll_hz; > + ulong gpll_hz; > + ulong cpll_hz; > + ulong npll_hz; > + ulong vpll_hz; > + ulong armclk_hz; > + ulong armclk_enter_hz; > + ulong armclk_init_hz; > + bool sync_kernel; > + bool set_armclk_rate; > +}; > + > +struct rk3568_pll { > + unsigned int con0; > + unsigned int con1; > + unsigned int con2; > + unsigned int con3; > + unsigned int con4; > + unsigned int reserved0[3]; > +}; > + > +struct rk3568_pmucru { > + struct rk3568_pll pll[2];/* Address Offset: 0x0000 */ > + unsigned int reserved0[16];/* Address Offset: 0x0040 */ > + unsigned int mode_con00;/* Address Offset: 0x0080 */ > + unsigned int reserved1[31];/* Address Offset: 0x0084 */ > + unsigned int pmu_clksel_con[10];/* Address Offset: 0x0100 */ > + unsigned int reserved2[22];/* Address Offset: 0x0128 */ > + unsigned int pmu_clkgate_con[3];/* Address Offset: 0x0180 */ > + unsigned int reserved3[29];/* Address Offset: 0x018C */ > + unsigned int pmu_softrst_con[1];/* Address Offset: 0x0200 */ > +}; > + > +check_member(rk3568_pmucru, mode_con00, 0x80); > +check_member(rk3568_pmucru, pmu_softrst_con[0], 0x200); > + > +struct rk3568_cru { > + struct rk3568_pll pll[6]; > + unsigned int mode_con00;/* Address Offset: 0x00C0 */ > + unsigned int misc_con[3];/* Address Offset: 0x00C4 */ > + unsigned int glb_cnt_th;/* Address Offset: 0x00D0 */ > + unsigned int glb_srst_fst;/* Address Offset: 0x00D4 */ > + unsigned int glb_srsr_snd; /* Address Offset: 0x00D8 */ > + unsigned int glb_rst_con;/* Address Offset: 0x00DC */ > + unsigned int glb_rst_st;/* Address Offset: 0x00E0 */ > + unsigned int reserved0[7];/* Address Offset: 0x00E4 */ > + unsigned int clksel_con[85]; /* Address Offset: 0x0100 */ > + unsigned int reserved1[43];/* Address Offset: 0x0254 */ > + unsigned int clkgate_con[36];/* Address Offset: 0x0300 */ > + unsigned int reserved2[28]; /* Address Offset: 0x0390 */ > + unsigned int softrst_con[30];/* Address Offset: 0x0400 */ > + unsigned int reserved3[2];/* Address Offset: 0x0478 */ > + unsigned int ssgtbl[32];/* Address Offset: 0x0480 */ > + unsigned int reserved4[32];/* Address Offset: 0x0500 */ > + unsigned int sdmmc0_con[2];/* Address Offset: 0x0580 */ > + unsigned int sdmmc1_con[2];/* Address Offset: 0x058C */ > + unsigned int sdmmc2_con[2];/* Address Offset: 0x0590 */ > + unsigned int emmc_con[2];/* Address Offset: 0x0598 */ > +}; > + > +check_member(rk3568_cru, mode_con00, 0xc0); > +check_member(rk3568_cru, softrst_con[0], 0x400); > + > +struct pll_rate_table { > + unsigned long rate; > + unsigned int fbdiv; > + unsigned int postdiv1; > + unsigned int refdiv; > + unsigned int postdiv2; > + unsigned int dsmpd; > + unsigned int frac; > +}; > + > +#define RK3568_PMU_MODE 0x80 > +#define RK3568_PMU_PLL_CON(x) ((x) * 0x4) > +#define RK3568_PLL_CON(x) ((x) * 0x4) > +#define RK3568_MODE_CON 0xc0 > + > +enum { > + /* CRU_PMU_CLK_SEL0_CON */ > + RTC32K_SEL_SHIFT = 6, > + RTC32K_SEL_MASK = 0x3 << RTC32K_SEL_SHIFT, > + RTC32K_SEL_PMUPVTM = 0, > + RTC32K_SEL_OSC1_32K, > + RTC32K_SEL_OSC0_DIV32K, > + > + /* CRU_PMU_CLK_SEL1_CON */ > + RTC32K_FRAC_NUMERATOR_SHIFT = 16, > + RTC32K_FRAC_NUMERATOR_MASK = 0xffff << 16, > + RTC32K_FRAC_DENOMINATOR_SHIFT = 0, > + RTC32K_FRAC_DENOMINATOR_MASK = 0xffff, > + > + /* CRU_PMU_CLK_SEL2_CON */ > + PCLK_PDPMU_SEL_SHIFT = 15, > + PCLK_PDPMU_SEL_MASK = 1 << PCLK_PDPMU_SEL_SHIFT, > + PCLK_PDPMU_SEL_PPLL = 0, > + PCLK_PDPMU_SEL_GPLL, > + PCLK_PDPMU_DIV_SHIFT = 0, > + PCLK_PDPMU_DIV_MASK = 0x1f, > + > + /* CRU_PMU_CLK_SEL3_CON */ > + CLK_I2C0_DIV_SHIFT = 0, > + CLK_I2C0_DIV_MASK = 0x7f, > + > + /* CRU_PMU_CLK_SEL6_CON */ > + CLK_PWM0_SEL_SHIFT = 7, > + CLK_PWM0_SEL_MASK = 1 << CLK_PWM0_SEL_SHIFT, > + CLK_PWM0_SEL_XIN24M = 0, > + CLK_PWM0_SEL_PPLL, > + CLK_PWM0_DIV_SHIFT = 0, > + CLK_PWM0_DIV_MASK = 0x7f, > + > + /* CRU_CLK_SEL0_CON */ > + CLK_CORE_PRE_SEL_SHIFT = 7, > + CLK_CORE_PRE_SEL_MASK = 1 << CLK_CORE_PRE_SEL_SHIFT, > + CLK_CORE_PRE_SEL_SRC = 0, > + CLK_CORE_PRE_SEL_APLL, > + > + /* CRU_CLK_SEL2_CON */ > + SCLK_CORE_PRE_SEL_SHIFT = 15, > + SCLK_CORE_PRE_SEL_MASK = 1 << SCLK_CORE_PRE_SEL_SHIFT, > + SCLK_CORE_PRE_SEL_SRC = 0, > + SCLK_CORE_PRE_SEL_NPLL, > + SCLK_CORE_SRC_SEL_SHIFT = 8, > + SCLK_CORE_SRC_SEL_MASK = 3 << SCLK_CORE_SRC_SEL_SHIFT, > + SCLK_CORE_SRC_SEL_APLL = 0, > + SCLK_CORE_SRC_SEL_GPLL, > + SCLK_CORE_SRC_SEL_NPLL, > + SCLK_CORE_SRC_DIV_SHIFT = 0, > + SCLK_CORE_SRC_DIV_MASK = 0x1f << SCLK_CORE_SRC_DIV_SHIFT, > + > + /* CRU_CLK_SEL3_CON */ > + GICCLK_CORE_DIV_SHIFT = 8, > + GICCLK_CORE_DIV_MASK = 0x1f << GICCLK_CORE_DIV_SHIFT, > + ATCLK_CORE_DIV_SHIFT = 0, > + ATCLK_CORE_DIV_MASK = 0x1f << ATCLK_CORE_DIV_SHIFT, > + > + /* CRU_CLK_SEL4_CON */ > + PERIPHCLK_CORE_PRE_DIV_SHIFT = 8, > + PERIPHCLK_CORE_PRE_DIV_MASK = 0x1f << PERIPHCLK_CORE_PRE_DIV_SHIFT, > + PCLK_CORE_PRE_DIV_SHIFT = 0, > + PCLK_CORE_PRE_DIV_MASK = 0x1f << PCLK_CORE_PRE_DIV_SHIFT, > + > + /* CRU_CLK_SEL5_CON */ > + ACLK_CORE_NIU2BUS_SEL_SHIFT = 14, > + ACLK_CORE_NIU2BUS_SEL_MASK = 0x3 << ACLK_CORE_NIU2BUS_SEL_SHIFT, > + ACLK_CORE_NDFT_DIV_SHIFT = 8, > + ACLK_CORE_NDFT_DIV_MASK = 0x1f << ACLK_CORE_NDFT_DIV_SHIFT, > + > + /* CRU_CLK_SEL10_CON */ > + HCLK_PERIMID_SEL_SHIFT = 6, > + HCLK_PERIMID_SEL_MASK = 3 << HCLK_PERIMID_SEL_SHIFT, > + HCLK_PERIMID_SEL_150M = 0, > + HCLK_PERIMID_SEL_100M, > + HCLK_PERIMID_SEL_75M, > + HCLK_PERIMID_SEL_24M, > + ACLK_PERIMID_SEL_SHIFT = 4, > + ACLK_PERIMID_SEL_MASK = 3 << ACLK_PERIMID_SEL_SHIFT, > + ACLK_PERIMID_SEL_300M = 0, > + ACLK_PERIMID_SEL_200M, > + ACLK_PERIMID_SEL_100M, > + ACLK_PERIMID_SEL_24M, > + > + /* CRU_CLK_SEL27_CON */ > + CLK_CRYPTO_PKA_SEL_SHIFT = 6, > + CLK_CRYPTO_PKA_SEL_MASK = 3 << CLK_CRYPTO_PKA_SEL_SHIFT, > + CLK_CRYPTO_PKA_SEL_300M = 0, > + CLK_CRYPTO_PKA_SEL_200M, > + CLK_CRYPTO_PKA_SEL_100M, > + CLK_CRYPTO_CORE_SEL_SHIFT = 4, > + CLK_CRYPTO_CORE_SEL_MASK = 3 << CLK_CRYPTO_CORE_SEL_SHIFT, > + CLK_CRYPTO_CORE_SEL_200M = 0, > + CLK_CRYPTO_CORE_SEL_150M, > + CLK_CRYPTO_CORE_SEL_100M, > + HCLK_SECURE_FLASH_SEL_SHIFT = 2, > + HCLK_SECURE_FLASH_SEL_MASK = 3 << HCLK_SECURE_FLASH_SEL_SHIFT, > + HCLK_SECURE_FLASH_SEL_150M = 0, > + HCLK_SECURE_FLASH_SEL_100M, > + HCLK_SECURE_FLASH_SEL_75M, > + HCLK_SECURE_FLASH_SEL_24M, > + ACLK_SECURE_FLASH_SEL_SHIFT = 0, > + ACLK_SECURE_FLASH_SEL_MASK = 3 << ACLK_SECURE_FLASH_SEL_SHIFT, > + ACLK_SECURE_FLASH_SEL_200M = 0, > + ACLK_SECURE_FLASH_SEL_150M, > + ACLK_SECURE_FLASH_SEL_100M, > + ACLK_SECURE_FLASH_SEL_24M, > + > + /* CRU_CLK_SEL28_CON */ > + CCLK_EMMC_SEL_SHIFT = 12, > + CCLK_EMMC_SEL_MASK = 7 << CCLK_EMMC_SEL_SHIFT, > + CCLK_EMMC_SEL_24M = 0, > + CCLK_EMMC_SEL_200M, > + CCLK_EMMC_SEL_150M, > + CCLK_EMMC_SEL_100M, > + CCLK_EMMC_SEL_50M, > + CCLK_EMMC_SEL_375K, > + BCLK_EMMC_SEL_SHIFT = 8, > + BCLK_EMMC_SEL_MASK = 3 << BCLK_EMMC_SEL_SHIFT, > + BCLK_EMMC_SEL_200M = 0, > + BCLK_EMMC_SEL_150M, > + BCLK_EMMC_SEL_125M, > + SCLK_SFC_SEL_SHIFT = 4, > + SCLK_SFC_SEL_MASK = 7 << SCLK_SFC_SEL_SHIFT, > + SCLK_SFC_SEL_24M = 0, > + SCLK_SFC_SEL_50M, > + SCLK_SFC_SEL_75M, > + SCLK_SFC_SEL_100M, > + SCLK_SFC_SEL_125M, > + SCLK_SFC_SEL_150M, > + NCLK_NANDC_SEL_SHIFT = 0, > + NCLK_NANDC_SEL_MASK = 3 << NCLK_NANDC_SEL_SHIFT, > + NCLK_NANDC_SEL_200M = 0, > + NCLK_NANDC_SEL_150M, > + NCLK_NANDC_SEL_100M, > + NCLK_NANDC_SEL_24M, > + > + /* CRU_CLK_SEL30_CON */ > + CLK_SDMMC1_SEL_SHIFT = 12, > + CLK_SDMMC1_SEL_MASK = 7 << CLK_SDMMC1_SEL_SHIFT, > + CLK_SDMMC0_SEL_SHIFT = 8, > + CLK_SDMMC0_SEL_MASK = 7 << CLK_SDMMC0_SEL_SHIFT, > + CLK_SDMMC_SEL_24M = 0, > + CLK_SDMMC_SEL_400M, > + CLK_SDMMC_SEL_300M, > + CLK_SDMMC_SEL_100M, > + CLK_SDMMC_SEL_50M, > + CLK_SDMMC_SEL_750K, > + > + /* CRU_CLK_SEL31_CON */ > + CLK_MAC0_OUT_SEL_SHIFT = 14, > + CLK_MAC0_OUT_SEL_MASK = 3 << CLK_MAC0_OUT_SEL_SHIFT, > + CLK_MAC0_OUT_SEL_125M = 0, > + CLK_MAC0_OUT_SEL_50M, > + CLK_MAC0_OUT_SEL_25M, > + CLK_MAC0_OUT_SEL_24M, > + CLK_GMAC0_PTP_REF_SEL_SHIFT = 12, > + CLK_GMAC0_PTP_REF_SEL_MASK = 3 << CLK_GMAC0_PTP_REF_SEL_SHIFT, > + CLK_GMAC0_PTP_REF_SEL_62_5M = 0, > + CLK_GMAC0_PTP_REF_SEL_100M, > + CLK_GMAC0_PTP_REF_SEL_50M, > + CLK_GMAC0_PTP_REF_SEL_24M, > + CLK_MAC0_2TOP_SEL_SHIFT = 8, > + CLK_MAC0_2TOP_SEL_MASK = 3 << CLK_MAC0_2TOP_SEL_SHIFT, > + CLK_MAC0_2TOP_SEL_125M = 0, > + CLK_MAC0_2TOP_SEL_50M, > + CLK_MAC0_2TOP_SEL_25M, > + CLK_MAC0_2TOP_SEL_PPLL, > + RGMII0_CLK_SEL_SHIFT = 4, > + RGMII0_CLK_SEL_MASK = 3 << RGMII0_CLK_SEL_SHIFT, > + RGMII0_CLK_SEL_125M = 0, > + RGMII0_CLK_SEL_125M_1, > + RGMII0_CLK_SEL_2_5M, > + RGMII0_CLK_SEL_25M, > + RMII0_CLK_SEL_SHIFT = 3, > + RMII0_CLK_SEL_MASK = 1 << RMII0_CLK_SEL_SHIFT, > + RMII0_CLK_SEL_2_5M = 0, > + RMII0_CLK_SEL_25M, > + RMII0_EXTCLK_SEL_SHIFT = 2, > + RMII0_EXTCLK_SEL_MASK = 1 << RMII0_EXTCLK_SEL_SHIFT, > + RMII0_EXTCLK_SEL_MAC0_TOP = 0, > + RMII0_EXTCLK_SEL_IO, > + RMII0_MODE_SHIFT = 0, > + RMII0_MODE_MASK = 3 << RMII0_MODE_SHIFT, > + RMII0_MODE_SEL_RGMII = 0, > + RMII0_MODE_SEL_RMII, > + RMII0_MODE_SEL_GMII, > + > + /* CRU_CLK_SEL32_CON */ > + CLK_SDMMC2_SEL_SHIFT = 8, > + CLK_SDMMC2_SEL_MASK = 7 << CLK_SDMMC2_SEL_SHIFT, > + > + /* CRU_CLK_SEL38_CON */ > + ACLK_VOP_PRE_SEL_SHIFT = 6, > + ACLK_VOP_PRE_SEL_MASK = 3 << ACLK_VOP_PRE_SEL_SHIFT, > + ACLK_VOP_PRE_SEL_CPLL = 0, > + ACLK_VOP_PRE_SEL_GPLL, > + ACLK_VOP_PRE_SEL_HPLL, > + ACLK_VOP_PRE_SEL_VPLL, > + ACLK_VOP_PRE_DIV_SHIFT = 0, > + ACLK_VOP_PRE_DIV_MASK = 0x1f << ACLK_VOP_PRE_DIV_SHIFT, > + > + /* CRU_CLK_SEL39_CON */ > + DCLK0_VOP_SEL_SHIFT = 10, > + DCLK0_VOP_SEL_MASK = 3 << DCLK0_VOP_SEL_SHIFT, > + DCLK_VOP_SEL_HPLL = 0, > + DCLK_VOP_SEL_VPLL, > + DCLK_VOP_SEL_GPLL, > + DCLK_VOP_SEL_CPLL, > + DCLK0_VOP_DIV_SHIFT = 0, > + DCLK0_VOP_DIV_MASK = 0xff << DCLK0_VOP_DIV_SHIFT, > + > + /* CRU_CLK_SEL40_CON */ > + DCLK1_VOP_SEL_SHIFT = 10, > + DCLK1_VOP_SEL_MASK = 3 << DCLK1_VOP_SEL_SHIFT, > + DCLK1_VOP_DIV_SHIFT = 0, > + DCLK1_VOP_DIV_MASK = 0xff << DCLK1_VOP_DIV_SHIFT, > + > + /* CRU_CLK_SEL41_CON */ > + DCLK2_VOP_SEL_SHIFT = 10, > + DCLK2_VOP_SEL_MASK = 3 << DCLK2_VOP_SEL_SHIFT, > + DCLK2_VOP_DIV_SHIFT = 0, > + DCLK2_VOP_DIV_MASK = 0xff << DCLK2_VOP_DIV_SHIFT, > + > + /* CRU_CLK_SEL43_CON */ > + DCLK_EBC_SEL_SHIFT = 6, > + DCLK_EBC_SEL_MASK = 3 << DCLK_EBC_SEL_SHIFT, > + DCLK_EBC_SEL_GPLL_400M = 0, > + DCLK_EBC_SEL_CPLL_333M, > + DCLK_EBC_SEL_GPLL_200M, > + > + /* CRU_CLK_SEL47_CON */ > + ACLK_RKVDEC_SEL_SHIFT = 7, > + ACLK_RKVDEC_SEL_MASK = 1 << ACLK_RKVDEC_SEL_SHIFT, > + ACLK_RKVDEC_SEL_GPLL = 0, > + ACLK_RKVDEC_SEL_CPLL, > + ACLK_RKVDEC_DIV_SHIFT = 0, > + ACLK_RKVDEC_DIV_MASK = 0x1f << ACLK_RKVDEC_DIV_SHIFT, > + > + /* CRU_CLK_SEL49_CON */ > + CLK_RKVDEC_CORE_SEL_SHIFT = 14, > + CLK_RKVDEC_CORE_SEL_MASK = 0x3 << CLK_RKVDEC_CORE_SEL_SHIFT, > + CLK_RKVDEC_CORE_SEL_GPLL = 0, > + CLK_RKVDEC_CORE_SEL_CPLL, > + CLK_RKVDEC_CORE_SEL_NPLL, > + CLK_RKVDEC_CORE_SEL_VPLL, > + CLK_RKVDEC_CORE_DIV_SHIFT = 8, > + CLK_RKVDEC_CORE_DIV_MASK = 0x1f << CLK_RKVDEC_CORE_DIV_SHIFT, > + > + /* CRU_CLK_SEL50_CON */ > + PCLK_BUS_SEL_SHIFT = 4, > + PCLK_BUS_SEL_MASK = 3 << PCLK_BUS_SEL_SHIFT, > + PCLK_BUS_SEL_100M = 0, > + PCLK_BUS_SEL_75M, > + PCLK_BUS_SEL_50M, > + PCLK_BUS_SEL_24M, > + ACLK_BUS_SEL_SHIFT = 0, > + ACLK_BUS_SEL_MASK = 3 << ACLK_BUS_SEL_SHIFT, > + ACLK_BUS_SEL_200M = 0, > + ACLK_BUS_SEL_150M, > + ACLK_BUS_SEL_100M, > + ACLK_BUS_SEL_24M, > + > + /* CRU_CLK_SEL51_CON */ > + CLK_TSADC_DIV_SHIFT = 8, > + CLK_TSADC_DIV_MASK = 0x7f << CLK_TSADC_DIV_SHIFT, > + CLK_TSADC_TSEN_SEL_SHIFT = 4, > + CLK_TSADC_TSEN_SEL_MASK = 0x3 << CLK_TSADC_TSEN_SEL_SHIFT, > + CLK_TSADC_TSEN_SEL_24M = 0, > + CLK_TSADC_TSEN_SEL_100M, > + CLK_TSADC_TSEN_SEL_CPLL_100M, > + CLK_TSADC_TSEN_DIV_SHIFT = 0, > + CLK_TSADC_TSEN_DIV_MASK = 0x7 << CLK_TSADC_TSEN_DIV_SHIFT, > + > + /* CRU_CLK_SEL52_CON */ > + CLK_UART_SEL_SHIFT = 12, > + CLK_UART_SEL_MASK = 0x3 << CLK_UART_SEL_SHIFT, > + CLK_UART_SEL_SRC = 0, > + CLK_UART_SEL_FRAC, > + CLK_UART_SEL_XIN24M, > + CLK_UART_SRC_SEL_SHIFT = 8, > + CLK_UART_SRC_SEL_MASK = 0x3 << CLK_UART_SRC_SEL_SHIFT, > + CLK_UART_SRC_SEL_GPLL = 0, > + CLK_UART_SRC_SEL_CPLL, > + CLK_UART_SRC_SEL_480M, > + CLK_UART_SRC_DIV_SHIFT = 0, > + CLK_UART_SRC_DIV_MASK = 0x3f << CLK_UART_SRC_DIV_SHIFT, > + > + /* CRU_CLK_SEL53_CON */ > + CLK_UART_FRAC_NUMERATOR_SHIFT = 16, > + CLK_UART_FRAC_NUMERATOR_MASK = 0xffff << 16, > + CLK_UART_FRAC_DENOMINATOR_SHIFT = 0, > + CLK_UART_FRAC_DENOMINATOR_MASK = 0xffff, > + > + /* CRU_CLK_SEL71_CON */ > + CLK_I2C_SEL_SHIFT = 8, > + CLK_I2C_SEL_MASK = 3 << CLK_I2C_SEL_SHIFT, > + CLK_I2C_SEL_200M = 0, > + CLK_I2C_SEL_100M, > + CLK_I2C_SEL_24M, > + CLK_I2C_SEL_CPLL_100M, > + > + /* CRU_CLK_SEL72_CON */ > + CLK_PWM3_SEL_SHIFT = 12, > + CLK_PWM3_SEL_MASK = 3 << CLK_PWM3_SEL_SHIFT, > + CLK_PWM2_SEL_SHIFT = 10, > + CLK_PWM2_SEL_MASK = 3 << CLK_PWM2_SEL_SHIFT, > + CLK_PWM1_SEL_SHIFT = 8, > + CLK_PWM1_SEL_MASK = 3 << CLK_PWM1_SEL_SHIFT, > + CLK_PWM_SEL_100M = 0, > + CLK_PWM_SEL_24M, > + CLK_PWM_SEL_CPLL_100M, > + CLK_SPI3_SEL_SHIFT = 6, > + CLK_SPI3_SEL_MASK = 3 << CLK_SPI3_SEL_SHIFT, > + CLK_SPI2_SEL_SHIFT = 4, > + CLK_SPI2_SEL_MASK = 3 << CLK_SPI2_SEL_SHIFT, > + CLK_SPI1_SEL_SHIFT = 2, > + CLK_SPI1_SEL_MASK = 3 << CLK_SPI1_SEL_SHIFT, > + CLK_SPI0_SEL_SHIFT = 0, > + CLK_SPI0_SEL_MASK = 3 << CLK_SPI0_SEL_SHIFT, > + CLK_SPI_SEL_200M = 0, > + CLK_SPI_SEL_24M, > + CLK_SPI_SEL_CPLL_100M, > + > + /* CRU_CLK_SEL73_CON */ > + PCLK_TOP_SEL_SHIFT = 12, > + PCLK_TOP_SEL_MASK = 3 << PCLK_TOP_SEL_SHIFT, > + PCLK_TOP_SEL_100M = 0, > + PCLK_TOP_SEL_75M, > + PCLK_TOP_SEL_50M, > + PCLK_TOP_SEL_24M, > + HCLK_TOP_SEL_SHIFT = 8, > + HCLK_TOP_SEL_MASK = 3 << HCLK_TOP_SEL_SHIFT, > + HCLK_TOP_SEL_150M = 0, > + HCLK_TOP_SEL_100M, > + HCLK_TOP_SEL_75M, > + HCLK_TOP_SEL_24M, > + ACLK_TOP_LOW_SEL_SHIFT = 4, > + ACLK_TOP_LOW_SEL_MASK = 3 << ACLK_TOP_LOW_SEL_SHIFT, > + ACLK_TOP_LOW_SEL_400M = 0, > + ACLK_TOP_LOW_SEL_300M, > + ACLK_TOP_LOW_SEL_200M, > + ACLK_TOP_LOW_SEL_24M, > + ACLK_TOP_HIGH_SEL_SHIFT = 0, > + ACLK_TOP_HIGH_SEL_MASK = 3 << ACLK_TOP_HIGH_SEL_SHIFT, > + ACLK_TOP_HIGH_SEL_500M = 0, > + ACLK_TOP_HIGH_SEL_400M, > + ACLK_TOP_HIGH_SEL_300M, > + ACLK_TOP_HIGH_SEL_24M, > + > + /* CRU_CLK_SEL78_CON */ > + CPLL_500M_DIV_SHIFT = 8, > + CPLL_500M_DIV_MASK = 0x1f << CPLL_500M_DIV_SHIFT, > + > + /* CRU_CLK_SEL79_CON */ > + CPLL_250M_DIV_SHIFT = 8, > + CPLL_250M_DIV_MASK = 0x1f << CPLL_250M_DIV_SHIFT, > + CPLL_333M_DIV_SHIFT = 0, > + CPLL_333M_DIV_MASK = 0x1f << CPLL_333M_DIV_SHIFT, > + > + /* CRU_CLK_SEL80_CON */ > + CPLL_62P5M_DIV_SHIFT = 8, > + CPLL_62P5M_DIV_MASK = 0x1f << CPLL_62P5M_DIV_SHIFT, > + CPLL_125M_DIV_SHIFT = 0, > + CPLL_125M_DIV_MASK = 0x1f << CPLL_125M_DIV_SHIFT, > + > + /* CRU_CLK_SEL81_CON */ > + CPLL_25M_DIV_SHIFT = 8, > + CPLL_25M_DIV_MASK = 0x1f << CPLL_25M_DIV_SHIFT, > + CPLL_50M_DIV_SHIFT = 0, > + CPLL_50M_DIV_MASK = 0x1f << CPLL_50M_DIV_SHIFT, > + > + /* CRU_CLK_SEL82_CON */ > + CPLL_100M_DIV_SHIFT = 0, > + CPLL_100M_DIV_MASK = 0x1f << CPLL_100M_DIV_SHIFT, > +}; > +#endif > diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile > index 4cfcf8330929..913f611a0ff8 100644 > --- a/drivers/clk/rockchip/Makefile > +++ b/drivers/clk/rockchip/Makefile > @@ -14,4 +14,5 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += clk_rk3308.o > obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o > obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o > obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o > +obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o > obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o > diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c > new file mode 100644 > index 000000000000..359aca358e0d > --- /dev/null > +++ b/drivers/clk/rockchip/clk_rk3568.c > @@ -0,0 +1,2908 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd Please remove "Fuzhou". > + * Author: Elaine Zhang <zhangqing@rock-chips.com> > + */ > + > +#include <common.h> > +#include <bitfield.h> > +#include <clk-uclass.h> > +#include <dm.h> > +#include <errno.h> > +#include <syscon.h> > +#include <asm/arch-rockchip/cru_rk3568.h> > +#include <asm/arch-rockchip/clock.h> > +#include <asm/arch-rockchip/hardware.h> > +#include <asm/io.h> > +#include <dm/lists.h> > +#include <dt-bindings/clock/rk3568-cru.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +#if CONFIG_IS_ENABLED(OF_PLATDATA) > +struct rk3568_clk_plat { > + struct dtd_rockchip_rk3568_cru dtd; > +}; > + > +struct rk3568_pmuclk_plat { > + struct dtd_rockchip_rk3568_pmucru dtd; > +}; > +#endif > + > +#define RK3568_CPUCLK_RATE(_rate, _aclk_div, _pclk_div) \ > +{ \ > + .rate = _rate##U, \ > + .aclk_div = _aclk_div, \ > + .pclk_div = _pclk_div, \ > +} > + > +#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) > + > +static struct rockchip_cpu_rate_table rk3568_cpu_rates[] = { > + RK3568_CPUCLK_RATE(1416000000, 1, 5), > + RK3568_CPUCLK_RATE(1296000000, 1, 5), > + RK3568_CPUCLK_RATE(1200000000, 1, 3), > + RK3568_CPUCLK_RATE(1104000000, 1, 3), > + RK3568_CPUCLK_RATE(1008000000, 1, 3), > + RK3568_CPUCLK_RATE(912000000, 1, 3), > + RK3568_CPUCLK_RATE(816000000, 1, 3), > + RK3568_CPUCLK_RATE(600000000, 1, 1), > + RK3568_CPUCLK_RATE(408000000, 1, 1), > + { /* sentinel */ }, > +}; > + > +static struct rockchip_pll_rate_table rk3568_pll_rates[] = { > + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ > + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), > + RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), > + RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), > + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), > + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), > + RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), > + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), > + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), > + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), > + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), > + RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), > + RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), > + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), > + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), > + RK3036_PLL_RATE(400000000, 1, 100, 6, 1, 1, 0), > + RK3036_PLL_RATE(200000000, 1, 100, 6, 2, 1, 0), > + RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), > + { /* sentinel */ }, > +}; > + > +static struct rockchip_pll_clock rk3568_pll_clks[] = { > + [APLL] = PLL(pll_rk3328, PLL_APLL, RK3568_PLL_CON(0), > + RK3568_MODE_CON, 0, 10, 0, rk3568_pll_rates), > + [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3568_PLL_CON(8), > + RK3568_MODE_CON, 2, 10, 0, NULL), > + [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3568_PLL_CON(24), > + RK3568_MODE_CON, 4, 10, 0, rk3568_pll_rates), > + [GPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PLL_CON(16), > + RK3568_MODE_CON, 6, 10, 0, rk3568_pll_rates), > + [NPLL] = PLL(pll_rk3328, PLL_NPLL, RK3568_PLL_CON(32), > + RK3568_MODE_CON, 10, 10, 0, rk3568_pll_rates), > + [VPLL] = PLL(pll_rk3328, PLL_VPLL, RK3568_PLL_CON(40), > + RK3568_MODE_CON, 12, 10, 0, rk3568_pll_rates), > + [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3568_PMU_PLL_CON(0), > + RK3568_PMU_MODE, 0, 10, 0, rk3568_pll_rates), > + [HPLL] = PLL(pll_rk3328, PLL_HPLL, RK3568_PMU_PLL_CON(16), > + RK3568_PMU_MODE, 2, 10, 0, rk3568_pll_rates), > +}; > + > +static ulong __maybe_unused > +rk3568_pmu_pll_set_rate(struct rk3568_clk_priv *priv, > + ulong pll_id, ulong rate) > +{ > + struct udevice *pmucru_dev; > + struct rk3568_pmuclk_priv *pmu_priv; > + int ret; > + > + ret = uclass_get_device_by_driver(UCLASS_CLK, > + DM_DRIVER_GET(rockchip_rk3568_pmucru), > + &pmucru_dev); > + if (ret) { > + printf("%s: could not find pmucru device\n", __func__); > + return ret; > + } > + pmu_priv = dev_get_priv(pmucru_dev); > + > + rockchip_pll_set_rate(&rk3568_pll_clks[pll_id], > + pmu_priv->pmucru, pll_id, rate); > + > + return 0; > +} > + > +static ulong rk3568_pmu_pll_get_rate(struct rk3568_clk_priv *priv, > + ulong pll_id) > +{ > + struct udevice *pmucru_dev; > + struct rk3568_pmuclk_priv *pmu_priv; > + int ret; > + > + ret = uclass_get_device_by_driver(UCLASS_CLK, > + DM_DRIVER_GET(rockchip_rk3568_pmucru), > + &pmucru_dev); > + if (ret) { > + printf("%s: could not find pmucru device\n", __func__); > + return ret; > + } > + pmu_priv = dev_get_priv(pmucru_dev); > + > + return rockchip_pll_get_rate(&rk3568_pll_clks[pll_id], > + pmu_priv->pmucru, pll_id); > +} > + > +/* > + * > + * rational_best_approximation(31415, 10000, > + * (1 << 8) - 1, (1 << 5) - 1, &n, &d); > + * > + * you may look at given_numerator as a fixed point number, > + * with the fractional part size described in given_denominator. > + * > + * for theoretical background, see: > + * http://en.wikipedia.org/wiki/Continued_fraction > + */ > +static void rational_best_approximation(unsigned long given_numerator, > + unsigned long given_denominator, > + unsigned long max_numerator, > + unsigned long max_denominator, > + unsigned long *best_numerator, > + unsigned long *best_denominator) > +{ > + unsigned long n, d, n0, d0, n1, d1; > + > + n = given_numerator; > + d = given_denominator; > + n0 = 0; > + d1 = 0; > + n1 = 1; > + d0 = 1; > + for (;;) { > + unsigned long t, a; > + > + if (n1 > max_numerator || d1 > max_denominator) { > + n1 = n0; > + d1 = d0; > + break; > + } > + if (d == 0) > + break; > + t = d; > + a = n / d; > + d = n % d; > + n = t; > + t = n0 + a * n1; > + n0 = n1; > + n1 = t; > + t = d0 + a * d1; > + d0 = d1; > + d1 = t; > + } > + *best_numerator = n1; > + *best_denominator = d1; > +} > + > +static ulong rk3568_rtc32k_get_pmuclk(struct rk3568_pmuclk_priv *priv) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + unsigned long m, n; > + u32 fracdiv; > + > + fracdiv = readl(&pmucru->pmu_clksel_con[1]); > + m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK; > + m >>= RTC32K_FRAC_NUMERATOR_SHIFT; > + n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK; > + n >>= RTC32K_FRAC_DENOMINATOR_SHIFT; > + > + return OSC_HZ * m / n; > +} > + > +static ulong rk3568_rtc32k_set_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong rate) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + unsigned long m, n, val; > + > + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, > + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); > + > + rational_best_approximation(rate, OSC_HZ, > + GENMASK(16 - 1, 0), > + GENMASK(16 - 1, 0), > + &m, &n); > + val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n; > + writel(val, &pmucru->pmu_clksel_con[1]); > + > + return rk3568_rtc32k_get_pmuclk(priv); > +} > + > +static ulong rk3568_i2c_get_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong clk_id) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + u32 div, con; > + > + switch (clk_id) { > + case CLK_I2C0: > + con = readl(&pmucru->pmu_clksel_con[3]); > + div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + return DIV_TO_RATE(priv->ppll_hz, div); > +} > + > +static ulong rk3568_i2c_set_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + int src_clk_div; > + > + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); > + assert(src_clk_div - 1 <= 127); > + > + switch (clk_id) { > + case CLK_I2C0: > + rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK, > + (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_i2c_get_pmuclk(priv, clk_id); > +} > + > +static ulong rk3568_pwm_get_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong clk_id) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + u32 div, sel, con, parent; > + > + switch (clk_id) { > + case CLK_PWM0: > + con = readl(&pmucru->pmu_clksel_con[6]); > + sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT; > + div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT; > + if (sel == CLK_PWM0_SEL_XIN24M) > + parent = OSC_HZ; > + else > + parent = priv->ppll_hz; > + break; > + default: > + return -ENOENT; > + } > + > + return DIV_TO_RATE(parent, div); > +} > + > +static ulong rk3568_pwm_set_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + int src_clk_div; > + > + switch (clk_id) { > + case CLK_PWM0: > + if (rate == OSC_HZ) { > + rk_clrsetreg(&pmucru->pmu_clksel_con[6], > + CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK, > + (CLK_PWM0_SEL_XIN24M << > + CLK_PWM0_SEL_SHIFT) | > + 0 << CLK_PWM0_SEL_SHIFT); > + } else { > + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); > + assert(src_clk_div - 1 <= 127); > + rk_clrsetreg(&pmucru->pmu_clksel_con[6], > + CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK, > + (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) | > + (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT); > + } > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_pwm_get_pmuclk(priv, clk_id); > +} > + > +static ulong rk3568_pmu_get_pmuclk(struct rk3568_pmuclk_priv *priv) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + u32 div, con, sel, parent; > + > + con = readl(&pmucru->pmu_clksel_con[2]); > + sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT; > + div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT; > + if (sel) > + parent = GPLL_HZ; > + else > + parent = priv->ppll_hz; > + > + return DIV_TO_RATE(parent, div); > +} > + > +static ulong rk3568_pmu_set_pmuclk(struct rk3568_pmuclk_priv *priv, > + ulong rate) > +{ > + struct rk3568_pmucru *pmucru = priv->pmucru; > + int src_clk_div; > + > + src_clk_div = DIV_ROUND_UP(priv->ppll_hz, rate); > + assert(src_clk_div - 1 <= 31); > + > + rk_clrsetreg(&pmucru->pmu_clksel_con[2], > + PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK, > + (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) | > + ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT)); > + > + return rk3568_pmu_get_pmuclk(priv); > +} > + > +static ulong rk3568_pmuclk_get_rate(struct clk *clk) > +{ > + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); > + ulong rate = 0; > + > + if (!priv->ppll_hz) { > + printf("%s ppll=%lu\n", __func__, priv->ppll_hz); > + return -ENOENT; > + } > + > + debug("%s %ld\n", __func__, clk->id); > + switch (clk->id) { > + case PLL_PPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], > + priv->pmucru, PPLL); > + break; > + case PLL_HPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], > + priv->pmucru, HPLL); > + break; > + case CLK_RTC_32K: > + case CLK_RTC32K_FRAC: > + rate = rk3568_rtc32k_get_pmuclk(priv); > + break; > + case CLK_I2C0: > + rate = rk3568_i2c_get_pmuclk(priv, clk->id); > + break; > + case CLK_PWM0: > + rate = rk3568_pwm_get_pmuclk(priv, clk->id); > + break; > + case PCLK_PMU: > + rate = rk3568_pmu_get_pmuclk(priv); > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +} > + > +static ulong rk3568_pmuclk_set_rate(struct clk *clk, ulong rate) > +{ > + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); > + ulong ret = 0; > + > + if (!priv->ppll_hz) { > + printf("%s ppll=%lu\n", __func__, priv->ppll_hz); > + return -ENOENT; > + } > + > + debug("%s %ld %ld\n", __func__, clk->id, rate); > + switch (clk->id) { > + case PLL_PPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], > + priv->pmucru, PPLL, rate); > + priv->ppll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[PPLL], > + priv->pmucru, PPLL); > + break; > + case PLL_HPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[HPLL], > + priv->pmucru, HPLL, rate); > + priv->hpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[HPLL], > + priv->pmucru, HPLL); > + break; > + case CLK_RTC_32K: > + case CLK_RTC32K_FRAC: > + ret = rk3568_rtc32k_set_pmuclk(priv, rate); > + break; > + case CLK_I2C0: > + ret = rk3568_i2c_set_pmuclk(priv, clk->id, rate); > + break; > + case CLK_PWM0: > + ret = rk3568_pwm_set_pmuclk(priv, clk->id, rate); > + break; > + case PCLK_PMU: > + ret = rk3568_pmu_set_pmuclk(priv, rate); > + break; > + default: > + return -ENOENT; > + } > + > + return ret; > +} > + > +static int rk3568_rtc32k_set_parent(struct clk *clk, struct clk *parent) > +{ > + struct rk3568_pmuclk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_pmucru *pmucru = priv->pmucru; > + > + if (parent->id == CLK_RTC32K_FRAC) > + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, > + RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT); > + else > + rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, > + RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT); > + > + return 0; > +} > + > +static int rk3568_pmuclk_set_parent(struct clk *clk, struct clk *parent) > +{ > + switch (clk->id) { > + case CLK_RTC_32K: > + return rk3568_rtc32k_set_parent(clk, parent); > + default: > + return -ENOENT; > + } > +} > + > +static struct clk_ops rk3568_pmuclk_ops = { > + .get_rate = rk3568_pmuclk_get_rate, > + .set_rate = rk3568_pmuclk_set_rate, > + .set_parent = rk3568_pmuclk_set_parent, > +}; > + > +static int rk3568_pmuclk_probe(struct udevice *dev) > +{ > + struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); > + int ret = 0; > + > + if (priv->ppll_hz != PPLL_HZ) { > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[PPLL], > + priv->pmucru, > + PPLL, PPLL_HZ); > + if (!ret) > + priv->ppll_hz = PPLL_HZ; > + } > + > + /* Ungate PCIe30phy refclk_m and refclk_n */ > + rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13); > + return 0; > +} > + > +static int rk3568_pmuclk_ofdata_to_platdata(struct udevice *dev) > +{ > + struct rk3568_pmuclk_priv *priv = dev_get_priv(dev); > + > + priv->pmucru = dev_read_addr_ptr(dev); > + > + return 0; > +} > + > +static int rk3568_pmuclk_bind(struct udevice *dev) > +{ > +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) > + int ret = 0; > + > + ret = offsetof(struct rk3568_pmucru, pmu_softrst_con[0]); > + ret = rockchip_reset_bind(dev, ret, 1); > + if (ret) > + debug("Warning: pmucru software reset driver bind faile\n"); > +#endif > + > + return 0; > +} > + > +static const struct udevice_id rk3568_pmuclk_ids[] = { > + { .compatible = "rockchip,rk3568-pmucru" }, > + { } > +}; > + > +U_BOOT_DRIVER(rockchip_rk3568_pmucru) = { > + .name = "rockchip_rk3568_pmucru", > + .id = UCLASS_CLK, > + .of_match = rk3568_pmuclk_ids, > + .priv_auto = sizeof(struct rk3568_pmuclk_priv), > + .of_to_plat = rk3568_pmuclk_ofdata_to_platdata, > + .ops = &rk3568_pmuclk_ops, > + .bind = rk3568_pmuclk_bind, > + .probe = rk3568_pmuclk_probe, > +#if CONFIG_IS_ENABLED(OF_PLATDATA) > + .plat_auto = sizeof(struct rk3568_pmuclk_plat), > +#endif > + > +}; > + > +static int rk3568_armclk_set_clk(struct rk3568_clk_priv *priv, ulong hz) > +{ > + struct rk3568_cru *cru = priv->cru; > + const struct rockchip_cpu_rate_table *rate; > + ulong old_rate; > + > + rate = rockchip_get_cpu_settings(rk3568_cpu_rates, hz); > + if (!rate) { > + printf("%s unsupported rate\n", __func__); > + return -EINVAL; > + } > + > + rk_clrsetreg(&cru->clksel_con[0], > + CLK_CORE_PRE_SEL_MASK, > + (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT)); > + rk_clrsetreg(&cru->clksel_con[2], > + SCLK_CORE_PRE_SEL_MASK | > + SCLK_CORE_SRC_SEL_MASK | > + SCLK_CORE_SRC_DIV_MASK, > + (SCLK_CORE_PRE_SEL_SRC << > + SCLK_CORE_PRE_SEL_SHIFT) | > + (SCLK_CORE_SRC_SEL_APLL << > + SCLK_CORE_SRC_SEL_SHIFT) | > + (1 << SCLK_CORE_SRC_DIV_SHIFT)); > + > + /* > + * set up dependent divisors for DBG and ACLK clocks. > + */ > + old_rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], > + priv->cru, APLL); > + if (old_rate > hz) { > + if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], > + priv->cru, APLL, hz)) > + return -EINVAL; > + rk_clrsetreg(&cru->clksel_con[3], > + GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, > + rate->pclk_div << GICCLK_CORE_DIV_SHIFT | > + rate->pclk_div << ATCLK_CORE_DIV_SHIFT); > + rk_clrsetreg(&cru->clksel_con[4], > + PERIPHCLK_CORE_PRE_DIV_MASK | > + PCLK_CORE_PRE_DIV_MASK, > + rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | > + rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); > + rk_clrsetreg(&cru->clksel_con[5], > + ACLK_CORE_NDFT_DIV_MASK, > + rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); > + } else if (old_rate < hz) { > + rk_clrsetreg(&cru->clksel_con[3], > + GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK, > + rate->pclk_div << GICCLK_CORE_DIV_SHIFT | > + rate->pclk_div << ATCLK_CORE_DIV_SHIFT); > + rk_clrsetreg(&cru->clksel_con[4], > + PERIPHCLK_CORE_PRE_DIV_MASK | > + PCLK_CORE_PRE_DIV_MASK, > + rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | > + rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT); > + rk_clrsetreg(&cru->clksel_con[5], > + ACLK_CORE_NDFT_DIV_MASK, > + rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT); > + if (rockchip_pll_set_rate(&rk3568_pll_clks[APLL], > + priv->cru, APLL, hz)) > + return -EINVAL; > + } > + > + return 0; > +} > + > +static ulong rk3568_cpll_div_get_rate(struct rk3568_clk_priv *priv, > + ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + int div, mask, shift, con; > + > + switch (clk_id) { > + case CPLL_500M: > + con = 78; > + mask = CPLL_500M_DIV_MASK; > + shift = CPLL_500M_DIV_SHIFT; > + break; > + case CPLL_333M: > + con = 79; > + mask = CPLL_333M_DIV_MASK; > + shift = CPLL_333M_DIV_SHIFT; > + break; > + case CPLL_250M: > + con = 79; > + mask = CPLL_250M_DIV_MASK; > + shift = CPLL_250M_DIV_SHIFT; > + break; > + case CPLL_125M: > + con = 80; > + mask = CPLL_125M_DIV_MASK; > + shift = CPLL_125M_DIV_SHIFT; > + break; > + case CPLL_100M: > + con = 82; > + mask = CPLL_100M_DIV_MASK; > + shift = CPLL_100M_DIV_SHIFT; > + break; > + case CPLL_62P5M: > + con = 80; > + mask = CPLL_62P5M_DIV_MASK; > + shift = CPLL_62P5M_DIV_SHIFT; > + break; > + case CPLL_50M: > + con = 81; > + mask = CPLL_50M_DIV_MASK; > + shift = CPLL_50M_DIV_SHIFT; > + break; > + case CPLL_25M: > + con = 81; > + mask = CPLL_25M_DIV_MASK; > + shift = CPLL_25M_DIV_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + div = (readl(&cru->clksel_con[con]) & mask) >> shift; > + return DIV_TO_RATE(priv->cpll_hz, div); > +} > + > +static ulong rk3568_cpll_div_set_rate(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int div, mask, shift, con; > + > + switch (clk_id) { > + case CPLL_500M: > + con = 78; > + mask = CPLL_500M_DIV_MASK; > + shift = CPLL_500M_DIV_SHIFT; > + break; > + case CPLL_333M: > + con = 79; > + mask = CPLL_333M_DIV_MASK; > + shift = CPLL_333M_DIV_SHIFT; > + break; > + case CPLL_250M: > + con = 79; > + mask = CPLL_250M_DIV_MASK; > + shift = CPLL_250M_DIV_SHIFT; > + break; > + case CPLL_125M: > + con = 80; > + mask = CPLL_125M_DIV_MASK; > + shift = CPLL_125M_DIV_SHIFT; > + break; > + case CPLL_100M: > + con = 82; > + mask = CPLL_100M_DIV_MASK; > + shift = CPLL_100M_DIV_SHIFT; > + break; > + case CPLL_62P5M: > + con = 80; > + mask = CPLL_62P5M_DIV_MASK; > + shift = CPLL_62P5M_DIV_SHIFT; > + break; > + case CPLL_50M: > + con = 81; > + mask = CPLL_50M_DIV_MASK; > + shift = CPLL_50M_DIV_SHIFT; > + break; > + case CPLL_25M: > + con = 81; > + mask = CPLL_25M_DIV_MASK; > + shift = CPLL_25M_DIV_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + div = DIV_ROUND_UP(priv->cpll_hz, rate); > + assert(div - 1 <= 31); > + rk_clrsetreg(&cru->clksel_con[con], > + mask, (div - 1) << shift); > + return rk3568_cpll_div_get_rate(priv, clk_id); > +} > + > +static ulong rk3568_bus_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, sel, rate; > + > + switch (clk_id) { > + case ACLK_BUS: > + con = readl(&cru->clksel_con[50]); > + sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT; > + if (sel == ACLK_BUS_SEL_200M) > + rate = 200 * MHz; > + else if (sel == ACLK_BUS_SEL_150M) > + rate = 150 * MHz; > + else if (sel == ACLK_BUS_SEL_100M) > + rate = 100 * MHz; > + else > + rate = OSC_HZ; > + break; > + case PCLK_BUS: > + case PCLK_WDT_NS: > + con = readl(&cru->clksel_con[50]); > + sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT; > + if (sel == PCLK_BUS_SEL_100M) > + rate = 100 * MHz; > + else if (sel == PCLK_BUS_SEL_75M) > + rate = 75 * MHz; > + else if (sel == PCLK_BUS_SEL_50M) > + rate = 50 * MHz; > + else > + rate = OSC_HZ; > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +} > + > +static ulong rk3568_bus_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (clk_id) { > + case ACLK_BUS: > + if (rate == 200 * MHz) > + src_clk = ACLK_BUS_SEL_200M; > + else if (rate == 150 * MHz) > + src_clk = ACLK_BUS_SEL_150M; > + else if (rate == 100 * MHz) > + src_clk = ACLK_BUS_SEL_100M; > + else > + src_clk = ACLK_BUS_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[50], > + ACLK_BUS_SEL_MASK, > + src_clk << ACLK_BUS_SEL_SHIFT); > + break; > + case PCLK_BUS: > + case PCLK_WDT_NS: > + if (rate == 100 * MHz) > + src_clk = PCLK_BUS_SEL_100M; > + else if (rate == 75 * MHz) > + src_clk = PCLK_BUS_SEL_75M; > + else if (rate == 50 * MHz) > + src_clk = PCLK_BUS_SEL_50M; > + else > + src_clk = PCLK_BUS_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[50], > + PCLK_BUS_SEL_MASK, > + src_clk << PCLK_BUS_SEL_SHIFT); > + break; > + > + default: > + printf("do not support this bus freq\n"); > + return -EINVAL; > + } > + > + return rk3568_bus_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_perimid_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, sel, rate; > + > + switch (clk_id) { > + case ACLK_PERIMID: > + con = readl(&cru->clksel_con[10]); > + sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT; > + if (sel == ACLK_PERIMID_SEL_300M) > + rate = 300 * MHz; > + else if (sel == ACLK_PERIMID_SEL_200M) > + rate = 200 * MHz; > + else if (sel == ACLK_PERIMID_SEL_100M) > + rate = 100 * MHz; > + else > + rate = OSC_HZ; > + break; > + case HCLK_PERIMID: > + con = readl(&cru->clksel_con[10]); > + sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT; > + if (sel == HCLK_PERIMID_SEL_150M) > + rate = 150 * MHz; > + else if (sel == HCLK_PERIMID_SEL_100M) > + rate = 100 * MHz; > + else if (sel == HCLK_PERIMID_SEL_75M) > + rate = 75 * MHz; > + else > + rate = OSC_HZ; > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +} > + > +static ulong rk3568_perimid_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (clk_id) { > + case ACLK_PERIMID: > + if (rate == 300 * MHz) > + src_clk = ACLK_PERIMID_SEL_300M; > + else if (rate == 200 * MHz) > + src_clk = ACLK_PERIMID_SEL_200M; > + else if (rate == 100 * MHz) > + src_clk = ACLK_PERIMID_SEL_100M; > + else > + src_clk = ACLK_PERIMID_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[10], > + ACLK_PERIMID_SEL_MASK, > + src_clk << ACLK_PERIMID_SEL_SHIFT); > + break; > + case HCLK_PERIMID: > + if (rate == 150 * MHz) > + src_clk = HCLK_PERIMID_SEL_150M; > + else if (rate == 100 * MHz) > + src_clk = HCLK_PERIMID_SEL_100M; > + else if (rate == 75 * MHz) > + src_clk = HCLK_PERIMID_SEL_75M; > + else > + src_clk = HCLK_PERIMID_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[10], > + HCLK_PERIMID_SEL_MASK, > + src_clk << HCLK_PERIMID_SEL_SHIFT); > + break; > + > + default: > + printf("do not support this permid freq\n"); > + return -EINVAL; > + } > + > + return rk3568_perimid_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_top_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, sel, rate; > + > + switch (clk_id) { > + case ACLK_TOP_HIGH: > + con = readl(&cru->clksel_con[73]); > + sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT; > + if (sel == ACLK_TOP_HIGH_SEL_500M) > + rate = 500 * MHz; > + else if (sel == ACLK_TOP_HIGH_SEL_400M) > + rate = 400 * MHz; > + else if (sel == ACLK_TOP_HIGH_SEL_300M) > + rate = 300 * MHz; > + else > + rate = OSC_HZ; > + break; > + case ACLK_TOP_LOW: > + con = readl(&cru->clksel_con[73]); > + sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT; > + if (sel == ACLK_TOP_LOW_SEL_400M) > + rate = 400 * MHz; > + else if (sel == ACLK_TOP_LOW_SEL_300M) > + rate = 300 * MHz; > + else if (sel == ACLK_TOP_LOW_SEL_200M) > + rate = 200 * MHz; > + else > + rate = OSC_HZ; > + break; > + case HCLK_TOP: > + con = readl(&cru->clksel_con[73]); > + sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT; > + if (sel == HCLK_TOP_SEL_150M) > + rate = 150 * MHz; > + else if (sel == HCLK_TOP_SEL_100M) > + rate = 100 * MHz; > + else if (sel == HCLK_TOP_SEL_75M) > + rate = 75 * MHz; > + else > + rate = OSC_HZ; > + break; > + case PCLK_TOP: > + con = readl(&cru->clksel_con[73]); > + sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; > + if (sel == PCLK_TOP_SEL_100M) > + rate = 100 * MHz; > + else if (sel == PCLK_TOP_SEL_75M) > + rate = 75 * MHz; > + else if (sel == PCLK_TOP_SEL_50M) > + rate = 50 * MHz; > + else > + rate = OSC_HZ; > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +} > + > +static ulong rk3568_top_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (clk_id) { > + case ACLK_TOP_HIGH: > + if (rate == 500 * MHz) > + src_clk = ACLK_TOP_HIGH_SEL_500M; > + else if (rate == 400 * MHz) > + src_clk = ACLK_TOP_HIGH_SEL_400M; > + else if (rate == 300 * MHz) > + src_clk = ACLK_TOP_HIGH_SEL_300M; > + else > + src_clk = ACLK_TOP_HIGH_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[73], > + ACLK_TOP_HIGH_SEL_MASK, > + src_clk << ACLK_TOP_HIGH_SEL_SHIFT); > + break; > + case ACLK_TOP_LOW: > + if (rate == 400 * MHz) > + src_clk = ACLK_TOP_LOW_SEL_400M; > + else if (rate == 300 * MHz) > + src_clk = ACLK_TOP_LOW_SEL_300M; > + else if (rate == 200 * MHz) > + src_clk = ACLK_TOP_LOW_SEL_200M; > + else > + src_clk = ACLK_TOP_LOW_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[73], > + ACLK_TOP_LOW_SEL_MASK, > + src_clk << ACLK_TOP_LOW_SEL_SHIFT); > + break; > + case HCLK_TOP: > + if (rate == 150 * MHz) > + src_clk = HCLK_TOP_SEL_150M; > + else if (rate == 100 * MHz) > + src_clk = HCLK_TOP_SEL_100M; > + else if (rate == 75 * MHz) > + src_clk = HCLK_TOP_SEL_75M; > + else > + src_clk = HCLK_TOP_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[73], > + HCLK_TOP_SEL_MASK, > + src_clk << HCLK_TOP_SEL_SHIFT); > + break; > + case PCLK_TOP: > + if (rate == 100 * MHz) > + src_clk = PCLK_TOP_SEL_100M; > + else if (rate == 75 * MHz) > + src_clk = PCLK_TOP_SEL_75M; > + else if (rate == 50 * MHz) > + src_clk = PCLK_TOP_SEL_50M; > + else > + src_clk = PCLK_TOP_SEL_24M; > + rk_clrsetreg(&cru->clksel_con[73], > + PCLK_TOP_SEL_MASK, > + src_clk << PCLK_TOP_SEL_SHIFT); > + break; > + > + default: > + printf("do not support this permid freq\n"); > + return -EINVAL; > + } > + > + return rk3568_top_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_i2c_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + ulong rate; > + > + switch (clk_id) { > + case CLK_I2C1: > + case CLK_I2C2: > + case CLK_I2C3: > + case CLK_I2C4: > + case CLK_I2C5: > + con = readl(&cru->clksel_con[71]); > + sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT; > + if (sel == CLK_I2C_SEL_200M) > + rate = 200 * MHz; > + else if (sel == CLK_I2C_SEL_100M) > + rate = 100 * MHz; > + else if (sel == CLK_I2C_SEL_CPLL_100M) > + rate = 100 * MHz; > + else > + rate = OSC_HZ; > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +} > + > +static ulong rk3568_i2c_set_clk(struct rk3568_clk_priv *priv, ulong clk_id, > + ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + if (rate == 200 * MHz) > + src_clk = CLK_I2C_SEL_200M; > + else if (rate == 100 * MHz) > + src_clk = CLK_I2C_SEL_100M; > + else > + src_clk = CLK_I2C_SEL_24M; > + > + switch (clk_id) { > + case CLK_I2C1: > + case CLK_I2C2: > + case CLK_I2C3: > + case CLK_I2C4: > + case CLK_I2C5: > + rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK, > + src_clk << CLK_I2C_SEL_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_i2c_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_spi_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[72]); > + > + switch (clk_id) { > + case CLK_SPI0: > + sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; > + break; > + case CLK_SPI1: > + sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; > + break; > + case CLK_SPI2: > + sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; > + break; > + case CLK_SPI3: > + sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + switch (sel) { > + case CLK_SPI_SEL_200M: > + return 200 * MHz; > + case CLK_SPI_SEL_24M: > + return OSC_HZ; > + case CLK_SPI_SEL_CPLL_100M: > + return 100 * MHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_spi_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + if (rate == 200 * MHz) > + src_clk = CLK_SPI_SEL_200M; > + else if (rate == 100 * MHz) > + src_clk = CLK_SPI_SEL_CPLL_100M; > + else > + src_clk = CLK_SPI_SEL_24M; > + > + switch (clk_id) { > + case CLK_SPI0: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_SPI0_SEL_MASK, > + src_clk << CLK_SPI0_SEL_SHIFT); > + break; > + case CLK_SPI1: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_SPI1_SEL_MASK, > + src_clk << CLK_SPI1_SEL_SHIFT); > + break; > + case CLK_SPI2: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_SPI2_SEL_MASK, > + src_clk << CLK_SPI2_SEL_SHIFT); > + break; > + case CLK_SPI3: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_SPI3_SEL_MASK, > + src_clk << CLK_SPI3_SEL_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_spi_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_pwm_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[72]); > + > + switch (clk_id) { > + case CLK_PWM1: > + sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; > + break; > + case CLK_PWM2: > + sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; > + break; > + case CLK_PWM3: > + sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + switch (sel) { > + case CLK_PWM_SEL_100M: > + return 100 * MHz; > + case CLK_PWM_SEL_24M: > + return OSC_HZ; > + case CLK_PWM_SEL_CPLL_100M: > + return 100 * MHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_pwm_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + if (rate == 100 * MHz) > + src_clk = CLK_PWM_SEL_100M; > + else > + src_clk = CLK_PWM_SEL_24M; > + > + switch (clk_id) { > + case CLK_PWM1: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_PWM1_SEL_MASK, > + src_clk << CLK_PWM1_SEL_SHIFT); > + break; > + case CLK_PWM2: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_PWM2_SEL_MASK, > + src_clk << CLK_PWM2_SEL_SHIFT); > + break; > + case CLK_PWM3: > + rk_clrsetreg(&cru->clksel_con[72], > + CLK_PWM3_SEL_MASK, > + src_clk << CLK_PWM3_SEL_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_pwm_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_adc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 div, sel, con, prate; > + > + switch (clk_id) { > + case CLK_SARADC: > + return OSC_HZ; > + case CLK_TSADC_TSEN: > + con = readl(&cru->clksel_con[51]); > + div = (con & CLK_TSADC_TSEN_DIV_MASK) >> > + CLK_TSADC_TSEN_DIV_SHIFT; > + sel = (con & CLK_TSADC_TSEN_SEL_MASK) >> > + CLK_TSADC_TSEN_SEL_SHIFT; > + if (sel == CLK_TSADC_TSEN_SEL_24M) > + prate = OSC_HZ; > + else > + prate = 100 * MHz; > + return DIV_TO_RATE(prate, div); > + case CLK_TSADC: > + con = readl(&cru->clksel_con[51]); > + div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT; > + prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); > + return DIV_TO_RATE(prate, div); > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_adc_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk_div; > + ulong prate = 0; > + > + switch (clk_id) { > + case CLK_SARADC: > + return OSC_HZ; > + case CLK_TSADC_TSEN: > + if (!(OSC_HZ % rate)) { > + src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); > + assert(src_clk_div - 1 <= 7); > + rk_clrsetreg(&cru->clksel_con[51], > + CLK_TSADC_TSEN_SEL_MASK | > + CLK_TSADC_TSEN_DIV_MASK, > + (CLK_TSADC_TSEN_SEL_24M << > + CLK_TSADC_TSEN_SEL_SHIFT) | > + (src_clk_div - 1) << > + CLK_TSADC_TSEN_DIV_SHIFT); > + } else { > + src_clk_div = DIV_ROUND_UP(100 * MHz, rate); > + assert(src_clk_div - 1 <= 7); > + rk_clrsetreg(&cru->clksel_con[51], > + CLK_TSADC_TSEN_SEL_MASK | > + CLK_TSADC_TSEN_DIV_MASK, > + (CLK_TSADC_TSEN_SEL_100M << > + CLK_TSADC_TSEN_SEL_SHIFT) | > + (src_clk_div - 1) << > + CLK_TSADC_TSEN_DIV_SHIFT); > + } > + break; > + case CLK_TSADC: > + prate = rk3568_adc_get_clk(priv, CLK_TSADC_TSEN); > + src_clk_div = DIV_ROUND_UP(prate, rate); > + assert(src_clk_div - 1 <= 128); > + rk_clrsetreg(&cru->clksel_con[51], > + CLK_TSADC_DIV_MASK, > + (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + return rk3568_adc_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_crypto_get_rate(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + switch (clk_id) { > + case ACLK_SECURE_FLASH: > + case ACLK_CRYPTO_NS: > + con = readl(&cru->clksel_con[27]); > + sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >> > + ACLK_SECURE_FLASH_SEL_SHIFT; > + if (sel == ACLK_SECURE_FLASH_SEL_200M) > + return 200 * MHz; > + else if (sel == ACLK_SECURE_FLASH_SEL_150M) > + return 150 * MHz; > + else if (sel == ACLK_SECURE_FLASH_SEL_100M) > + return 100 * MHz; > + else > + return 24 * MHz; > + case HCLK_SECURE_FLASH: > + case HCLK_CRYPTO_NS: > + case CLK_CRYPTO_NS_RNG: > + con = readl(&cru->clksel_con[27]); > + sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >> > + HCLK_SECURE_FLASH_SEL_SHIFT; > + if (sel == HCLK_SECURE_FLASH_SEL_150M) > + return 150 * MHz; > + else if (sel == HCLK_SECURE_FLASH_SEL_100M) > + return 100 * MHz; > + else if (sel == HCLK_SECURE_FLASH_SEL_75M) > + return 75 * MHz; > + else > + return 24 * MHz; > + case CLK_CRYPTO_NS_CORE: > + con = readl(&cru->clksel_con[27]); > + sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> > + CLK_CRYPTO_CORE_SEL_SHIFT; > + if (sel == CLK_CRYPTO_CORE_SEL_200M) > + return 200 * MHz; > + else if (sel == CLK_CRYPTO_CORE_SEL_150M) > + return 150 * MHz; > + else > + return 100 * MHz; > + case CLK_CRYPTO_NS_PKA: > + con = readl(&cru->clksel_con[27]); > + sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> > + CLK_CRYPTO_PKA_SEL_SHIFT; > + if (sel == CLK_CRYPTO_PKA_SEL_300M) > + return 300 * MHz; > + else if (sel == CLK_CRYPTO_PKA_SEL_200M) > + return 200 * MHz; > + else > + return 100 * MHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_crypto_set_rate(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 src_clk, mask, shift; > + > + switch (clk_id) { > + case ACLK_SECURE_FLASH: > + case ACLK_CRYPTO_NS: > + mask = ACLK_SECURE_FLASH_SEL_MASK; > + shift = ACLK_SECURE_FLASH_SEL_SHIFT; > + if (rate == 200 * MHz) > + src_clk = ACLK_SECURE_FLASH_SEL_200M; > + else if (rate == 150 * MHz) > + src_clk = ACLK_SECURE_FLASH_SEL_150M; > + else if (rate == 100 * MHz) > + src_clk = ACLK_SECURE_FLASH_SEL_100M; > + else > + src_clk = ACLK_SECURE_FLASH_SEL_24M; > + break; > + case HCLK_SECURE_FLASH: > + case HCLK_CRYPTO_NS: > + case CLK_CRYPTO_NS_RNG: > + mask = HCLK_SECURE_FLASH_SEL_MASK; > + shift = HCLK_SECURE_FLASH_SEL_SHIFT; > + if (rate == 150 * MHz) > + src_clk = HCLK_SECURE_FLASH_SEL_150M; > + else if (rate == 100 * MHz) > + src_clk = HCLK_SECURE_FLASH_SEL_100M; > + else if (rate == 75 * MHz) > + src_clk = HCLK_SECURE_FLASH_SEL_75M; > + else > + src_clk = HCLK_SECURE_FLASH_SEL_24M; > + break; > + case CLK_CRYPTO_NS_CORE: > + mask = CLK_CRYPTO_CORE_SEL_MASK; > + shift = CLK_CRYPTO_CORE_SEL_SHIFT; > + if (rate == 200 * MHz) > + src_clk = CLK_CRYPTO_CORE_SEL_200M; > + else if (rate == 150 * MHz) > + src_clk = CLK_CRYPTO_CORE_SEL_150M; > + else > + src_clk = CLK_CRYPTO_CORE_SEL_100M; > + break; > + case CLK_CRYPTO_NS_PKA: > + mask = CLK_CRYPTO_PKA_SEL_MASK; > + shift = CLK_CRYPTO_PKA_SEL_SHIFT; > + if (rate == 300 * MHz) > + src_clk = CLK_CRYPTO_PKA_SEL_300M; > + else if (rate == 200 * MHz) > + src_clk = CLK_CRYPTO_PKA_SEL_200M; > + else > + src_clk = CLK_CRYPTO_PKA_SEL_100M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift); > + > + return rk3568_crypto_get_rate(priv, clk_id); > +} > + > +static ulong rk3568_sdmmc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + switch (clk_id) { > + case HCLK_SDMMC0: > + case CLK_SDMMC0: > + con = readl(&cru->clksel_con[30]); > + sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT; > + break; > + case CLK_SDMMC1: > + con = readl(&cru->clksel_con[30]); > + sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT; > + break; > + case CLK_SDMMC2: > + con = readl(&cru->clksel_con[32]); > + sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT; > + break; > + default: > + return -ENOENT; > + } > + > + switch (sel) { > + case CLK_SDMMC_SEL_24M: > + return OSC_HZ; > + case CLK_SDMMC_SEL_400M: > + return 400 * MHz; > + case CLK_SDMMC_SEL_300M: > + return 300 * MHz; > + case CLK_SDMMC_SEL_100M: > + return 100 * MHz; > + case CLK_SDMMC_SEL_50M: > + return 50 * MHz; > + case CLK_SDMMC_SEL_750K: > + return 750 * KHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_sdmmc_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case OSC_HZ: > + src_clk = CLK_SDMMC_SEL_24M; > + break; > + case 400 * MHz: > + src_clk = CLK_SDMMC_SEL_400M; > + break; > + case 300 * MHz: > + src_clk = CLK_SDMMC_SEL_300M; > + break; > + case 100 * MHz: > + src_clk = CLK_SDMMC_SEL_100M; > + break; > + case 52 * MHz: > + case 50 * MHz: > + src_clk = CLK_SDMMC_SEL_50M; > + break; > + case 750 * KHz: > + case 400 * KHz: > + src_clk = CLK_SDMMC_SEL_750K; > + break; > + default: > + return -ENOENT; > + } > + > + switch (clk_id) { > + case HCLK_SDMMC0: > + case CLK_SDMMC0: > + rk_clrsetreg(&cru->clksel_con[30], > + CLK_SDMMC0_SEL_MASK, > + src_clk << CLK_SDMMC0_SEL_SHIFT); > + break; > + case CLK_SDMMC1: > + rk_clrsetreg(&cru->clksel_con[30], > + CLK_SDMMC1_SEL_MASK, > + src_clk << CLK_SDMMC1_SEL_SHIFT); > + break; > + case CLK_SDMMC2: > + rk_clrsetreg(&cru->clksel_con[32], > + CLK_SDMMC2_SEL_MASK, > + src_clk << CLK_SDMMC2_SEL_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_sdmmc_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_sfc_get_clk(struct rk3568_clk_priv *priv) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[28]); > + sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT; > + switch (sel) { > + case SCLK_SFC_SEL_24M: > + return OSC_HZ; > + case SCLK_SFC_SEL_50M: > + return 50 * MHz; > + case SCLK_SFC_SEL_75M: > + return 75 * MHz; > + case SCLK_SFC_SEL_100M: > + return 100 * MHz; > + case SCLK_SFC_SEL_125M: > + return 125 * MHz; > + case SCLK_SFC_SEL_150M: > + return 150 * KHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_sfc_set_clk(struct rk3568_clk_priv *priv, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case OSC_HZ: > + src_clk = SCLK_SFC_SEL_24M; > + break; > + case 50 * MHz: > + src_clk = SCLK_SFC_SEL_50M; > + break; > + case 75 * MHz: > + src_clk = SCLK_SFC_SEL_75M; > + break; > + case 100 * MHz: > + src_clk = SCLK_SFC_SEL_100M; > + break; > + case 125 * MHz: > + src_clk = SCLK_SFC_SEL_125M; > + break; > + case 150 * KHz: > + src_clk = SCLK_SFC_SEL_150M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[28], > + SCLK_SFC_SEL_MASK, > + src_clk << SCLK_SFC_SEL_SHIFT); > + > + return rk3568_sfc_get_clk(priv); > +} > + > +static ulong rk3568_nand_get_clk(struct rk3568_clk_priv *priv) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[28]); > + sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT; > + switch (sel) { > + case NCLK_NANDC_SEL_200M: > + return 200 * MHz; > + case NCLK_NANDC_SEL_150M: > + return 150 * MHz; > + case NCLK_NANDC_SEL_100M: > + return 100 * MHz; > + case NCLK_NANDC_SEL_24M: > + return OSC_HZ; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_nand_set_clk(struct rk3568_clk_priv *priv, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case OSC_HZ: > + src_clk = NCLK_NANDC_SEL_24M; > + break; > + case 100 * MHz: > + src_clk = NCLK_NANDC_SEL_100M; > + break; > + case 150 * MHz: > + src_clk = NCLK_NANDC_SEL_150M; > + break; > + case 200 * MHz: > + src_clk = NCLK_NANDC_SEL_200M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[28], > + NCLK_NANDC_SEL_MASK, > + src_clk << NCLK_NANDC_SEL_SHIFT); > + > + return rk3568_nand_get_clk(priv); > +} > + > +static ulong rk3568_emmc_get_clk(struct rk3568_clk_priv *priv) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[28]); > + sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT; > + switch (sel) { > + case CCLK_EMMC_SEL_200M: > + return 200 * MHz; > + case CCLK_EMMC_SEL_150M: > + return 150 * MHz; > + case CCLK_EMMC_SEL_100M: > + return 100 * MHz; > + case CCLK_EMMC_SEL_50M: > + return 50 * MHz; > + case CCLK_EMMC_SEL_375K: > + return 375 * KHz; > + case CCLK_EMMC_SEL_24M: > + return OSC_HZ; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_emmc_set_clk(struct rk3568_clk_priv *priv, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case OSC_HZ: > + src_clk = CCLK_EMMC_SEL_24M; > + break; > + case 52 * MHz: > + case 50 * MHz: > + src_clk = CCLK_EMMC_SEL_50M; > + break; > + case 100 * MHz: > + src_clk = CCLK_EMMC_SEL_100M; > + break; > + case 150 * MHz: > + src_clk = CCLK_EMMC_SEL_150M; > + break; > + case 200 * MHz: > + src_clk = CCLK_EMMC_SEL_200M; > + break; > + case 400 * KHz: > + case 375 * KHz: > + src_clk = CCLK_EMMC_SEL_375K; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[28], > + CCLK_EMMC_SEL_MASK, > + src_clk << CCLK_EMMC_SEL_SHIFT); > + > + return rk3568_emmc_get_clk(priv); > +} > + > +#ifndef CONFIG_SPL_BUILD > +static ulong rk3568_aclk_vop_get_clk(struct rk3568_clk_priv *priv) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 div, sel, con, parent; > + > + con = readl(&cru->clksel_con[38]); > + div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT; > + sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT; > + if (sel == ACLK_VOP_PRE_SEL_GPLL) > + parent = priv->gpll_hz; > + else if (sel == ACLK_VOP_PRE_SEL_CPLL) > + parent = priv->cpll_hz; > + else if (sel == ACLK_VOP_PRE_SEL_VPLL) > + parent = priv->vpll_hz; > + else > + parent = priv->hpll_hz; > + > + return DIV_TO_RATE(parent, div); > +} > + > +static ulong rk3568_aclk_vop_set_clk(struct rk3568_clk_priv *priv, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk_div, src_clk_mux; > + > + if ((priv->cpll_hz % rate) == 0) { > + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); > + src_clk_mux = ACLK_VOP_PRE_SEL_CPLL; > + } else { > + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); > + src_clk_mux = ACLK_VOP_PRE_SEL_GPLL; > + } > + assert(src_clk_div - 1 <= 31); > + rk_clrsetreg(&cru->clksel_con[38], > + ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK, > + src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT | > + (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT); > + > + return rk3568_aclk_vop_get_clk(priv); > +} > + > +static ulong rk3568_dclk_vop_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 conid, div, sel, con, parent; > + > + switch (clk_id) { > + case DCLK_VOP0: > + conid = 39; > + break; > + case DCLK_VOP1: > + conid = 40; > + break; > + case DCLK_VOP2: > + conid = 41; > + break; > + default: > + return -ENOENT; > + } > + > + con = readl(&cru->clksel_con[conid]); > + div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT; > + sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; > + if (sel == DCLK_VOP_SEL_HPLL) > + parent = rk3568_pmu_pll_get_rate(priv, HPLL); > + else if (sel == DCLK_VOP_SEL_VPLL) > + parent = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], > + priv->cru, VPLL); > + else if (sel == DCLK_VOP_SEL_GPLL) > + parent = priv->gpll_hz; > + else if (sel == DCLK_VOP_SEL_CPLL) > + parent = priv->cpll_hz; > + else > + return -ENOENT; > + > + return DIV_TO_RATE(parent, div); > +} > + > +#define RK3568_VOP_PLL_LIMIT_FREQ 600000000 > + > +static ulong rk3568_dclk_vop_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + ulong pll_rate, now, best_rate = 0; > + u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; > + > + switch (clk_id) { > + case DCLK_VOP0: > + conid = 39; > + break; > + case DCLK_VOP1: > + conid = 40; > + break; > + case DCLK_VOP2: > + conid = 41; > + break; > + default: > + return -ENOENT; > + } > + > + con = readl(&cru->clksel_con[conid]); > + sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT; > + > + if (sel == DCLK_VOP_SEL_HPLL) { > + div = 1; > + rk_clrsetreg(&cru->clksel_con[conid], > + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, > + (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) | > + ((div - 1) << DCLK0_VOP_DIV_SHIFT)); > + rk3568_pmu_pll_set_rate(priv, HPLL, div * rate); > + } else if (sel == DCLK_VOP_SEL_VPLL) { > + div = DIV_ROUND_UP(RK3568_VOP_PLL_LIMIT_FREQ, rate); > + rk_clrsetreg(&cru->clksel_con[conid], > + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, > + (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) | > + ((div - 1) << DCLK0_VOP_DIV_SHIFT)); > + rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], > + priv->cru, VPLL, div * rate); > + } else { > + for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++) { > + switch (i) { > + case DCLK_VOP_SEL_GPLL: > + pll_rate = priv->gpll_hz; > + break; > + case DCLK_VOP_SEL_CPLL: > + pll_rate = priv->cpll_hz; > + break; > + default: > + printf("do not support this vop pll sel\n"); > + return -EINVAL; > + } > + > + div = DIV_ROUND_UP(pll_rate, rate); > + if (div > 255) > + continue; > + now = pll_rate / div; > + if (abs(rate - now) < abs(rate - best_rate)) { > + best_rate = now; > + best_div = div; > + best_sel = i; > + } > + debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", > + pll_rate, best_rate, best_div, best_sel); > + } > + > + if (best_rate) { > + rk_clrsetreg(&cru->clksel_con[conid], > + DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK, > + best_sel << DCLK0_VOP_SEL_SHIFT | > + (best_div - 1) << DCLK0_VOP_DIV_SHIFT); > + } else { > + printf("do not support this vop freq %lu\n", rate); > + return -EINVAL; > + } > + } > + return rk3568_dclk_vop_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_gmac_src_get_clk(struct rk3568_clk_priv *priv, > + ulong mac_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[31 + mac_id * 2]); > + sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT; > + > + switch (sel) { > + case CLK_MAC0_2TOP_SEL_125M: > + return 125 * MHz; > + case CLK_MAC0_2TOP_SEL_50M: > + return 50 * MHz; > + case CLK_MAC0_2TOP_SEL_25M: > + return 25 * MHz; > + case CLK_MAC0_2TOP_SEL_PPLL: > + return rk3568_pmu_pll_get_rate(priv, HPLL); > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_gmac_src_set_clk(struct rk3568_clk_priv *priv, > + ulong mac_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case 125 * MHz: > + src_clk = CLK_MAC0_2TOP_SEL_125M; > + break; > + case 50 * MHz: > + src_clk = CLK_MAC0_2TOP_SEL_50M; > + break; > + case 25 * MHz: > + src_clk = CLK_MAC0_2TOP_SEL_25M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], > + CLK_MAC0_2TOP_SEL_MASK, > + src_clk << CLK_MAC0_2TOP_SEL_SHIFT); > + > + return rk3568_gmac_src_get_clk(priv, mac_id); > +} > + > +static ulong rk3568_gmac_out_get_clk(struct rk3568_clk_priv *priv, > + ulong mac_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[31 + mac_id * 2]); > + sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT; > + > + switch (sel) { > + case CLK_MAC0_OUT_SEL_125M: > + return 125 * MHz; > + case CLK_MAC0_OUT_SEL_50M: > + return 50 * MHz; > + case CLK_MAC0_OUT_SEL_25M: > + return 25 * MHz; > + case CLK_MAC0_OUT_SEL_24M: > + return OSC_HZ; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_gmac_out_set_clk(struct rk3568_clk_priv *priv, > + ulong mac_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case 125 * MHz: > + src_clk = CLK_MAC0_OUT_SEL_125M; > + break; > + case 50 * MHz: > + src_clk = CLK_MAC0_OUT_SEL_50M; > + break; > + case 25 * MHz: > + src_clk = CLK_MAC0_OUT_SEL_25M; > + break; > + case 24 * MHz: > + src_clk = CLK_MAC0_OUT_SEL_24M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], > + CLK_MAC0_OUT_SEL_MASK, > + src_clk << CLK_MAC0_OUT_SEL_SHIFT); > + > + return rk3568_gmac_out_get_clk(priv, mac_id); > +} > + > +static ulong rk3568_gmac_ptp_ref_get_clk(struct rk3568_clk_priv *priv, > + ulong mac_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 sel, con; > + > + con = readl(&cru->clksel_con[31 + mac_id * 2]); > + sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT; > + > + switch (sel) { > + case CLK_GMAC0_PTP_REF_SEL_62_5M: > + return 62500 * KHz; > + case CLK_GMAC0_PTP_REF_SEL_100M: > + return 100 * MHz; > + case CLK_GMAC0_PTP_REF_SEL_50M: > + return 50 * MHz; > + case CLK_GMAC0_PTP_REF_SEL_24M: > + return OSC_HZ; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_gmac_ptp_ref_set_clk(struct rk3568_clk_priv *priv, > + ulong mac_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk; > + > + switch (rate) { > + case 62500 * KHz: > + src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M; > + break; > + case 100 * MHz: > + src_clk = CLK_GMAC0_PTP_REF_SEL_100M; > + break; > + case 50 * MHz: > + src_clk = CLK_GMAC0_PTP_REF_SEL_50M; > + break; > + case 24 * MHz: > + src_clk = CLK_GMAC0_PTP_REF_SEL_24M; > + break; > + default: > + return -ENOENT; > + } > + > + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], > + CLK_GMAC0_PTP_REF_SEL_MASK, > + src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT); > + > + return rk3568_gmac_ptp_ref_get_clk(priv, mac_id); > +} > + > +static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv, > + ulong mac_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, sel, div_sel; > + > + con = readl(&cru->clksel_con[31 + mac_id * 2]); > + sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT; > + > + if (sel == RMII0_MODE_SEL_RGMII) { > + if (rate == 2500000) > + div_sel = RGMII0_CLK_SEL_2_5M; > + else if (rate == 25000000) > + div_sel = RGMII0_CLK_SEL_25M; > + else > + div_sel = RGMII0_CLK_SEL_125M; > + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], > + RGMII0_CLK_SEL_MASK, > + div_sel << RGMII0_CLK_SEL_SHIFT); > + } else if (sel == RMII0_MODE_SEL_RMII) { > + if (rate == 2500000) > + div_sel = RMII0_CLK_SEL_2_5M; > + else > + div_sel = RMII0_CLK_SEL_25M; > + rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], > + RMII0_CLK_SEL_MASK, > + div_sel << RMII0_CLK_SEL_SHIFT); > + } > + > + return 0; > +} > + > +static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, div, p_rate; > + > + con = readl(&cru->clksel_con[79]); > + div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT; > + p_rate = DIV_TO_RATE(priv->cpll_hz, div); > + > + con = readl(&cru->clksel_con[43]); > + div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; > + switch (div) { > + case DCLK_EBC_SEL_GPLL_400M: > + return 400 * MHz; > + case DCLK_EBC_SEL_CPLL_333M: > + return p_rate; > + case DCLK_EBC_SEL_GPLL_200M: > + return 200 * MHz; > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk_div; > + > + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); > + assert(src_clk_div - 1 <= 31); > + rk_clrsetreg(&cru->clksel_con[79], > + CPLL_333M_DIV_MASK, > + (src_clk_div - 1) << CPLL_333M_DIV_SHIFT); > + rk_clrsetreg(&cru->clksel_con[43], > + DCLK_EBC_SEL_MASK, > + DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT); > + > + return rk3568_ebc_get_clk(priv); > +} > + > +static ulong rk3568_rkvdec_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 con, div, src, p_rate; > + > + switch (clk_id) { > + case ACLK_RKVDEC_PRE: > + case ACLK_RKVDEC: > + con = readl(&cru->clksel_con[47]); > + src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT; > + div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT; > + if (src == ACLK_RKVDEC_SEL_CPLL) > + p_rate = priv->cpll_hz; > + else > + p_rate = priv->gpll_hz; > + return DIV_TO_RATE(p_rate, div); > + case CLK_RKVDEC_CORE: > + con = readl(&cru->clksel_con[49]); > + src = (con & CLK_RKVDEC_CORE_SEL_MASK) > + >> CLK_RKVDEC_CORE_SEL_SHIFT; > + div = (con & CLK_RKVDEC_CORE_DIV_MASK) > + >> CLK_RKVDEC_CORE_DIV_SHIFT; > + if (src == CLK_RKVDEC_CORE_SEL_CPLL) > + p_rate = priv->cpll_hz; > + else if (src == CLK_RKVDEC_CORE_SEL_NPLL) > + p_rate = priv->npll_hz; > + else if (src == CLK_RKVDEC_CORE_SEL_VPLL) > + p_rate = priv->vpll_hz; > + else > + p_rate = priv->gpll_hz; > + return DIV_TO_RATE(p_rate, div); > + default: > + return -ENOENT; > + } > +} > + > +static ulong rk3568_rkvdec_set_clk(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + int src_clk_div, src, p_rate; > + > + switch (clk_id) { > + case ACLK_RKVDEC_PRE: > + case ACLK_RKVDEC: > + src = (readl(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK) > + >> ACLK_RKVDEC_SEL_SHIFT; > + if (src == ACLK_RKVDEC_SEL_CPLL) > + p_rate = priv->cpll_hz; > + else > + p_rate = priv->gpll_hz; > + src_clk_div = DIV_ROUND_UP(p_rate, rate); > + assert(src_clk_div - 1 <= 31); > + rk_clrsetreg(&cru->clksel_con[47], > + ACLK_RKVDEC_SEL_MASK | > + ACLK_RKVDEC_DIV_MASK, > + (src << ACLK_RKVDEC_SEL_SHIFT) | > + (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT); > + break; > + case CLK_RKVDEC_CORE: > + src = (readl(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK) > + >> CLK_RKVDEC_CORE_SEL_SHIFT; > + if (src == CLK_RKVDEC_CORE_SEL_CPLL) > + p_rate = priv->cpll_hz; > + else if (src == CLK_RKVDEC_CORE_SEL_NPLL) > + p_rate = priv->npll_hz; > + else if (src == CLK_RKVDEC_CORE_SEL_VPLL) > + p_rate = priv->vpll_hz; > + else > + p_rate = priv->gpll_hz; > + src_clk_div = DIV_ROUND_UP(p_rate, rate); > + assert(src_clk_div - 1 <= 31); > + rk_clrsetreg(&cru->clksel_con[49], > + CLK_RKVDEC_CORE_SEL_MASK | > + CLK_RKVDEC_CORE_DIV_MASK, > + (src << CLK_RKVDEC_CORE_SEL_SHIFT) | > + (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT); > + break; > + default: > + return -ENOENT; > + } > + > + return rk3568_rkvdec_get_clk(priv, clk_id); > +} > + > +static ulong rk3568_uart_get_rate(struct rk3568_clk_priv *priv, ulong clk_id) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 reg, con, fracdiv, div, src, p_src, p_rate; > + unsigned long m, n; > + > + switch (clk_id) { > + case SCLK_UART1: > + reg = 52; > + break; > + case SCLK_UART2: > + reg = 54; > + break; > + case SCLK_UART3: > + reg = 56; > + break; > + case SCLK_UART4: > + reg = 58; > + break; > + case SCLK_UART5: > + reg = 60; > + break; > + case SCLK_UART6: > + reg = 62; > + break; > + case SCLK_UART7: > + reg = 64; > + break; > + case SCLK_UART8: > + reg = 66; > + break; > + case SCLK_UART9: > + reg = 68; > + break; > + default: > + return -ENOENT; > + } > + con = readl(&cru->clksel_con[reg]); > + src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; > + div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT; > + p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; > + if (p_src == CLK_UART_SRC_SEL_GPLL) > + p_rate = priv->gpll_hz; > + else if (p_src == CLK_UART_SRC_SEL_CPLL) > + p_rate = priv->cpll_hz; > + else > + p_rate = 480000000; > + if (src == CLK_UART_SEL_SRC) { > + return DIV_TO_RATE(p_rate, div); > + } else if (src == CLK_UART_SEL_FRAC) { > + fracdiv = readl(&cru->clksel_con[reg + 1]); > + n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; > + n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; > + m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; > + m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; > + return DIV_TO_RATE(p_rate, div) * n / m; > + } else { > + return OSC_HZ; > + } > +} > + > +static ulong rk3568_uart_set_rate(struct rk3568_clk_priv *priv, > + ulong clk_id, ulong rate) > +{ > + struct rk3568_cru *cru = priv->cru; > + u32 reg, clk_src, uart_src, div; > + unsigned long m = 0, n = 0, val; > + > + if (priv->gpll_hz % rate == 0) { > + clk_src = CLK_UART_SRC_SEL_GPLL; > + uart_src = CLK_UART_SEL_SRC; > + div = DIV_ROUND_UP(priv->gpll_hz, rate); > + } else if (priv->cpll_hz % rate == 0) { > + clk_src = CLK_UART_SRC_SEL_CPLL; > + uart_src = CLK_UART_SEL_SRC; > + div = DIV_ROUND_UP(priv->gpll_hz, rate); > + } else if (rate == OSC_HZ) { > + clk_src = CLK_UART_SRC_SEL_GPLL; > + uart_src = CLK_UART_SEL_XIN24M; > + div = 2; > + } else { > + clk_src = CLK_UART_SRC_SEL_GPLL; > + uart_src = CLK_UART_SEL_FRAC; > + div = 2; > + rational_best_approximation(rate, priv->gpll_hz / div, > + GENMASK(16 - 1, 0), > + GENMASK(16 - 1, 0), > + &m, &n); > + } > + > + switch (clk_id) { > + case SCLK_UART1: > + reg = 52; > + break; > + case SCLK_UART2: > + reg = 54; > + break; > + case SCLK_UART3: > + reg = 56; > + break; > + case SCLK_UART4: > + reg = 58; > + break; > + case SCLK_UART5: > + reg = 60; > + break; > + case SCLK_UART6: > + reg = 62; > + break; > + case SCLK_UART7: > + reg = 64; > + break; > + case SCLK_UART8: > + reg = 66; > + break; > + case SCLK_UART9: > + reg = 68; > + break; > + default: > + return -ENOENT; > + } > + rk_clrsetreg(&cru->clksel_con[reg], > + CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK | > + CLK_UART_SRC_DIV_MASK, > + (clk_src << CLK_UART_SRC_SEL_SHIFT) | > + (uart_src << CLK_UART_SEL_SHIFT) | > + ((div - 1) << CLK_UART_SRC_DIV_SHIFT)); > + if (m && n) { > + val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; > + writel(val, &cru->clksel_con[reg + 1]); > + } > + > + return rk3568_uart_get_rate(priv, clk_id); > +} > +#endif > + > +static ulong rk3568_clk_get_rate(struct clk *clk) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + ulong rate = 0; > + > + if (!priv->gpll_hz) { > + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); > + return -ENOENT; > + } > + > + switch (clk->id) { > + case PLL_APLL: > + case ARMCLK: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[APLL], priv->cru, > + APLL); > + break; > + case PLL_CPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], priv->cru, > + CPLL); > + break; > + case PLL_GPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], priv->cru, > + GPLL); > + break; > + case PLL_NPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[NPLL], priv->cru, > + NPLL); > + break; > + case PLL_VPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], priv->cru, > + VPLL); > + break; > + case PLL_DPLL: > + rate = rockchip_pll_get_rate(&rk3568_pll_clks[DPLL], priv->cru, > + DPLL); > + break; > + case ACLK_BUS: > + case PCLK_BUS: > + case PCLK_WDT_NS: > + rate = rk3568_bus_get_clk(priv, clk->id); > + break; > + case ACLK_PERIMID: > + case HCLK_PERIMID: > + rate = rk3568_perimid_get_clk(priv, clk->id); > + break; > + case ACLK_TOP_HIGH: > + case ACLK_TOP_LOW: > + case HCLK_TOP: > + case PCLK_TOP: > + rate = rk3568_top_get_clk(priv, clk->id); > + break; > + case CLK_I2C1: > + case CLK_I2C2: > + case CLK_I2C3: > + case CLK_I2C4: > + case CLK_I2C5: > + rate = rk3568_i2c_get_clk(priv, clk->id); > + break; > + case CLK_SPI0: > + case CLK_SPI1: > + case CLK_SPI2: > + case CLK_SPI3: > + rate = rk3568_spi_get_clk(priv, clk->id); > + break; > + case CLK_PWM1: > + case CLK_PWM2: > + case CLK_PWM3: > + rate = rk3568_pwm_get_clk(priv, clk->id); > + break; > + case CLK_SARADC: > + case CLK_TSADC_TSEN: > + case CLK_TSADC: > + rate = rk3568_adc_get_clk(priv, clk->id); > + break; > + case HCLK_SDMMC0: > + case CLK_SDMMC0: > + case CLK_SDMMC1: > + case CLK_SDMMC2: > + rate = rk3568_sdmmc_get_clk(priv, clk->id); > + break; > + case SCLK_SFC: > + rate = rk3568_sfc_get_clk(priv); > + break; > + case NCLK_NANDC: > + rate = rk3568_nand_get_clk(priv); > + break; > + case CCLK_EMMC: > + rate = rk3568_emmc_get_clk(priv); > + break; > +#ifndef CONFIG_SPL_BUILD > + case ACLK_VOP: > + rate = rk3568_aclk_vop_get_clk(priv); > + break; > + case DCLK_VOP0: > + case DCLK_VOP1: > + case DCLK_VOP2: > + rate = rk3568_dclk_vop_get_clk(priv, clk->id); > + break; > + case SCLK_GMAC0: > + case CLK_MAC0_2TOP: > + case CLK_MAC0_REFOUT: > + rate = rk3568_gmac_src_get_clk(priv, 0); > + break; > + case CLK_MAC0_OUT: > + rate = rk3568_gmac_out_get_clk(priv, 0); > + break; > + case CLK_GMAC0_PTP_REF: > + rate = rk3568_gmac_ptp_ref_get_clk(priv, 0); > + break; > + case SCLK_GMAC1: > + case CLK_MAC1_2TOP: > + case CLK_MAC1_REFOUT: > + rate = rk3568_gmac_src_get_clk(priv, 1); > + break; > + case CLK_MAC1_OUT: > + rate = rk3568_gmac_out_get_clk(priv, 1); > + break; > + case CLK_GMAC1_PTP_REF: > + rate = rk3568_gmac_ptp_ref_get_clk(priv, 1); > + break; > + case DCLK_EBC: > + rate = rk3568_ebc_get_clk(priv); > + break; > + case ACLK_RKVDEC_PRE: > + case ACLK_RKVDEC: > + case CLK_RKVDEC_CORE: > + rate = rk3568_rkvdec_get_clk(priv, clk->id); > + break; > + case TCLK_WDT_NS: > + rate = OSC_HZ; > + break; > + case SCLK_UART1: > + case SCLK_UART2: > + case SCLK_UART3: > + case SCLK_UART4: > + case SCLK_UART5: > + case SCLK_UART6: > + case SCLK_UART7: > + case SCLK_UART8: > + case SCLK_UART9: > + rate = rk3568_uart_get_rate(priv, clk->id); > + break; > +#endif > + case ACLK_SECURE_FLASH: > + case ACLK_CRYPTO_NS: > + case HCLK_SECURE_FLASH: > + case HCLK_CRYPTO_NS: > + case CLK_CRYPTO_NS_RNG: > + case CLK_CRYPTO_NS_CORE: > + case CLK_CRYPTO_NS_PKA: > + rate = rk3568_crypto_get_rate(priv, clk->id); > + break; > + case CPLL_500M: > + case CPLL_333M: > + case CPLL_250M: > + case CPLL_125M: > + case CPLL_100M: > + case CPLL_62P5M: > + case CPLL_50M: > + case CPLL_25M: > + rate = rk3568_cpll_div_get_rate(priv, clk->id); > + break; > + default: > + return -ENOENT; > + } > + > + return rate; > +}; > + > +static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + ulong ret = 0; > + > + if (!priv->gpll_hz) { > + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); > + return -ENOENT; > + } > + > + switch (clk->id) { > + case PLL_APLL: > + case ARMCLK: > + if (priv->armclk_hz) > + rk3568_armclk_set_clk(priv, rate); > + priv->armclk_hz = rate; > + break; > + case PLL_CPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, > + CPLL, rate); > + priv->cpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[CPLL], > + priv->cru, CPLL); > + break; > + case PLL_GPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, > + GPLL, rate); > + priv->gpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[GPLL], > + priv->cru, GPLL); > + break; > + case PLL_NPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[NPLL], priv->cru, > + NPLL, rate); > + break; > + case PLL_VPLL: > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[VPLL], priv->cru, > + VPLL, rate); > + priv->vpll_hz = rockchip_pll_get_rate(&rk3568_pll_clks[VPLL], > + priv->cru, > + VPLL); > + break; > + case ACLK_BUS: > + case PCLK_BUS: > + case PCLK_WDT_NS: > + ret = rk3568_bus_set_clk(priv, clk->id, rate); > + break; > + case ACLK_PERIMID: > + case HCLK_PERIMID: > + ret = rk3568_perimid_set_clk(priv, clk->id, rate); > + break; > + case ACLK_TOP_HIGH: > + case ACLK_TOP_LOW: > + case HCLK_TOP: > + case PCLK_TOP: > + ret = rk3568_top_set_clk(priv, clk->id, rate); > + break; > + case CLK_I2C1: > + case CLK_I2C2: > + case CLK_I2C3: > + case CLK_I2C4: > + case CLK_I2C5: > + ret = rk3568_i2c_set_clk(priv, clk->id, rate); > + break; > + case CLK_SPI0: > + case CLK_SPI1: > + case CLK_SPI2: > + case CLK_SPI3: > + ret = rk3568_spi_set_clk(priv, clk->id, rate); > + break; > + case CLK_PWM1: > + case CLK_PWM2: > + case CLK_PWM3: > + ret = rk3568_pwm_set_clk(priv, clk->id, rate); > + break; > + case CLK_SARADC: > + case CLK_TSADC_TSEN: > + case CLK_TSADC: > + ret = rk3568_adc_set_clk(priv, clk->id, rate); > + break; > + case HCLK_SDMMC0: > + case CLK_SDMMC0: > + case CLK_SDMMC1: > + case CLK_SDMMC2: > + ret = rk3568_sdmmc_set_clk(priv, clk->id, rate); > + break; > + case SCLK_SFC: > + ret = rk3568_sfc_set_clk(priv, rate); > + break; > + case NCLK_NANDC: > + ret = rk3568_nand_set_clk(priv, rate); > + break; > + case CCLK_EMMC: > + ret = rk3568_emmc_set_clk(priv, rate); > + break; > +#ifndef CONFIG_SPL_BUILD > + case ACLK_VOP: > + ret = rk3568_aclk_vop_set_clk(priv, rate); > + break; > + case DCLK_VOP0: > + case DCLK_VOP1: > + case DCLK_VOP2: > + ret = rk3568_dclk_vop_set_clk(priv, clk->id, rate); > + break; > + case SCLK_GMAC0: > + case CLK_MAC0_2TOP: > + case CLK_MAC0_REFOUT: > + ret = rk3568_gmac_src_set_clk(priv, 0, rate); > + break; > + case CLK_MAC0_OUT: > + ret = rk3568_gmac_out_set_clk(priv, 0, rate); > + break; > + case SCLK_GMAC0_RX_TX: > + ret = rk3568_gmac_tx_rx_set_clk(priv, 0, rate); > + break; > + case CLK_GMAC0_PTP_REF: > + ret = rk3568_gmac_ptp_ref_set_clk(priv, 0, rate); > + break; > + case SCLK_GMAC1: > + case CLK_MAC1_2TOP: > + case CLK_MAC1_REFOUT: > + ret = rk3568_gmac_src_set_clk(priv, 1, rate); > + break; > + case CLK_MAC1_OUT: > + ret = rk3568_gmac_out_set_clk(priv, 1, rate); > + break; > + case SCLK_GMAC1_RX_TX: > + ret = rk3568_gmac_tx_rx_set_clk(priv, 1, rate); > + break; > + case CLK_GMAC1_PTP_REF: > + ret = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate); > + break; > + case DCLK_EBC: > + ret = rk3568_ebc_set_clk(priv, rate); > + break; > + case ACLK_RKVDEC_PRE: > + case ACLK_RKVDEC: > + case CLK_RKVDEC_CORE: > + ret = rk3568_rkvdec_set_clk(priv, clk->id, rate); I don't thing we need to set rkvdec clock in the U-Boot, pls remove it. Thanks, - Kever > + break; > + case TCLK_WDT_NS: > + ret = OSC_HZ; > + break; > + case SCLK_UART1: > + case SCLK_UART2: > + case SCLK_UART3: > + case SCLK_UART4: > + case SCLK_UART5: > + case SCLK_UART6: > + case SCLK_UART7: > + case SCLK_UART8: > + case SCLK_UART9: > + ret = rk3568_uart_set_rate(priv, clk->id, rate); > + break; > +#endif > + case ACLK_SECURE_FLASH: > + case ACLK_CRYPTO_NS: > + case HCLK_SECURE_FLASH: > + case HCLK_CRYPTO_NS: > + case CLK_CRYPTO_NS_RNG: > + case CLK_CRYPTO_NS_CORE: > + case CLK_CRYPTO_NS_PKA: > + ret = rk3568_crypto_set_rate(priv, clk->id, rate); > + break; > + case CPLL_500M: > + case CPLL_333M: > + case CPLL_250M: > + case CPLL_125M: > + case CPLL_100M: > + case CPLL_62P5M: > + case CPLL_50M: > + case CPLL_25M: > + ret = rk3568_cpll_div_set_rate(priv, clk->id, rate); > + break; > + default: > + return -ENOENT; > + } > + > + return ret; > +}; > + > +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) > +static int rk3568_gmac0_src_set_parent(struct clk *clk, struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + > + if (parent->id == CLK_MAC0_2TOP) > + rk_clrsetreg(&cru->clksel_con[31], > + RMII0_EXTCLK_SEL_MASK, > + RMII0_EXTCLK_SEL_MAC0_TOP << > + RMII0_EXTCLK_SEL_SHIFT); > + else > + rk_clrsetreg(&cru->clksel_con[31], > + RMII0_EXTCLK_SEL_MASK, > + RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); > + return 0; > +} > + > +static int rk3568_gmac1_src_set_parent(struct clk *clk, struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + > + if (parent->id == CLK_MAC1_2TOP) > + rk_clrsetreg(&cru->clksel_con[33], > + RMII0_EXTCLK_SEL_MASK, > + RMII0_EXTCLK_SEL_MAC0_TOP << > + RMII0_EXTCLK_SEL_SHIFT); > + else > + rk_clrsetreg(&cru->clksel_con[33], > + RMII0_EXTCLK_SEL_MASK, > + RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT); > + return 0; > +} > + > +static int rk3568_gmac0_tx_rx_set_parent(struct clk *clk, struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + > + if (parent->id == SCLK_GMAC0_RGMII_SPEED) > + rk_clrsetreg(&cru->clksel_con[31], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); > + else if (parent->id == SCLK_GMAC0_RMII_SPEED) > + rk_clrsetreg(&cru->clksel_con[31], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); > + else > + rk_clrsetreg(&cru->clksel_con[31], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); > + > + return 0; > +} > + > +static int rk3568_gmac1_tx_rx_set_parent(struct clk *clk, struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + > + if (parent->id == SCLK_GMAC1_RGMII_SPEED) > + rk_clrsetreg(&cru->clksel_con[33], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT); > + else if (parent->id == SCLK_GMAC1_RMII_SPEED) > + rk_clrsetreg(&cru->clksel_con[33], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT); > + else > + rk_clrsetreg(&cru->clksel_con[33], > + RMII0_MODE_MASK, > + RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT); > + > + return 0; > +} > + > +static int __maybe_unused rk3568_dclk_vop_set_parent(struct clk *clk, > + struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + u32 con_id; > + > + switch (clk->id) { > + case DCLK_VOP0: > + con_id = 39; > + break; > + case DCLK_VOP1: > + con_id = 40; > + break; > + case DCLK_VOP2: > + con_id = 41; > + break; > + default: > + return -EINVAL; > + } > + if (parent->id == PLL_VPLL) { > + rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, > + DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT); > + } else { > + rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK, > + DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT); > + } > + > + return 0; > +} > + > +static int __maybe_unused rk3568_rkvdec_set_parent(struct clk *clk, > + struct clk *parent) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); > + struct rk3568_cru *cru = priv->cru; > + u32 con_id, mask, shift; > + > + switch (clk->id) { > + case ACLK_RKVDEC_PRE: > + con_id = 47; > + mask = ACLK_RKVDEC_SEL_MASK; > + shift = ACLK_RKVDEC_SEL_SHIFT; > + break; > + case CLK_RKVDEC_CORE: > + con_id = 49; > + mask = CLK_RKVDEC_CORE_SEL_MASK; > + shift = CLK_RKVDEC_CORE_SEL_SHIFT; > + break; > + default: > + return -EINVAL; > + } > + if (parent->id == PLL_CPLL) { > + rk_clrsetreg(&cru->clksel_con[con_id], mask, > + ACLK_RKVDEC_SEL_CPLL << shift); > + } else { > + rk_clrsetreg(&cru->clksel_con[con_id], mask, > + ACLK_RKVDEC_SEL_GPLL << shift); > + } > + > + return 0; > +} > + > +static int rk3568_clk_set_parent(struct clk *clk, struct clk *parent) > +{ > + switch (clk->id) { > + case SCLK_GMAC0: > + return rk3568_gmac0_src_set_parent(clk, parent); > + case SCLK_GMAC1: > + return rk3568_gmac1_src_set_parent(clk, parent); > + case SCLK_GMAC0_RX_TX: > + return rk3568_gmac0_tx_rx_set_parent(clk, parent); > + case SCLK_GMAC1_RX_TX: > + return rk3568_gmac1_tx_rx_set_parent(clk, parent); > + case DCLK_VOP0: > + case DCLK_VOP1: > + case DCLK_VOP2: > + return rk3568_dclk_vop_set_parent(clk, parent); > + case ACLK_RKVDEC_PRE: > + case CLK_RKVDEC_CORE: > + return rk3568_rkvdec_set_parent(clk, parent); > + default: > + return -ENOENT; > + } > + > + return 0; > +} > +#endif > + > +static struct clk_ops rk3568_clk_ops = { > + .get_rate = rk3568_clk_get_rate, > + .set_rate = rk3568_clk_set_rate, > +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) > + .set_parent = rk3568_clk_set_parent, > +#endif > +}; > + > +static void rk3568_clk_init(struct rk3568_clk_priv *priv) > +{ > + int ret; > + > + priv->sync_kernel = false; > + if (!priv->armclk_enter_hz) { > + priv->armclk_enter_hz = > + rockchip_pll_get_rate(&rk3568_pll_clks[APLL], > + priv->cru, APLL); > + priv->armclk_init_hz = priv->armclk_enter_hz; > + } > + > + if (priv->armclk_init_hz != APLL_HZ) { > + ret = rk3568_armclk_set_clk(priv, APLL_HZ); > + if (!ret) > + priv->armclk_init_hz = APLL_HZ; > + } > + if (priv->cpll_hz != CPLL_HZ) { > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[CPLL], priv->cru, > + CPLL, CPLL_HZ); > + if (!ret) > + priv->cpll_hz = CPLL_HZ; > + } > + if (priv->gpll_hz != GPLL_HZ) { > + ret = rockchip_pll_set_rate(&rk3568_pll_clks[GPLL], priv->cru, > + GPLL, GPLL_HZ); > + if (!ret) > + priv->gpll_hz = GPLL_HZ; > + } > + > +#ifdef CONFIG_SPL_BUILD > + ret = rk3568_bus_set_clk(priv, ACLK_BUS, 150000000); > + if (ret < 0) > + printf("Fail to set the ACLK_BUS clock.\n"); > +#endif > + > + priv->ppll_hz = rk3568_pmu_pll_get_rate(priv, PPLL); > + priv->hpll_hz = rk3568_pmu_pll_get_rate(priv, HPLL); > +} > + > +static int rk3568_clk_probe(struct udevice *dev) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(dev); > + int ret; > + > + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); > + if (IS_ERR(priv->grf)) > + return PTR_ERR(priv->grf); > + > + rk3568_clk_init(priv); > + > + /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ > + ret = clk_set_defaults(dev, 1); > + if (ret) > + debug("%s clk_set_defaults failed %d\n", __func__, ret); > + else > + priv->sync_kernel = true; > + > + return 0; > +} > + > +static int rk3568_clk_ofdata_to_platdata(struct udevice *dev) > +{ > + struct rk3568_clk_priv *priv = dev_get_priv(dev); > + > + priv->cru = dev_read_addr_ptr(dev); > + > + return 0; > +} > + > +static int rk3568_clk_bind(struct udevice *dev) > +{ > + int ret; > + struct udevice *sys_child; > + struct sysreset_reg *priv; > + > + /* The reset driver does not have a device node, so bind it here */ > + ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", > + &sys_child); > + if (ret) { > + debug("Warning: No sysreset driver: ret=%d\n", ret); > + } else { > + priv = malloc(sizeof(struct sysreset_reg)); > + priv->glb_srst_fst_value = offsetof(struct rk3568_cru, > + glb_srst_fst); > + priv->glb_srst_snd_value = offsetof(struct rk3568_cru, > + glb_srsr_snd); > + } > + > +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) > + ret = offsetof(struct rk3568_cru, softrst_con[0]); > + ret = rockchip_reset_bind(dev, ret, 30); > + if (ret) > + debug("Warning: software reset driver bind faile\n"); > +#endif > + > + return 0; > +} > + > +static const struct udevice_id rk3568_clk_ids[] = { > + { .compatible = "rockchip,rk3568-cru" }, > + { } > +}; > + > +U_BOOT_DRIVER(rockchip_rk3568_cru) = { > + .name = "rockchip_rk3568_cru", > + .id = UCLASS_CLK, > + .of_match = rk3568_clk_ids, > + .priv_auto = sizeof(struct rk3568_clk_priv), > + .of_to_plat = rk3568_clk_ofdata_to_platdata, > + .ops = &rk3568_clk_ops, > + .bind = rk3568_clk_bind, > + .probe = rk3568_clk_probe, > +#if CONFIG_IS_ENABLED(OF_PLATDATA) > + .plat_auto = sizeof(struct rk3568_clk_plat), > +#endif > +}; ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2021-05-21 13:34 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-19 8:49 [PATCH v1 0/2] clk: rockchip: rk3568: add clock driver Elaine at denx.de 2021-05-19 8:49 ` [PATCH v1 1/2] rockchip: rk3568: add device tree file Elaine at denx.de 2021-05-21 13:22 ` Kever Yang 2021-05-19 8:49 ` [PATCH v1 2/2] rockchip: rk3568: add clock driver Elaine at denx.de 2021-05-21 13:33 ` Kever Yang
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.