* [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
* [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
* [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
* [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 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
* 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
* 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
* 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
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.