Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2017 Broadcom
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     { /* sentinel */ }
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);