* [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver @ 2021-05-26 8:46 Elaine, Zhang 2021-05-26 8:46 ` [PATCH v2 1/2] rockchip: rk3568: add device tree file Elaine, Zhang ` (3 more replies) 0 siblings, 4 replies; 10+ messages in thread From: Elaine, Zhang @ 2021-05-26 8:46 UTC (permalink / raw) To: sjg, philipp.tomsich, kever.yang, lukma; +Cc: zhangqing, u-boot, chenjh 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 -- 2.17.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/2] rockchip: rk3568: add device tree file 2021-05-26 8:46 [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver Elaine, Zhang @ 2021-05-26 8:46 ` Elaine, Zhang 2021-06-08 7:09 ` Kever Yang 2021-05-26 8:46 ` [PATCH v2 2/2] rockchip: rk3568: add clock driver Elaine, Zhang ` (2 subsequent siblings) 3 siblings, 1 reply; 10+ messages in thread From: Elaine, Zhang @ 2021-05-26 8:46 UTC (permalink / raw) To: sjg, philipp.tomsich, kever.yang, lukma; +Cc: zhangqing, u-boot, chenjh From: Elaine Zhang <zhangqing@rock-chips.com> Add dts binding header for rk3568, files origin from kernel. Signed-off-by: Elaine Zhang <zhangqing@rock-chips.com> --- include/dt-bindings/clock/rk3568-cru.h | 925 +++++++++++++++++++++++++ 1 file changed, 925 insertions(+) create mode 100644 include/dt-bindings/clock/rk3568-cru.h diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h new file mode 100644 index 000000000000..c1942422a438 --- /dev/null +++ b/include/dt-bindings/clock/rk3568-cru.h @@ -0,0 +1,925 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H + +/* pmucru-clocks indices */ + +/* pmucru plls */ +#define PLL_PPLL 1 +#define PLL_HPLL 2 + +/* pmucru clocks */ +#define XIN_OSC0_DIV 4 +#define CLK_RTC_32K 5 +#define CLK_PMU 6 +#define CLK_I2C0 7 +#define CLK_RTC32K_FRAC 8 +#define CLK_UART0_DIV 9 +#define CLK_UART0_FRAC 10 +#define SCLK_UART0 11 +#define DBCLK_GPIO0 12 +#define CLK_PWM0 13 +#define CLK_CAPTURE_PWM0_NDFT 14 +#define CLK_PMUPVTM 15 +#define CLK_CORE_PMUPVTM 16 +#define CLK_REF24M 17 +#define XIN_OSC0_USBPHY0_G 18 +#define CLK_USBPHY0_REF 19 +#define XIN_OSC0_USBPHY1_G 20 +#define CLK_USBPHY1_REF 21 +#define XIN_OSC0_MIPIDSIPHY0_G 22 +#define CLK_MIPIDSIPHY0_REF 23 +#define XIN_OSC0_MIPIDSIPHY1_G 24 +#define CLK_MIPIDSIPHY1_REF 25 +#define CLK_WIFI_DIV 26 +#define CLK_WIFI_OSC0 27 +#define CLK_WIFI 28 +#define CLK_PCIEPHY0_DIV 29 +#define CLK_PCIEPHY0_OSC0 30 +#define CLK_PCIEPHY0_REF 31 +#define CLK_PCIEPHY1_DIV 32 +#define CLK_PCIEPHY1_OSC0 33 +#define CLK_PCIEPHY1_REF 34 +#define CLK_PCIEPHY2_DIV 35 +#define CLK_PCIEPHY2_OSC0 36 +#define CLK_PCIEPHY2_REF 37 +#define CLK_PCIE30PHY_REF_M 38 +#define CLK_PCIE30PHY_REF_N 39 +#define CLK_HDMI_REF 40 +#define XIN_OSC0_EDPPHY_G 41 +#define PCLK_PDPMU 42 +#define PCLK_PMU 43 +#define PCLK_UART0 44 +#define PCLK_I2C0 45 +#define PCLK_GPIO0 46 +#define PCLK_PMUPVTM 47 +#define PCLK_PWM0 48 +#define CLK_PDPMU 49 +#define SCLK_32K_IOE 50 + +#define CLKPMU_NR_CLKS (SCLK_32K_IOE + 1) + +/* cru-clocks indices */ + +/* cru plls */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_GPLL 4 +#define PLL_VPLL 5 +#define PLL_NPLL 6 + +/* cru clocks */ +#define CPLL_333M 9 +#define ARMCLK 10 +#define USB480M 11 +#define ACLK_CORE_NIU2BUS 18 +#define CLK_CORE_PVTM 19 +#define CLK_CORE_PVTM_CORE 20 +#define CLK_CORE_PVTPLL 21 +#define CLK_GPU_SRC 22 +#define CLK_GPU_PRE_NDFT 23 +#define CLK_GPU_PRE_MUX 24 +#define ACLK_GPU_PRE 25 +#define PCLK_GPU_PRE 26 +#define CLK_GPU 27 +#define CLK_GPU_NP5 28 +#define PCLK_GPU_PVTM 29 +#define CLK_GPU_PVTM 30 +#define CLK_GPU_PVTM_CORE 31 +#define CLK_GPU_PVTPLL 32 +#define CLK_NPU_SRC 33 +#define CLK_NPU_PRE_NDFT 34 +#define CLK_NPU 35 +#define CLK_NPU_NP5 36 +#define HCLK_NPU_PRE 37 +#define PCLK_NPU_PRE 38 +#define ACLK_NPU_PRE 39 +#define ACLK_NPU 40 +#define HCLK_NPU 41 +#define PCLK_NPU_PVTM 42 +#define CLK_NPU_PVTM 43 +#define CLK_NPU_PVTM_CORE 44 +#define CLK_NPU_PVTPLL 45 +#define CLK_DDRPHY1X_SRC 46 +#define CLK_DDRPHY1X_HWFFC_SRC 47 +#define CLK_DDR1X 48 +#define CLK_MSCH 49 +#define CLK24_DDRMON 50 +#define ACLK_GIC_AUDIO 51 +#define HCLK_GIC_AUDIO 52 +#define HCLK_SDMMC_BUFFER 53 +#define DCLK_SDMMC_BUFFER 54 +#define ACLK_GIC600 55 +#define ACLK_SPINLOCK 56 +#define HCLK_I2S0_8CH 57 +#define HCLK_I2S1_8CH 58 +#define HCLK_I2S2_2CH 59 +#define HCLK_I2S3_2CH 60 +#define CLK_I2S0_8CH_TX_SRC 61 +#define CLK_I2S0_8CH_TX_FRAC 62 +#define MCLK_I2S0_8CH_TX 63 +#define I2S0_MCLKOUT_TX 64 +#define CLK_I2S0_8CH_RX_SRC 65 +#define CLK_I2S0_8CH_RX_FRAC 66 +#define MCLK_I2S0_8CH_RX 67 +#define I2S0_MCLKOUT_RX 68 +#define CLK_I2S1_8CH_TX_SRC 69 +#define CLK_I2S1_8CH_TX_FRAC 70 +#define MCLK_I2S1_8CH_TX 71 +#define I2S1_MCLKOUT_TX 72 +#define CLK_I2S1_8CH_RX_SRC 73 +#define CLK_I2S1_8CH_RX_FRAC 74 +#define MCLK_I2S1_8CH_RX 75 +#define I2S1_MCLKOUT_RX 76 +#define CLK_I2S2_2CH_SRC 77 +#define CLK_I2S2_2CH_FRAC 78 +#define MCLK_I2S2_2CH 79 +#define I2S2_MCLKOUT 80 +#define CLK_I2S3_2CH_TX_SRC 81 +#define CLK_I2S3_2CH_TX_FRAC 82 +#define MCLK_I2S3_2CH_TX 83 +#define I2S3_MCLKOUT_TX 84 +#define CLK_I2S3_2CH_RX_SRC 85 +#define CLK_I2S3_2CH_RX_FRAC 86 +#define MCLK_I2S3_2CH_RX 87 +#define I2S3_MCLKOUT_RX 88 +#define HCLK_PDM 89 +#define MCLK_PDM 90 +#define HCLK_VAD 91 +#define HCLK_SPDIF_8CH 92 +#define MCLK_SPDIF_8CH_SRC 93 +#define MCLK_SPDIF_8CH_FRAC 94 +#define MCLK_SPDIF_8CH 95 +#define HCLK_AUDPWM 96 +#define SCLK_AUDPWM_SRC 97 +#define SCLK_AUDPWM_FRAC 98 +#define SCLK_AUDPWM 99 +#define HCLK_ACDCDIG 100 +#define CLK_ACDCDIG_I2C 101 +#define CLK_ACDCDIG_DAC 102 +#define CLK_ACDCDIG_ADC 103 +#define ACLK_SECURE_FLASH 104 +#define HCLK_SECURE_FLASH 105 +#define ACLK_CRYPTO_NS 106 +#define HCLK_CRYPTO_NS 107 +#define CLK_CRYPTO_NS_CORE 108 +#define CLK_CRYPTO_NS_PKA 109 +#define CLK_CRYPTO_NS_RNG 110 +#define HCLK_TRNG_NS 111 +#define CLK_TRNG_NS 112 +#define PCLK_OTPC_NS 113 +#define CLK_OTPC_NS_SBPI 114 +#define CLK_OTPC_NS_USR 115 +#define HCLK_NANDC 116 +#define NCLK_NANDC 117 +#define HCLK_SFC 118 +#define HCLK_SFC_XIP 119 +#define SCLK_SFC 120 +#define ACLK_EMMC 121 +#define HCLK_EMMC 122 +#define BCLK_EMMC 123 +#define CCLK_EMMC 124 +#define TCLK_EMMC 125 +#define ACLK_PIPE 126 +#define PCLK_PIPE 127 +#define PCLK_PIPE_GRF 128 +#define ACLK_PCIE20_MST 129 +#define ACLK_PCIE20_SLV 130 +#define ACLK_PCIE20_DBI 131 +#define PCLK_PCIE20 132 +#define CLK_PCIE20_AUX_NDFT 133 +#define CLK_PCIE20_AUX_DFT 134 +#define CLK_PCIE20_PIPE_DFT 135 +#define ACLK_PCIE30X1_MST 136 +#define ACLK_PCIE30X1_SLV 137 +#define ACLK_PCIE30X1_DBI 138 +#define PCLK_PCIE30X1 139 +#define CLK_PCIE30X1_AUX_NDFT 140 +#define CLK_PCIE30X1_AUX_DFT 141 +#define CLK_PCIE30X1_PIPE_DFT 142 +#define ACLK_PCIE30X2_MST 143 +#define ACLK_PCIE30X2_SLV 144 +#define ACLK_PCIE30X2_DBI 145 +#define PCLK_PCIE30X2 146 +#define CLK_PCIE30X2_AUX_NDFT 147 +#define CLK_PCIE30X2_AUX_DFT 148 +#define CLK_PCIE30X2_PIPE_DFT 149 +#define ACLK_SATA0 150 +#define CLK_SATA0_PMALIVE 151 +#define CLK_SATA0_RXOOB 152 +#define CLK_SATA0_PIPE_NDFT 153 +#define CLK_SATA0_PIPE_DFT 154 +#define ACLK_SATA1 155 +#define CLK_SATA1_PMALIVE 156 +#define CLK_SATA1_RXOOB 157 +#define CLK_SATA1_PIPE_NDFT 158 +#define CLK_SATA1_PIPE_DFT 159 +#define ACLK_SATA2 160 +#define CLK_SATA2_PMALIVE 161 +#define CLK_SATA2_RXOOB 162 +#define CLK_SATA2_PIPE_NDFT 163 +#define CLK_SATA2_PIPE_DFT 164 +#define ACLK_USB3OTG0 165 +#define CLK_USB3OTG0_REF 166 +#define CLK_USB3OTG0_SUSPEND 167 +#define ACLK_USB3OTG1 168 +#define CLK_USB3OTG1_REF 169 +#define CLK_USB3OTG1_SUSPEND 170 +#define CLK_XPCS_EEE 171 +#define PCLK_XPCS 172 +#define ACLK_PHP 173 +#define HCLK_PHP 174 +#define PCLK_PHP 175 +#define HCLK_SDMMC0 176 +#define CLK_SDMMC0 177 +#define HCLK_SDMMC1 178 +#define CLK_SDMMC1 179 +#define ACLK_GMAC0 180 +#define PCLK_GMAC0 181 +#define CLK_MAC0_2TOP 182 +#define CLK_MAC0_OUT 183 +#define CLK_MAC0_REFOUT 184 +#define CLK_GMAC0_PTP_REF 185 +#define ACLK_USB 186 +#define HCLK_USB 187 +#define PCLK_USB 188 +#define HCLK_USB2HOST0 189 +#define HCLK_USB2HOST0_ARB 190 +#define HCLK_USB2HOST1 191 +#define HCLK_USB2HOST1_ARB 192 +#define HCLK_SDMMC2 193 +#define CLK_SDMMC2 194 +#define ACLK_GMAC1 195 +#define PCLK_GMAC1 196 +#define CLK_MAC1_2TOP 197 +#define CLK_MAC1_OUT 198 +#define CLK_MAC1_REFOUT 199 +#define CLK_GMAC1_PTP_REF 200 +#define ACLK_PERIMID 201 +#define HCLK_PERIMID 202 +#define ACLK_VI 203 +#define HCLK_VI 204 +#define PCLK_VI 205 +#define ACLK_VICAP 206 +#define HCLK_VICAP 207 +#define DCLK_VICAP 208 +#define ICLK_VICAP_G 209 +#define ACLK_ISP 210 +#define HCLK_ISP 211 +#define CLK_ISP 212 +#define PCLK_CSI2HOST1 213 +#define CLK_CIF_OUT 214 +#define CLK_CAM0_OUT 215 +#define CLK_CAM1_OUT 216 +#define ACLK_VO 217 +#define HCLK_VO 218 +#define PCLK_VO 219 +#define ACLK_VOP_PRE 220 +#define ACLK_VOP 221 +#define HCLK_VOP 222 +#define DCLK_VOP0 223 +#define DCLK_VOP1 224 +#define DCLK_VOP2 225 +#define CLK_VOP_PWM 226 +#define ACLK_HDCP 227 +#define HCLK_HDCP 228 +#define PCLK_HDCP 229 +#define PCLK_HDMI_HOST 230 +#define CLK_HDMI_SFR 231 +#define PCLK_DSITX_0 232 +#define PCLK_DSITX_1 233 +#define PCLK_EDP_CTRL 234 +#define CLK_EDP_200M 235 +#define ACLK_VPU_PRE 236 +#define HCLK_VPU_PRE 237 +#define ACLK_VPU 238 +#define HCLK_VPU 239 +#define ACLK_RGA_PRE 240 +#define HCLK_RGA_PRE 241 +#define PCLK_RGA_PRE 242 +#define ACLK_RGA 243 +#define HCLK_RGA 244 +#define CLK_RGA_CORE 245 +#define ACLK_IEP 246 +#define HCLK_IEP 247 +#define CLK_IEP_CORE 248 +#define HCLK_EBC 249 +#define DCLK_EBC 250 +#define ACLK_JDEC 251 +#define HCLK_JDEC 252 +#define ACLK_JENC 253 +#define HCLK_JENC 254 +#define PCLK_EINK 255 +#define HCLK_EINK 256 +#define ACLK_RKVENC_PRE 257 +#define HCLK_RKVENC_PRE 258 +#define ACLK_RKVENC 259 +#define HCLK_RKVENC 260 +#define CLK_RKVENC_CORE 261 +#define ACLK_RKVDEC_PRE 262 +#define HCLK_RKVDEC_PRE 263 +#define ACLK_RKVDEC 264 +#define HCLK_RKVDEC 265 +#define CLK_RKVDEC_CA 266 +#define CLK_RKVDEC_CORE 267 +#define CLK_RKVDEC_HEVC_CA 268 +#define ACLK_BUS 269 +#define PCLK_BUS 270 +#define PCLK_TSADC 271 +#define CLK_TSADC_TSEN 272 +#define CLK_TSADC 273 +#define PCLK_SARADC 274 +#define CLK_SARADC 275 +#define PCLK_SCR 276 +#define PCLK_WDT_NS 277 +#define TCLK_WDT_NS 278 +#define ACLK_DMAC0 279 +#define ACLK_DMAC1 280 +#define ACLK_MCU 281 +#define PCLK_INTMUX 282 +#define PCLK_MAILBOX 283 +#define PCLK_UART1 284 +#define CLK_UART1_SRC 285 +#define CLK_UART1_FRAC 286 +#define SCLK_UART1 287 +#define PCLK_UART2 288 +#define CLK_UART2_SRC 289 +#define CLK_UART2_FRAC 290 +#define SCLK_UART2 291 +#define PCLK_UART3 292 +#define CLK_UART3_SRC 293 +#define CLK_UART3_FRAC 294 +#define SCLK_UART3 295 +#define PCLK_UART4 296 +#define CLK_UART4_SRC 297 +#define CLK_UART4_FRAC 298 +#define SCLK_UART4 299 +#define PCLK_UART5 300 +#define CLK_UART5_SRC 301 +#define CLK_UART5_FRAC 302 +#define SCLK_UART5 303 +#define PCLK_UART6 304 +#define CLK_UART6_SRC 305 +#define CLK_UART6_FRAC 306 +#define SCLK_UART6 307 +#define PCLK_UART7 308 +#define CLK_UART7_SRC 309 +#define CLK_UART7_FRAC 310 +#define SCLK_UART7 311 +#define PCLK_UART8 312 +#define CLK_UART8_SRC 313 +#define CLK_UART8_FRAC 314 +#define SCLK_UART8 315 +#define PCLK_UART9 316 +#define CLK_UART9_SRC 317 +#define CLK_UART9_FRAC 318 +#define SCLK_UART9 319 +#define PCLK_CAN0 320 +#define CLK_CAN0 321 +#define PCLK_CAN1 322 +#define CLK_CAN1 323 +#define PCLK_CAN2 324 +#define CLK_CAN2 325 +#define CLK_I2C 326 +#define PCLK_I2C1 327 +#define CLK_I2C1 328 +#define PCLK_I2C2 329 +#define CLK_I2C2 330 +#define PCLK_I2C3 331 +#define CLK_I2C3 332 +#define PCLK_I2C4 333 +#define CLK_I2C4 334 +#define PCLK_I2C5 335 +#define CLK_I2C5 336 +#define PCLK_SPI0 337 +#define CLK_SPI0 338 +#define PCLK_SPI1 339 +#define CLK_SPI1 340 +#define PCLK_SPI2 341 +#define CLK_SPI2 342 +#define PCLK_SPI3 343 +#define CLK_SPI3 344 +#define PCLK_PWM1 345 +#define CLK_PWM1 346 +#define CLK_PWM1_CAPTURE 347 +#define PCLK_PWM2 348 +#define CLK_PWM2 349 +#define CLK_PWM2_CAPTURE 350 +#define PCLK_PWM3 351 +#define CLK_PWM3 352 +#define CLK_PWM3_CAPTURE 353 +#define DBCLK_GPIO 354 +#define PCLK_GPIO1 355 +#define DBCLK_GPIO1 356 +#define PCLK_GPIO2 357 +#define DBCLK_GPIO2 358 +#define PCLK_GPIO3 359 +#define DBCLK_GPIO3 360 +#define PCLK_GPIO4 361 +#define DBCLK_GPIO4 362 +#define OCC_SCAN_CLK_GPIO 363 +#define PCLK_TIMER 364 +#define CLK_TIMER0 365 +#define CLK_TIMER1 366 +#define CLK_TIMER2 367 +#define CLK_TIMER3 368 +#define CLK_TIMER4 369 +#define CLK_TIMER5 370 +#define ACLK_TOP_HIGH 371 +#define ACLK_TOP_LOW 372 +#define HCLK_TOP 373 +#define PCLK_TOP 374 +#define PCLK_PCIE30PHY 375 +#define CLK_OPTC_ARB 376 +#define PCLK_MIPICSIPHY 377 +#define PCLK_MIPIDSIPHY0 378 +#define PCLK_MIPIDSIPHY1 379 +#define PCLK_PIPEPHY0 380 +#define PCLK_PIPEPHY1 381 +#define PCLK_PIPEPHY2 382 +#define PCLK_CPU_BOOST 383 +#define CLK_CPU_BOOST 384 +#define PCLK_OTPPHY 385 +#define SCLK_GMAC0 386 +#define SCLK_GMAC0_RGMII_SPEED 387 +#define SCLK_GMAC0_RMII_SPEED 388 +#define SCLK_GMAC0_RX_TX 389 +#define SCLK_GMAC1 390 +#define SCLK_GMAC1_RGMII_SPEED 391 +#define SCLK_GMAC1_RMII_SPEED 392 +#define SCLK_GMAC1_RX_TX 393 +#define SCLK_SDMMC0_DRV 394 +#define SCLK_SDMMC0_SAMPLE 395 +#define SCLK_SDMMC1_DRV 396 +#define SCLK_SDMMC1_SAMPLE 397 +#define SCLK_SDMMC2_DRV 398 +#define SCLK_SDMMC2_SAMPLE 399 +#define SCLK_EMMC_DRV 400 +#define SCLK_EMMC_SAMPLE 401 +#define PCLK_EDPPHY_GRF 402 +#define CLK_HDMI_CEC 403 +#define CLK_I2S0_8CH_TX 404 +#define CLK_I2S0_8CH_RX 405 +#define CLK_I2S1_8CH_TX 406 +#define CLK_I2S1_8CH_RX 407 +#define CLK_I2S2_2CH 408 +#define CLK_I2S3_2CH_TX 409 +#define CLK_I2S3_2CH_RX 410 +#define CPLL_500M 411 +#define CPLL_250M 412 +#define CPLL_125M 413 +#define CPLL_62P5M 414 +#define CPLL_50M 415 +#define CPLL_25M 416 +#define CPLL_100M 417 + +#define PCLK_CORE_PVTM 450 + +#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1) + +/* pmu soft-reset indices */ +/* pmucru_softrst_con0 */ +#define SRST_P_PDPMU_NIU 0 +#define SRST_P_PMUCRU 1 +#define SRST_P_PMUGRF 2 +#define SRST_P_I2C0 3 +#define SRST_I2C0 4 +#define SRST_P_UART0 5 +#define SRST_S_UART0 6 +#define SRST_P_PWM0 7 +#define SRST_PWM0 8 +#define SRST_P_GPIO0 9 +#define SRST_GPIO0 10 +#define SRST_P_PMUPVTM 11 +#define SRST_PMUPVTM 12 + +/* soft-reset indices */ + +/* cru_softrst_con0 */ +#define SRST_NCORERESET0 0 +#define SRST_NCORERESET1 1 +#define SRST_NCORERESET2 2 +#define SRST_NCORERESET3 3 +#define SRST_NCPUPORESET0 4 +#define SRST_NCPUPORESET1 5 +#define SRST_NCPUPORESET2 6 +#define SRST_NCPUPORESET3 7 +#define SRST_NSRESET 8 +#define SRST_NSPORESET 9 +#define SRST_NATRESET 10 +#define SRST_NGICRESET 11 +#define SRST_NPRESET 12 +#define SRST_NPERIPHRESET 13 + +/* cru_softrst_con1 */ +#define SRST_A_CORE_NIU2DDR 16 +#define SRST_A_CORE_NIU2BUS 17 +#define SRST_P_DBG_NIU 18 +#define SRST_P_DBG 19 +#define SRST_P_DBG_DAPLITE 20 +#define SRST_DAP 21 +#define SRST_A_ADB400_CORE2GIC 22 +#define SRST_A_ADB400_GIC2CORE 23 +#define SRST_P_CORE_GRF 24 +#define SRST_P_CORE_PVTM 25 +#define SRST_CORE_PVTM 26 +#define SRST_CORE_PVTPLL 27 + +/* cru_softrst_con2 */ +#define SRST_GPU 32 +#define SRST_A_GPU_NIU 33 +#define SRST_P_GPU_NIU 34 +#define SRST_P_GPU_PVTM 35 +#define SRST_GPU_PVTM 36 +#define SRST_GPU_PVTPLL 37 +#define SRST_A_NPU_NIU 40 +#define SRST_H_NPU_NIU 41 +#define SRST_P_NPU_NIU 42 +#define SRST_A_NPU 43 +#define SRST_H_NPU 44 +#define SRST_P_NPU_PVTM 45 +#define SRST_NPU_PVTM 46 +#define SRST_NPU_PVTPLL 47 + +/* cru_softrst_con3 */ +#define SRST_A_MSCH 51 +#define SRST_HWFFC_CTRL 52 +#define SRST_DDR_ALWAYSON 53 +#define SRST_A_DDRSPLIT 54 +#define SRST_DDRDFI_CTL 55 +#define SRST_A_DMA2DDR 57 + +/* cru_softrst_con4 */ +#define SRST_A_PERIMID_NIU 64 +#define SRST_H_PERIMID_NIU 65 +#define SRST_A_GIC_AUDIO_NIU 66 +#define SRST_H_GIC_AUDIO_NIU 67 +#define SRST_A_GIC600 68 +#define SRST_A_GIC600_DEBUG 69 +#define SRST_A_GICADB_CORE2GIC 70 +#define SRST_A_GICADB_GIC2CORE 71 +#define SRST_A_SPINLOCK 72 +#define SRST_H_SDMMC_BUFFER 73 +#define SRST_D_SDMMC_BUFFER 74 +#define SRST_H_I2S0_8CH 75 +#define SRST_H_I2S1_8CH 76 +#define SRST_H_I2S2_2CH 77 +#define SRST_H_I2S3_2CH 78 + +/* cru_softrst_con5 */ +#define SRST_M_I2S0_8CH_TX 80 +#define SRST_M_I2S0_8CH_RX 81 +#define SRST_M_I2S1_8CH_TX 82 +#define SRST_M_I2S1_8CH_RX 83 +#define SRST_M_I2S2_2CH 84 +#define SRST_M_I2S3_2CH_TX 85 +#define SRST_M_I2S3_2CH_RX 86 +#define SRST_H_PDM 87 +#define SRST_M_PDM 88 +#define SRST_H_VAD 89 +#define SRST_H_SPDIF_8CH 90 +#define SRST_M_SPDIF_8CH 91 +#define SRST_H_AUDPWM 92 +#define SRST_S_AUDPWM 93 +#define SRST_H_ACDCDIG 94 +#define SRST_ACDCDIG 95 + +/* cru_softrst_con6 */ +#define SRST_A_SECURE_FLASH_NIU 96 +#define SRST_H_SECURE_FLASH_NIU 97 +#define SRST_A_CRYPTO_NS 103 +#define SRST_H_CRYPTO_NS 104 +#define SRST_CRYPTO_NS_CORE 105 +#define SRST_CRYPTO_NS_PKA 106 +#define SRST_CRYPTO_NS_RNG 107 +#define SRST_H_TRNG_NS 108 +#define SRST_TRNG_NS 109 + +/* cru_softrst_con7 */ +#define SRST_H_NANDC 112 +#define SRST_N_NANDC 113 +#define SRST_H_SFC 114 +#define SRST_H_SFC_XIP 115 +#define SRST_S_SFC 116 +#define SRST_A_EMMC 117 +#define SRST_H_EMMC 118 +#define SRST_B_EMMC 119 +#define SRST_C_EMMC 120 +#define SRST_T_EMMC 121 + +/* cru_softrst_con8 */ +#define SRST_A_PIPE_NIU 128 +#define SRST_P_PIPE_NIU 130 +#define SRST_P_PIPE_GRF 133 +#define SRST_A_SATA0 134 +#define SRST_SATA0_PIPE 135 +#define SRST_SATA0_PMALIVE 136 +#define SRST_SATA0_RXOOB 137 +#define SRST_A_SATA1 138 +#define SRST_SATA1_PIPE 139 +#define SRST_SATA1_PMALIVE 140 +#define SRST_SATA1_RXOOB 141 + +/* cru_softrst_con9 */ +#define SRST_A_SATA2 144 +#define SRST_SATA2_PIPE 145 +#define SRST_SATA2_PMALIVE 146 +#define SRST_SATA2_RXOOB 147 +#define SRST_USB3OTG0 148 +#define SRST_USB3OTG1 149 +#define SRST_XPCS 150 +#define SRST_XPCS_TX_DIV10 151 +#define SRST_XPCS_RX_DIV10 152 +#define SRST_XPCS_XGXS_RX 153 + +/* cru_softrst_con10 */ +#define SRST_P_PCIE20 160 +#define SRST_PCIE20_POWERUP 161 +#define SRST_MSTR_ARESET_PCIE20 162 +#define SRST_SLV_ARESET_PCIE20 163 +#define SRST_DBI_ARESET_PCIE20 164 +#define SRST_BRESET_PCIE20 165 +#define SRST_PERST_PCIE20 166 +#define SRST_CORE_RST_PCIE20 167 +#define SRST_NSTICKY_RST_PCIE20 168 +#define SRST_STICKY_RST_PCIE20 169 +#define SRST_PWR_RST_PCIE20 170 + +/* cru_softrst_con11 */ +#define SRST_P_PCIE30X1 176 +#define SRST_PCIE30X1_POWERUP 177 +#define SRST_M_ARESET_PCIE30X1 178 +#define SRST_S_ARESET_PCIE30X1 179 +#define SRST_D_ARESET_PCIE30X1 180 +#define SRST_BRESET_PCIE30X1 181 +#define SRST_PERST_PCIE30X1 182 +#define SRST_CORE_RST_PCIE30X1 183 +#define SRST_NSTC_RST_PCIE30X1 184 +#define SRST_STC_RST_PCIE30X1 185 +#define SRST_PWR_RST_PCIE30X1 186 + +/* cru_softrst_con12 */ +#define SRST_P_PCIE30X2 192 +#define SRST_PCIE30X2_POWERUP 193 +#define SRST_M_ARESET_PCIE30X2 194 +#define SRST_S_ARESET_PCIE30X2 195 +#define SRST_D_ARESET_PCIE30X2 196 +#define SRST_BRESET_PCIE30X2 197 +#define SRST_PERST_PCIE30X2 198 +#define SRST_CORE_RST_PCIE30X2 199 +#define SRST_NSTC_RST_PCIE30X2 200 +#define SRST_STC_RST_PCIE30X2 201 +#define SRST_PWR_RST_PCIE30X2 202 + +/* cru_softrst_con13 */ +#define SRST_A_PHP_NIU 208 +#define SRST_H_PHP_NIU 209 +#define SRST_P_PHP_NIU 210 +#define SRST_H_SDMMC0 211 +#define SRST_SDMMC0 212 +#define SRST_H_SDMMC1 213 +#define SRST_SDMMC1 214 +#define SRST_A_GMAC0 215 +#define SRST_GMAC0_TIMESTAMP 216 + +/* cru_softrst_con14 */ +#define SRST_A_USB_NIU 224 +#define SRST_H_USB_NIU 225 +#define SRST_P_USB_NIU 226 +#define SRST_P_USB_GRF 227 +#define SRST_H_USB2HOST0 228 +#define SRST_H_USB2HOST0_ARB 229 +#define SRST_USB2HOST0_UTMI 230 +#define SRST_H_USB2HOST1 231 +#define SRST_H_USB2HOST1_ARB 232 +#define SRST_USB2HOST1_UTMI 233 +#define SRST_H_SDMMC2 234 +#define SRST_SDMMC2 235 +#define SRST_A_GMAC1 236 +#define SRST_GMAC1_TIMESTAMP 237 + +/* cru_softrst_con15 */ +#define SRST_A_VI_NIU 240 +#define SRST_H_VI_NIU 241 +#define SRST_P_VI_NIU 242 +#define SRST_A_VICAP 247 +#define SRST_H_VICAP 248 +#define SRST_D_VICAP 249 +#define SRST_I_VICAP 250 +#define SRST_P_VICAP 251 +#define SRST_H_ISP 252 +#define SRST_ISP 253 +#define SRST_P_CSI2HOST1 255 + +/* cru_softrst_con16 */ +#define SRST_A_VO_NIU 256 +#define SRST_H_VO_NIU 257 +#define SRST_P_VO_NIU 258 +#define SRST_A_VOP_NIU 259 +#define SRST_A_VOP 260 +#define SRST_H_VOP 261 +#define SRST_VOP0 262 +#define SRST_VOP1 263 +#define SRST_VOP2 264 +#define SRST_VOP_PWM 265 +#define SRST_A_HDCP 266 +#define SRST_H_HDCP 267 +#define SRST_P_HDCP 268 +#define SRST_P_HDMI_HOST 270 +#define SRST_HDMI_HOST 271 + +/* cru_softrst_con17 */ +#define SRST_P_DSITX_0 272 +#define SRST_P_DSITX_1 273 +#define SRST_P_EDP_CTRL 274 +#define SRST_EDP_24M 275 +#define SRST_A_VPU_NIU 280 +#define SRST_H_VPU_NIU 281 +#define SRST_A_VPU 282 +#define SRST_H_VPU 283 +#define SRST_H_EINK 286 +#define SRST_P_EINK 287 + +/* cru_softrst_con18 */ +#define SRST_A_RGA_NIU 288 +#define SRST_H_RGA_NIU 289 +#define SRST_P_RGA_NIU 290 +#define SRST_A_RGA 292 +#define SRST_H_RGA 293 +#define SRST_RGA_CORE 294 +#define SRST_A_IEP 295 +#define SRST_H_IEP 296 +#define SRST_IEP_CORE 297 +#define SRST_H_EBC 298 +#define SRST_D_EBC 299 +#define SRST_A_JDEC 300 +#define SRST_H_JDEC 301 +#define SRST_A_JENC 302 +#define SRST_H_JENC 303 + +/* cru_softrst_con19 */ +#define SRST_A_VENC_NIU 304 +#define SRST_H_VENC_NIU 305 +#define SRST_A_RKVENC 307 +#define SRST_H_RKVENC 308 +#define SRST_RKVENC_CORE 309 + +/* cru_softrst_con20 */ +#define SRST_A_RKVDEC_NIU 320 +#define SRST_H_RKVDEC_NIU 321 +#define SRST_A_RKVDEC 322 +#define SRST_H_RKVDEC 323 +#define SRST_RKVDEC_CA 324 +#define SRST_RKVDEC_CORE 325 +#define SRST_RKVDEC_HEVC_CA 326 + +/* cru_softrst_con21 */ +#define SRST_A_BUS_NIU 336 +#define SRST_P_BUS_NIU 338 +#define SRST_P_CAN0 340 +#define SRST_CAN0 341 +#define SRST_P_CAN1 342 +#define SRST_CAN1 343 +#define SRST_P_CAN2 344 +#define SRST_CAN2 345 +#define SRST_P_GPIO1 346 +#define SRST_GPIO1 347 +#define SRST_P_GPIO2 348 +#define SRST_GPIO2 349 +#define SRST_P_GPIO3 350 +#define SRST_GPIO3 351 + +/* cru_softrst_con22 */ +#define SRST_P_GPIO4 352 +#define SRST_GPIO4 353 +#define SRST_P_I2C1 354 +#define SRST_I2C1 355 +#define SRST_P_I2C2 356 +#define SRST_I2C2 357 +#define SRST_P_I2C3 358 +#define SRST_I2C3 359 +#define SRST_P_I2C4 360 +#define SRST_I2C4 361 +#define SRST_P_I2C5 362 +#define SRST_I2C5 363 +#define SRST_P_OTPC_NS 364 +#define SRST_OTPC_NS_SBPI 365 +#define SRST_OTPC_NS_USR 366 + +/* cru_softrst_con23 */ +#define SRST_P_PWM1 368 +#define SRST_PWM1 369 +#define SRST_P_PWM2 370 +#define SRST_PWM2 371 +#define SRST_P_PWM3 372 +#define SRST_PWM3 373 +#define SRST_P_SPI0 374 +#define SRST_SPI0 375 +#define SRST_P_SPI1 376 +#define SRST_SPI1 377 +#define SRST_P_SPI2 378 +#define SRST_SPI2 379 +#define SRST_P_SPI3 380 +#define SRST_SPI3 381 + +/* cru_softrst_con24 */ +#define SRST_P_SARADC 384 +#define SRST_P_TSADC 385 +#define SRST_TSADC 386 +#define SRST_P_TIMER 387 +#define SRST_TIMER0 388 +#define SRST_TIMER1 389 +#define SRST_TIMER2 390 +#define SRST_TIMER3 391 +#define SRST_TIMER4 392 +#define SRST_TIMER5 393 +#define SRST_P_UART1 394 +#define SRST_S_UART1 395 + +/* cru_softrst_con25 */ +#define SRST_P_UART2 400 +#define SRST_S_UART2 401 +#define SRST_P_UART3 402 +#define SRST_S_UART3 403 +#define SRST_P_UART4 404 +#define SRST_S_UART4 405 +#define SRST_P_UART5 406 +#define SRST_S_UART5 407 +#define SRST_P_UART6 408 +#define SRST_S_UART6 409 +#define SRST_P_UART7 410 +#define SRST_S_UART7 411 +#define SRST_P_UART8 412 +#define SRST_S_UART8 413 +#define SRST_P_UART9 414 +#define SRST_S_UART9 415 + +/* cru_softrst_con26 */ +#define SRST_P_GRF 416 +#define SRST_P_GRF_VCCIO12 417 +#define SRST_P_GRF_VCCIO34 418 +#define SRST_P_GRF_VCCIO567 419 +#define SRST_P_SCR 420 +#define SRST_P_WDT_NS 421 +#define SRST_T_WDT_NS 422 +#define SRST_P_DFT2APB 423 +#define SRST_A_MCU 426 +#define SRST_P_INTMUX 427 +#define SRST_P_MAILBOX 428 + +/* cru_softrst_con27 */ +#define SRST_A_TOP_HIGH_NIU 432 +#define SRST_A_TOP_LOW_NIU 433 +#define SRST_H_TOP_NIU 434 +#define SRST_P_TOP_NIU 435 +#define SRST_P_TOP_CRU 438 +#define SRST_P_DDRPHY 439 +#define SRST_DDRPHY 440 +#define SRST_P_MIPICSIPHY 442 +#define SRST_P_MIPIDSIPHY0 443 +#define SRST_P_MIPIDSIPHY1 444 +#define SRST_P_PCIE30PHY 445 +#define SRST_PCIE30PHY 446 +#define SRST_P_PCIE30PHY_GRF 447 + +/* cru_softrst_con28 */ +#define SRST_P_APB2ASB_LEFT 448 +#define SRST_P_APB2ASB_BOTTOM 449 +#define SRST_P_ASB2APB_LEFT 450 +#define SRST_P_ASB2APB_BOTTOM 451 +#define SRST_P_PIPEPHY0 452 +#define SRST_PIPEPHY0 453 +#define SRST_P_PIPEPHY1 454 +#define SRST_PIPEPHY1 455 +#define SRST_P_PIPEPHY2 456 +#define SRST_PIPEPHY2 457 +#define SRST_P_USB2PHY0_GRF 458 +#define SRST_P_USB2PHY1_GRF 459 +#define SRST_P_CPU_BOOST 460 +#define SRST_CPU_BOOST 461 +#define SRST_P_OTPPHY 462 +#define SRST_OTPPHY 463 + +/* cru_softrst_con29 */ +#define SRST_USB2PHY0_POR 464 +#define SRST_USB2PHY0_USB3OTG0 465 +#define SRST_USB2PHY0_USB3OTG1 466 +#define SRST_USB2PHY1_POR 467 +#define SRST_USB2PHY1_USB2HOST0 468 +#define SRST_USB2PHY1_USB2HOST1 469 +#define SRST_P_EDPPHY_GRF 470 +#define SRST_TSADCPHY 471 +#define SRST_GMAC0_DELAYLINE 472 +#define SRST_GMAC1_DELAYLINE 473 +#define SRST_OTPC_ARB 474 +#define SRST_P_PIPEPHY0_GRF 475 +#define SRST_P_PIPEPHY1_GRF 476 +#define SRST_P_PIPEPHY2_GRF 477 + +#endif -- 2.17.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/2] rockchip: rk3568: add device tree file 2021-05-26 8:46 ` [PATCH v2 1/2] rockchip: rk3568: add device tree file Elaine, Zhang @ 2021-06-08 7:09 ` Kever Yang 0 siblings, 0 replies; 10+ messages in thread From: Kever Yang @ 2021-06-08 7:09 UTC (permalink / raw) To: sjg, philipp.tomsich, lukma; +Cc: zhangqing, u-boot, chenjh 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 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 2/2] rockchip: rk3568: add clock driver 2021-05-26 8:46 [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver Elaine, Zhang 2021-05-26 8:46 ` [PATCH v2 1/2] rockchip: rk3568: add device tree file Elaine, Zhang @ 2021-05-26 8:46 ` Elaine, Zhang 2021-06-08 7:09 ` Kever Yang 2021-05-26 8:46 ` [PATCH v5 0/6] power: pmic: support more PMIC Elaine, Zhang 2021-05-26 8:46 ` [PATCH v5 1/6] dm: regulator: support regulator more state Elaine, Zhang 3 siblings, 1 reply; 10+ messages in thread From: Elaine, Zhang @ 2021-05-26 8:46 UTC (permalink / raw) To: sjg, philipp.tomsich, kever.yang, lukma; +Cc: zhangqing, u-boot, chenjh 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 +}; -- 2.17.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] rockchip: rk3568: add clock driver 2021-05-26 8:46 ` [PATCH v2 2/2] rockchip: rk3568: add clock driver Elaine, Zhang @ 2021-06-08 7:09 ` Kever Yang 0 siblings, 0 replies; 10+ messages in thread From: Kever Yang @ 2021-06-08 7:09 UTC (permalink / raw) To: sjg, lukma; +Cc: zhangqing, u-boot, chenjh 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: > + * 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 > +}; ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 0/6] power: pmic: support more PMIC 2021-05-26 8:46 [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver Elaine, Zhang 2021-05-26 8:46 ` [PATCH v2 1/2] rockchip: rk3568: add device tree file Elaine, Zhang 2021-05-26 8:46 ` [PATCH v2 2/2] rockchip: rk3568: add clock driver Elaine, Zhang @ 2021-05-26 8:46 ` Elaine, Zhang 2021-05-26 22:03 ` Jaehoon Chung 2021-05-26 8:46 ` [PATCH v5 1/6] dm: regulator: support regulator more state Elaine, Zhang 3 siblings, 1 reply; 10+ messages in thread From: Elaine, Zhang @ 2021-05-26 8:46 UTC (permalink / raw) To: sjg, philipp.tomsich, kever.yang, lukma; +Cc: zhangqing, u-boot, chenjh 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(-) -- 1.9.1 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v5 0/6] power: pmic: support more PMIC 2021-05-26 8:46 ` [PATCH v5 0/6] power: pmic: support more PMIC Elaine, Zhang @ 2021-05-26 22:03 ` Jaehoon Chung 0 siblings, 0 replies; 10+ messages in thread From: Jaehoon Chung @ 2021-05-26 22:03 UTC (permalink / raw) To: Elaine, Zhang, sjg, philipp.tomsich, kever.yang, lukma Cc: zhangqing, u-boot, chenjh 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(-) > ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v5 1/6] dm: regulator: support regulator more state 2021-05-26 8:46 [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver Elaine, Zhang ` (2 preceding siblings ...) 2021-05-26 8:46 ` [PATCH v5 0/6] power: pmic: support more PMIC Elaine, Zhang @ 2021-05-26 8:46 ` Elaine, Zhang 2021-05-26 22:18 ` Jaehoon Chung 3 siblings, 1 reply; 10+ messages in thread From: Elaine, Zhang @ 2021-05-26 8:46 UTC (permalink / raw) To: sjg, philipp.tomsich, kever.yang, lukma; +Cc: zhangqing, u-boot, chenjh 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 Yang<kever.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) { -- 1.9.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v5 1/6] dm: regulator: support regulator more state 2021-05-26 8:46 ` [PATCH v5 1/6] dm: regulator: support regulator more state Elaine, Zhang @ 2021-05-26 22:18 ` Jaehoon Chung 2021-05-27 1:42 ` zhangqing 0 siblings, 1 reply; 10+ messages in thread From: Jaehoon Chung @ 2021-05-26 22:18 UTC (permalink / raw) To: Elaine, Zhang, sjg, philipp.tomsich, kever.yang, lukma Cc: zhangqing, u-boot, chenjh 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 Yang<kever.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) > { > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Re: [PATCH v5 1/6] dm: regulator: support regulator more state 2021-05-26 22:18 ` Jaehoon Chung @ 2021-05-27 1:42 ` zhangqing 0 siblings, 0 replies; 10+ messages in thread From: zhangqing @ 2021-05-27 1:42 UTC (permalink / raw) To: Jaehoon Chung, Elaine, Zhang, sjg, philipp.tomsich, 杨凯, lukma Cc: u-boot, 陈健洪 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 Yang<kever.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) > { > ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-06-08 7:16 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-26 8:46 [PATCH v2 0/2] clk: rockchip: rk3568: add clock driver Elaine, Zhang 2021-05-26 8:46 ` [PATCH v2 1/2] rockchip: rk3568: add device tree file Elaine, Zhang 2021-06-08 7:09 ` Kever Yang 2021-05-26 8:46 ` [PATCH v2 2/2] rockchip: rk3568: add clock driver Elaine, Zhang 2021-06-08 7:09 ` Kever Yang 2021-05-26 8:46 ` [PATCH v5 0/6] power: pmic: support more PMIC Elaine, Zhang 2021-05-26 22:03 ` Jaehoon Chung 2021-05-26 8:46 ` [PATCH v5 1/6] dm: regulator: support regulator more state Elaine, Zhang 2021-05-26 22:18 ` Jaehoon Chung 2021-05-27 1:42 ` zhangqing
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.