1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2017, Intel Corporation 4 */ 5 #include <linux/slab.h> 6 #include <linux/clk-provider.h> 7 #include <linux/io.h> 8 9 #include "stratix10-clk.h" 10 #include "clk.h" 11 12 /* Clock Manager offsets */ 13 #define CLK_MGR_PLL_CLK_SRC_SHIFT 16 14 #define CLK_MGR_PLL_CLK_SRC_MASK 0x3 15 16 /* PLL Clock enable bits */ 17 #define SOCFPGA_PLL_POWER 0 18 #define SOCFPGA_PLL_RESET_MASK 0x2 19 #define SOCFPGA_PLL_REFDIV_MASK 0x00003F00 20 #define SOCFPGA_PLL_REFDIV_SHIFT 8 21 #define SOCFPGA_PLL_AREFDIV_MASK 0x00000F00 22 #define SOCFPGA_PLL_DREFDIV_MASK 0x00003000 23 #define SOCFPGA_PLL_DREFDIV_SHIFT 12 24 #define SOCFPGA_PLL_MDIV_MASK 0xFF000000 25 #define SOCFPGA_PLL_MDIV_SHIFT 24 26 #define SOCFPGA_AGILEX_PLL_MDIV_MASK 0x000003FF 27 #define SWCTRLBTCLKSEL_MASK 0x200 28 #define SWCTRLBTCLKSEL_SHIFT 9 29 30 #define SOCFPGA_BOOT_CLK "boot_clk" 31 32 #define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw.hw) 33 34 static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk, 35 unsigned long parent_rate) 36 { 37 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 38 unsigned long arefdiv, reg, mdiv; 39 unsigned long long vco_freq; 40 41 /* read VCO1 reg for numerator and denominator */ 42 reg = readl(socfpgaclk->hw.reg); 43 arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; 44 45 vco_freq = (unsigned long long)parent_rate / arefdiv; 46 47 /* Read mdiv and fdiv from the fdbck register */ 48 reg = readl(socfpgaclk->hw.reg + 0x24); 49 mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK; 50 51 vco_freq = (unsigned long long)vco_freq * mdiv; 52 return (unsigned long)vco_freq; 53 } 54 55 static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, 56 unsigned long parent_rate) 57 { 58 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 59 unsigned long mdiv; 60 unsigned long refdiv; 61 unsigned long reg; 62 unsigned long long vco_freq; 63 64 /* read VCO1 reg for numerator and denominator */ 65 reg = readl(socfpgaclk->hw.reg); 66 refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; 67 68 vco_freq = parent_rate; 69 do_div(vco_freq, refdiv); 70 71 /* Read mdiv and fdiv from the fdbck register */ 72 reg = readl(socfpgaclk->hw.reg + 0x4); 73 mdiv = (reg & SOCFPGA_PLL_MDIV_MASK) >> SOCFPGA_PLL_MDIV_SHIFT; 74 vco_freq = (unsigned long long)vco_freq * (mdiv + 6); 75 76 return (unsigned long)vco_freq; 77 } 78 79 static unsigned long clk_boot_clk_recalc_rate(struct clk_hw *hwclk, 80 unsigned long parent_rate) 81 { 82 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 83 u32 div = 1; 84 85 div = ((readl(socfpgaclk->hw.reg) & 86 SWCTRLBTCLKSEL_MASK) >> 87 SWCTRLBTCLKSEL_SHIFT); 88 div += 1; 89 return parent_rate /= div; 90 } 91 92 93 static u8 clk_pll_get_parent(struct clk_hw *hwclk) 94 { 95 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 96 u32 pll_src; 97 98 pll_src = readl(socfpgaclk->hw.reg); 99 return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) & 100 CLK_MGR_PLL_CLK_SRC_MASK; 101 } 102 103 static u8 clk_boot_get_parent(struct clk_hw *hwclk) 104 { 105 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 106 u32 pll_src; 107 108 pll_src = readl(socfpgaclk->hw.reg); 109 return (pll_src >> SWCTRLBTCLKSEL_SHIFT) & 110 SWCTRLBTCLKSEL_MASK; 111 } 112 113 static int clk_pll_prepare(struct clk_hw *hwclk) 114 { 115 struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk); 116 u32 reg; 117 118 /* Bring PLL out of reset */ 119 reg = readl(socfpgaclk->hw.reg); 120 reg |= SOCFPGA_PLL_RESET_MASK; 121 writel(reg, socfpgaclk->hw.reg); 122 123 return 0; 124 } 125 126 static const struct clk_ops agilex_clk_pll_ops = { 127 .recalc_rate = agilex_clk_pll_recalc_rate, 128 .get_parent = clk_pll_get_parent, 129 .prepare = clk_pll_prepare, 130 }; 131 132 static const struct clk_ops clk_pll_ops = { 133 .recalc_rate = clk_pll_recalc_rate, 134 .get_parent = clk_pll_get_parent, 135 .prepare = clk_pll_prepare, 136 }; 137 138 static const struct clk_ops clk_boot_ops = { 139 .recalc_rate = clk_boot_clk_recalc_rate, 140 .get_parent = clk_boot_get_parent, 141 .prepare = clk_pll_prepare, 142 }; 143 144 struct clk *s10_register_pll(const struct stratix10_pll_clock *clks, 145 void __iomem *reg) 146 { 147 struct clk *clk; 148 struct socfpga_pll *pll_clk; 149 struct clk_init_data init; 150 const char *name = clks->name; 151 152 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); 153 if (WARN_ON(!pll_clk)) 154 return NULL; 155 156 pll_clk->hw.reg = reg + clks->offset; 157 158 if (streq(name, SOCFPGA_BOOT_CLK)) 159 init.ops = &clk_boot_ops; 160 else 161 init.ops = &clk_pll_ops; 162 163 init.name = name; 164 init.flags = clks->flags; 165 166 init.num_parents = clks->num_parents; 167 init.parent_names = NULL; 168 init.parent_data = clks->parent_data; 169 pll_clk->hw.hw.init = &init; 170 171 pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER; 172 173 clk = clk_register(NULL, &pll_clk->hw.hw); 174 if (WARN_ON(IS_ERR(clk))) { 175 kfree(pll_clk); 176 return NULL; 177 } 178 return clk; 179 } 180 181 struct clk *agilex_register_pll(const struct stratix10_pll_clock *clks, 182 void __iomem *reg) 183 { 184 struct clk *clk; 185 struct socfpga_pll *pll_clk; 186 struct clk_init_data init; 187 const char *name = clks->name; 188 189 pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); 190 if (WARN_ON(!pll_clk)) 191 return NULL; 192 193 pll_clk->hw.reg = reg + clks->offset; 194 195 if (streq(name, SOCFPGA_BOOT_CLK)) 196 init.ops = &clk_boot_ops; 197 else 198 init.ops = &agilex_clk_pll_ops; 199 200 init.name = name; 201 init.flags = clks->flags; 202 203 init.num_parents = clks->num_parents; 204 init.parent_names = NULL; 205 init.parent_data = clks->parent_data; 206 pll_clk->hw.hw.init = &init; 207 208 pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER; 209 210 clk = clk_register(NULL, &pll_clk->hw.hw); 211 if (WARN_ON(IS_ERR(clk))) { 212 kfree(pll_clk); 213 return NULL; 214 } 215 return clk; 216 } 217