[PATCH v2 0/2] clk: rockchip: rk3568: add clock driver

From: Elaine Zhang zhangqing@rock-chips.com
Add basic clock for rk3568 which including cpu, bus, mmc, i2c, pwm, gmac ...clocks init.
Change in V2: [PATCH v2 0/1]: No change. [PATCH v2 0/2]: update the copyright info and remove unused clock set/get.
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 | 2959 +++++++++++++++++ include/dt-bindings/clock/rk3568-cru.h | 925 ++++++ 4 files changed, 4389 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

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

On 2021/5/26 下午4:46, 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

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 | 2959 +++++++++++++++++ 3 files changed, 3464 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..553c6c0dafbd --- /dev/null +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -0,0 +1,2959 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 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), +}; + +#ifndef CONFIG_SPL_BUILD +static ulong +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; +} +#endif + +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); +} + +static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv) +{ + struct rk3568_cru *cru = priv->cru; + u32 sel, con; + + con = readl(&cru->clksel_con[28]); + sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT; + switch (sel) { + case BCLK_EMMC_SEL_200M: + return 200 * MHz; + case BCLK_EMMC_SEL_150M: + return 150 * MHz; + case BCLK_EMMC_SEL_125M: + return 125 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk; + + switch (rate) { + case 200 * MHz: + src_clk = BCLK_EMMC_SEL_200M; + break; + case 150 * MHz: + src_clk = BCLK_EMMC_SEL_150M; + break; + case 125 * MHz: + src_clk = BCLK_EMMC_SEL_125M; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[28], + BCLK_EMMC_SEL_MASK, + src_clk << BCLK_EMMC_SEL_SHIFT); + + return rk3568_emmc_get_bclk(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; + case BCLK_EMMC: + rate = rk3568_emmc_get_bclk(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; + case BCLK_EMMC: + ret = rk3568_emmc_set_bclk(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 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 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 +};

