1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2017 Broadcom 4 */ 5 6 #include <linux/err.h> 7 #include <linux/clk-provider.h> 8 #include <linux/of_device.h> 9 #include <linux/platform_device.h> 10 11 #include <dt-bindings/clock/bcm-sr.h> 12 #include "clk-iproc.h" 13 14 #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, } 15 16 #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \ 17 .pwr_shift = ps, .iso_shift = is } 18 19 #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, } 20 21 #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \ 22 .p_reset_shift = prs } 23 24 #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \ 25 .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \ 26 .ka_shift = kas, .ka_width = kaw } 27 28 #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo } 29 30 #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \ 31 .hold_shift = hs, .bypass_shift = bs } 32 33 34 static const struct iproc_pll_ctrl sr_genpll0 = { 35 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 36 IPROC_CLK_PLL_NEEDS_SW_CFG, 37 .aon = AON_VAL(0x0, 5, 1, 0), 38 .reset = RESET_VAL(0x0, 12, 11), 39 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), 40 .sw_ctrl = SW_CTRL_VAL(0x10, 31), 41 .ndiv_int = REG_VAL(0x10, 20, 10), 42 .ndiv_frac = REG_VAL(0x10, 0, 20), 43 .pdiv = REG_VAL(0x14, 0, 4), 44 .status = REG_VAL(0x30, 12, 1), 45 }; 46 47 static const struct iproc_clk_ctrl sr_genpll0_clk[] = { 48 [BCM_SR_GENPLL0_125M_CLK] = { 49 .channel = BCM_SR_GENPLL0_125M_CLK, 50 .flags = IPROC_CLK_AON, 51 .enable = ENABLE_VAL(0x4, 6, 0, 12), 52 .mdiv = REG_VAL(0x18, 0, 9), 53 }, 54 [BCM_SR_GENPLL0_SCR_CLK] = { 55 .channel = BCM_SR_GENPLL0_SCR_CLK, 56 .flags = IPROC_CLK_AON, 57 .enable = ENABLE_VAL(0x4, 7, 1, 13), 58 .mdiv = REG_VAL(0x18, 10, 9), 59 }, 60 [BCM_SR_GENPLL0_250M_CLK] = { 61 .channel = BCM_SR_GENPLL0_250M_CLK, 62 .flags = IPROC_CLK_AON, 63 .enable = ENABLE_VAL(0x4, 8, 2, 14), 64 .mdiv = REG_VAL(0x18, 20, 9), 65 }, 66 [BCM_SR_GENPLL0_PCIE_AXI_CLK] = { 67 .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK, 68 .flags = IPROC_CLK_AON, 69 .enable = ENABLE_VAL(0x4, 9, 3, 15), 70 .mdiv = REG_VAL(0x1c, 0, 9), 71 }, 72 [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = { 73 .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK, 74 .flags = IPROC_CLK_AON, 75 .enable = ENABLE_VAL(0x4, 10, 4, 16), 76 .mdiv = REG_VAL(0x1c, 10, 9), 77 }, 78 [BCM_SR_GENPLL0_PAXC_AXI_CLK] = { 79 .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK, 80 .flags = IPROC_CLK_AON, 81 .enable = ENABLE_VAL(0x4, 11, 5, 17), 82 .mdiv = REG_VAL(0x1c, 20, 9), 83 }, 84 }; 85 86 static int sr_genpll0_clk_init(struct platform_device *pdev) 87 { 88 iproc_pll_clk_setup(pdev->dev.of_node, 89 &sr_genpll0, NULL, 0, sr_genpll0_clk, 90 ARRAY_SIZE(sr_genpll0_clk)); 91 return 0; 92 } 93 94 static const struct iproc_pll_ctrl sr_genpll2 = { 95 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 96 IPROC_CLK_PLL_NEEDS_SW_CFG, 97 .aon = AON_VAL(0x0, 1, 13, 12), 98 .reset = RESET_VAL(0x0, 12, 11), 99 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), 100 .sw_ctrl = SW_CTRL_VAL(0x10, 31), 101 .ndiv_int = REG_VAL(0x10, 20, 10), 102 .ndiv_frac = REG_VAL(0x10, 0, 20), 103 .pdiv = REG_VAL(0x14, 0, 4), 104 .status = REG_VAL(0x30, 12, 1), 105 }; 106 107 static const struct iproc_clk_ctrl sr_genpll2_clk[] = { 108 [BCM_SR_GENPLL2_NIC_CLK] = { 109 .channel = BCM_SR_GENPLL2_NIC_CLK, 110 .flags = IPROC_CLK_AON, 111 .enable = ENABLE_VAL(0x4, 6, 0, 12), 112 .mdiv = REG_VAL(0x18, 0, 9), 113 }, 114 [BCM_SR_GENPLL2_TS_500_CLK] = { 115 .channel = BCM_SR_GENPLL2_TS_500_CLK, 116 .flags = IPROC_CLK_AON, 117 .enable = ENABLE_VAL(0x4, 7, 1, 13), 118 .mdiv = REG_VAL(0x18, 10, 9), 119 }, 120 [BCM_SR_GENPLL2_125_NITRO_CLK] = { 121 .channel = BCM_SR_GENPLL2_125_NITRO_CLK, 122 .flags = IPROC_CLK_AON, 123 .enable = ENABLE_VAL(0x4, 8, 2, 14), 124 .mdiv = REG_VAL(0x18, 20, 9), 125 }, 126 [BCM_SR_GENPLL2_CHIMP_CLK] = { 127 .channel = BCM_SR_GENPLL2_CHIMP_CLK, 128 .flags = IPROC_CLK_AON, 129 .enable = ENABLE_VAL(0x4, 9, 3, 15), 130 .mdiv = REG_VAL(0x1c, 0, 9), 131 }, 132 [BCM_SR_GENPLL2_NIC_FLASH_CLK] = { 133 .channel = BCM_SR_GENPLL2_NIC_FLASH_CLK, 134 .flags = IPROC_CLK_AON, 135 .enable = ENABLE_VAL(0x4, 10, 4, 16), 136 .mdiv = REG_VAL(0x1c, 10, 9), 137 }, 138 [BCM_SR_GENPLL2_FS4_CLK] = { 139 .channel = BCM_SR_GENPLL2_FS4_CLK, 140 .enable = ENABLE_VAL(0x4, 11, 5, 17), 141 .mdiv = REG_VAL(0x1c, 20, 9), 142 }, 143 }; 144 145 static int sr_genpll2_clk_init(struct platform_device *pdev) 146 { 147 iproc_pll_clk_setup(pdev->dev.of_node, 148 &sr_genpll2, NULL, 0, sr_genpll2_clk, 149 ARRAY_SIZE(sr_genpll2_clk)); 150 return 0; 151 } 152 153 static const struct iproc_pll_ctrl sr_genpll3 = { 154 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 155 IPROC_CLK_PLL_NEEDS_SW_CFG, 156 .aon = AON_VAL(0x0, 1, 19, 18), 157 .reset = RESET_VAL(0x0, 12, 11), 158 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), 159 .sw_ctrl = SW_CTRL_VAL(0x10, 31), 160 .ndiv_int = REG_VAL(0x10, 20, 10), 161 .ndiv_frac = REG_VAL(0x10, 0, 20), 162 .pdiv = REG_VAL(0x14, 0, 4), 163 .status = REG_VAL(0x30, 12, 1), 164 }; 165 166 static const struct iproc_clk_ctrl sr_genpll3_clk[] = { 167 [BCM_SR_GENPLL3_HSLS_CLK] = { 168 .channel = BCM_SR_GENPLL3_HSLS_CLK, 169 .flags = IPROC_CLK_AON, 170 .enable = ENABLE_VAL(0x4, 6, 0, 12), 171 .mdiv = REG_VAL(0x18, 0, 9), 172 }, 173 [BCM_SR_GENPLL3_SDIO_CLK] = { 174 .channel = BCM_SR_GENPLL3_SDIO_CLK, 175 .flags = IPROC_CLK_AON, 176 .enable = ENABLE_VAL(0x4, 7, 1, 13), 177 .mdiv = REG_VAL(0x18, 10, 9), 178 }, 179 }; 180 181 static void sr_genpll3_clk_init(struct device_node *node) 182 { 183 iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk, 184 ARRAY_SIZE(sr_genpll3_clk)); 185 } 186 CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init); 187 188 static const struct iproc_pll_ctrl sr_genpll4 = { 189 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 190 IPROC_CLK_PLL_NEEDS_SW_CFG, 191 .aon = AON_VAL(0x0, 1, 25, 24), 192 .reset = RESET_VAL(0x0, 12, 11), 193 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), 194 .sw_ctrl = SW_CTRL_VAL(0x10, 31), 195 .ndiv_int = REG_VAL(0x10, 20, 10), 196 .ndiv_frac = REG_VAL(0x10, 0, 20), 197 .pdiv = REG_VAL(0x14, 0, 4), 198 .status = REG_VAL(0x30, 12, 1), 199 }; 200 201 static const struct iproc_clk_ctrl sr_genpll4_clk[] = { 202 [BCM_SR_GENPLL4_CCN_CLK] = { 203 .channel = BCM_SR_GENPLL4_CCN_CLK, 204 .flags = IPROC_CLK_AON, 205 .enable = ENABLE_VAL(0x4, 6, 0, 12), 206 .mdiv = REG_VAL(0x18, 0, 9), 207 }, 208 [BCM_SR_GENPLL4_TPIU_PLL_CLK] = { 209 .channel = BCM_SR_GENPLL4_TPIU_PLL_CLK, 210 .flags = IPROC_CLK_AON, 211 .enable = ENABLE_VAL(0x4, 7, 1, 13), 212 .mdiv = REG_VAL(0x18, 10, 9), 213 }, 214 [BCM_SR_GENPLL4_NOC_CLK] = { 215 .channel = BCM_SR_GENPLL4_NOC_CLK, 216 .flags = IPROC_CLK_AON, 217 .enable = ENABLE_VAL(0x4, 8, 2, 14), 218 .mdiv = REG_VAL(0x18, 20, 9), 219 }, 220 [BCM_SR_GENPLL4_CHCLK_FS4_CLK] = { 221 .channel = BCM_SR_GENPLL4_CHCLK_FS4_CLK, 222 .flags = IPROC_CLK_AON, 223 .enable = ENABLE_VAL(0x4, 9, 3, 15), 224 .mdiv = REG_VAL(0x1c, 0, 9), 225 }, 226 [BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK] = { 227 .channel = BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK, 228 .flags = IPROC_CLK_AON, 229 .enable = ENABLE_VAL(0x4, 10, 4, 16), 230 .mdiv = REG_VAL(0x1c, 10, 9), 231 }, 232 }; 233 234 static int sr_genpll4_clk_init(struct platform_device *pdev) 235 { 236 iproc_pll_clk_setup(pdev->dev.of_node, 237 &sr_genpll4, NULL, 0, sr_genpll4_clk, 238 ARRAY_SIZE(sr_genpll4_clk)); 239 return 0; 240 } 241 242 static const struct iproc_pll_ctrl sr_genpll5 = { 243 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC | 244 IPROC_CLK_PLL_NEEDS_SW_CFG, 245 .aon = AON_VAL(0x0, 1, 1, 0), 246 .reset = RESET_VAL(0x0, 12, 11), 247 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3), 248 .sw_ctrl = SW_CTRL_VAL(0x10, 31), 249 .ndiv_int = REG_VAL(0x10, 20, 10), 250 .ndiv_frac = REG_VAL(0x10, 0, 20), 251 .pdiv = REG_VAL(0x14, 0, 4), 252 .status = REG_VAL(0x30, 12, 1), 253 }; 254 255 static const struct iproc_clk_ctrl sr_genpll5_clk[] = { 256 [BCM_SR_GENPLL5_FS4_HF_CLK] = { 257 .channel = BCM_SR_GENPLL5_FS4_HF_CLK, 258 .enable = ENABLE_VAL(0x4, 6, 0, 12), 259 .mdiv = REG_VAL(0x18, 0, 9), 260 }, 261 [BCM_SR_GENPLL5_CRYPTO_AE_CLK] = { 262 .channel = BCM_SR_GENPLL5_CRYPTO_AE_CLK, 263 .enable = ENABLE_VAL(0x4, 7, 1, 12), 264 .mdiv = REG_VAL(0x18, 10, 9), 265 }, 266 [BCM_SR_GENPLL5_RAID_AE_CLK] = { 267 .channel = BCM_SR_GENPLL5_RAID_AE_CLK, 268 .enable = ENABLE_VAL(0x4, 8, 2, 14), 269 .mdiv = REG_VAL(0x18, 20, 9), 270 }, 271 }; 272 273 static int sr_genpll5_clk_init(struct platform_device *pdev) 274 { 275 iproc_pll_clk_setup(pdev->dev.of_node, 276 &sr_genpll5, NULL, 0, sr_genpll5_clk, 277 ARRAY_SIZE(sr_genpll5_clk)); 278 return 0; 279 } 280 281 static const struct iproc_pll_ctrl sr_lcpll0 = { 282 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, 283 .aon = AON_VAL(0x0, 2, 19, 18), 284 .reset = RESET_VAL(0x0, 31, 30), 285 .sw_ctrl = SW_CTRL_VAL(0x4, 31), 286 .ndiv_int = REG_VAL(0x4, 16, 10), 287 .pdiv = REG_VAL(0x4, 26, 4), 288 .status = REG_VAL(0x38, 12, 1), 289 }; 290 291 static const struct iproc_clk_ctrl sr_lcpll0_clk[] = { 292 [BCM_SR_LCPLL0_SATA_REFP_CLK] = { 293 .channel = BCM_SR_LCPLL0_SATA_REFP_CLK, 294 .flags = IPROC_CLK_AON, 295 .enable = ENABLE_VAL(0x0, 7, 1, 13), 296 .mdiv = REG_VAL(0x14, 0, 9), 297 }, 298 [BCM_SR_LCPLL0_SATA_REFN_CLK] = { 299 .channel = BCM_SR_LCPLL0_SATA_REFN_CLK, 300 .flags = IPROC_CLK_AON, 301 .enable = ENABLE_VAL(0x0, 8, 2, 14), 302 .mdiv = REG_VAL(0x14, 10, 9), 303 }, 304 [BCM_SR_LCPLL0_SATA_350_CLK] = { 305 .channel = BCM_SR_LCPLL0_SATA_350_CLK, 306 .flags = IPROC_CLK_AON, 307 .enable = ENABLE_VAL(0x0, 9, 3, 15), 308 .mdiv = REG_VAL(0x14, 20, 9), 309 }, 310 [BCM_SR_LCPLL0_SATA_500_CLK] = { 311 .channel = BCM_SR_LCPLL0_SATA_500_CLK, 312 .flags = IPROC_CLK_AON, 313 .enable = ENABLE_VAL(0x0, 10, 4, 16), 314 .mdiv = REG_VAL(0x18, 0, 9), 315 }, 316 }; 317 318 static int sr_lcpll0_clk_init(struct platform_device *pdev) 319 { 320 iproc_pll_clk_setup(pdev->dev.of_node, 321 &sr_lcpll0, NULL, 0, sr_lcpll0_clk, 322 ARRAY_SIZE(sr_lcpll0_clk)); 323 return 0; 324 } 325 326 static const struct iproc_pll_ctrl sr_lcpll1 = { 327 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, 328 .aon = AON_VAL(0x0, 2, 22, 21), 329 .reset = RESET_VAL(0x0, 31, 30), 330 .sw_ctrl = SW_CTRL_VAL(0x4, 31), 331 .ndiv_int = REG_VAL(0x4, 16, 10), 332 .pdiv = REG_VAL(0x4, 26, 4), 333 .status = REG_VAL(0x38, 12, 1), 334 }; 335 336 static const struct iproc_clk_ctrl sr_lcpll1_clk[] = { 337 [BCM_SR_LCPLL1_WAN_CLK] = { 338 .channel = BCM_SR_LCPLL1_WAN_CLK, 339 .flags = IPROC_CLK_AON, 340 .enable = ENABLE_VAL(0x0, 7, 1, 13), 341 .mdiv = REG_VAL(0x14, 0, 9), 342 }, 343 [BCM_SR_LCPLL1_USB_REF_CLK] = { 344 .channel = BCM_SR_LCPLL1_USB_REF_CLK, 345 .flags = IPROC_CLK_AON, 346 .enable = ENABLE_VAL(0x0, 8, 2, 14), 347 .mdiv = REG_VAL(0x14, 10, 9), 348 }, 349 [BCM_SR_LCPLL1_CRMU_TS_CLK] = { 350 .channel = BCM_SR_LCPLL1_CRMU_TS_CLK, 351 .flags = IPROC_CLK_AON, 352 .enable = ENABLE_VAL(0x0, 9, 3, 15), 353 .mdiv = REG_VAL(0x14, 20, 9), 354 }, 355 }; 356 357 static int sr_lcpll1_clk_init(struct platform_device *pdev) 358 { 359 iproc_pll_clk_setup(pdev->dev.of_node, 360 &sr_lcpll1, NULL, 0, sr_lcpll1_clk, 361 ARRAY_SIZE(sr_lcpll1_clk)); 362 return 0; 363 } 364 365 static const struct iproc_pll_ctrl sr_lcpll_pcie = { 366 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG, 367 .aon = AON_VAL(0x0, 2, 25, 24), 368 .reset = RESET_VAL(0x0, 31, 30), 369 .sw_ctrl = SW_CTRL_VAL(0x4, 31), 370 .ndiv_int = REG_VAL(0x4, 16, 10), 371 .pdiv = REG_VAL(0x4, 26, 4), 372 .status = REG_VAL(0x38, 12, 1), 373 }; 374 375 static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = { 376 [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = { 377 .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK, 378 .flags = IPROC_CLK_AON, 379 .enable = ENABLE_VAL(0x0, 7, 1, 13), 380 .mdiv = REG_VAL(0x14, 0, 9), 381 }, 382 }; 383 384 static int sr_lcpll_pcie_clk_init(struct platform_device *pdev) 385 { 386 iproc_pll_clk_setup(pdev->dev.of_node, 387 &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk, 388 ARRAY_SIZE(sr_lcpll_pcie_clk)); 389 return 0; 390 } 391 392 static const struct of_device_id sr_clk_dt_ids[] = { 393 { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init }, 394 { .compatible = "brcm,sr-genpll2", .data = sr_genpll2_clk_init }, 395 { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init }, 396 { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init }, 397 { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init }, 398 { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init }, 399 { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init }, 400 { /* sentinel */ } 401 }; 402 403 static int sr_clk_probe(struct platform_device *pdev) 404 { 405 int (*probe_func)(struct platform_device *); 406 407 probe_func = of_device_get_match_data(&pdev->dev); 408 if (!probe_func) 409 return -ENODEV; 410 411 return probe_func(pdev); 412 } 413 414 static struct platform_driver sr_clk_driver = { 415 .driver = { 416 .name = "sr-clk", 417 .of_match_table = sr_clk_dt_ids, 418 }, 419 .probe = sr_clk_probe, 420 }; 421 builtin_platform_driver(sr_clk_driver); 422