1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Microchip LAN966x SoC Clock driver. 4 * 5 * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries 6 * 7 * Author: Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com> 8 */ 9 10 #include <linux/bitfield.h> 11 #include <linux/clk-provider.h> 12 #include <linux/io.h> 13 #include <linux/kernel.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 #include <linux/platform_device.h> 17 #include <linux/slab.h> 18 19 #include <dt-bindings/clock/microchip,lan966x.h> 20 21 #define GCK_ENA BIT(0) 22 #define GCK_SRC_SEL GENMASK(9, 8) 23 #define GCK_PRESCALER GENMASK(23, 16) 24 25 #define DIV_MAX 255 26 27 static const char *clk_names[N_CLOCKS] = { 28 "qspi0", "qspi1", "qspi2", "sdmmc0", 29 "pi", "mcan0", "mcan1", "flexcom0", 30 "flexcom1", "flexcom2", "flexcom3", 31 "flexcom4", "timer1", "usb_refclk", 32 }; 33 34 struct lan966x_gck { 35 struct clk_hw hw; 36 void __iomem *reg; 37 }; 38 #define to_lan966x_gck(hw) container_of(hw, struct lan966x_gck, hw) 39 40 static const struct clk_parent_data lan966x_gck_pdata[] = { 41 { .fw_name = "cpu", }, 42 { .fw_name = "ddr", }, 43 { .fw_name = "sys", }, 44 }; 45 46 static struct clk_init_data init = { 47 .parent_data = lan966x_gck_pdata, 48 .num_parents = ARRAY_SIZE(lan966x_gck_pdata), 49 }; 50 51 struct clk_gate_soc_desc { 52 const char *name; 53 int bit_idx; 54 }; 55 56 static const struct clk_gate_soc_desc clk_gate_desc[] = { 57 { "uhphs", 11 }, 58 { "udphs", 10 }, 59 { "mcramc", 9 }, 60 { "hmatrix", 8 }, 61 { } 62 }; 63 64 static DEFINE_SPINLOCK(clk_gate_lock); 65 static void __iomem *base; 66 67 static int lan966x_gck_enable(struct clk_hw *hw) 68 { 69 struct lan966x_gck *gck = to_lan966x_gck(hw); 70 u32 val = readl(gck->reg); 71 72 val |= GCK_ENA; 73 writel(val, gck->reg); 74 75 return 0; 76 } 77 78 static void lan966x_gck_disable(struct clk_hw *hw) 79 { 80 struct lan966x_gck *gck = to_lan966x_gck(hw); 81 u32 val = readl(gck->reg); 82 83 val &= ~GCK_ENA; 84 writel(val, gck->reg); 85 } 86 87 static int lan966x_gck_set_rate(struct clk_hw *hw, 88 unsigned long rate, 89 unsigned long parent_rate) 90 { 91 struct lan966x_gck *gck = to_lan966x_gck(hw); 92 u32 div, val = readl(gck->reg); 93 94 if (rate == 0 || parent_rate == 0) 95 return -EINVAL; 96 97 /* Set Prescalar */ 98 div = parent_rate / rate; 99 val &= ~GCK_PRESCALER; 100 val |= FIELD_PREP(GCK_PRESCALER, (div - 1)); 101 writel(val, gck->reg); 102 103 return 0; 104 } 105 106 static long lan966x_gck_round_rate(struct clk_hw *hw, unsigned long rate, 107 unsigned long *parent_rate) 108 { 109 unsigned int div; 110 111 if (rate == 0 || *parent_rate == 0) 112 return -EINVAL; 113 114 if (rate >= *parent_rate) 115 return *parent_rate; 116 117 div = DIV_ROUND_CLOSEST(*parent_rate, rate); 118 119 return *parent_rate / div; 120 } 121 122 static unsigned long lan966x_gck_recalc_rate(struct clk_hw *hw, 123 unsigned long parent_rate) 124 { 125 struct lan966x_gck *gck = to_lan966x_gck(hw); 126 u32 div, val = readl(gck->reg); 127 128 div = FIELD_GET(GCK_PRESCALER, val); 129 130 return parent_rate / (div + 1); 131 } 132 133 static int lan966x_gck_determine_rate(struct clk_hw *hw, 134 struct clk_rate_request *req) 135 { 136 struct clk_hw *parent; 137 int i; 138 139 for (i = 0; i < clk_hw_get_num_parents(hw); ++i) { 140 parent = clk_hw_get_parent_by_index(hw, i); 141 if (!parent) 142 continue; 143 144 /* Allowed prescaler divider range is 0-255 */ 145 if (clk_hw_get_rate(parent) / req->rate <= DIV_MAX) { 146 req->best_parent_hw = parent; 147 req->best_parent_rate = clk_hw_get_rate(parent); 148 149 return 0; 150 } 151 } 152 153 return -EINVAL; 154 } 155 156 static u8 lan966x_gck_get_parent(struct clk_hw *hw) 157 { 158 struct lan966x_gck *gck = to_lan966x_gck(hw); 159 u32 val = readl(gck->reg); 160 161 return FIELD_GET(GCK_SRC_SEL, val); 162 } 163 164 static int lan966x_gck_set_parent(struct clk_hw *hw, u8 index) 165 { 166 struct lan966x_gck *gck = to_lan966x_gck(hw); 167 u32 val = readl(gck->reg); 168 169 val &= ~GCK_SRC_SEL; 170 val |= FIELD_PREP(GCK_SRC_SEL, index); 171 writel(val, gck->reg); 172 173 return 0; 174 } 175 176 static const struct clk_ops lan966x_gck_ops = { 177 .enable = lan966x_gck_enable, 178 .disable = lan966x_gck_disable, 179 .set_rate = lan966x_gck_set_rate, 180 .round_rate = lan966x_gck_round_rate, 181 .recalc_rate = lan966x_gck_recalc_rate, 182 .determine_rate = lan966x_gck_determine_rate, 183 .set_parent = lan966x_gck_set_parent, 184 .get_parent = lan966x_gck_get_parent, 185 }; 186 187 static struct clk_hw *lan966x_gck_clk_register(struct device *dev, int i) 188 { 189 struct lan966x_gck *priv; 190 int ret; 191 192 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 193 if (!priv) 194 return ERR_PTR(-ENOMEM); 195 196 priv->reg = base + (i * 4); 197 priv->hw.init = &init; 198 ret = devm_clk_hw_register(dev, &priv->hw); 199 if (ret) 200 return ERR_PTR(ret); 201 202 return &priv->hw; 203 }; 204 205 static int lan966x_gate_clk_register(struct device *dev, 206 struct clk_hw_onecell_data *hw_data, 207 void __iomem *gate_base) 208 { 209 int i; 210 211 for (i = GCK_GATE_UHPHS; i < N_CLOCKS; ++i) { 212 int idx = i - GCK_GATE_UHPHS; 213 214 hw_data->hws[i] = 215 devm_clk_hw_register_gate(dev, clk_gate_desc[idx].name, 216 "lan966x", 0, gate_base, 217 clk_gate_desc[idx].bit_idx, 218 0, &clk_gate_lock); 219 220 if (IS_ERR(hw_data->hws[i])) 221 return dev_err_probe(dev, PTR_ERR(hw_data->hws[i]), 222 "failed to register %s clock\n", 223 clk_gate_desc[idx].name); 224 } 225 226 return 0; 227 } 228 229 static int lan966x_clk_probe(struct platform_device *pdev) 230 { 231 struct clk_hw_onecell_data *hw_data; 232 struct device *dev = &pdev->dev; 233 void __iomem *gate_base; 234 struct resource *res; 235 int i, ret; 236 237 hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, N_CLOCKS), 238 GFP_KERNEL); 239 if (!hw_data) 240 return -ENOMEM; 241 242 base = devm_platform_ioremap_resource(pdev, 0); 243 if (IS_ERR(base)) 244 return PTR_ERR(base); 245 246 init.ops = &lan966x_gck_ops; 247 248 hw_data->num = GCK_GATE_UHPHS; 249 250 for (i = 0; i < GCK_GATE_UHPHS; i++) { 251 init.name = clk_names[i]; 252 hw_data->hws[i] = lan966x_gck_clk_register(dev, i); 253 if (IS_ERR(hw_data->hws[i])) { 254 dev_err(dev, "failed to register %s clock\n", 255 init.name); 256 return PTR_ERR(hw_data->hws[i]); 257 } 258 } 259 260 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 261 if (res) { 262 gate_base = devm_ioremap_resource(&pdev->dev, res); 263 if (IS_ERR(gate_base)) 264 return PTR_ERR(gate_base); 265 266 hw_data->num = N_CLOCKS; 267 268 ret = lan966x_gate_clk_register(dev, hw_data, gate_base); 269 if (ret) 270 return ret; 271 } 272 273 return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, hw_data); 274 } 275 276 static const struct of_device_id lan966x_clk_dt_ids[] = { 277 { .compatible = "microchip,lan966x-gck", }, 278 { } 279 }; 280 MODULE_DEVICE_TABLE(of, lan966x_clk_dt_ids); 281 282 static struct platform_driver lan966x_clk_driver = { 283 .probe = lan966x_clk_probe, 284 .driver = { 285 .name = "lan966x-clk", 286 .of_match_table = lan966x_clk_dt_ids, 287 }, 288 }; 289 module_platform_driver(lan966x_clk_driver); 290 291 MODULE_AUTHOR("Kavyasree Kotagiri <kavyasree.kotagiri@microchip.com>"); 292 MODULE_DESCRIPTION("LAN966X clock driver"); 293 MODULE_LICENSE("GPL v2"); 294