On 2021/5/26 下午4:46, 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
Reviewed-by: Kever Yang kever.yang@rock-chips.com
Thanks, - Kever
.../include/asm/arch-rockchip/cru_rk3568.h | 504 +++ drivers/clk/rockchip/Makefile | 1 + drivers/clk/rockchip/clk_rk3568.c | 2959 +++++++++++++++++ 3 files changed, 3464 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..553c6c0dafbd --- /dev/null +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -0,0 +1,2959 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright (c) 2021 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),
+};
+#ifndef CONFIG_SPL_BUILD +static ulong +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;
+} +#endif
+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:
- */
+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);
+}
+static ulong rk3568_emmc_get_bclk(struct rk3568_clk_priv *priv) +{
- struct rk3568_cru *cru = priv->cru;
- u32 sel, con;
- con = readl(&cru->clksel_con[28]);
- sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
- switch (sel) {
- case BCLK_EMMC_SEL_200M:
return 200 * MHz;
- case BCLK_EMMC_SEL_150M:
return 150 * MHz;
- case BCLK_EMMC_SEL_125M:
return 125 * MHz;
- default:
return -ENOENT;
- }
+}
+static ulong rk3568_emmc_set_bclk(struct rk3568_clk_priv *priv, ulong rate) +{
- struct rk3568_cru *cru = priv->cru;
- int src_clk;
- switch (rate) {
- case 200 * MHz:
src_clk = BCLK_EMMC_SEL_200M;
break;
- case 150 * MHz:
src_clk = BCLK_EMMC_SEL_150M;
break;
- case 125 * MHz:
src_clk = BCLK_EMMC_SEL_125M;
break;
- default:
return -ENOENT;
- }
- rk_clrsetreg(&cru->clksel_con[28],
BCLK_EMMC_SEL_MASK,
src_clk << BCLK_EMMC_SEL_SHIFT);
- return rk3568_emmc_get_bclk(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;
- case BCLK_EMMC:
rate = rk3568_emmc_get_bclk(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;
- case BCLK_EMMC:
ret = rk3568_emmc_set_bclk(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 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 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 +};

From: Elaine Zhang zhangqing@rock-chips.com
Support more PMIC and improve compatibility between pmics.
Change in V5: [PATCH v5 1/6]: Fixed test case run error. [PATCH v5 2/6]: Resolve compile warning. [PATCH v5 3/6]: No change. [PATCH v5 4/6]: No change. [PATCH v5 5/6]: No change. [PATCH v5 6/6]: No change.
Change in V4: [PATCH v4 1/6]: No change. [PATCH v4 2/6]: No change. [PATCH v4 3/6]: No change. [PATCH v4 4/6]: No change. [PATCH v4 5/6]: Resolve code conflicts after ptach v3 5/8 and 6/8 deletion.. [PATCH v4 6/6]: Resolve code conflicts after ptach v3 5/8 and 6/8 deletion. Remove [PATCH v3 5/8] and [PATCH v3 6/8], There is no application scenario.
Change in V3: [PATCH v3 1/8]: Add document instructions, Correct error handling. [PATCH v3 2/8]: No change. [PATCH v3 3/8]: No change. [PATCH v3 4/8]: No change. [PATCH v3 5/8]: Update commit message. [PATCH v3 6/8]: Update commit message. [PATCH v3 7/8]: No change. [PATCH v3 8/8]: No change.
Change in V2: [PATCH v2 1/8]: Add regulator suspend volatge and en/disable test. [PATCH v2 2/8]: Split the [PATCH v1 2/7], rk808 and rk818 updates. [PATCH v2 3/8]: Split the [PATCH v1 2/7], support rk816 pmic and update commit message. [PATCH v2 4/8]: Update commit message. [PATCH v2 5/8]: No change. [PATCH v2 6/8]: No change. [PATCH v2 7/8]: Remove rk809 keywords and update commit message. [PATCH v2 8/8]: Update commit message.
Elaine Zhang (3): power: regulator: rk8xx: update the driver for rk808 and rk818 power: pmic: rk816: support rk816 pmic power: pmic: rk805: support rk805 pmic
Joseph Chen (3): dm: regulator: support regulator more state power: pmic: rk817: support rk817 pmic power: pmic: rk809: support rk809 pmic
doc/device-tree-bindings/regulator/regulator.txt | 27 + drivers/power/pmic/rk8xx.c | 89 ++- drivers/power/regulator/regulator-uclass.c | 70 ++ drivers/power/regulator/rk8xx.c | 939 +++++++++++++++++++++-- include/power/regulator.h | 64 ++ include/power/rk8xx_pmic.h | 42 + test/dm/regulator.c | 57 ++ 7 files changed, 1200 insertions(+), 88 deletions(-)

Hi,
On 5/26/21 5:46 PM, Elaine@denx.de wrote:
From: Elaine Zhang zhangqing@rock-chips.com
Support more PMIC and improve compatibility between pmics.
I didn't see your full patchset, except [PATCH V5 1/6]. If i missed something, let me know, plz.
Best Regards, Jaehoon Chung
Change in V5: [PATCH v5 1/6]: Fixed test case run error. [PATCH v5 2/6]: Resolve compile warning. [PATCH v5 3/6]: No change. [PATCH v5 4/6]: No change. [PATCH v5 5/6]: No change. [PATCH v5 6/6]: No change.
Change in V4: [PATCH v4 1/6]: No change. [PATCH v4 2/6]: No change. [PATCH v4 3/6]: No change. [PATCH v4 4/6]: No change. [PATCH v4 5/6]: Resolve code conflicts after ptach v3 5/8 and 6/8 deletion.. [PATCH v4 6/6]: Resolve code conflicts after ptach v3 5/8 and 6/8 deletion. Remove [PATCH v3 5/8] and [PATCH v3 6/8], There is no application scenario.
Change in V3: [PATCH v3 1/8]: Add document instructions, Correct error handling. [PATCH v3 2/8]: No change. [PATCH v3 3/8]: No change. [PATCH v3 4/8]: No change. [PATCH v3 5/8]: Update commit message. [PATCH v3 6/8]: Update commit message. [PATCH v3 7/8]: No change. [PATCH v3 8/8]: No change.
Change in V2: [PATCH v2 1/8]: Add regulator suspend volatge and en/disable test. [PATCH v2 2/8]: Split the [PATCH v1 2/7], rk808 and rk818 updates. [PATCH v2 3/8]: Split the [PATCH v1 2/7], support rk816 pmic and update commit message. [PATCH v2 4/8]: Update commit message. [PATCH v2 5/8]: No change. [PATCH v2 6/8]: No change. [PATCH v2 7/8]: Remove rk809 keywords and update commit message. [PATCH v2 8/8]: Update commit message.
Elaine Zhang (3): power: regulator: rk8xx: update the driver for rk808 and rk818 power: pmic: rk816: support rk816 pmic power: pmic: rk805: support rk805 pmic
Joseph Chen (3): dm: regulator: support regulator more state power: pmic: rk817: support rk817 pmic power: pmic: rk809: support rk809 pmic
doc/device-tree-bindings/regulator/regulator.txt | 27 + drivers/power/pmic/rk8xx.c | 89 ++- drivers/power/regulator/regulator-uclass.c | 70 ++ drivers/power/regulator/rk8xx.c | 939 +++++++++++++++++++++-- include/power/regulator.h | 64 ++ include/power/rk8xx_pmic.h | 42 + test/dm/regulator.c | 57 ++ 7 files changed, 1200 insertions(+), 88 deletions(-)

From: Joseph Chen chenjh@rock-chips.com
support parse regulator standard property: regulator-off-in-suspend; regulator-init-microvolt; regulator-suspend-microvolt: regulator_get_suspend_enable regulator_set_suspend_enable regulator_get_suspend_value regulator_set_suspend_value
Signed-off-by: Joseph Chen chenjh@rock-chips.com Signed-off-by: Elaine Zhang zhangqing@rock-chips.com Reviewed-by: Kever Yangkever.yang@rock-chips.com --- doc/device-tree-bindings/regulator/regulator.txt | 27 +++++++++ drivers/power/regulator/regulator-uclass.c | 70 ++++++++++++++++++++++++ include/power/regulator.h | 64 ++++++++++++++++++++++ test/dm/regulator.c | 57 +++++++++++++++++++ 4 files changed, 218 insertions(+)
diff --git a/doc/device-tree-bindings/regulator/regulator.txt b/doc/device-tree-bindings/regulator/regulator.txt index 4ba642b7c77f..6c9a02120fde 100644 --- a/doc/device-tree-bindings/regulator/regulator.txt +++ b/doc/device-tree-bindings/regulator/regulator.txt @@ -36,6 +36,28 @@ Optional properties: - regulator-always-on: regulator should never be disabled - regulator-boot-on: enabled by bootloader/firmware - regulator-ramp-delay: ramp delay for regulator (in uV/us) +- regulator-init-microvolt: a init allowed Voltage value +- regulator-state-(standby|mem|disk) + type: object + description: + sub-nodes for regulator state in Standby, Suspend-to-RAM, and + Suspend-to-DISK modes. Equivalent with standby, mem, and disk Linux + sleep states. + + properties: + regulator-on-in-suspend: + description: regulator should be on in suspend state. + type: boolean + + regulator-off-in-suspend: + description: regulator should be off in suspend state. + type: boolean + + regulator-suspend-microvolt: + description: the default voltage which regulator would be set in + suspend. This property is now deprecated, instead setting voltage + for suspend mode via the API which regulator driver provides is + recommended.
Note The "regulator-name" constraint is used for setting the device's uclass @@ -59,7 +81,12 @@ ldo0 { regulator-max-microvolt = <1800000>; regulator-min-microamp = <100000>; regulator-max-microamp = <100000>; + regulator-init-microvolt = <1800000>; regulator-always-on; regulator-boot-on; regulator-ramp-delay = <12000>; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; }; diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 76be95bcd159..4986c87e7ba6 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -77,6 +77,33 @@ int regulator_set_value(struct udevice *dev, int uV) return ret; }
+int regulator_set_suspend_value(struct udevice *dev, int uV) +{ + const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); + struct dm_regulator_uclass_platdata *uc_pdata; + + uc_pdata = dev_get_uclass_platdata(dev); + if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV) + return -EINVAL; + if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV) + return -EINVAL; + + if (!ops->set_suspend_value) + return -ENOSYS; + + return ops->set_suspend_value(dev, uV); +} + +int regulator_get_suspend_value(struct udevice *dev) +{ + const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); + + if (!ops->get_suspend_value) + return -ENOSYS; + + return ops->get_suspend_value(dev); +} + /* * To be called with at most caution as there is no check * before setting the actual voltage value. @@ -170,6 +197,26 @@ int regulator_set_enable_if_allowed(struct udevice *dev, bool enable) return ret; }
+int regulator_set_suspend_enable(struct udevice *dev, bool enable) +{ + const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); + + if (!ops->set_suspend_enable) + return -ENOSYS; + + return ops->set_suspend_enable(dev, enable); +} + +int regulator_get_suspend_enable(struct udevice *dev) +{ + const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); + + if (!ops->get_suspend_enable) + return -ENOSYS; + + return ops->get_suspend_enable(dev); +} + int regulator_get_mode(struct udevice *dev) { const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); @@ -235,6 +282,14 @@ int regulator_autoset(struct udevice *dev) int ret = 0;
uc_pdata = dev_get_uclass_platdata(dev); + + ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on); + if (!ret && uc_pdata->suspend_on) { + ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV); + if (!ret) + return ret; + } + if (!uc_pdata->always_on && !uc_pdata->boot_on) return -EMEDIUMTYPE;
@@ -243,6 +298,8 @@ int regulator_autoset(struct udevice *dev)
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) ret = regulator_set_value(dev, uc_pdata->min_uV); + if (uc_pdata->init_uV > 0) + ret = regulator_set_value(dev, uc_pdata->init_uV); if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)) ret = regulator_set_current(dev, uc_pdata->min_uA);
@@ -363,6 +420,7 @@ static int regulator_post_bind(struct udevice *dev) static int regulator_pre_probe(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata; + ofnode node;
uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata) @@ -373,6 +431,8 @@ static int regulator_pre_probe(struct udevice *dev) -ENODATA); uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt", -ENODATA); + uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt", + -ENODATA); uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp", -ENODATA); uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp", @@ -382,6 +442,16 @@ static int regulator_pre_probe(struct udevice *dev) uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay", 0);
+ node = dev_read_subnode(dev, "regulator-state-mem"); + if (ofnode_valid(node)) { + uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend"); + if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV)) + uc_pdata->suspend_uV = uc_pdata->max_uV; + } else { + uc_pdata->suspend_on = true; + uc_pdata->suspend_uV = uc_pdata->max_uV; + } + /* Those values are optional (-ENODATA if unset) */ if ((uc_pdata->min_uV != -ENODATA) && (uc_pdata->max_uV != -ENODATA) && diff --git a/include/power/regulator.h b/include/power/regulator.h index 6c6e2cd4f996..dd61eb4ccbde 100644 --- a/include/power/regulator.h +++ b/include/power/regulator.h @@ -168,6 +168,7 @@ struct dm_regulator_uclass_platdata { int mode_count; int min_uV; int max_uV; + int init_uV; int min_uA; int max_uA; unsigned int ramp_delay; @@ -177,6 +178,8 @@ struct dm_regulator_uclass_platdata { int flags; u8 ctrl_reg; u8 volt_reg; + bool suspend_on; + u32 suspend_uV; };
/* Regulator device operations */ @@ -194,6 +197,19 @@ struct dm_regulator_ops { int (*set_value)(struct udevice *dev, int uV);
/** + * The regulator suspend output value function calls operates + * on a micro Volts. + * + * get/set_suspen_value - get/set suspend mode output value + * @dev - regulator device + * Sets: + * @uV - set the suspend output value [micro Volts] + * @return output value [uV] on success or negative errno if fail. + */ + int (*set_suspend_value)(struct udevice *dev, int uV); + int (*get_suspend_value)(struct udevice *dev); + + /** * The regulator output current function calls operates on a micro Amps. * * get/set_current - get/set output current of the given output number @@ -218,6 +234,19 @@ struct dm_regulator_ops { int (*set_enable)(struct udevice *dev, bool enable);
/** + * The most basic feature of the regulator output is its enable state + * in suspend mode. + * + * get/set_suspend_enable - get/set enable state of the suspend output + * @dev - regulator device + * Sets: + * @enable - set true - enable or false - disable + * @return true/false for get or -errno if fail; 0 / -errno for set. + */ + int (*set_suspend_enable)(struct udevice *dev, bool enable); + int (*get_suspend_enable)(struct udevice *dev); + + /** * The 'get/set_mode()' function calls should operate on a driver- * specific mode id definitions, which should be found in: * field 'id' of struct dm_regulator_mode. @@ -262,6 +291,23 @@ int regulator_get_value(struct udevice *dev); int regulator_set_value(struct udevice *dev, int uV);
/** + * regulator_set_suspend_value: set the suspend microvoltage value of a given regulator. + * + * @dev - pointer to the regulator device + * @uV - the output suspend value to set [micro Volts] + * @return - 0 on success or -errno val if fails + */ +int regulator_set_suspend_value(struct udevice *dev, int uV); + +/** + * regulator_get_suspend_value: get the suspend microvoltage value of a given regulator. + * + * @dev - pointer to the regulator device + * @return - positive output value [uV] on success or negative errno if fail. + */ +int regulator_get_suspend_value(struct udevice *dev); + +/** * regulator_set_value_force: set the microvoltage value of a given regulator * without any min-,max condition check * @@ -317,6 +363,24 @@ int regulator_set_enable(struct udevice *dev, bool enable); int regulator_set_enable_if_allowed(struct udevice *dev, bool enable);
/** + * regulator_set_suspend_enable: set regulator suspend enable state + * + * @dev - pointer to the regulator device + * @enable - set true or false + * @return - 0 on success or -errno val if fails + */ +int regulator_set_suspend_enable(struct udevice *dev, bool enable); + + +/** + * regulator_get_suspend_enable: get regulator suspend enable state + * + * @dev - pointer to the regulator device + * @return - true/false of enable state or -errno val if fails + */ +int regulator_get_suspend_enable(struct udevice *dev); + +/** * regulator_get_mode: get active operation mode id of a given regulator * * @dev - pointer to the regulator device diff --git a/test/dm/regulator.c b/test/dm/regulator.c index e510539542b6..b967902493dd 100644 --- a/test/dm/regulator.c +++ b/test/dm/regulator.c @@ -215,6 +215,63 @@ static int dm_test_power_regulator_set_get_mode(struct unit_test_state *uts) } DM_TEST(dm_test_power_regulator_set_get_mode, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Voltage method */ +static int dm_test_power_regulator_set_get_suspend_voltage(struct unit_test_state *uts) +{ + struct dm_regulator_uclass_platdata *uc_pdata; + const struct dm_regulator_ops *ops; + struct udevice *dev; + const char *platname; + int val_set, val_get; + + /* Set and get Voltage of BUCK1 - set to 'min' constraint */ + platname = regulator_names[BUCK1][PLATNAME]; + ut_assertok(regulator_get_by_platname(platname, &dev)); + + uc_pdata = dev_get_uclass_platdata(dev); + ut_assert(uc_pdata); + + ops = dev_get_driver_ops(dev); + + if (ops->set_suspend_value && ops->get_suspend_value) { + val_set = uc_pdata->suspend_uV; + ut_assertok(regulator_set_suspend_value(dev, val_set)); + val_get = regulator_get_suspend_value(dev); + ut_assert(val_get >= 0); + + ut_asserteq(val_set, val_get); + } + return 0; +} +DM_TEST(dm_test_power_regulator_set_get_suspend_voltage, DM_TESTF_SCAN_FDT); + +/* Test regulator set and get suspend Enable method */ +static int dm_test_power_regulator_set_get_suspend_enable(struct unit_test_state *uts) +{ + const struct dm_regulator_ops *ops; + const char *platname; + struct udevice *dev; + bool val_set = true; + + /* Set the Enable of LDO1 - default is disabled */ + platname = regulator_names[LDO1][PLATNAME]; + ut_assertok(regulator_get_by_platname(platname, &dev)); + + ops = dev_get_driver_ops(dev); + + if (ops->set_suspend_enable && ops->get_suspend_enable) { + ut_assertok(regulator_set_suspend_enable(dev, val_set)); + + /* + * Get the Enable state of LDO1 and + * compare it with the requested one + */ + ut_asserteq(regulator_get_suspend_enable(dev), val_set); + } + return 0; +} +DM_TEST(dm_test_power_regulator_set_get_suspend_enable, DM_TESTF_SCAN_FDT); + /* Test regulator autoset method */ static int dm_test_power_regulator_autoset(struct unit_test_state *uts) {

Hi,
On 5/26/21 5:46 PM, Elaine@denx.de wrote:
From: Joseph Chen chenjh@rock-chips.com
Is it right patch? This patch had been already applied.
Best Regards, Jaehoon Chung
support parse regulator standard property: regulator-off-in-suspend; regulator-init-microvolt; regulator-suspend-microvolt: regulator_get_suspend_enable regulator_set_suspend_enable regulator_get_suspend_value regulator_set_suspend_value
Signed-off-by: Joseph Chen chenjh@rock-chips.com Signed-off-by: Elaine Zhang zhangqing@rock-chips.com Reviewed-by: Kever Yangkever.yang@rock-chips.com
doc/device-tree-bindings/regulator/regulator.txt | 27 +++++++++ drivers/power/regulator/regulator-uclass.c | 70 ++++++++++++++++++++++++ include/power/regulator.h | 64 ++++++++++++++++++++++ test/dm/regulator.c | 57 +++++++++++++++++++ 4 files changed, 218 insertions(+)
diff --git a/doc/device-tree-bindings/regulator/regulator.txt b/doc/device-tree-bindings/regulator/regulator.txt index 4ba642b7c77f..6c9a02120fde 100644 --- a/doc/device-tree-bindings/regulator/regulator.txt +++ b/doc/device-tree-bindings/regulator/regulator.txt @@ -36,6 +36,28 @@ Optional properties:
- regulator-always-on: regulator should never be disabled
- regulator-boot-on: enabled by bootloader/firmware
- regulator-ramp-delay: ramp delay for regulator (in uV/us)
+- regulator-init-microvolt: a init allowed Voltage value +- regulator-state-(standby|mem|disk)
- type: object
- description:
- sub-nodes for regulator state in Standby, Suspend-to-RAM, and
- Suspend-to-DISK modes. Equivalent with standby, mem, and disk Linux
- sleep states.
- properties:
regulator-on-in-suspend:
description: regulator should be on in suspend state.
type: boolean
regulator-off-in-suspend:
description: regulator should be off in suspend state.
type: boolean
regulator-suspend-microvolt:
description: the default voltage which regulator would be set in
suspend. This property is now deprecated, instead setting voltage
for suspend mode via the API which regulator driver provides is
recommended.
Note The "regulator-name" constraint is used for setting the device's uclass @@ -59,7 +81,12 @@ ldo0 { regulator-max-microvolt = <1800000>; regulator-min-microamp = <100000>; regulator-max-microamp = <100000>;
- regulator-init-microvolt = <1800000>; regulator-always-on; regulator-boot-on; regulator-ramp-delay = <12000>;
- regulator-state-mem {
regulator-on-in-suspend;
regulator-suspend-microvolt = <1800000>;
- };
}; diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 76be95bcd159..4986c87e7ba6 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -77,6 +77,33 @@ int regulator_set_value(struct udevice *dev, int uV) return ret; }
+int regulator_set_suspend_value(struct udevice *dev, int uV) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- struct dm_regulator_uclass_platdata *uc_pdata;
- uc_pdata = dev_get_uclass_platdata(dev);
- if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
return -EINVAL;
- if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
return -EINVAL;
- if (!ops->set_suspend_value)
return -ENOSYS;
- return ops->set_suspend_value(dev, uV);
+}
+int regulator_get_suspend_value(struct udevice *dev) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_value)
return -ENOSYS;
- return ops->get_suspend_value(dev);
+}
/*
- To be called with at most caution as there is no check
- before setting the actual voltage value.
@@ -170,6 +197,26 @@ int regulator_set_enable_if_allowed(struct udevice *dev, bool enable) return ret; }
+int regulator_set_suspend_enable(struct udevice *dev, bool enable) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->set_suspend_enable)
return -ENOSYS;
- return ops->set_suspend_enable(dev, enable);
+}
+int regulator_get_suspend_enable(struct udevice *dev) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_enable)
return -ENOSYS;
- return ops->get_suspend_enable(dev);
+}
int regulator_get_mode(struct udevice *dev) { const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); @@ -235,6 +282,14 @@ int regulator_autoset(struct udevice *dev) int ret = 0;
uc_pdata = dev_get_uclass_platdata(dev);
- ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
- if (!ret && uc_pdata->suspend_on) {
ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
if (!ret)
return ret;
- }
- if (!uc_pdata->always_on && !uc_pdata->boot_on) return -EMEDIUMTYPE;
@@ -243,6 +298,8 @@ int regulator_autoset(struct udevice *dev)
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) ret = regulator_set_value(dev, uc_pdata->min_uV);
- if (uc_pdata->init_uV > 0)
if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)) ret = regulator_set_current(dev, uc_pdata->min_uA);ret = regulator_set_value(dev, uc_pdata->init_uV);
@@ -363,6 +420,7 @@ static int regulator_post_bind(struct udevice *dev) static int regulator_pre_probe(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata;
ofnode node;
uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata)
@@ -373,6 +431,8 @@ static int regulator_pre_probe(struct udevice *dev) -ENODATA); uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt", -ENODATA);
- uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp", -ENODATA); uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp",-ENODATA);
@@ -382,6 +442,16 @@ static int regulator_pre_probe(struct udevice *dev) uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay", 0);
- node = dev_read_subnode(dev, "regulator-state-mem");
- if (ofnode_valid(node)) {
uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
uc_pdata->suspend_uV = uc_pdata->max_uV;
- } else {
uc_pdata->suspend_on = true;
uc_pdata->suspend_uV = uc_pdata->max_uV;
- }
- /* Those values are optional (-ENODATA if unset) */ if ((uc_pdata->min_uV != -ENODATA) && (uc_pdata->max_uV != -ENODATA) &&
diff --git a/include/power/regulator.h b/include/power/regulator.h index 6c6e2cd4f996..dd61eb4ccbde 100644 --- a/include/power/regulator.h +++ b/include/power/regulator.h @@ -168,6 +168,7 @@ struct dm_regulator_uclass_platdata { int mode_count; int min_uV; int max_uV;
- int init_uV; int min_uA; int max_uA; unsigned int ramp_delay;
@@ -177,6 +178,8 @@ struct dm_regulator_uclass_platdata { int flags; u8 ctrl_reg; u8 volt_reg;
- bool suspend_on;
- u32 suspend_uV;
};
/* Regulator device operations */ @@ -194,6 +197,19 @@ struct dm_regulator_ops { int (*set_value)(struct udevice *dev, int uV);
/**
* The regulator suspend output value function calls operates
* on a micro Volts.
*
* get/set_suspen_value - get/set suspend mode output value
* @dev - regulator device
* Sets:
* @uV - set the suspend output value [micro Volts]
* @return output value [uV] on success or negative errno if fail.
*/
- int (*set_suspend_value)(struct udevice *dev, int uV);
- int (*get_suspend_value)(struct udevice *dev);
- /**
- The regulator output current function calls operates on a micro Amps.
- get/set_current - get/set output current of the given output number
@@ -218,6 +234,19 @@ struct dm_regulator_ops { int (*set_enable)(struct udevice *dev, bool enable);
/**
* The most basic feature of the regulator output is its enable state
* in suspend mode.
*
* get/set_suspend_enable - get/set enable state of the suspend output
* @dev - regulator device
* Sets:
* @enable - set true - enable or false - disable
* @return true/false for get or -errno if fail; 0 / -errno for set.
*/
- int (*set_suspend_enable)(struct udevice *dev, bool enable);
- int (*get_suspend_enable)(struct udevice *dev);
- /**
- The 'get/set_mode()' function calls should operate on a driver-
- specific mode id definitions, which should be found in:
- field 'id' of struct dm_regulator_mode.
@@ -262,6 +291,23 @@ int regulator_get_value(struct udevice *dev); int regulator_set_value(struct udevice *dev, int uV);
/**
- regulator_set_suspend_value: set the suspend microvoltage value of a given regulator.
- @dev - pointer to the regulator device
- @uV - the output suspend value to set [micro Volts]
- @return - 0 on success or -errno val if fails
- */
+int regulator_set_suspend_value(struct udevice *dev, int uV);
+/**
- regulator_get_suspend_value: get the suspend microvoltage value of a given regulator.
- @dev - pointer to the regulator device
- @return - positive output value [uV] on success or negative errno if fail.
- */
+int regulator_get_suspend_value(struct udevice *dev);
+/**
- regulator_set_value_force: set the microvoltage value of a given regulator
without any min-,max condition check
@@ -317,6 +363,24 @@ int regulator_set_enable(struct udevice *dev, bool enable); int regulator_set_enable_if_allowed(struct udevice *dev, bool enable);
/**
- regulator_set_suspend_enable: set regulator suspend enable state
- @dev - pointer to the regulator device
- @enable - set true or false
- @return - 0 on success or -errno val if fails
- */
+int regulator_set_suspend_enable(struct udevice *dev, bool enable);
+/**
- regulator_get_suspend_enable: get regulator suspend enable state
- @dev - pointer to the regulator device
- @return - true/false of enable state or -errno val if fails
- */
+int regulator_get_suspend_enable(struct udevice *dev);
+/**
- regulator_get_mode: get active operation mode id of a given regulator
- @dev - pointer to the regulator device
diff --git a/test/dm/regulator.c b/test/dm/regulator.c index e510539542b6..b967902493dd 100644 --- a/test/dm/regulator.c +++ b/test/dm/regulator.c @@ -215,6 +215,63 @@ static int dm_test_power_regulator_set_get_mode(struct unit_test_state *uts) } DM_TEST(dm_test_power_regulator_set_get_mode, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Voltage method */ +static int dm_test_power_regulator_set_get_suspend_voltage(struct unit_test_state *uts) +{
- struct dm_regulator_uclass_platdata *uc_pdata;
- const struct dm_regulator_ops *ops;
- struct udevice *dev;
- const char *platname;
- int val_set, val_get;
- /* Set and get Voltage of BUCK1 - set to 'min' constraint */
- platname = regulator_names[BUCK1][PLATNAME];
- ut_assertok(regulator_get_by_platname(platname, &dev));
- uc_pdata = dev_get_uclass_platdata(dev);
- ut_assert(uc_pdata);
- ops = dev_get_driver_ops(dev);
- if (ops->set_suspend_value && ops->get_suspend_value) {
val_set = uc_pdata->suspend_uV;
ut_assertok(regulator_set_suspend_value(dev, val_set));
val_get = regulator_get_suspend_value(dev);
ut_assert(val_get >= 0);
ut_asserteq(val_set, val_get);
- }
- return 0;
+} +DM_TEST(dm_test_power_regulator_set_get_suspend_voltage, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Enable method */ +static int dm_test_power_regulator_set_get_suspend_enable(struct unit_test_state *uts) +{
- const struct dm_regulator_ops *ops;
- const char *platname;
- struct udevice *dev;
- bool val_set = true;
- /* Set the Enable of LDO1 - default is disabled */
- platname = regulator_names[LDO1][PLATNAME];
- ut_assertok(regulator_get_by_platname(platname, &dev));
- ops = dev_get_driver_ops(dev);
- if (ops->set_suspend_enable && ops->get_suspend_enable) {
ut_assertok(regulator_set_suspend_enable(dev, val_set));
/*
* Get the Enable state of LDO1 and
* compare it with the requested one
*/
ut_asserteq(regulator_get_suspend_enable(dev), val_set);
- }
- return 0;
+} +DM_TEST(dm_test_power_regulator_set_get_suspend_enable, DM_TESTF_SCAN_FDT);
/* Test regulator autoset method */ static int dm_test_power_regulator_autoset(struct unit_test_state *uts) {

Hi,
Please ignore these two emails, they are sent in error.
[PATCH v5 0/6] power: pmic: support more PMIC PATCH v5 1/6] dm: regulator: support regulator more state
张晴 瑞芯微电子股份有限公司 Rockchip Electronics Co.,Ltd 地址:福建省福州市铜盘路软件大道89号软件园A区21号楼 Add:No.21 Building, A District, No.89 Software Boulevard Fuzhou, Fujian 350003, P.R.China Tel:+86-0591-83991906-8601 邮编:350003 E-mail:elaine.zhang@rock-chips.com
From: Jaehoon Chung Date: 2021-05-27 06:18 To: Elaine; Zhang; sjg; philipp.tomsich; kever.yang; lukma CC: zhangqing; u-boot; chenjh Subject: Re: [PATCH v5 1/6] dm: regulator: support regulator more state Hi,
On 5/26/21 5:46 PM, Elaine@denx.de wrote:
From: Joseph Chen chenjh@rock-chips.com
Is it right patch? This patch had been already applied.
Best Regards, Jaehoon Chung
support parse regulator standard property: regulator-off-in-suspend; regulator-init-microvolt; regulator-suspend-microvolt: regulator_get_suspend_enable regulator_set_suspend_enable regulator_get_suspend_value regulator_set_suspend_value
Signed-off-by: Joseph Chen chenjh@rock-chips.com Signed-off-by: Elaine Zhang zhangqing@rock-chips.com Reviewed-by: Kever Yangkever.yang@rock-chips.com
doc/device-tree-bindings/regulator/regulator.txt | 27 +++++++++ drivers/power/regulator/regulator-uclass.c | 70 ++++++++++++++++++++++++ include/power/regulator.h | 64 ++++++++++++++++++++++ test/dm/regulator.c | 57 +++++++++++++++++++ 4 files changed, 218 insertions(+)
diff --git a/doc/device-tree-bindings/regulator/regulator.txt b/doc/device-tree-bindings/regulator/regulator.txt index 4ba642b7c77f..6c9a02120fde 100644 --- a/doc/device-tree-bindings/regulator/regulator.txt +++ b/doc/device-tree-bindings/regulator/regulator.txt @@ -36,6 +36,28 @@ Optional properties:
- regulator-always-on: regulator should never be disabled
- regulator-boot-on: enabled by bootloader/firmware
- regulator-ramp-delay: ramp delay for regulator (in uV/us)
+- regulator-init-microvolt: a init allowed Voltage value +- regulator-state-(standby|mem|disk)
- type: object
- description:
- sub-nodes for regulator state in Standby, Suspend-to-RAM, and
- Suspend-to-DISK modes. Equivalent with standby, mem, and disk Linux
- sleep states.
- properties:
regulator-on-in-suspend:
description: regulator should be on in suspend state.
type: boolean
regulator-off-in-suspend:
description: regulator should be off in suspend state.
type: boolean
regulator-suspend-microvolt:
description: the default voltage which regulator would be set in
suspend. This property is now deprecated, instead setting voltage
for suspend mode via the API which regulator driver provides is
recommended.
Note The "regulator-name" constraint is used for setting the device's uclass @@ -59,7 +81,12 @@ ldo0 { regulator-max-microvolt = <1800000>; regulator-min-microamp = <100000>; regulator-max-microamp = <100000>;
- regulator-init-microvolt = <1800000>;
regulator-always-on; regulator-boot-on; regulator-ramp-delay = <12000>;
- regulator-state-mem {
- regulator-on-in-suspend;
- regulator-suspend-microvolt = <1800000>;
- };
}; diff --git a/drivers/power/regulator/regulator-uclass.c b/drivers/power/regulator/regulator-uclass.c index 76be95bcd159..4986c87e7ba6 100644 --- a/drivers/power/regulator/regulator-uclass.c +++ b/drivers/power/regulator/regulator-uclass.c @@ -77,6 +77,33 @@ int regulator_set_value(struct udevice *dev, int uV) return ret; }
+int regulator_set_suspend_value(struct udevice *dev, int uV) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- struct dm_regulator_uclass_platdata *uc_pdata;
- uc_pdata = dev_get_uclass_platdata(dev);
- if (uc_pdata->min_uV != -ENODATA && uV < uc_pdata->min_uV)
- return -EINVAL;
- if (uc_pdata->max_uV != -ENODATA && uV > uc_pdata->max_uV)
- return -EINVAL;
- if (!ops->set_suspend_value)
- return -ENOSYS;
- return ops->set_suspend_value(dev, uV);
+}
+int regulator_get_suspend_value(struct udevice *dev) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_value)
- return -ENOSYS;
- return ops->get_suspend_value(dev);
+}
/*
- To be called with at most caution as there is no check
- before setting the actual voltage value.
@@ -170,6 +197,26 @@ int regulator_set_enable_if_allowed(struct udevice *dev, bool enable) return ret; }
+int regulator_set_suspend_enable(struct udevice *dev, bool enable) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->set_suspend_enable)
- return -ENOSYS;
- return ops->set_suspend_enable(dev, enable);
+}
+int regulator_get_suspend_enable(struct udevice *dev) +{
- const struct dm_regulator_ops *ops = dev_get_driver_ops(dev);
- if (!ops->get_suspend_enable)
- return -ENOSYS;
- return ops->get_suspend_enable(dev);
+}
int regulator_get_mode(struct udevice *dev) { const struct dm_regulator_ops *ops = dev_get_driver_ops(dev); @@ -235,6 +282,14 @@ int regulator_autoset(struct udevice *dev) int ret = 0;
uc_pdata = dev_get_uclass_platdata(dev);
- ret = regulator_set_suspend_enable(dev, uc_pdata->suspend_on);
- if (!ret && uc_pdata->suspend_on) {
- ret = regulator_set_suspend_value(dev, uc_pdata->suspend_uV);
- if (!ret)
- return ret;
- }
if (!uc_pdata->always_on && !uc_pdata->boot_on) return -EMEDIUMTYPE;
@@ -243,6 +298,8 @@ int regulator_autoset(struct udevice *dev)
if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV) ret = regulator_set_value(dev, uc_pdata->min_uV);
- if (uc_pdata->init_uV > 0)
- ret = regulator_set_value(dev, uc_pdata->init_uV);
if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)) ret = regulator_set_current(dev, uc_pdata->min_uA);
@@ -363,6 +420,7 @@ static int regulator_post_bind(struct udevice *dev) static int regulator_pre_probe(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata;
- ofnode node;
uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata) @@ -373,6 +431,8 @@ static int regulator_pre_probe(struct udevice *dev) -ENODATA); uc_pdata->max_uV = dev_read_u32_default(dev, "regulator-max-microvolt", -ENODATA);
- uc_pdata->init_uV = dev_read_u32_default(dev, "regulator-init-microvolt",
- -ENODATA);
uc_pdata->min_uA = dev_read_u32_default(dev, "regulator-min-microamp", -ENODATA); uc_pdata->max_uA = dev_read_u32_default(dev, "regulator-max-microamp", @@ -382,6 +442,16 @@ static int regulator_pre_probe(struct udevice *dev) uc_pdata->ramp_delay = dev_read_u32_default(dev, "regulator-ramp-delay", 0);
- node = dev_read_subnode(dev, "regulator-state-mem");
- if (ofnode_valid(node)) {
- uc_pdata->suspend_on = !ofnode_read_bool(node, "regulator-off-in-suspend");
- if (ofnode_read_u32(node, "regulator-suspend-microvolt", &uc_pdata->suspend_uV))
- uc_pdata->suspend_uV = uc_pdata->max_uV;
- } else {
- uc_pdata->suspend_on = true;
- uc_pdata->suspend_uV = uc_pdata->max_uV;
- }
/* Those values are optional (-ENODATA if unset) */ if ((uc_pdata->min_uV != -ENODATA) && (uc_pdata->max_uV != -ENODATA) && diff --git a/include/power/regulator.h b/include/power/regulator.h index 6c6e2cd4f996..dd61eb4ccbde 100644 --- a/include/power/regulator.h +++ b/include/power/regulator.h @@ -168,6 +168,7 @@ struct dm_regulator_uclass_platdata { int mode_count; int min_uV; int max_uV;
- int init_uV;
int min_uA; int max_uA; unsigned int ramp_delay; @@ -177,6 +178,8 @@ struct dm_regulator_uclass_platdata { int flags; u8 ctrl_reg; u8 volt_reg;
- bool suspend_on;
- u32 suspend_uV;
};
/* Regulator device operations */ @@ -194,6 +197,19 @@ struct dm_regulator_ops { int (*set_value)(struct udevice *dev, int uV);
/**
- The regulator suspend output value function calls operates
- on a micro Volts.
- get/set_suspen_value - get/set suspend mode output value
- @dev - regulator device
- Sets:
- @uV - set the suspend output value [micro Volts]
- @return output value [uV] on success or negative errno if fail.
- */
- int (*set_suspend_value)(struct udevice *dev, int uV);
- int (*get_suspend_value)(struct udevice *dev);
- /**
- The regulator output current function calls operates on a micro Amps.
- get/set_current - get/set output current of the given output number
@@ -218,6 +234,19 @@ struct dm_regulator_ops { int (*set_enable)(struct udevice *dev, bool enable);
/**
- The most basic feature of the regulator output is its enable state
- in suspend mode.
- get/set_suspend_enable - get/set enable state of the suspend output
- @dev - regulator device
- Sets:
- @enable - set true - enable or false - disable
- @return true/false for get or -errno if fail; 0 / -errno for set.
- */
- int (*set_suspend_enable)(struct udevice *dev, bool enable);
- int (*get_suspend_enable)(struct udevice *dev);
- /**
- The 'get/set_mode()' function calls should operate on a driver-
- specific mode id definitions, which should be found in:
- field 'id' of struct dm_regulator_mode.
@@ -262,6 +291,23 @@ int regulator_get_value(struct udevice *dev); int regulator_set_value(struct udevice *dev, int uV);
/**
- regulator_set_suspend_value: set the suspend microvoltage value of a given regulator.
- @dev - pointer to the regulator device
- @uV - the output suspend value to set [micro Volts]
- @return - 0 on success or -errno val if fails
- */
+int regulator_set_suspend_value(struct udevice *dev, int uV);
+/**
- regulator_get_suspend_value: get the suspend microvoltage value of a given regulator.
- @dev - pointer to the regulator device
- @return - positive output value [uV] on success or negative errno if fail.
- */
+int regulator_get_suspend_value(struct udevice *dev);
+/**
- regulator_set_value_force: set the microvoltage value of a given regulator
without any min-,max condition check
@@ -317,6 +363,24 @@ int regulator_set_enable(struct udevice *dev, bool enable); int regulator_set_enable_if_allowed(struct udevice *dev, bool enable);
/**
- regulator_set_suspend_enable: set regulator suspend enable state
- @dev - pointer to the regulator device
- @enable - set true or false
- @return - 0 on success or -errno val if fails
- */
+int regulator_set_suspend_enable(struct udevice *dev, bool enable);
+/**
- regulator_get_suspend_enable: get regulator suspend enable state
- @dev - pointer to the regulator device
- @return - true/false of enable state or -errno val if fails
- */
+int regulator_get_suspend_enable(struct udevice *dev);
+/**
- regulator_get_mode: get active operation mode id of a given regulator
- @dev - pointer to the regulator device
diff --git a/test/dm/regulator.c b/test/dm/regulator.c index e510539542b6..b967902493dd 100644 --- a/test/dm/regulator.c +++ b/test/dm/regulator.c @@ -215,6 +215,63 @@ static int dm_test_power_regulator_set_get_mode(struct unit_test_state *uts) } DM_TEST(dm_test_power_regulator_set_get_mode, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Voltage method */ +static int dm_test_power_regulator_set_get_suspend_voltage(struct unit_test_state *uts) +{
- struct dm_regulator_uclass_platdata *uc_pdata;
- const struct dm_regulator_ops *ops;
- struct udevice *dev;
- const char *platname;
- int val_set, val_get;
- /* Set and get Voltage of BUCK1 - set to 'min' constraint */
- platname = regulator_names[BUCK1][PLATNAME];
- ut_assertok(regulator_get_by_platname(platname, &dev));
- uc_pdata = dev_get_uclass_platdata(dev);
- ut_assert(uc_pdata);
- ops = dev_get_driver_ops(dev);
- if (ops->set_suspend_value && ops->get_suspend_value) {
- val_set = uc_pdata->suspend_uV;
- ut_assertok(regulator_set_suspend_value(dev, val_set));
- val_get = regulator_get_suspend_value(dev);
- ut_assert(val_get >= 0);
- ut_asserteq(val_set, val_get);
- }
- return 0;
+} +DM_TEST(dm_test_power_regulator_set_get_suspend_voltage, DM_TESTF_SCAN_FDT);
+/* Test regulator set and get suspend Enable method */ +static int dm_test_power_regulator_set_get_suspend_enable(struct unit_test_state *uts) +{
- const struct dm_regulator_ops *ops;
- const char *platname;
- struct udevice *dev;
- bool val_set = true;
- /* Set the Enable of LDO1 - default is disabled */
- platname = regulator_names[LDO1][PLATNAME];
- ut_assertok(regulator_get_by_platname(platname, &dev));
- ops = dev_get_driver_ops(dev);
- if (ops->set_suspend_enable && ops->get_suspend_enable) {
- ut_assertok(regulator_set_suspend_enable(dev, val_set));
- /*
- Get the Enable state of LDO1 and
- compare it with the requested one
- */
- ut_asserteq(regulator_get_suspend_enable(dev), val_set);
- }
- return 0;
+} +DM_TEST(dm_test_power_regulator_set_get_suspend_enable, DM_TESTF_SCAN_FDT);
/* Test regulator autoset method */ static int dm_test_power_regulator_autoset(struct unit_test_state *uts) {
participants (4)
-
Elaine@denx.de
-
Jaehoon Chung
-
Kever Yang
-
zhangqing@rock-chips.com