clk-aspeed.c (98f3118debb3876399a8da59d72b4908431f1027) | clk-aspeed.c (15ed8ce5f84e2b3718690915dbee12ebd497dc0f) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2 3#define pr_fmt(fmt) "clk-aspeed: " fmt 4 5#include <linux/clk-provider.h> 6#include <linux/mfd/syscon.h> 7#include <linux/of_address.h> 8#include <linux/of_device.h> --- 190 unchanged lines hidden (view full) --- 199}; 200 201static const struct aspeed_clk_soc_data ast2400_data = { 202 .div_table = ast2400_div_table, 203 .mac_div_table = ast2400_div_table, 204 .calc_pll = aspeed_ast2400_calc_pll, 205}; 206 | 1// SPDX-License-Identifier: GPL-2.0+ 2 3#define pr_fmt(fmt) "clk-aspeed: " fmt 4 5#include <linux/clk-provider.h> 6#include <linux/mfd/syscon.h> 7#include <linux/of_address.h> 8#include <linux/of_device.h> --- 190 unchanged lines hidden (view full) --- 199}; 200 201static const struct aspeed_clk_soc_data ast2400_data = { 202 .div_table = ast2400_div_table, 203 .mac_div_table = ast2400_div_table, 204 .calc_pll = aspeed_ast2400_calc_pll, 205}; 206 |
207static int aspeed_clk_enable(struct clk_hw *hw) 208{ 209 struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); 210 unsigned long flags; 211 u32 clk = BIT(gate->clock_idx); 212 u32 rst = BIT(gate->reset_idx); 213 214 spin_lock_irqsave(gate->lock, flags); 215 216 if (gate->reset_idx >= 0) { 217 /* Put IP in reset */ 218 regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, rst); 219 220 /* Delay 100us */ 221 udelay(100); 222 } 223 224 /* Enable clock */ 225 regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, 0); 226 227 if (gate->reset_idx >= 0) { 228 /* A delay of 10ms is specified by the ASPEED docs */ 229 mdelay(10); 230 231 /* Take IP out of reset */ 232 regmap_update_bits(gate->map, ASPEED_RESET_CTRL, rst, 0); 233 } 234 235 spin_unlock_irqrestore(gate->lock, flags); 236 237 return 0; 238} 239 240static void aspeed_clk_disable(struct clk_hw *hw) 241{ 242 struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); 243 unsigned long flags; 244 u32 clk = BIT(gate->clock_idx); 245 246 spin_lock_irqsave(gate->lock, flags); 247 248 regmap_update_bits(gate->map, ASPEED_CLK_STOP_CTRL, clk, clk); 249 250 spin_unlock_irqrestore(gate->lock, flags); 251} 252 253static int aspeed_clk_is_enabled(struct clk_hw *hw) 254{ 255 struct aspeed_clk_gate *gate = to_aspeed_clk_gate(hw); 256 u32 clk = BIT(gate->clock_idx); 257 u32 reg; 258 259 regmap_read(gate->map, ASPEED_CLK_STOP_CTRL, ®); 260 261 return (reg & clk) ? 0 : 1; 262} 263 264static const struct clk_ops aspeed_clk_gate_ops = { 265 .enable = aspeed_clk_enable, 266 .disable = aspeed_clk_disable, 267 .is_enabled = aspeed_clk_is_enabled, 268}; 269 270static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev, 271 const char *name, const char *parent_name, unsigned long flags, 272 struct regmap *map, u8 clock_idx, u8 reset_idx, 273 u8 clk_gate_flags, spinlock_t *lock) 274{ 275 struct aspeed_clk_gate *gate; 276 struct clk_init_data init; 277 struct clk_hw *hw; 278 int ret; 279 280 gate = kzalloc(sizeof(*gate), GFP_KERNEL); 281 if (!gate) 282 return ERR_PTR(-ENOMEM); 283 284 init.name = name; 285 init.ops = &aspeed_clk_gate_ops; 286 init.flags = flags; 287 init.parent_names = parent_name ? &parent_name : NULL; 288 init.num_parents = parent_name ? 1 : 0; 289 290 gate->map = map; 291 gate->clock_idx = clock_idx; 292 gate->reset_idx = reset_idx; 293 gate->flags = clk_gate_flags; 294 gate->lock = lock; 295 gate->hw.init = &init; 296 297 hw = &gate->hw; 298 ret = clk_hw_register(dev, hw); 299 if (ret) { 300 kfree(gate); 301 hw = ERR_PTR(ret); 302 } 303 304 return hw; 305} 306 |
|
207static int aspeed_clk_probe(struct platform_device *pdev) 208{ 209 const struct aspeed_clk_soc_data *soc_data; 210 struct device *dev = &pdev->dev; 211 struct regmap *map; 212 struct clk_hw *hw; 213 u32 val, rate; | 307static int aspeed_clk_probe(struct platform_device *pdev) 308{ 309 const struct aspeed_clk_soc_data *soc_data; 310 struct device *dev = &pdev->dev; 311 struct regmap *map; 312 struct clk_hw *hw; 313 u32 val, rate; |
314 int i; |
|
214 215 map = syscon_node_to_regmap(dev->of_node); 216 if (IS_ERR(map)) { 217 dev_err(dev, "no syscon regmap\n"); 218 return PTR_ERR(map); 219 } 220 221 /* SoC generations share common layouts but have different divisors */ --- 56 unchanged lines hidden (view full) --- 278 hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0, 279 scu_base + ASPEED_CLK_SELECTION_2, 0, 2, 0, 280 soc_data->div_table, 281 &aspeed_clk_lock); 282 if (IS_ERR(hw)) 283 return PTR_ERR(hw); 284 aspeed_clk_data->hws[ASPEED_CLK_BCLK] = hw; 285 | 315 316 map = syscon_node_to_regmap(dev->of_node); 317 if (IS_ERR(map)) { 318 dev_err(dev, "no syscon regmap\n"); 319 return PTR_ERR(map); 320 } 321 322 /* SoC generations share common layouts but have different divisors */ --- 56 unchanged lines hidden (view full) --- 379 hw = clk_hw_register_divider_table(dev, "bclk", "hpll", 0, 380 scu_base + ASPEED_CLK_SELECTION_2, 0, 2, 0, 381 soc_data->div_table, 382 &aspeed_clk_lock); 383 if (IS_ERR(hw)) 384 return PTR_ERR(hw); 385 aspeed_clk_data->hws[ASPEED_CLK_BCLK] = hw; 386 |
387 /* 388 * TODO: There are a number of clocks that not included in this driver 389 * as more information is required: 390 * D2-PLL 391 * D-PLL 392 * YCLK 393 * RGMII 394 * RMII 395 * UART[1..5] clock source mux 396 * Video Engine (ECLK) mux and clock divider 397 */ 398 399 for (i = 0; i < ARRAY_SIZE(aspeed_gates); i++) { 400 const struct aspeed_gate_data *gd = &aspeed_gates[i]; 401 402 hw = aspeed_clk_hw_register_gate(dev, 403 gd->name, 404 gd->parent_name, 405 gd->flags, 406 map, 407 gd->clock_idx, 408 gd->reset_idx, 409 CLK_GATE_SET_TO_DISABLE, 410 &aspeed_clk_lock); 411 if (IS_ERR(hw)) 412 return PTR_ERR(hw); 413 aspeed_clk_data->hws[i] = hw; 414 } 415 |
|
286 return 0; 287}; 288 289static const struct of_device_id aspeed_clk_dt_ids[] = { 290 { .compatible = "aspeed,ast2400-scu", .data = &ast2400_data }, 291 { .compatible = "aspeed,ast2500-scu", .data = &ast2500_data }, 292 { } 293}; --- 155 unchanged lines hidden --- | 416 return 0; 417}; 418 419static const struct of_device_id aspeed_clk_dt_ids[] = { 420 { .compatible = "aspeed,ast2400-scu", .data = &ast2400_data }, 421 { .compatible = "aspeed,ast2500-scu", .data = &ast2500_data }, 422 { } 423}; --- 155 unchanged lines hidden --- |