Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 
0003 #include <linux/delay.h>
0004 #include <linux/clk-provider.h>
0005 #include <linux/of.h>
0006 #include <linux/of_address.h>
0007 #include <linux/of_device.h>
0008 #include <linux/platform_device.h>
0009 #include <dt-bindings/clock/en7523-clk.h>
0010 
0011 #define REG_PCI_CONTROL         0x88
0012 #define   REG_PCI_CONTROL_PERSTOUT  BIT(29)
0013 #define   REG_PCI_CONTROL_PERSTOUT1 BIT(26)
0014 #define   REG_PCI_CONTROL_REFCLK_EN1    BIT(22)
0015 #define REG_GSW_CLK_DIV_SEL     0x1b4
0016 #define REG_EMI_CLK_DIV_SEL     0x1b8
0017 #define REG_BUS_CLK_DIV_SEL     0x1bc
0018 #define REG_SPI_CLK_DIV_SEL     0x1c4
0019 #define REG_SPI_CLK_FREQ_SEL        0x1c8
0020 #define REG_NPU_CLK_DIV_SEL     0x1fc
0021 #define REG_CRYPTO_CLKSRC       0x200
0022 #define REG_RESET_CONTROL       0x834
0023 #define   REG_RESET_CONTROL_PCIEHB  BIT(29)
0024 #define   REG_RESET_CONTROL_PCIE1   BIT(27)
0025 #define   REG_RESET_CONTROL_PCIE2   BIT(26)
0026 
0027 struct en_clk_desc {
0028     int id;
0029     const char *name;
0030     u32 base_reg;
0031     u8 base_bits;
0032     u8 base_shift;
0033     union {
0034         const unsigned int *base_values;
0035         unsigned int base_value;
0036     };
0037     size_t n_base_values;
0038 
0039     u16 div_reg;
0040     u8 div_bits;
0041     u8 div_shift;
0042     u16 div_val0;
0043     u8 div_step;
0044 };
0045 
0046 struct en_clk_gate {
0047     void __iomem *base;
0048     struct clk_hw hw;
0049 };
0050 
0051 static const u32 gsw_base[] = { 400000000, 500000000 };
0052 static const u32 emi_base[] = { 333000000, 400000000 };
0053 static const u32 bus_base[] = { 500000000, 540000000 };
0054 static const u32 slic_base[] = { 100000000, 3125000 };
0055 static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
0056 
0057 static const struct en_clk_desc en7523_base_clks[] = {
0058     {
0059         .id = EN7523_CLK_GSW,
0060         .name = "gsw",
0061 
0062         .base_reg = REG_GSW_CLK_DIV_SEL,
0063         .base_bits = 1,
0064         .base_shift = 8,
0065         .base_values = gsw_base,
0066         .n_base_values = ARRAY_SIZE(gsw_base),
0067 
0068         .div_bits = 3,
0069         .div_shift = 0,
0070         .div_step = 1,
0071     }, {
0072         .id = EN7523_CLK_EMI,
0073         .name = "emi",
0074 
0075         .base_reg = REG_EMI_CLK_DIV_SEL,
0076         .base_bits = 1,
0077         .base_shift = 8,
0078         .base_values = emi_base,
0079         .n_base_values = ARRAY_SIZE(emi_base),
0080 
0081         .div_bits = 3,
0082         .div_shift = 0,
0083         .div_step = 1,
0084     }, {
0085         .id = EN7523_CLK_BUS,
0086         .name = "bus",
0087 
0088         .base_reg = REG_BUS_CLK_DIV_SEL,
0089         .base_bits = 1,
0090         .base_shift = 8,
0091         .base_values = bus_base,
0092         .n_base_values = ARRAY_SIZE(bus_base),
0093 
0094         .div_bits = 3,
0095         .div_shift = 0,
0096         .div_step = 1,
0097     }, {
0098         .id = EN7523_CLK_SLIC,
0099         .name = "slic",
0100 
0101         .base_reg = REG_SPI_CLK_FREQ_SEL,
0102         .base_bits = 1,
0103         .base_shift = 0,
0104         .base_values = slic_base,
0105         .n_base_values = ARRAY_SIZE(slic_base),
0106 
0107         .div_reg = REG_SPI_CLK_DIV_SEL,
0108         .div_bits = 5,
0109         .div_shift = 24,
0110         .div_val0 = 20,
0111         .div_step = 2,
0112     }, {
0113         .id = EN7523_CLK_SPI,
0114         .name = "spi",
0115 
0116         .base_reg = REG_SPI_CLK_DIV_SEL,
0117 
0118         .base_value = 400000000,
0119 
0120         .div_bits = 5,
0121         .div_shift = 8,
0122         .div_val0 = 40,
0123         .div_step = 2,
0124     }, {
0125         .id = EN7523_CLK_NPU,
0126         .name = "npu",
0127 
0128         .base_reg = REG_NPU_CLK_DIV_SEL,
0129         .base_bits = 2,
0130         .base_shift = 8,
0131         .base_values = npu_base,
0132         .n_base_values = ARRAY_SIZE(npu_base),
0133 
0134         .div_bits = 3,
0135         .div_shift = 0,
0136         .div_step = 1,
0137     }, {
0138         .id = EN7523_CLK_CRYPTO,
0139         .name = "crypto",
0140 
0141         .base_reg = REG_CRYPTO_CLKSRC,
0142         .base_bits = 1,
0143         .base_shift = 8,
0144         .base_values = emi_base,
0145         .n_base_values = ARRAY_SIZE(emi_base),
0146     }
0147 };
0148 
0149 static const struct of_device_id of_match_clk_en7523[] = {
0150     { .compatible = "airoha,en7523-scu", },
0151     { /* sentinel */ }
0152 };
0153 
0154 static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
0155 {
0156     const struct en_clk_desc *desc = &en7523_base_clks[i];
0157     u32 val;
0158 
0159     if (!desc->base_bits)
0160         return desc->base_value;
0161 
0162     val = readl(base + desc->base_reg);
0163     val >>= desc->base_shift;
0164     val &= (1 << desc->base_bits) - 1;
0165 
0166     if (val >= desc->n_base_values)
0167         return 0;
0168 
0169     return desc->base_values[val];
0170 }
0171 
0172 static u32 en7523_get_div(void __iomem *base, int i)
0173 {
0174     const struct en_clk_desc *desc = &en7523_base_clks[i];
0175     u32 reg, val;
0176 
0177     if (!desc->div_bits)
0178         return 1;
0179 
0180     reg = desc->div_reg ? desc->div_reg : desc->base_reg;
0181     val = readl(base + reg);
0182     val >>= desc->div_shift;
0183     val &= (1 << desc->div_bits) - 1;
0184 
0185     if (!val && desc->div_val0)
0186         return desc->div_val0;
0187 
0188     return (val + 1) * desc->div_step;
0189 }
0190 
0191 static int en7523_pci_is_enabled(struct clk_hw *hw)
0192 {
0193     struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
0194 
0195     return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
0196 }
0197 
0198 static int en7523_pci_prepare(struct clk_hw *hw)
0199 {
0200     struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
0201     void __iomem *np_base = cg->base;
0202     u32 val, mask;
0203 
0204     /* Need to pull device low before reset */
0205     val = readl(np_base + REG_PCI_CONTROL);
0206     val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
0207     writel(val, np_base + REG_PCI_CONTROL);
0208     usleep_range(1000, 2000);
0209 
0210     /* Enable PCIe port 1 */
0211     val |= REG_PCI_CONTROL_REFCLK_EN1;
0212     writel(val, np_base + REG_PCI_CONTROL);
0213     usleep_range(1000, 2000);
0214 
0215     /* Reset to default */
0216     val = readl(np_base + REG_RESET_CONTROL);
0217     mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
0218            REG_RESET_CONTROL_PCIEHB;
0219     writel(val & ~mask, np_base + REG_RESET_CONTROL);
0220     usleep_range(1000, 2000);
0221     writel(val | mask, np_base + REG_RESET_CONTROL);
0222     msleep(100);
0223     writel(val & ~mask, np_base + REG_RESET_CONTROL);
0224     usleep_range(5000, 10000);
0225 
0226     /* Release device */
0227     mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
0228     val = readl(np_base + REG_PCI_CONTROL);
0229     writel(val & ~mask, np_base + REG_PCI_CONTROL);
0230     usleep_range(1000, 2000);
0231     writel(val | mask, np_base + REG_PCI_CONTROL);
0232     msleep(250);
0233 
0234     return 0;
0235 }
0236 
0237 static void en7523_pci_unprepare(struct clk_hw *hw)
0238 {
0239     struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
0240     void __iomem *np_base = cg->base;
0241     u32 val;
0242 
0243     val = readl(np_base + REG_PCI_CONTROL);
0244     val &= ~REG_PCI_CONTROL_REFCLK_EN1;
0245     writel(val, np_base + REG_PCI_CONTROL);
0246 }
0247 
0248 static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
0249                            void __iomem *np_base)
0250 {
0251     static const struct clk_ops pcie_gate_ops = {
0252         .is_enabled = en7523_pci_is_enabled,
0253         .prepare = en7523_pci_prepare,
0254         .unprepare = en7523_pci_unprepare,
0255     };
0256     struct clk_init_data init = {
0257         .name = "pcie",
0258         .ops = &pcie_gate_ops,
0259     };
0260     struct en_clk_gate *cg;
0261 
0262     cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
0263     if (!cg)
0264         return NULL;
0265 
0266     cg->base = np_base;
0267     cg->hw.init = &init;
0268     en7523_pci_unprepare(&cg->hw);
0269 
0270     if (clk_hw_register(dev, &cg->hw))
0271         return NULL;
0272 
0273     return &cg->hw;
0274 }
0275 
0276 static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
0277                    void __iomem *base, void __iomem *np_base)
0278 {
0279     struct clk_hw *hw;
0280     u32 rate;
0281     int i;
0282 
0283     for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
0284         const struct en_clk_desc *desc = &en7523_base_clks[i];
0285 
0286         rate = en7523_get_base_rate(base, i);
0287         rate /= en7523_get_div(base, i);
0288 
0289         hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
0290         if (IS_ERR(hw)) {
0291             pr_err("Failed to register clk %s: %ld\n",
0292                    desc->name, PTR_ERR(hw));
0293             continue;
0294         }
0295 
0296         clk_data->hws[desc->id] = hw;
0297     }
0298 
0299     hw = en7523_register_pcie_clk(dev, np_base);
0300     clk_data->hws[EN7523_CLK_PCIE] = hw;
0301 
0302     clk_data->num = EN7523_NUM_CLOCKS;
0303 }
0304 
0305 static int en7523_clk_probe(struct platform_device *pdev)
0306 {
0307     struct device_node *node = pdev->dev.of_node;
0308     struct clk_hw_onecell_data *clk_data;
0309     void __iomem *base, *np_base;
0310     int r;
0311 
0312     base = devm_platform_ioremap_resource(pdev, 0);
0313     if (IS_ERR(base))
0314         return PTR_ERR(base);
0315 
0316     np_base = devm_platform_ioremap_resource(pdev, 1);
0317     if (IS_ERR(np_base))
0318         return PTR_ERR(np_base);
0319 
0320     clk_data = devm_kzalloc(&pdev->dev,
0321                 struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
0322                 GFP_KERNEL);
0323     if (!clk_data)
0324         return -ENOMEM;
0325 
0326     en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
0327 
0328     r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
0329     if (r)
0330         dev_err(&pdev->dev,
0331             "could not register clock provider: %s: %d\n",
0332             pdev->name, r);
0333 
0334     return r;
0335 }
0336 
0337 static struct platform_driver clk_en7523_drv = {
0338     .probe = en7523_clk_probe,
0339     .driver = {
0340         .name = "clk-en7523",
0341         .of_match_table = of_match_clk_en7523,
0342         .suppress_bind_attrs = true,
0343     },
0344 };
0345 
0346 static int __init clk_en7523_init(void)
0347 {
0348     return platform_driver_register(&clk_en7523_drv);
0349 }
0350 
0351 arch_initcall(clk_en7523_init);