1108 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * MTMIPS SoCs Clock Driver4 * Author: Sergio Paracuellos <sergio.paracuellos@gmail.com>5 */6 7#include <linux/bitops.h>8#include <linux/clk-provider.h>9#include <linux/mfd/syscon.h>10#include <linux/platform_device.h>11#include <linux/regmap.h>12#include <linux/reset-controller.h>13#include <linux/slab.h>14 15/* Configuration registers */16#define SYSC_REG_SYSTEM_CONFIG 0x1017#define SYSC_REG_CLKCFG0 0x2c18#define SYSC_REG_RESET_CTRL 0x3419#define SYSC_REG_CPU_SYS_CLKCFG 0x3c20#define SYSC_REG_CPLL_CONFIG0 0x5421#define SYSC_REG_CPLL_CONFIG1 0x5822 23/* RT2880 SoC */24#define RT2880_CONFIG_CPUCLK_SHIFT 2025#define RT2880_CONFIG_CPUCLK_MASK 0x326#define RT2880_CONFIG_CPUCLK_250 0x027#define RT2880_CONFIG_CPUCLK_266 0x128#define RT2880_CONFIG_CPUCLK_280 0x229#define RT2880_CONFIG_CPUCLK_300 0x330 31/* RT305X SoC */32#define RT305X_SYSCFG_CPUCLK_SHIFT 1833#define RT305X_SYSCFG_CPUCLK_MASK 0x134#define RT305X_SYSCFG_CPUCLK_LOW 0x035#define RT305X_SYSCFG_CPUCLK_HIGH 0x136 37/* RT3352 SoC */38#define RT3352_SYSCFG0_CPUCLK_SHIFT 839#define RT3352_SYSCFG0_CPUCLK_MASK 0x140#define RT3352_SYSCFG0_CPUCLK_LOW 0x041#define RT3352_SYSCFG0_CPUCLK_HIGH 0x142 43/* RT3383 SoC */44#define RT3883_SYSCFG0_DRAM_TYPE_DDR2 BIT(17)45#define RT3883_SYSCFG0_CPUCLK_SHIFT 846#define RT3883_SYSCFG0_CPUCLK_MASK 0x347#define RT3883_SYSCFG0_CPUCLK_250 0x048#define RT3883_SYSCFG0_CPUCLK_384 0x149#define RT3883_SYSCFG0_CPUCLK_480 0x250#define RT3883_SYSCFG0_CPUCLK_500 0x351 52/* RT5350 SoC */53#define RT5350_CLKCFG0_XTAL_SEL BIT(20)54#define RT5350_SYSCFG0_CPUCLK_SHIFT 855#define RT5350_SYSCFG0_CPUCLK_MASK 0x356#define RT5350_SYSCFG0_CPUCLK_360 0x057#define RT5350_SYSCFG0_CPUCLK_320 0x258#define RT5350_SYSCFG0_CPUCLK_300 0x359 60/* MT7620 and MT76x8 SoCs */61#define MT7620_XTAL_FREQ_SEL BIT(6)62#define CPLL_CFG0_SW_CFG BIT(31)63#define CPLL_CFG0_PLL_MULT_RATIO_SHIFT 1664#define CPLL_CFG0_PLL_MULT_RATIO_MASK 0x765#define CPLL_CFG0_LC_CURFCK BIT(15)66#define CPLL_CFG0_BYPASS_REF_CLK BIT(14)67#define CPLL_CFG0_PLL_DIV_RATIO_SHIFT 1068#define CPLL_CFG0_PLL_DIV_RATIO_MASK 0x369#define CPLL_CFG1_CPU_AUX1 BIT(25)70#define CPLL_CFG1_CPU_AUX0 BIT(24)71#define CLKCFG0_PERI_CLK_SEL BIT(4)72#define CPU_SYS_CLKCFG_OCP_RATIO_SHIFT 1673#define CPU_SYS_CLKCFG_OCP_RATIO_MASK 0xf74#define CPU_SYS_CLKCFG_OCP_RATIO_1 0 /* 1:1 (Reserved) */75#define CPU_SYS_CLKCFG_OCP_RATIO_1_5 1 /* 1:1.5 (Reserved) */76#define CPU_SYS_CLKCFG_OCP_RATIO_2 2 /* 1:2 */77#define CPU_SYS_CLKCFG_OCP_RATIO_2_5 3 /* 1:2.5 (Reserved) */78#define CPU_SYS_CLKCFG_OCP_RATIO_3 4 /* 1:3 */79#define CPU_SYS_CLKCFG_OCP_RATIO_3_5 5 /* 1:3.5 (Reserved) */80#define CPU_SYS_CLKCFG_OCP_RATIO_4 6 /* 1:4 */81#define CPU_SYS_CLKCFG_OCP_RATIO_5 7 /* 1:5 */82#define CPU_SYS_CLKCFG_OCP_RATIO_10 8 /* 1:10 */83#define CPU_SYS_CLKCFG_CPU_FDIV_SHIFT 884#define CPU_SYS_CLKCFG_CPU_FDIV_MASK 0x1f85#define CPU_SYS_CLKCFG_CPU_FFRAC_SHIFT 086#define CPU_SYS_CLKCFG_CPU_FFRAC_MASK 0x1f87 88/* clock scaling */89#define CLKCFG_FDIV_MASK 0x1f0090#define CLKCFG_FDIV_USB_VAL 0x030091#define CLKCFG_FFRAC_MASK 0x001f92#define CLKCFG_FFRAC_USB_VAL 0x000393 94struct mtmips_clk;95struct mtmips_clk_fixed;96struct mtmips_clk_factor;97 98struct mtmips_clk_data {99 struct mtmips_clk *clk_base;100 size_t num_clk_base;101 struct mtmips_clk_fixed *clk_fixed;102 size_t num_clk_fixed;103 struct mtmips_clk_factor *clk_factor;104 size_t num_clk_factor;105 struct mtmips_clk *clk_periph;106 size_t num_clk_periph;107};108 109struct mtmips_clk_priv {110 struct regmap *sysc;111 const struct mtmips_clk_data *data;112};113 114struct mtmips_clk {115 struct clk_hw hw;116 struct mtmips_clk_priv *priv;117};118 119struct mtmips_clk_fixed {120 const char *name;121 const char *parent;122 unsigned long rate;123 struct clk_hw *hw;124};125 126struct mtmips_clk_factor {127 const char *name;128 const char *parent;129 int mult;130 int div;131 unsigned long flags;132 struct clk_hw *hw;133};134 135static unsigned long mtmips_pherip_clk_rate(struct clk_hw *hw,136 unsigned long parent_rate)137{138 return parent_rate;139}140 141static const struct clk_ops mtmips_periph_clk_ops = {142 .recalc_rate = mtmips_pherip_clk_rate,143};144 145#define CLK_PERIPH(_name, _parent) { \146 .init = &(const struct clk_init_data) { \147 .name = _name, \148 .ops = &mtmips_periph_clk_ops, \149 .parent_data = &(const struct clk_parent_data) {\150 .name = _parent, \151 .fw_name = _parent \152 }, \153 .num_parents = 1, \154 /* \155 * There are drivers for these SoCs that are \156 * older than clock driver and are not prepared \157 * for the clock. We don't want the kernel to \158 * disable anything so we add CLK_IS_CRITICAL \159 * flag here. \160 */ \161 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL \162 }, \163}164 165static struct mtmips_clk rt2880_pherip_clks[] = {166 { CLK_PERIPH("300100.timer", "bus") },167 { CLK_PERIPH("300120.watchdog", "bus") },168 { CLK_PERIPH("300500.uart", "bus") },169 { CLK_PERIPH("300900.i2c", "bus") },170 { CLK_PERIPH("300c00.uartlite", "bus") },171 { CLK_PERIPH("400000.ethernet", "bus") },172 { CLK_PERIPH("480000.wmac", "xtal") }173};174 175static struct mtmips_clk rt305x_pherip_clks[] = {176 { CLK_PERIPH("10000100.timer", "bus") },177 { CLK_PERIPH("10000120.watchdog", "bus") },178 { CLK_PERIPH("10000500.uart", "bus") },179 { CLK_PERIPH("10000900.i2c", "bus") },180 { CLK_PERIPH("10000a00.i2s", "bus") },181 { CLK_PERIPH("10000b00.spi", "bus") },182 { CLK_PERIPH("10000b40.spi", "bus") },183 { CLK_PERIPH("10000c00.uartlite", "bus") },184 { CLK_PERIPH("10100000.ethernet", "bus") },185 { CLK_PERIPH("10180000.wmac", "xtal") }186};187 188static struct mtmips_clk rt5350_pherip_clks[] = {189 { CLK_PERIPH("10000100.timer", "bus") },190 { CLK_PERIPH("10000120.watchdog", "bus") },191 { CLK_PERIPH("10000500.uart", "periph") },192 { CLK_PERIPH("10000900.i2c", "periph") },193 { CLK_PERIPH("10000a00.i2s", "periph") },194 { CLK_PERIPH("10000b00.spi", "bus") },195 { CLK_PERIPH("10000b40.spi", "bus") },196 { CLK_PERIPH("10000c00.uartlite", "periph") },197 { CLK_PERIPH("10100000.ethernet", "bus") },198 { CLK_PERIPH("10180000.wmac", "xtal") }199};200 201static struct mtmips_clk mt7620_pherip_clks[] = {202 { CLK_PERIPH("10000100.timer", "periph") },203 { CLK_PERIPH("10000120.watchdog", "periph") },204 { CLK_PERIPH("10000500.uart", "periph") },205 { CLK_PERIPH("10000900.i2c", "periph") },206 { CLK_PERIPH("10000a00.i2s", "periph") },207 { CLK_PERIPH("10000b00.spi", "bus") },208 { CLK_PERIPH("10000b40.spi", "bus") },209 { CLK_PERIPH("10000c00.uartlite", "periph") },210 { CLK_PERIPH("10180000.wmac", "xtal") }211};212 213static struct mtmips_clk mt76x8_pherip_clks[] = {214 { CLK_PERIPH("10000100.timer", "periph") },215 { CLK_PERIPH("10000120.watchdog", "periph") },216 { CLK_PERIPH("10000900.i2c", "periph") },217 { CLK_PERIPH("10000a00.i2s", "pcmi2s") },218 { CLK_PERIPH("10000b00.spi", "bus") },219 { CLK_PERIPH("10000b40.spi", "bus") },220 { CLK_PERIPH("10000c00.uart0", "periph") },221 { CLK_PERIPH("10000d00.uart1", "periph") },222 { CLK_PERIPH("10000e00.uart2", "periph") },223 { CLK_PERIPH("10300000.wmac", "xtal") }224};225 226static int mtmips_register_pherip_clocks(struct device_node *np,227 struct clk_hw_onecell_data *clk_data,228 struct mtmips_clk_priv *priv)229{230 struct clk_hw **hws = clk_data->hws;231 struct mtmips_clk *sclk;232 size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed +233 priv->data->num_clk_factor;234 int ret, i;235 236 for (i = 0; i < priv->data->num_clk_periph; i++) {237 int idx = idx_start + i;238 239 sclk = &priv->data->clk_periph[i];240 ret = of_clk_hw_register(np, &sclk->hw);241 if (ret) {242 pr_err("Couldn't register peripheral clock %d\n", idx);243 goto err_clk_unreg;244 }245 246 hws[idx] = &sclk->hw;247 }248 249 return 0;250 251err_clk_unreg:252 while (--i >= 0) {253 sclk = &priv->data->clk_periph[i];254 clk_hw_unregister(&sclk->hw);255 }256 return ret;257}258 259#define CLK_FIXED(_name, _parent, _rate) \260 { \261 .name = _name, \262 .parent = _parent, \263 .rate = _rate \264 }265 266static struct mtmips_clk_fixed rt305x_fixed_clocks[] = {267 CLK_FIXED("xtal", NULL, 40000000)268};269 270static struct mtmips_clk_fixed rt3352_fixed_clocks[] = {271 CLK_FIXED("periph", "xtal", 40000000)272};273 274static struct mtmips_clk_fixed mt76x8_fixed_clocks[] = {275 CLK_FIXED("pcmi2s", "xtal", 480000000),276 CLK_FIXED("periph", "xtal", 40000000)277};278 279static int mtmips_register_fixed_clocks(struct clk_hw_onecell_data *clk_data,280 struct mtmips_clk_priv *priv)281{282 struct clk_hw **hws = clk_data->hws;283 struct mtmips_clk_fixed *sclk;284 size_t idx_start = priv->data->num_clk_base;285 int ret, i;286 287 for (i = 0; i < priv->data->num_clk_fixed; i++) {288 int idx = idx_start + i;289 290 sclk = &priv->data->clk_fixed[i];291 sclk->hw = clk_hw_register_fixed_rate(NULL, sclk->name,292 sclk->parent, 0,293 sclk->rate);294 if (IS_ERR(sclk->hw)) {295 ret = PTR_ERR(sclk->hw);296 pr_err("Couldn't register fixed clock %d\n", idx);297 goto err_clk_unreg;298 }299 300 hws[idx] = sclk->hw;301 }302 303 return 0;304 305err_clk_unreg:306 while (--i >= 0) {307 sclk = &priv->data->clk_fixed[i];308 clk_hw_unregister_fixed_rate(sclk->hw);309 }310 return ret;311}312 313#define CLK_FACTOR(_name, _parent, _mult, _div) \314 { \315 .name = _name, \316 .parent = _parent, \317 .mult = _mult, \318 .div = _div, \319 .flags = CLK_SET_RATE_PARENT \320 }321 322static struct mtmips_clk_factor rt2880_factor_clocks[] = {323 CLK_FACTOR("bus", "cpu", 1, 2)324};325 326static struct mtmips_clk_factor rt305x_factor_clocks[] = {327 CLK_FACTOR("bus", "cpu", 1, 3)328};329 330static int mtmips_register_factor_clocks(struct clk_hw_onecell_data *clk_data,331 struct mtmips_clk_priv *priv)332{333 struct clk_hw **hws = clk_data->hws;334 struct mtmips_clk_factor *sclk;335 size_t idx_start = priv->data->num_clk_base + priv->data->num_clk_fixed;336 int ret, i;337 338 for (i = 0; i < priv->data->num_clk_factor; i++) {339 int idx = idx_start + i;340 341 sclk = &priv->data->clk_factor[i];342 sclk->hw = clk_hw_register_fixed_factor(NULL, sclk->name,343 sclk->parent, sclk->flags,344 sclk->mult, sclk->div);345 if (IS_ERR(sclk->hw)) {346 ret = PTR_ERR(sclk->hw);347 pr_err("Couldn't register factor clock %d\n", idx);348 goto err_clk_unreg;349 }350 351 hws[idx] = sclk->hw;352 }353 354 return 0;355 356err_clk_unreg:357 while (--i >= 0) {358 sclk = &priv->data->clk_factor[i];359 clk_hw_unregister_fixed_factor(sclk->hw);360 }361 return ret;362}363 364static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw)365{366 return container_of(hw, struct mtmips_clk, hw);367}368 369static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw,370 unsigned long parent_rate)371{372 struct mtmips_clk *clk = to_mtmips_clk(hw);373 struct regmap *sysc = clk->priv->sysc;374 u32 val;375 376 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &val);377 if (!(val & RT5350_CLKCFG0_XTAL_SEL))378 return 20000000;379 380 return 40000000;381}382 383static unsigned long rt5350_cpu_recalc_rate(struct clk_hw *hw,384 unsigned long xtal_clk)385{386 struct mtmips_clk *clk = to_mtmips_clk(hw);387 struct regmap *sysc = clk->priv->sysc;388 u32 t;389 390 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);391 t = (t >> RT5350_SYSCFG0_CPUCLK_SHIFT) & RT5350_SYSCFG0_CPUCLK_MASK;392 393 switch (t) {394 case RT5350_SYSCFG0_CPUCLK_360:395 return 360000000;396 case RT5350_SYSCFG0_CPUCLK_320:397 return 320000000;398 case RT5350_SYSCFG0_CPUCLK_300:399 return 300000000;400 default:401 BUG();402 }403}404 405static unsigned long rt5350_bus_recalc_rate(struct clk_hw *hw,406 unsigned long parent_rate)407{408 if (parent_rate == 320000000)409 return parent_rate / 4;410 411 return parent_rate / 3;412}413 414static unsigned long rt3352_cpu_recalc_rate(struct clk_hw *hw,415 unsigned long xtal_clk)416{417 struct mtmips_clk *clk = to_mtmips_clk(hw);418 struct regmap *sysc = clk->priv->sysc;419 u32 t;420 421 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);422 t = (t >> RT3352_SYSCFG0_CPUCLK_SHIFT) & RT3352_SYSCFG0_CPUCLK_MASK;423 424 switch (t) {425 case RT3352_SYSCFG0_CPUCLK_LOW:426 return 384000000;427 case RT3352_SYSCFG0_CPUCLK_HIGH:428 return 400000000;429 default:430 BUG();431 }432}433 434static unsigned long rt305x_cpu_recalc_rate(struct clk_hw *hw,435 unsigned long xtal_clk)436{437 struct mtmips_clk *clk = to_mtmips_clk(hw);438 struct regmap *sysc = clk->priv->sysc;439 u32 t;440 441 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);442 t = (t >> RT305X_SYSCFG_CPUCLK_SHIFT) & RT305X_SYSCFG_CPUCLK_MASK;443 444 switch (t) {445 case RT305X_SYSCFG_CPUCLK_LOW:446 return 320000000;447 case RT305X_SYSCFG_CPUCLK_HIGH:448 return 384000000;449 default:450 BUG();451 }452}453 454static unsigned long rt3883_cpu_recalc_rate(struct clk_hw *hw,455 unsigned long xtal_clk)456{457 struct mtmips_clk *clk = to_mtmips_clk(hw);458 struct regmap *sysc = clk->priv->sysc;459 u32 t;460 461 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);462 t = (t >> RT3883_SYSCFG0_CPUCLK_SHIFT) & RT3883_SYSCFG0_CPUCLK_MASK;463 464 switch (t) {465 case RT3883_SYSCFG0_CPUCLK_250:466 return 250000000;467 case RT3883_SYSCFG0_CPUCLK_384:468 return 384000000;469 case RT3883_SYSCFG0_CPUCLK_480:470 return 480000000;471 case RT3883_SYSCFG0_CPUCLK_500:472 return 500000000;473 default:474 BUG();475 }476}477 478static unsigned long rt3883_bus_recalc_rate(struct clk_hw *hw,479 unsigned long parent_rate)480{481 struct mtmips_clk *clk = to_mtmips_clk(hw);482 struct regmap *sysc = clk->priv->sysc;483 u32 ddr2;484 u32 t;485 486 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);487 ddr2 = t & RT3883_SYSCFG0_DRAM_TYPE_DDR2;488 489 switch (parent_rate) {490 case 250000000:491 return (ddr2) ? 125000000 : 83000000;492 case 384000000:493 return (ddr2) ? 128000000 : 96000000;494 case 480000000:495 return (ddr2) ? 160000000 : 120000000;496 case 500000000:497 return (ddr2) ? 166000000 : 125000000;498 default:499 WARN_ON_ONCE(parent_rate == 0);500 return parent_rate / 4;501 }502}503 504static unsigned long rt2880_cpu_recalc_rate(struct clk_hw *hw,505 unsigned long xtal_clk)506{507 struct mtmips_clk *clk = to_mtmips_clk(hw);508 struct regmap *sysc = clk->priv->sysc;509 u32 t;510 511 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);512 t = (t >> RT2880_CONFIG_CPUCLK_SHIFT) & RT2880_CONFIG_CPUCLK_MASK;513 514 switch (t) {515 case RT2880_CONFIG_CPUCLK_250:516 return 250000000;517 case RT2880_CONFIG_CPUCLK_266:518 return 266000000;519 case RT2880_CONFIG_CPUCLK_280:520 return 280000000;521 case RT2880_CONFIG_CPUCLK_300:522 return 300000000;523 default:524 BUG();525 }526}527 528static u32 mt7620_calc_rate(u32 ref_rate, u32 mul, u32 div)529{530 u64 t;531 532 t = ref_rate;533 t *= mul;534 t = div_u64(t, div);535 536 return t;537}538 539static unsigned long mt7620_pll_recalc_rate(struct clk_hw *hw,540 unsigned long parent_rate)541{542 static const u32 clk_divider[] = { 2, 3, 4, 8 };543 struct mtmips_clk *clk = to_mtmips_clk(hw);544 struct regmap *sysc = clk->priv->sysc;545 unsigned long cpu_pll;546 u32 t;547 u32 mul;548 u32 div;549 550 regmap_read(sysc, SYSC_REG_CPLL_CONFIG0, &t);551 if (t & CPLL_CFG0_BYPASS_REF_CLK) {552 cpu_pll = parent_rate;553 } else if ((t & CPLL_CFG0_SW_CFG) == 0) {554 cpu_pll = 600000000;555 } else {556 mul = (t >> CPLL_CFG0_PLL_MULT_RATIO_SHIFT) &557 CPLL_CFG0_PLL_MULT_RATIO_MASK;558 mul += 24;559 if (t & CPLL_CFG0_LC_CURFCK)560 mul *= 2;561 562 div = (t >> CPLL_CFG0_PLL_DIV_RATIO_SHIFT) &563 CPLL_CFG0_PLL_DIV_RATIO_MASK;564 565 WARN_ON_ONCE(div >= ARRAY_SIZE(clk_divider));566 567 cpu_pll = mt7620_calc_rate(parent_rate, mul, clk_divider[div]);568 }569 570 regmap_read(sysc, SYSC_REG_CPLL_CONFIG1, &t);571 if (t & CPLL_CFG1_CPU_AUX1)572 return parent_rate;573 574 if (t & CPLL_CFG1_CPU_AUX0)575 return 480000000;576 577 return cpu_pll;578}579 580static unsigned long mt7620_cpu_recalc_rate(struct clk_hw *hw,581 unsigned long parent_rate)582{583 struct mtmips_clk *clk = to_mtmips_clk(hw);584 struct regmap *sysc = clk->priv->sysc;585 u32 t;586 u32 mul;587 u32 div;588 589 regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);590 mul = t & CPU_SYS_CLKCFG_CPU_FFRAC_MASK;591 div = (t >> CPU_SYS_CLKCFG_CPU_FDIV_SHIFT) &592 CPU_SYS_CLKCFG_CPU_FDIV_MASK;593 594 return mt7620_calc_rate(parent_rate, mul, div);595}596 597static unsigned long mt7620_bus_recalc_rate(struct clk_hw *hw,598 unsigned long parent_rate)599{600 static const u32 ocp_dividers[16] = {601 [CPU_SYS_CLKCFG_OCP_RATIO_2] = 2,602 [CPU_SYS_CLKCFG_OCP_RATIO_3] = 3,603 [CPU_SYS_CLKCFG_OCP_RATIO_4] = 4,604 [CPU_SYS_CLKCFG_OCP_RATIO_5] = 5,605 [CPU_SYS_CLKCFG_OCP_RATIO_10] = 10,606 };607 struct mtmips_clk *clk = to_mtmips_clk(hw);608 struct regmap *sysc = clk->priv->sysc;609 u32 t;610 u32 ocp_ratio;611 u32 div;612 613 regmap_read(sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);614 ocp_ratio = (t >> CPU_SYS_CLKCFG_OCP_RATIO_SHIFT) &615 CPU_SYS_CLKCFG_OCP_RATIO_MASK;616 617 if (WARN_ON_ONCE(ocp_ratio >= ARRAY_SIZE(ocp_dividers)))618 return parent_rate;619 620 div = ocp_dividers[ocp_ratio];621 622 if (WARN(!div, "invalid divider for OCP ratio %u", ocp_ratio))623 return parent_rate;624 625 return parent_rate / div;626}627 628static unsigned long mt7620_periph_recalc_rate(struct clk_hw *hw,629 unsigned long parent_rate)630{631 struct mtmips_clk *clk = to_mtmips_clk(hw);632 struct regmap *sysc = clk->priv->sysc;633 u32 t;634 635 regmap_read(sysc, SYSC_REG_CLKCFG0, &t);636 if (t & CLKCFG0_PERI_CLK_SEL)637 return parent_rate;638 639 return 40000000;640}641 642static unsigned long mt76x8_xtal_recalc_rate(struct clk_hw *hw,643 unsigned long parent_rate)644{645 struct mtmips_clk *clk = to_mtmips_clk(hw);646 struct regmap *sysc = clk->priv->sysc;647 u32 t;648 649 regmap_read(sysc, SYSC_REG_SYSTEM_CONFIG, &t);650 if (t & MT7620_XTAL_FREQ_SEL)651 return 40000000;652 653 return 20000000;654}655 656static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw,657 unsigned long xtal_clk)658{659 if (xtal_clk == 40000000)660 return 580000000;661 662 return 575000000;663}664 665#define CLK_BASE(_name, _parent, _recalc) { \666 .init = &(const struct clk_init_data) { \667 .name = _name, \668 .ops = &(const struct clk_ops) { \669 .recalc_rate = _recalc, \670 }, \671 .parent_data = &(const struct clk_parent_data) { \672 .name = _parent, \673 .fw_name = _parent \674 }, \675 .num_parents = _parent ? 1 : 0 \676 }, \677}678 679static struct mtmips_clk rt2880_clks_base[] = {680 { CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) }681};682 683static struct mtmips_clk rt305x_clks_base[] = {684 { CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) }685};686 687static struct mtmips_clk rt3352_clks_base[] = {688 { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) },689 { CLK_BASE("cpu", "xtal", rt3352_cpu_recalc_rate) }690};691 692static struct mtmips_clk rt3883_clks_base[] = {693 { CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) },694 { CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) }695};696 697static struct mtmips_clk rt5350_clks_base[] = {698 { CLK_BASE("xtal", NULL, rt5350_xtal_recalc_rate) },699 { CLK_BASE("cpu", "xtal", rt5350_cpu_recalc_rate) },700 { CLK_BASE("bus", "cpu", rt5350_bus_recalc_rate) }701};702 703static struct mtmips_clk mt7620_clks_base[] = {704 { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) },705 { CLK_BASE("pll", "xtal", mt7620_pll_recalc_rate) },706 { CLK_BASE("cpu", "pll", mt7620_cpu_recalc_rate) },707 { CLK_BASE("periph", "xtal", mt7620_periph_recalc_rate) },708 { CLK_BASE("bus", "cpu", mt7620_bus_recalc_rate) }709};710 711static struct mtmips_clk mt76x8_clks_base[] = {712 { CLK_BASE("xtal", NULL, mt76x8_xtal_recalc_rate) },713 { CLK_BASE("cpu", "xtal", mt76x8_cpu_recalc_rate) }714};715 716static int mtmips_register_clocks(struct device_node *np,717 struct clk_hw_onecell_data *clk_data,718 struct mtmips_clk_priv *priv)719{720 struct clk_hw **hws = clk_data->hws;721 struct mtmips_clk *sclk;722 int ret, i;723 724 for (i = 0; i < priv->data->num_clk_base; i++) {725 sclk = &priv->data->clk_base[i];726 sclk->priv = priv;727 ret = of_clk_hw_register(np, &sclk->hw);728 if (ret) {729 pr_err("Couldn't register top clock %i\n", i);730 goto err_clk_unreg;731 }732 733 hws[i] = &sclk->hw;734 }735 736 return 0;737 738err_clk_unreg:739 while (--i >= 0) {740 sclk = &priv->data->clk_base[i];741 clk_hw_unregister(&sclk->hw);742 }743 return ret;744}745 746static const struct mtmips_clk_data rt2880_clk_data = {747 .clk_base = rt2880_clks_base,748 .num_clk_base = ARRAY_SIZE(rt2880_clks_base),749 .clk_fixed = rt305x_fixed_clocks,750 .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),751 .clk_factor = rt2880_factor_clocks,752 .num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks),753 .clk_periph = rt2880_pherip_clks,754 .num_clk_periph = ARRAY_SIZE(rt2880_pherip_clks),755};756 757static const struct mtmips_clk_data rt305x_clk_data = {758 .clk_base = rt305x_clks_base,759 .num_clk_base = ARRAY_SIZE(rt305x_clks_base),760 .clk_fixed = rt305x_fixed_clocks,761 .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),762 .clk_factor = rt305x_factor_clocks,763 .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),764 .clk_periph = rt305x_pherip_clks,765 .num_clk_periph = ARRAY_SIZE(rt305x_pherip_clks),766};767 768static const struct mtmips_clk_data rt3352_clk_data = {769 .clk_base = rt3352_clks_base,770 .num_clk_base = ARRAY_SIZE(rt3352_clks_base),771 .clk_fixed = rt3352_fixed_clocks,772 .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks),773 .clk_factor = rt305x_factor_clocks,774 .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),775 .clk_periph = rt5350_pherip_clks,776 .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),777};778 779static const struct mtmips_clk_data rt3883_clk_data = {780 .clk_base = rt3883_clks_base,781 .num_clk_base = ARRAY_SIZE(rt3883_clks_base),782 .clk_fixed = rt305x_fixed_clocks,783 .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks),784 .clk_factor = NULL,785 .num_clk_factor = 0,786 .clk_periph = rt5350_pherip_clks,787 .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),788};789 790static const struct mtmips_clk_data rt5350_clk_data = {791 .clk_base = rt5350_clks_base,792 .num_clk_base = ARRAY_SIZE(rt5350_clks_base),793 .clk_fixed = rt3352_fixed_clocks,794 .num_clk_fixed = ARRAY_SIZE(rt3352_fixed_clocks),795 .clk_factor = NULL,796 .num_clk_factor = 0,797 .clk_periph = rt5350_pherip_clks,798 .num_clk_periph = ARRAY_SIZE(rt5350_pherip_clks),799};800 801static const struct mtmips_clk_data mt7620_clk_data = {802 .clk_base = mt7620_clks_base,803 .num_clk_base = ARRAY_SIZE(mt7620_clks_base),804 .clk_fixed = NULL,805 .num_clk_fixed = 0,806 .clk_factor = NULL,807 .num_clk_factor = 0,808 .clk_periph = mt7620_pherip_clks,809 .num_clk_periph = ARRAY_SIZE(mt7620_pherip_clks),810};811 812static const struct mtmips_clk_data mt76x8_clk_data = {813 .clk_base = mt76x8_clks_base,814 .num_clk_base = ARRAY_SIZE(mt76x8_clks_base),815 .clk_fixed = mt76x8_fixed_clocks,816 .num_clk_fixed = ARRAY_SIZE(mt76x8_fixed_clocks),817 .clk_factor = rt305x_factor_clocks,818 .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks),819 .clk_periph = mt76x8_pherip_clks,820 .num_clk_periph = ARRAY_SIZE(mt76x8_pherip_clks),821};822 823static const struct of_device_id mtmips_of_match[] = {824 {825 .compatible = "ralink,rt2880-reset",826 .data = NULL,827 },828 {829 .compatible = "ralink,rt2880-sysc",830 .data = &rt2880_clk_data,831 },832 {833 .compatible = "ralink,rt3050-sysc",834 .data = &rt305x_clk_data,835 },836 {837 .compatible = "ralink,rt3052-sysc",838 .data = &rt305x_clk_data,839 },840 {841 .compatible = "ralink,rt3352-sysc",842 .data = &rt3352_clk_data,843 },844 {845 .compatible = "ralink,rt3883-sysc",846 .data = &rt3883_clk_data,847 },848 {849 .compatible = "ralink,rt5350-sysc",850 .data = &rt5350_clk_data,851 },852 {853 .compatible = "ralink,mt7620-sysc",854 .data = &mt7620_clk_data,855 },856 {857 .compatible = "ralink,mt7628-sysc",858 .data = &mt76x8_clk_data,859 },860 {861 .compatible = "ralink,mt7688-sysc",862 .data = &mt76x8_clk_data,863 },864 {}865};866 867static void __init mtmips_clk_regs_init(struct device_node *node,868 struct mtmips_clk_priv *priv)869{870 u32 t;871 872 if (!of_device_is_compatible(node, "ralink,mt7620-sysc"))873 return;874 875 /*876 * When the CPU goes into sleep mode, the BUS877 * clock will be too low for USB to function properly.878 * Adjust the busses fractional divider to fix this879 */880 regmap_read(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, &t);881 t &= ~(CLKCFG_FDIV_MASK | CLKCFG_FFRAC_MASK);882 t |= CLKCFG_FDIV_USB_VAL | CLKCFG_FFRAC_USB_VAL;883 regmap_write(priv->sysc, SYSC_REG_CPU_SYS_CLKCFG, t);884}885 886static void __init mtmips_clk_init(struct device_node *node)887{888 const struct of_device_id *match;889 const struct mtmips_clk_data *data;890 struct mtmips_clk_priv *priv;891 struct clk_hw_onecell_data *clk_data;892 int ret, i, count;893 894 priv = kzalloc(sizeof(*priv), GFP_KERNEL);895 if (!priv)896 return;897 898 priv->sysc = syscon_node_to_regmap(node);899 if (IS_ERR(priv->sysc)) {900 pr_err("Could not get sysc syscon regmap\n");901 goto free_clk_priv;902 }903 904 mtmips_clk_regs_init(node, priv);905 906 match = of_match_node(mtmips_of_match, node);907 if (WARN_ON(!match))908 return;909 910 data = match->data;911 priv->data = data;912 count = priv->data->num_clk_base + priv->data->num_clk_fixed +913 priv->data->num_clk_factor + priv->data->num_clk_periph;914 clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL);915 if (!clk_data)916 goto free_clk_priv;917 918 ret = mtmips_register_clocks(node, clk_data, priv);919 if (ret) {920 pr_err("Couldn't register top clocks\n");921 goto free_clk_data;922 }923 924 ret = mtmips_register_fixed_clocks(clk_data, priv);925 if (ret) {926 pr_err("Couldn't register fixed clocks\n");927 goto unreg_clk_top;928 }929 930 ret = mtmips_register_factor_clocks(clk_data, priv);931 if (ret) {932 pr_err("Couldn't register factor clocks\n");933 goto unreg_clk_fixed;934 }935 936 ret = mtmips_register_pherip_clocks(node, clk_data, priv);937 if (ret) {938 pr_err("Couldn't register peripheral clocks\n");939 goto unreg_clk_factor;940 }941 942 clk_data->num = count;943 944 ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);945 if (ret) {946 pr_err("Couldn't add clk hw provider\n");947 goto unreg_clk_periph;948 }949 950 return;951 952unreg_clk_periph:953 for (i = 0; i < priv->data->num_clk_periph; i++) {954 struct mtmips_clk *sclk = &priv->data->clk_periph[i];955 956 clk_hw_unregister(&sclk->hw);957 }958 959unreg_clk_factor:960 for (i = 0; i < priv->data->num_clk_factor; i++) {961 struct mtmips_clk_factor *sclk = &priv->data->clk_factor[i];962 963 clk_hw_unregister_fixed_factor(sclk->hw);964 }965 966unreg_clk_fixed:967 for (i = 0; i < priv->data->num_clk_fixed; i++) {968 struct mtmips_clk_fixed *sclk = &priv->data->clk_fixed[i];969 970 clk_hw_unregister_fixed_rate(sclk->hw);971 }972 973unreg_clk_top:974 for (i = 0; i < priv->data->num_clk_base; i++) {975 struct mtmips_clk *sclk = &priv->data->clk_base[i];976 977 clk_hw_unregister(&sclk->hw);978 }979 980free_clk_data:981 kfree(clk_data);982 983free_clk_priv:984 kfree(priv);985}986CLK_OF_DECLARE_DRIVER(rt2880_clk, "ralink,rt2880-sysc", mtmips_clk_init);987CLK_OF_DECLARE_DRIVER(rt3050_clk, "ralink,rt3050-sysc", mtmips_clk_init);988CLK_OF_DECLARE_DRIVER(rt3052_clk, "ralink,rt3052-sysc", mtmips_clk_init);989CLK_OF_DECLARE_DRIVER(rt3352_clk, "ralink,rt3352-sysc", mtmips_clk_init);990CLK_OF_DECLARE_DRIVER(rt3883_clk, "ralink,rt3883-sysc", mtmips_clk_init);991CLK_OF_DECLARE_DRIVER(rt5350_clk, "ralink,rt5350-sysc", mtmips_clk_init);992CLK_OF_DECLARE_DRIVER(mt7620_clk, "ralink,mt7620-sysc", mtmips_clk_init);993CLK_OF_DECLARE_DRIVER(mt7628_clk, "ralink,mt7628-sysc", mtmips_clk_init);994CLK_OF_DECLARE_DRIVER(mt7688_clk, "ralink,mt7688-sysc", mtmips_clk_init);995 996struct mtmips_rst {997 struct reset_controller_dev rcdev;998 struct regmap *sysc;999};1000 1001static struct mtmips_rst *to_mtmips_rst(struct reset_controller_dev *dev)1002{1003 return container_of(dev, struct mtmips_rst, rcdev);1004}1005 1006static int mtmips_assert_device(struct reset_controller_dev *rcdev,1007 unsigned long id)1008{1009 struct mtmips_rst *data = to_mtmips_rst(rcdev);1010 struct regmap *sysc = data->sysc;1011 1012 return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), BIT(id));1013}1014 1015static int mtmips_deassert_device(struct reset_controller_dev *rcdev,1016 unsigned long id)1017{1018 struct mtmips_rst *data = to_mtmips_rst(rcdev);1019 struct regmap *sysc = data->sysc;1020 1021 return regmap_update_bits(sysc, SYSC_REG_RESET_CTRL, BIT(id), 0);1022}1023 1024static int mtmips_reset_device(struct reset_controller_dev *rcdev,1025 unsigned long id)1026{1027 int ret;1028 1029 ret = mtmips_assert_device(rcdev, id);1030 if (ret < 0)1031 return ret;1032 1033 return mtmips_deassert_device(rcdev, id);1034}1035 1036static int mtmips_rst_xlate(struct reset_controller_dev *rcdev,1037 const struct of_phandle_args *reset_spec)1038{1039 unsigned long id = reset_spec->args[0];1040 1041 if (id == 0 || id >= rcdev->nr_resets)1042 return -EINVAL;1043 1044 return id;1045}1046 1047static const struct reset_control_ops reset_ops = {1048 .reset = mtmips_reset_device,1049 .assert = mtmips_assert_device,1050 .deassert = mtmips_deassert_device1051};1052 1053static int mtmips_reset_init(struct device *dev, struct regmap *sysc)1054{1055 struct mtmips_rst *rst_data;1056 1057 rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL);1058 if (!rst_data)1059 return -ENOMEM;1060 1061 rst_data->sysc = sysc;1062 rst_data->rcdev.ops = &reset_ops;1063 rst_data->rcdev.owner = THIS_MODULE;1064 rst_data->rcdev.nr_resets = 32;1065 rst_data->rcdev.of_reset_n_cells = 1;1066 rst_data->rcdev.of_xlate = mtmips_rst_xlate;1067 rst_data->rcdev.of_node = dev_of_node(dev);1068 1069 return devm_reset_controller_register(dev, &rst_data->rcdev);1070}1071 1072static int mtmips_clk_probe(struct platform_device *pdev)1073{1074 struct device_node *np = pdev->dev.of_node;1075 struct device *dev = &pdev->dev;1076 struct mtmips_clk_priv *priv;1077 int ret;1078 1079 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);1080 if (!priv)1081 return -ENOMEM;1082 1083 priv->sysc = syscon_node_to_regmap(np);1084 if (IS_ERR(priv->sysc))1085 return dev_err_probe(dev, PTR_ERR(priv->sysc),1086 "Could not get sysc syscon regmap\n");1087 1088 ret = mtmips_reset_init(dev, priv->sysc);1089 if (ret)1090 return dev_err_probe(dev, ret, "Could not init reset controller\n");1091 1092 return 0;1093}1094 1095static struct platform_driver mtmips_clk_driver = {1096 .probe = mtmips_clk_probe,1097 .driver = {1098 .name = "mtmips-clk",1099 .of_match_table = mtmips_of_match,1100 },1101};1102 1103static int __init mtmips_clk_reset_init(void)1104{1105 return platform_driver_register(&mtmips_clk_driver);1106}1107arch_initcall(mtmips_clk_reset_init);1108