851 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Clock control for Cirrus EP93xx chips.4 * Copyright (C) 2021 Nikita Shubin <nikita.shubin@maquefel.me>5 *6 * Based on a rewrite of arch/arm/mach-ep93xx/clock.c:7 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>8 */9#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt10 11#include <linux/bits.h>12#include <linux/cleanup.h>13#include <linux/clk-provider.h>14#include <linux/math.h>15#include <linux/platform_device.h>16#include <linux/regmap.h>17#include <linux/spinlock.h>18 19#include <linux/soc/cirrus/ep93xx.h>20#include <dt-bindings/clock/cirrus,ep9301-syscon.h>21 22#include <asm/div64.h>23 24#define EP93XX_EXT_CLK_RATE 1474560025#define EP93XX_EXT_RTC_RATE 3276826 27#define EP93XX_SYSCON_POWER_STATE 0x0028#define EP93XX_SYSCON_PWRCNT 0x0429#define EP93XX_SYSCON_PWRCNT_UARTBAUD BIT(29)30#define EP93XX_SYSCON_PWRCNT_USH_EN 2831#define EP93XX_SYSCON_PWRCNT_DMA_M2M1 2732#define EP93XX_SYSCON_PWRCNT_DMA_M2M0 2633#define EP93XX_SYSCON_PWRCNT_DMA_M2P8 2534#define EP93XX_SYSCON_PWRCNT_DMA_M2P9 2435#define EP93XX_SYSCON_PWRCNT_DMA_M2P6 2336#define EP93XX_SYSCON_PWRCNT_DMA_M2P7 2237#define EP93XX_SYSCON_PWRCNT_DMA_M2P4 2138#define EP93XX_SYSCON_PWRCNT_DMA_M2P5 2039#define EP93XX_SYSCON_PWRCNT_DMA_M2P2 1940#define EP93XX_SYSCON_PWRCNT_DMA_M2P3 1841#define EP93XX_SYSCON_PWRCNT_DMA_M2P0 1742#define EP93XX_SYSCON_PWRCNT_DMA_M2P1 1643#define EP93XX_SYSCON_CLKSET1 0x2044#define EP93XX_SYSCON_CLKSET1_NBYP1 BIT(23)45#define EP93XX_SYSCON_CLKSET2 0x2446#define EP93XX_SYSCON_CLKSET2_NBYP2 BIT(19)47#define EP93XX_SYSCON_CLKSET2_PLL2_EN BIT(18)48#define EP93XX_SYSCON_DEVCFG 0x8049#define EP93XX_SYSCON_DEVCFG_U3EN 2450#define EP93XX_SYSCON_DEVCFG_U2EN 2051#define EP93XX_SYSCON_DEVCFG_U1EN 1852#define EP93XX_SYSCON_VIDCLKDIV 0x8453#define EP93XX_SYSCON_CLKDIV_ENABLE 1554#define EP93XX_SYSCON_CLKDIV_ESEL BIT(14)55#define EP93XX_SYSCON_CLKDIV_PSEL BIT(13)56#define EP93XX_SYSCON_CLKDIV_MASK GENMASK(14, 13)57#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT 858#define EP93XX_SYSCON_I2SCLKDIV 0x8c59#define EP93XX_SYSCON_I2SCLKDIV_SENA 3160#define EP93XX_SYSCON_I2SCLKDIV_ORIDE BIT(29)61#define EP93XX_SYSCON_I2SCLKDIV_SPOL BIT(19)62#define EP93XX_SYSCON_KEYTCHCLKDIV 0x9063#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN 3164#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV 1665#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN 1566#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV 067#define EP93XX_SYSCON_CHIPID 0x9468#define EP93XX_SYSCON_CHIPID_ID 0x921369 70#define EP93XX_FIXED_CLK_COUNT 2171 72static const char ep93xx_adc_divisors[] = { 16, 4 };73static const char ep93xx_sclk_divisors[] = { 2, 4 };74static const char ep93xx_lrclk_divisors[] = { 32, 64, 128 };75 76struct ep93xx_clk {77 struct clk_hw hw;78 u16 idx;79 u16 reg;80 u32 mask;81 u8 bit_idx;82 u8 shift;83 u8 width;84 u8 num_div;85 const char *div;86};87 88struct ep93xx_clk_priv {89 spinlock_t lock;90 struct ep93xx_regmap_adev *aux_dev;91 struct device *dev;92 void __iomem *base;93 struct regmap *map;94 struct clk_hw *fixed[EP93XX_FIXED_CLK_COUNT];95 struct ep93xx_clk reg[];96};97 98static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw)99{100 return container_of(hw, struct ep93xx_clk, hw);101}102 103static struct ep93xx_clk_priv *ep93xx_priv_from(struct ep93xx_clk *clk)104{105 return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]);106}107 108static void ep93xx_clk_write(struct ep93xx_clk_priv *priv, unsigned int reg, unsigned int val)109{110 struct ep93xx_regmap_adev *aux = priv->aux_dev;111 112 aux->write(aux->map, aux->lock, reg, val);113}114 115static int ep93xx_clk_is_enabled(struct clk_hw *hw)116{117 struct ep93xx_clk *clk = ep93xx_clk_from(hw);118 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);119 u32 val;120 121 regmap_read(priv->map, clk->reg, &val);122 123 return !!(val & BIT(clk->bit_idx));124}125 126static int ep93xx_clk_enable(struct clk_hw *hw)127{128 struct ep93xx_clk *clk = ep93xx_clk_from(hw);129 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);130 u32 val;131 132 guard(spinlock_irqsave)(&priv->lock);133 134 regmap_read(priv->map, clk->reg, &val);135 val |= BIT(clk->bit_idx);136 137 ep93xx_clk_write(priv, clk->reg, val);138 139 return 0;140}141 142static void ep93xx_clk_disable(struct clk_hw *hw)143{144 struct ep93xx_clk *clk = ep93xx_clk_from(hw);145 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);146 u32 val;147 148 guard(spinlock_irqsave)(&priv->lock);149 150 regmap_read(priv->map, clk->reg, &val);151 val &= ~BIT(clk->bit_idx);152 153 ep93xx_clk_write(priv, clk->reg, val);154}155 156static const struct clk_ops clk_ep93xx_gate_ops = {157 .enable = ep93xx_clk_enable,158 .disable = ep93xx_clk_disable,159 .is_enabled = ep93xx_clk_is_enabled,160};161 162static int ep93xx_clk_register_gate(struct ep93xx_clk *clk,163 const char *name,164 struct clk_parent_data *parent_data,165 unsigned long flags,166 unsigned int reg,167 u8 bit_idx)168{169 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);170 struct clk_init_data init = { };171 172 init.name = name;173 init.ops = &clk_ep93xx_gate_ops;174 init.flags = flags;175 init.parent_data = parent_data;176 init.num_parents = 1;177 178 clk->reg = reg;179 clk->bit_idx = bit_idx;180 clk->hw.init = &init;181 182 return devm_clk_hw_register(priv->dev, &clk->hw);183}184 185static u8 ep93xx_mux_get_parent(struct clk_hw *hw)186{187 struct ep93xx_clk *clk = ep93xx_clk_from(hw);188 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);189 u32 val;190 191 regmap_read(priv->map, clk->reg, &val);192 193 val &= EP93XX_SYSCON_CLKDIV_MASK;194 195 switch (val) {196 case EP93XX_SYSCON_CLKDIV_ESEL:197 return 1; /* PLL1 */198 case EP93XX_SYSCON_CLKDIV_MASK:199 return 2; /* PLL2 */200 default:201 return 0; /* XTALI */202 };203}204 205static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)206{207 struct ep93xx_clk *clk = ep93xx_clk_from(hw);208 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);209 u32 val;210 211 if (index >= 3)212 return -EINVAL;213 214 guard(spinlock_irqsave)(&priv->lock);215 216 regmap_read(priv->map, clk->reg, &val);217 val &= ~(EP93XX_SYSCON_CLKDIV_MASK);218 val |= index > 0 ? EP93XX_SYSCON_CLKDIV_ESEL : 0;219 val |= index > 1 ? EP93XX_SYSCON_CLKDIV_PSEL : 0;220 221 ep93xx_clk_write(priv, clk->reg, val);222 223 return 0;224}225 226static bool is_best(unsigned long rate, unsigned long now,227 unsigned long best)228{229 return abs_diff(rate, now) < abs_diff(rate, best);230}231 232static int ep93xx_mux_determine_rate(struct clk_hw *hw,233 struct clk_rate_request *req)234{235 unsigned long best_rate = 0, actual_rate, mclk_rate;236 unsigned long rate = req->rate;237 struct clk_hw *parent_best = NULL;238 unsigned long parent_rate_best;239 unsigned long parent_rate;240 int div, pdiv;241 unsigned int i;242 243 /*244 * Try the two pll's and the external clock,245 * because the valid predividers are 2, 2.5 and 3, we multiply246 * all the clocks by 2 to avoid floating point math.247 *248 * This is based on the algorithm in the ep93xx raster guide:249 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf250 *251 */252 for (i = 0; i < clk_hw_get_num_parents(hw); i++) {253 struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);254 255 parent_rate = clk_hw_get_rate(parent);256 mclk_rate = parent_rate * 2;257 258 /* Try each predivider value */259 for (pdiv = 4; pdiv <= 6; pdiv++) {260 div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);261 if (!in_range(div, 1, 127))262 continue;263 264 actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);265 if (is_best(rate, actual_rate, best_rate)) {266 best_rate = actual_rate;267 parent_rate_best = parent_rate;268 parent_best = parent;269 }270 }271 }272 273 if (!parent_best)274 return -EINVAL;275 276 req->best_parent_rate = parent_rate_best;277 req->best_parent_hw = parent_best;278 req->rate = best_rate;279 280 return 0;281}282 283static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,284 unsigned long parent_rate)285{286 struct ep93xx_clk *clk = ep93xx_clk_from(hw);287 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);288 unsigned int pdiv, div;289 u32 val;290 291 regmap_read(priv->map, clk->reg, &val);292 pdiv = (val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & GENMASK(1, 0);293 div = val & GENMASK(6, 0);294 if (!div)295 return 0;296 297 return DIV_ROUND_CLOSEST(parent_rate * 2, (pdiv + 3) * div);298}299 300static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,301 unsigned long parent_rate)302{303 struct ep93xx_clk *clk = ep93xx_clk_from(hw);304 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);305 int pdiv, div, npdiv, ndiv;306 unsigned long actual_rate, mclk_rate, rate_err = ULONG_MAX;307 u32 val;308 309 regmap_read(priv->map, clk->reg, &val);310 mclk_rate = parent_rate * 2;311 312 for (pdiv = 4; pdiv <= 6; pdiv++) {313 div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);314 if (!in_range(div, 1, 127))315 continue;316 317 actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);318 if (abs(actual_rate - rate) < rate_err) {319 npdiv = pdiv - 3;320 ndiv = div;321 rate_err = abs(actual_rate - rate);322 }323 }324 325 if (rate_err == ULONG_MAX)326 return -EINVAL;327 328 /*329 * Clear old dividers.330 * Bit 7 is reserved bit in all ClkDiv registers.331 */332 val &= ~(GENMASK(9, 0) & ~BIT(7));333 334 /* Set the new pdiv and div bits for the new clock rate */335 val |= (npdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | ndiv;336 337 ep93xx_clk_write(priv, clk->reg, val);338 339 return 0;340}341 342static const struct clk_ops clk_ddiv_ops = {343 .enable = ep93xx_clk_enable,344 .disable = ep93xx_clk_disable,345 .is_enabled = ep93xx_clk_is_enabled,346 .get_parent = ep93xx_mux_get_parent,347 .set_parent = ep93xx_mux_set_parent_lock,348 .determine_rate = ep93xx_mux_determine_rate,349 .recalc_rate = ep93xx_ddiv_recalc_rate,350 .set_rate = ep93xx_ddiv_set_rate,351};352 353static int ep93xx_clk_register_ddiv(struct ep93xx_clk *clk,354 const char *name,355 struct clk_parent_data *parent_data,356 u8 num_parents,357 unsigned int reg,358 u8 bit_idx)359{360 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);361 struct clk_init_data init = { };362 363 init.name = name;364 init.ops = &clk_ddiv_ops;365 init.flags = 0;366 init.parent_data = parent_data;367 init.num_parents = num_parents;368 369 clk->reg = reg;370 clk->bit_idx = bit_idx;371 clk->hw.init = &init;372 373 return devm_clk_hw_register(priv->dev, &clk->hw);374}375 376static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,377 unsigned long parent_rate)378{379 struct ep93xx_clk *clk = ep93xx_clk_from(hw);380 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);381 u32 val;382 u8 index;383 384 regmap_read(priv->map, clk->reg, &val);385 index = (val & clk->mask) >> clk->shift;386 if (index >= clk->num_div)387 return 0;388 389 return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]);390}391 392static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,393 unsigned long *parent_rate)394{395 struct ep93xx_clk *clk = ep93xx_clk_from(hw);396 unsigned long best = 0, now;397 unsigned int i;398 399 for (i = 0; i < clk->num_div; i++) {400 if ((rate * clk->div[i]) == *parent_rate)401 return rate;402 403 now = DIV_ROUND_CLOSEST(*parent_rate, clk->div[i]);404 if (!best || is_best(rate, now, best))405 best = now;406 }407 408 return best;409}410 411static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,412 unsigned long parent_rate)413{414 struct ep93xx_clk *clk = ep93xx_clk_from(hw);415 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);416 unsigned int i;417 u32 val;418 419 regmap_read(priv->map, clk->reg, &val);420 val &= ~clk->mask;421 for (i = 0; i < clk->num_div; i++)422 if (rate == DIV_ROUND_CLOSEST(parent_rate, clk->div[i]))423 break;424 425 if (i == clk->num_div)426 return -EINVAL;427 428 val |= i << clk->shift;429 430 ep93xx_clk_write(priv, clk->reg, val);431 432 return 0;433}434 435static const struct clk_ops ep93xx_div_ops = {436 .enable = ep93xx_clk_enable,437 .disable = ep93xx_clk_disable,438 .is_enabled = ep93xx_clk_is_enabled,439 .recalc_rate = ep93xx_div_recalc_rate,440 .round_rate = ep93xx_div_round_rate,441 .set_rate = ep93xx_div_set_rate,442};443 444static int ep93xx_register_div(struct ep93xx_clk *clk,445 const char *name,446 const struct clk_parent_data *parent_data,447 unsigned int reg,448 u8 enable_bit,449 u8 shift,450 u8 width,451 const char *clk_divisors,452 u8 num_div)453{454 struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);455 struct clk_init_data init = { };456 457 init.name = name;458 init.ops = &ep93xx_div_ops;459 init.flags = 0;460 init.parent_data = parent_data;461 init.num_parents = 1;462 463 clk->reg = reg;464 clk->bit_idx = enable_bit;465 clk->mask = GENMASK(shift + width - 1, shift);466 clk->shift = shift;467 clk->div = clk_divisors;468 clk->num_div = num_div;469 clk->hw.init = &init;470 471 return devm_clk_hw_register(priv->dev, &clk->hw);472}473 474struct ep93xx_gate {475 unsigned int idx;476 unsigned int bit;477 const char *name;478};479 480static const struct ep93xx_gate ep93xx_uarts[] = {481 { EP93XX_CLK_UART1, EP93XX_SYSCON_DEVCFG_U1EN, "uart1" },482 { EP93XX_CLK_UART2, EP93XX_SYSCON_DEVCFG_U2EN, "uart2" },483 { EP93XX_CLK_UART3, EP93XX_SYSCON_DEVCFG_U3EN, "uart3" },484};485 486static int ep93xx_uart_clock_init(struct ep93xx_clk_priv *priv)487{488 struct clk_parent_data parent_data = { };489 unsigned int i, idx, ret, clk_uart_div;490 struct ep93xx_clk *clk;491 u32 val;492 493 regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val);494 if (val & EP93XX_SYSCON_PWRCNT_UARTBAUD)495 clk_uart_div = 1;496 else497 clk_uart_div = 2;498 499 priv->fixed[EP93XX_CLK_UART] =500 devm_clk_hw_register_fixed_factor_index(priv->dev, "uart",501 0, /* XTALI external clock */502 0, 1, clk_uart_div);503 parent_data.hw = priv->fixed[EP93XX_CLK_UART];504 505 /* parenting uart gate clocks to uart clock */506 for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {507 idx = ep93xx_uarts[i].idx - EP93XX_CLK_UART1;508 clk = &priv->reg[idx];509 clk->idx = idx;510 ret = ep93xx_clk_register_gate(clk,511 ep93xx_uarts[i].name,512 &parent_data, CLK_SET_RATE_PARENT,513 EP93XX_SYSCON_DEVCFG,514 ep93xx_uarts[i].bit);515 if (ret)516 return dev_err_probe(priv->dev, ret,517 "failed to register uart[%d] clock\n", i);518 }519 520 return 0;521}522 523static const struct ep93xx_gate ep93xx_dmas[] = {524 { EP93XX_CLK_M2M0, EP93XX_SYSCON_PWRCNT_DMA_M2M0, "m2m0" },525 { EP93XX_CLK_M2M1, EP93XX_SYSCON_PWRCNT_DMA_M2M1, "m2m1" },526 { EP93XX_CLK_M2P0, EP93XX_SYSCON_PWRCNT_DMA_M2P0, "m2p0" },527 { EP93XX_CLK_M2P1, EP93XX_SYSCON_PWRCNT_DMA_M2P1, "m2p1" },528 { EP93XX_CLK_M2P2, EP93XX_SYSCON_PWRCNT_DMA_M2P2, "m2p2" },529 { EP93XX_CLK_M2P3, EP93XX_SYSCON_PWRCNT_DMA_M2P3, "m2p3" },530 { EP93XX_CLK_M2P4, EP93XX_SYSCON_PWRCNT_DMA_M2P4, "m2p4" },531 { EP93XX_CLK_M2P5, EP93XX_SYSCON_PWRCNT_DMA_M2P5, "m2p5" },532 { EP93XX_CLK_M2P6, EP93XX_SYSCON_PWRCNT_DMA_M2P6, "m2p6" },533 { EP93XX_CLK_M2P7, EP93XX_SYSCON_PWRCNT_DMA_M2P7, "m2p7" },534 { EP93XX_CLK_M2P8, EP93XX_SYSCON_PWRCNT_DMA_M2P8, "m2p8" },535 { EP93XX_CLK_M2P9, EP93XX_SYSCON_PWRCNT_DMA_M2P9, "m2p9" },536};537 538static int ep93xx_dma_clock_init(struct ep93xx_clk_priv *priv)539{540 struct clk_parent_data parent_data = { };541 unsigned int i, idx;542 543 parent_data.hw = priv->fixed[EP93XX_CLK_HCLK];544 for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {545 idx = ep93xx_dmas[i].idx;546 priv->fixed[idx] = devm_clk_hw_register_gate_parent_data(priv->dev,547 ep93xx_dmas[i].name,548 &parent_data, 0,549 priv->base + EP93XX_SYSCON_PWRCNT,550 ep93xx_dmas[i].bit,551 0,552 &priv->lock);553 if (IS_ERR(priv->fixed[idx]))554 return PTR_ERR(priv->fixed[idx]);555 }556 557 return 0;558}559 560static struct clk_hw *of_clk_ep93xx_get(struct of_phandle_args *clkspec, void *data)561{562 struct ep93xx_clk_priv *priv = data;563 unsigned int idx = clkspec->args[0];564 565 if (idx < EP93XX_CLK_UART1)566 return priv->fixed[idx];567 568 if (idx <= EP93XX_CLK_I2S_LRCLK)569 return &priv->reg[idx - EP93XX_CLK_UART1].hw;570 571 return ERR_PTR(-EINVAL);572}573 574/*575 * PLL rate = 14.7456 MHz * (X1FBD + 1) * (X2FBD + 1) / (X2IPD + 1) / 2^PS576 */577static unsigned long calc_pll_rate(u64 rate, u32 config_word)578{579 rate *= ((config_word >> 11) & GENMASK(4, 0)) + 1; /* X1FBD */580 rate *= ((config_word >> 5) & GENMASK(5, 0)) + 1; /* X2FBD */581 do_div(rate, (config_word & GENMASK(4, 0)) + 1); /* X2IPD */582 rate >>= (config_word >> 16) & GENMASK(1, 0); /* PS */583 584 return rate;585}586 587static int ep93xx_plls_init(struct ep93xx_clk_priv *priv)588{589 const char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };590 const char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };591 const char pclk_divisors[] = { 1, 2, 4, 8 };592 struct clk_parent_data xtali = { .index = 0 };593 unsigned int clk_f_div, clk_h_div, clk_p_div;594 unsigned long clk_pll1_rate, clk_pll2_rate;595 struct device *dev = priv->dev;596 struct clk_hw *hw, *pll1;597 u32 value;598 599 /* Determine the bootloader configured pll1 rate */600 regmap_read(priv->map, EP93XX_SYSCON_CLKSET1, &value);601 602 if (value & EP93XX_SYSCON_CLKSET1_NBYP1)603 clk_pll1_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);604 else605 clk_pll1_rate = EP93XX_EXT_CLK_RATE;606 607 pll1 = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll1", &xtali,608 0, clk_pll1_rate);609 if (IS_ERR(pll1))610 return PTR_ERR(pll1);611 612 priv->fixed[EP93XX_CLK_PLL1] = pll1;613 614 /* Initialize the pll1 derived clocks */615 clk_f_div = fclk_divisors[(value >> 25) & GENMASK(2, 0)];616 clk_h_div = hclk_divisors[(value >> 20) & GENMASK(2, 0)];617 clk_p_div = pclk_divisors[(value >> 18) & GENMASK(1, 0)];618 619 hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "fclk", pll1, 0, 1, clk_f_div);620 if (IS_ERR(hw))621 return PTR_ERR(hw);622 623 priv->fixed[EP93XX_CLK_FCLK] = hw;624 625 hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "hclk", pll1, 0, 1, clk_h_div);626 if (IS_ERR(hw))627 return PTR_ERR(hw);628 629 priv->fixed[EP93XX_CLK_HCLK] = hw;630 631 hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "pclk", hw, 0, 1, clk_p_div);632 if (IS_ERR(hw))633 return PTR_ERR(hw);634 635 priv->fixed[EP93XX_CLK_PCLK] = hw;636 637 /* Determine the bootloader configured pll2 rate */638 regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);639 if (!(value & EP93XX_SYSCON_CLKSET2_NBYP2))640 clk_pll2_rate = EP93XX_EXT_CLK_RATE;641 else if (value & EP93XX_SYSCON_CLKSET2_PLL2_EN)642 clk_pll2_rate = calc_pll_rate(EP93XX_EXT_CLK_RATE, value);643 else644 clk_pll2_rate = 0;645 646 hw = devm_clk_hw_register_fixed_rate_parent_data(dev, "pll2", &xtali,647 0, clk_pll2_rate);648 if (IS_ERR(hw))649 return PTR_ERR(hw);650 651 priv->fixed[EP93XX_CLK_PLL2] = hw;652 653 return 0;654}655 656static int ep93xx_clk_probe(struct auxiliary_device *adev,657 const struct auxiliary_device_id *id)658{659 struct ep93xx_regmap_adev *rdev = to_ep93xx_regmap_adev(adev);660 struct clk_parent_data xtali = { .index = 0 };661 struct clk_parent_data ddiv_pdata[3] = { };662 unsigned int clk_spi_div, clk_usb_div;663 struct clk_parent_data pdata = {};664 struct device *dev = &adev->dev;665 struct ep93xx_clk_priv *priv;666 struct ep93xx_clk *clk;667 struct clk_hw *hw;668 unsigned int idx;669 int ret;670 u32 value;671 672 priv = devm_kzalloc(dev, struct_size(priv, reg, 10), GFP_KERNEL);673 if (!priv)674 return -ENOMEM;675 676 spin_lock_init(&priv->lock);677 priv->dev = dev;678 priv->aux_dev = rdev;679 priv->map = rdev->map;680 priv->base = rdev->base;681 682 ret = ep93xx_plls_init(priv);683 if (ret)684 return ret;685 686 regmap_read(priv->map, EP93XX_SYSCON_CLKSET2, &value);687 clk_usb_div = (value >> 28 & GENMASK(3, 0)) + 1;688 hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, "usb_clk",689 priv->fixed[EP93XX_CLK_PLL2], 0, 1,690 clk_usb_div);691 if (IS_ERR(hw))692 return PTR_ERR(hw);693 694 priv->fixed[EP93XX_CLK_USB] = hw;695 696 ret = ep93xx_uart_clock_init(priv);697 if (ret)698 return ret;699 700 ret = ep93xx_dma_clock_init(priv);701 if (ret)702 return ret;703 704 clk_spi_div = id->driver_data;705 hw = devm_clk_hw_register_fixed_factor_index(dev, "ep93xx-spi.0",706 0, /* XTALI external clock */707 0, 1, clk_spi_div);708 if (IS_ERR(hw))709 return PTR_ERR(hw);710 711 priv->fixed[EP93XX_CLK_SPI] = hw;712 713 /* PWM clock */714 hw = devm_clk_hw_register_fixed_factor_index(dev, "pwm_clk", 0, /* XTALI external clock */715 0, 1, 1);716 if (IS_ERR(hw))717 return PTR_ERR(hw);718 719 priv->fixed[EP93XX_CLK_PWM] = hw;720 721 /* USB clock */722 pdata.hw = priv->fixed[EP93XX_CLK_USB];723 hw = devm_clk_hw_register_gate_parent_data(priv->dev, "ohci-platform", &pdata,724 0, priv->base + EP93XX_SYSCON_PWRCNT,725 EP93XX_SYSCON_PWRCNT_USH_EN, 0,726 &priv->lock);727 if (IS_ERR(hw))728 return PTR_ERR(hw);729 730 priv->fixed[EP93XX_CLK_USB] = hw;731 732 ddiv_pdata[0].index = 0; /* XTALI external clock */733 ddiv_pdata[1].hw = priv->fixed[EP93XX_CLK_PLL1];734 ddiv_pdata[2].hw = priv->fixed[EP93XX_CLK_PLL2];735 736 /* touchscreen/ADC clock */737 idx = EP93XX_CLK_ADC - EP93XX_CLK_UART1;738 clk = &priv->reg[idx];739 clk->idx = idx;740 ret = ep93xx_register_div(clk, "ep93xx-adc", &xtali,741 EP93XX_SYSCON_KEYTCHCLKDIV,742 EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,743 EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,744 1,745 ep93xx_adc_divisors,746 ARRAY_SIZE(ep93xx_adc_divisors));747 748 749 /* keypad clock */750 idx = EP93XX_CLK_KEYPAD - EP93XX_CLK_UART1;751 clk = &priv->reg[idx];752 clk->idx = idx;753 ret = ep93xx_register_div(clk, "ep93xx-keypad", &xtali,754 EP93XX_SYSCON_KEYTCHCLKDIV,755 EP93XX_SYSCON_KEYTCHCLKDIV_KEN,756 EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,757 1,758 ep93xx_adc_divisors,759 ARRAY_SIZE(ep93xx_adc_divisors));760 761 /*762 * On reset PDIV and VDIV is set to zero, while PDIV zero763 * means clock disable, VDIV shouldn't be zero.764 * So we set both video and i2s dividers to minimum.765 * ENA - Enable CLK divider.766 * PDIV - 00 - Disable clock767 * VDIV - at least 2768 */769 770 /* Check and enable video clk registers */771 regmap_read(priv->map, EP93XX_SYSCON_VIDCLKDIV, &value);772 value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;773 ep93xx_clk_write(priv, EP93XX_SYSCON_VIDCLKDIV, value);774 775 /* Check and enable i2s clk registers */776 regmap_read(priv->map, EP93XX_SYSCON_I2SCLKDIV, &value);777 value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;778 779 /*780 * Override the SAI_MSTR_CLK_CFG from the I2S block and use the781 * I2SClkDiv Register settings. LRCLK transitions on the falling SCLK782 * edge.783 */784 value |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;785 ep93xx_clk_write(priv, EP93XX_SYSCON_I2SCLKDIV, value);786 787 /* video clk */788 idx = EP93XX_CLK_VIDEO - EP93XX_CLK_UART1;789 clk = &priv->reg[idx];790 clk->idx = idx;791 ret = ep93xx_clk_register_ddiv(clk, "ep93xx-fb",792 ddiv_pdata, ARRAY_SIZE(ddiv_pdata),793 EP93XX_SYSCON_VIDCLKDIV,794 EP93XX_SYSCON_CLKDIV_ENABLE);795 796 /* i2s clk */797 idx = EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1;798 clk = &priv->reg[idx];799 clk->idx = idx;800 ret = ep93xx_clk_register_ddiv(clk, "mclk",801 ddiv_pdata, ARRAY_SIZE(ddiv_pdata),802 EP93XX_SYSCON_I2SCLKDIV,803 EP93XX_SYSCON_CLKDIV_ENABLE);804 805 /* i2s sclk */806 idx = EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1;807 clk = &priv->reg[idx];808 clk->idx = idx;809 pdata.hw = &priv->reg[EP93XX_CLK_I2S_MCLK - EP93XX_CLK_UART1].hw;810 ret = ep93xx_register_div(clk, "sclk", &pdata,811 EP93XX_SYSCON_I2SCLKDIV,812 EP93XX_SYSCON_I2SCLKDIV_SENA,813 16, /* EP93XX_I2SCLKDIV_SDIV_SHIFT */814 1, /* EP93XX_I2SCLKDIV_SDIV_WIDTH */815 ep93xx_sclk_divisors,816 ARRAY_SIZE(ep93xx_sclk_divisors));817 818 /* i2s lrclk */819 idx = EP93XX_CLK_I2S_LRCLK - EP93XX_CLK_UART1;820 clk = &priv->reg[idx];821 clk->idx = idx;822 pdata.hw = &priv->reg[EP93XX_CLK_I2S_SCLK - EP93XX_CLK_UART1].hw;823 ret = ep93xx_register_div(clk, "lrclk", &pdata,824 EP93XX_SYSCON_I2SCLKDIV,825 EP93XX_SYSCON_I2SCLKDIV_SENA,826 17, /* EP93XX_I2SCLKDIV_LRDIV32_SHIFT */827 2, /* EP93XX_I2SCLKDIV_LRDIV32_WIDTH */828 ep93xx_lrclk_divisors,829 ARRAY_SIZE(ep93xx_lrclk_divisors));830 831 /* IrDa clk uses same pattern but no init code presents in original clock driver */832 return devm_of_clk_add_hw_provider(priv->dev, of_clk_ep93xx_get, priv);833}834 835static const struct auxiliary_device_id ep93xx_clk_ids[] = {836 { .name = "soc_ep93xx.clk-ep93xx", .driver_data = 2, },837 { .name = "soc_ep93xx.clk-ep93xx.e2", .driver_data = 1, },838 { /* sentinel */ }839};840MODULE_DEVICE_TABLE(auxiliary, ep93xx_clk_ids);841 842static struct auxiliary_driver ep93xx_clk_driver = {843 .probe = ep93xx_clk_probe,844 .id_table = ep93xx_clk_ids,845};846module_auxiliary_driver(ep93xx_clk_driver);847 848MODULE_LICENSE("GPL");849MODULE_AUTHOR("Nikita Shubin <nikita.shubin@maquefel.me>");850MODULE_DESCRIPTION("Clock control for Cirrus EP93xx chips");851