0001
0002
0003
0004
0005
0006 #include <linux/err.h>
0007 #include <linux/clk-provider.h>
0008 #include <linux/of_device.h>
0009 #include <linux/platform_device.h>
0010
0011 #include <dt-bindings/clock/bcm-sr.h>
0012 #include "clk-iproc.h"
0013
0014 #define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
0015
0016 #define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
0017 .pwr_shift = ps, .iso_shift = is }
0018
0019 #define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
0020
0021 #define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
0022 .p_reset_shift = prs }
0023
0024 #define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
0025 .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \
0026 .ka_shift = kas, .ka_width = kaw }
0027
0028 #define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
0029
0030 #define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
0031 .hold_shift = hs, .bypass_shift = bs }
0032
0033
0034 static const struct iproc_pll_ctrl sr_genpll0 = {
0035 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
0036 IPROC_CLK_PLL_NEEDS_SW_CFG,
0037 .aon = AON_VAL(0x0, 5, 1, 0),
0038 .reset = RESET_VAL(0x0, 12, 11),
0039 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
0040 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
0041 .ndiv_int = REG_VAL(0x10, 20, 10),
0042 .ndiv_frac = REG_VAL(0x10, 0, 20),
0043 .pdiv = REG_VAL(0x14, 0, 4),
0044 .status = REG_VAL(0x30, 12, 1),
0045 };
0046
0047 static const struct iproc_clk_ctrl sr_genpll0_clk[] = {
0048 [BCM_SR_GENPLL0_125M_CLK] = {
0049 .channel = BCM_SR_GENPLL0_125M_CLK,
0050 .flags = IPROC_CLK_AON,
0051 .enable = ENABLE_VAL(0x4, 6, 0, 12),
0052 .mdiv = REG_VAL(0x18, 0, 9),
0053 },
0054 [BCM_SR_GENPLL0_SCR_CLK] = {
0055 .channel = BCM_SR_GENPLL0_SCR_CLK,
0056 .flags = IPROC_CLK_AON,
0057 .enable = ENABLE_VAL(0x4, 7, 1, 13),
0058 .mdiv = REG_VAL(0x18, 10, 9),
0059 },
0060 [BCM_SR_GENPLL0_250M_CLK] = {
0061 .channel = BCM_SR_GENPLL0_250M_CLK,
0062 .flags = IPROC_CLK_AON,
0063 .enable = ENABLE_VAL(0x4, 8, 2, 14),
0064 .mdiv = REG_VAL(0x18, 20, 9),
0065 },
0066 [BCM_SR_GENPLL0_PCIE_AXI_CLK] = {
0067 .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK,
0068 .flags = IPROC_CLK_AON,
0069 .enable = ENABLE_VAL(0x4, 9, 3, 15),
0070 .mdiv = REG_VAL(0x1c, 0, 9),
0071 },
0072 [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = {
0073 .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK,
0074 .flags = IPROC_CLK_AON,
0075 .enable = ENABLE_VAL(0x4, 10, 4, 16),
0076 .mdiv = REG_VAL(0x1c, 10, 9),
0077 },
0078 [BCM_SR_GENPLL0_PAXC_AXI_CLK] = {
0079 .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK,
0080 .flags = IPROC_CLK_AON,
0081 .enable = ENABLE_VAL(0x4, 11, 5, 17),
0082 .mdiv = REG_VAL(0x1c, 20, 9),
0083 },
0084 };
0085
0086 static int sr_genpll0_clk_init(struct platform_device *pdev)
0087 {
0088 iproc_pll_clk_setup(pdev->dev.of_node,
0089 &sr_genpll0, NULL, 0, sr_genpll0_clk,
0090 ARRAY_SIZE(sr_genpll0_clk));
0091 return 0;
0092 }
0093
0094 static const struct iproc_pll_ctrl sr_genpll2 = {
0095 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
0096 IPROC_CLK_PLL_NEEDS_SW_CFG,
0097 .aon = AON_VAL(0x0, 1, 13, 12),
0098 .reset = RESET_VAL(0x0, 12, 11),
0099 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
0100 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
0101 .ndiv_int = REG_VAL(0x10, 20, 10),
0102 .ndiv_frac = REG_VAL(0x10, 0, 20),
0103 .pdiv = REG_VAL(0x14, 0, 4),
0104 .status = REG_VAL(0x30, 12, 1),
0105 };
0106
0107 static const struct iproc_clk_ctrl sr_genpll2_clk[] = {
0108 [BCM_SR_GENPLL2_NIC_CLK] = {
0109 .channel = BCM_SR_GENPLL2_NIC_CLK,
0110 .flags = IPROC_CLK_AON,
0111 .enable = ENABLE_VAL(0x4, 6, 0, 12),
0112 .mdiv = REG_VAL(0x18, 0, 9),
0113 },
0114 [BCM_SR_GENPLL2_TS_500_CLK] = {
0115 .channel = BCM_SR_GENPLL2_TS_500_CLK,
0116 .flags = IPROC_CLK_AON,
0117 .enable = ENABLE_VAL(0x4, 7, 1, 13),
0118 .mdiv = REG_VAL(0x18, 10, 9),
0119 },
0120 [BCM_SR_GENPLL2_125_NITRO_CLK] = {
0121 .channel = BCM_SR_GENPLL2_125_NITRO_CLK,
0122 .flags = IPROC_CLK_AON,
0123 .enable = ENABLE_VAL(0x4, 8, 2, 14),
0124 .mdiv = REG_VAL(0x18, 20, 9),
0125 },
0126 [BCM_SR_GENPLL2_CHIMP_CLK] = {
0127 .channel = BCM_SR_GENPLL2_CHIMP_CLK,
0128 .flags = IPROC_CLK_AON,
0129 .enable = ENABLE_VAL(0x4, 9, 3, 15),
0130 .mdiv = REG_VAL(0x1c, 0, 9),
0131 },
0132 [BCM_SR_GENPLL2_NIC_FLASH_CLK] = {
0133 .channel = BCM_SR_GENPLL2_NIC_FLASH_CLK,
0134 .flags = IPROC_CLK_AON,
0135 .enable = ENABLE_VAL(0x4, 10, 4, 16),
0136 .mdiv = REG_VAL(0x1c, 10, 9),
0137 },
0138 [BCM_SR_GENPLL2_FS4_CLK] = {
0139 .channel = BCM_SR_GENPLL2_FS4_CLK,
0140 .enable = ENABLE_VAL(0x4, 11, 5, 17),
0141 .mdiv = REG_VAL(0x1c, 20, 9),
0142 },
0143 };
0144
0145 static int sr_genpll2_clk_init(struct platform_device *pdev)
0146 {
0147 iproc_pll_clk_setup(pdev->dev.of_node,
0148 &sr_genpll2, NULL, 0, sr_genpll2_clk,
0149 ARRAY_SIZE(sr_genpll2_clk));
0150 return 0;
0151 }
0152
0153 static const struct iproc_pll_ctrl sr_genpll3 = {
0154 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
0155 IPROC_CLK_PLL_NEEDS_SW_CFG,
0156 .aon = AON_VAL(0x0, 1, 19, 18),
0157 .reset = RESET_VAL(0x0, 12, 11),
0158 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
0159 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
0160 .ndiv_int = REG_VAL(0x10, 20, 10),
0161 .ndiv_frac = REG_VAL(0x10, 0, 20),
0162 .pdiv = REG_VAL(0x14, 0, 4),
0163 .status = REG_VAL(0x30, 12, 1),
0164 };
0165
0166 static const struct iproc_clk_ctrl sr_genpll3_clk[] = {
0167 [BCM_SR_GENPLL3_HSLS_CLK] = {
0168 .channel = BCM_SR_GENPLL3_HSLS_CLK,
0169 .flags = IPROC_CLK_AON,
0170 .enable = ENABLE_VAL(0x4, 6, 0, 12),
0171 .mdiv = REG_VAL(0x18, 0, 9),
0172 },
0173 [BCM_SR_GENPLL3_SDIO_CLK] = {
0174 .channel = BCM_SR_GENPLL3_SDIO_CLK,
0175 .flags = IPROC_CLK_AON,
0176 .enable = ENABLE_VAL(0x4, 7, 1, 13),
0177 .mdiv = REG_VAL(0x18, 10, 9),
0178 },
0179 };
0180
0181 static void sr_genpll3_clk_init(struct device_node *node)
0182 {
0183 iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk,
0184 ARRAY_SIZE(sr_genpll3_clk));
0185 }
0186 CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init);
0187
0188 static const struct iproc_pll_ctrl sr_genpll4 = {
0189 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
0190 IPROC_CLK_PLL_NEEDS_SW_CFG,
0191 .aon = AON_VAL(0x0, 1, 25, 24),
0192 .reset = RESET_VAL(0x0, 12, 11),
0193 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
0194 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
0195 .ndiv_int = REG_VAL(0x10, 20, 10),
0196 .ndiv_frac = REG_VAL(0x10, 0, 20),
0197 .pdiv = REG_VAL(0x14, 0, 4),
0198 .status = REG_VAL(0x30, 12, 1),
0199 };
0200
0201 static const struct iproc_clk_ctrl sr_genpll4_clk[] = {
0202 [BCM_SR_GENPLL4_CCN_CLK] = {
0203 .channel = BCM_SR_GENPLL4_CCN_CLK,
0204 .flags = IPROC_CLK_AON,
0205 .enable = ENABLE_VAL(0x4, 6, 0, 12),
0206 .mdiv = REG_VAL(0x18, 0, 9),
0207 },
0208 [BCM_SR_GENPLL4_TPIU_PLL_CLK] = {
0209 .channel = BCM_SR_GENPLL4_TPIU_PLL_CLK,
0210 .flags = IPROC_CLK_AON,
0211 .enable = ENABLE_VAL(0x4, 7, 1, 13),
0212 .mdiv = REG_VAL(0x18, 10, 9),
0213 },
0214 [BCM_SR_GENPLL4_NOC_CLK] = {
0215 .channel = BCM_SR_GENPLL4_NOC_CLK,
0216 .flags = IPROC_CLK_AON,
0217 .enable = ENABLE_VAL(0x4, 8, 2, 14),
0218 .mdiv = REG_VAL(0x18, 20, 9),
0219 },
0220 [BCM_SR_GENPLL4_CHCLK_FS4_CLK] = {
0221 .channel = BCM_SR_GENPLL4_CHCLK_FS4_CLK,
0222 .flags = IPROC_CLK_AON,
0223 .enable = ENABLE_VAL(0x4, 9, 3, 15),
0224 .mdiv = REG_VAL(0x1c, 0, 9),
0225 },
0226 [BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK] = {
0227 .channel = BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK,
0228 .flags = IPROC_CLK_AON,
0229 .enable = ENABLE_VAL(0x4, 10, 4, 16),
0230 .mdiv = REG_VAL(0x1c, 10, 9),
0231 },
0232 };
0233
0234 static int sr_genpll4_clk_init(struct platform_device *pdev)
0235 {
0236 iproc_pll_clk_setup(pdev->dev.of_node,
0237 &sr_genpll4, NULL, 0, sr_genpll4_clk,
0238 ARRAY_SIZE(sr_genpll4_clk));
0239 return 0;
0240 }
0241
0242 static const struct iproc_pll_ctrl sr_genpll5 = {
0243 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
0244 IPROC_CLK_PLL_NEEDS_SW_CFG,
0245 .aon = AON_VAL(0x0, 1, 1, 0),
0246 .reset = RESET_VAL(0x0, 12, 11),
0247 .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
0248 .sw_ctrl = SW_CTRL_VAL(0x10, 31),
0249 .ndiv_int = REG_VAL(0x10, 20, 10),
0250 .ndiv_frac = REG_VAL(0x10, 0, 20),
0251 .pdiv = REG_VAL(0x14, 0, 4),
0252 .status = REG_VAL(0x30, 12, 1),
0253 };
0254
0255 static const struct iproc_clk_ctrl sr_genpll5_clk[] = {
0256 [BCM_SR_GENPLL5_FS4_HF_CLK] = {
0257 .channel = BCM_SR_GENPLL5_FS4_HF_CLK,
0258 .enable = ENABLE_VAL(0x4, 6, 0, 12),
0259 .mdiv = REG_VAL(0x18, 0, 9),
0260 },
0261 [BCM_SR_GENPLL5_CRYPTO_AE_CLK] = {
0262 .channel = BCM_SR_GENPLL5_CRYPTO_AE_CLK,
0263 .enable = ENABLE_VAL(0x4, 7, 1, 12),
0264 .mdiv = REG_VAL(0x18, 10, 9),
0265 },
0266 [BCM_SR_GENPLL5_RAID_AE_CLK] = {
0267 .channel = BCM_SR_GENPLL5_RAID_AE_CLK,
0268 .enable = ENABLE_VAL(0x4, 8, 2, 14),
0269 .mdiv = REG_VAL(0x18, 20, 9),
0270 },
0271 };
0272
0273 static int sr_genpll5_clk_init(struct platform_device *pdev)
0274 {
0275 iproc_pll_clk_setup(pdev->dev.of_node,
0276 &sr_genpll5, NULL, 0, sr_genpll5_clk,
0277 ARRAY_SIZE(sr_genpll5_clk));
0278 return 0;
0279 }
0280
0281 static const struct iproc_pll_ctrl sr_lcpll0 = {
0282 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
0283 .aon = AON_VAL(0x0, 2, 19, 18),
0284 .reset = RESET_VAL(0x0, 31, 30),
0285 .sw_ctrl = SW_CTRL_VAL(0x4, 31),
0286 .ndiv_int = REG_VAL(0x4, 16, 10),
0287 .pdiv = REG_VAL(0x4, 26, 4),
0288 .status = REG_VAL(0x38, 12, 1),
0289 };
0290
0291 static const struct iproc_clk_ctrl sr_lcpll0_clk[] = {
0292 [BCM_SR_LCPLL0_SATA_REFP_CLK] = {
0293 .channel = BCM_SR_LCPLL0_SATA_REFP_CLK,
0294 .flags = IPROC_CLK_AON,
0295 .enable = ENABLE_VAL(0x0, 7, 1, 13),
0296 .mdiv = REG_VAL(0x14, 0, 9),
0297 },
0298 [BCM_SR_LCPLL0_SATA_REFN_CLK] = {
0299 .channel = BCM_SR_LCPLL0_SATA_REFN_CLK,
0300 .flags = IPROC_CLK_AON,
0301 .enable = ENABLE_VAL(0x0, 8, 2, 14),
0302 .mdiv = REG_VAL(0x14, 10, 9),
0303 },
0304 [BCM_SR_LCPLL0_SATA_350_CLK] = {
0305 .channel = BCM_SR_LCPLL0_SATA_350_CLK,
0306 .flags = IPROC_CLK_AON,
0307 .enable = ENABLE_VAL(0x0, 9, 3, 15),
0308 .mdiv = REG_VAL(0x14, 20, 9),
0309 },
0310 [BCM_SR_LCPLL0_SATA_500_CLK] = {
0311 .channel = BCM_SR_LCPLL0_SATA_500_CLK,
0312 .flags = IPROC_CLK_AON,
0313 .enable = ENABLE_VAL(0x0, 10, 4, 16),
0314 .mdiv = REG_VAL(0x18, 0, 9),
0315 },
0316 };
0317
0318 static int sr_lcpll0_clk_init(struct platform_device *pdev)
0319 {
0320 iproc_pll_clk_setup(pdev->dev.of_node,
0321 &sr_lcpll0, NULL, 0, sr_lcpll0_clk,
0322 ARRAY_SIZE(sr_lcpll0_clk));
0323 return 0;
0324 }
0325
0326 static const struct iproc_pll_ctrl sr_lcpll1 = {
0327 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
0328 .aon = AON_VAL(0x0, 2, 22, 21),
0329 .reset = RESET_VAL(0x0, 31, 30),
0330 .sw_ctrl = SW_CTRL_VAL(0x4, 31),
0331 .ndiv_int = REG_VAL(0x4, 16, 10),
0332 .pdiv = REG_VAL(0x4, 26, 4),
0333 .status = REG_VAL(0x38, 12, 1),
0334 };
0335
0336 static const struct iproc_clk_ctrl sr_lcpll1_clk[] = {
0337 [BCM_SR_LCPLL1_WAN_CLK] = {
0338 .channel = BCM_SR_LCPLL1_WAN_CLK,
0339 .flags = IPROC_CLK_AON,
0340 .enable = ENABLE_VAL(0x0, 7, 1, 13),
0341 .mdiv = REG_VAL(0x14, 0, 9),
0342 },
0343 [BCM_SR_LCPLL1_USB_REF_CLK] = {
0344 .channel = BCM_SR_LCPLL1_USB_REF_CLK,
0345 .flags = IPROC_CLK_AON,
0346 .enable = ENABLE_VAL(0x0, 8, 2, 14),
0347 .mdiv = REG_VAL(0x14, 10, 9),
0348 },
0349 [BCM_SR_LCPLL1_CRMU_TS_CLK] = {
0350 .channel = BCM_SR_LCPLL1_CRMU_TS_CLK,
0351 .flags = IPROC_CLK_AON,
0352 .enable = ENABLE_VAL(0x0, 9, 3, 15),
0353 .mdiv = REG_VAL(0x14, 20, 9),
0354 },
0355 };
0356
0357 static int sr_lcpll1_clk_init(struct platform_device *pdev)
0358 {
0359 iproc_pll_clk_setup(pdev->dev.of_node,
0360 &sr_lcpll1, NULL, 0, sr_lcpll1_clk,
0361 ARRAY_SIZE(sr_lcpll1_clk));
0362 return 0;
0363 }
0364
0365 static const struct iproc_pll_ctrl sr_lcpll_pcie = {
0366 .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
0367 .aon = AON_VAL(0x0, 2, 25, 24),
0368 .reset = RESET_VAL(0x0, 31, 30),
0369 .sw_ctrl = SW_CTRL_VAL(0x4, 31),
0370 .ndiv_int = REG_VAL(0x4, 16, 10),
0371 .pdiv = REG_VAL(0x4, 26, 4),
0372 .status = REG_VAL(0x38, 12, 1),
0373 };
0374
0375 static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = {
0376 [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = {
0377 .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK,
0378 .flags = IPROC_CLK_AON,
0379 .enable = ENABLE_VAL(0x0, 7, 1, 13),
0380 .mdiv = REG_VAL(0x14, 0, 9),
0381 },
0382 };
0383
0384 static int sr_lcpll_pcie_clk_init(struct platform_device *pdev)
0385 {
0386 iproc_pll_clk_setup(pdev->dev.of_node,
0387 &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk,
0388 ARRAY_SIZE(sr_lcpll_pcie_clk));
0389 return 0;
0390 }
0391
0392 static const struct of_device_id sr_clk_dt_ids[] = {
0393 { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init },
0394 { .compatible = "brcm,sr-genpll2", .data = sr_genpll2_clk_init },
0395 { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init },
0396 { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init },
0397 { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init },
0398 { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init },
0399 { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init },
0400 { }
0401 };
0402
0403 static int sr_clk_probe(struct platform_device *pdev)
0404 {
0405 int (*probe_func)(struct platform_device *);
0406
0407 probe_func = of_device_get_match_data(&pdev->dev);
0408 if (!probe_func)
0409 return -ENODEV;
0410
0411 return probe_func(pdev);
0412 }
0413
0414 static struct platform_driver sr_clk_driver = {
0415 .driver = {
0416 .name = "sr-clk",
0417 .of_match_table = sr_clk_dt_ids,
0418 },
0419 .probe = sr_clk_probe,
0420 };
0421 builtin_platform_driver(sr_clk_driver);