Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: ep93xx: add DT support for Cirrus EP93xx

Rewrite EP93xx clock driver located in arch/arm/mach-ep93xx/clock.c
trying to do everything the device tree way:

- provide clock acces via of
- drop clk_hw_register_clkdev
- drop init code and use module_auxiliary_driver

Co-developed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

authored by

Nikita Shubin and committed by
Arnd Bergmann
8a6b7e2b ede5bbe4

+855
+8
drivers/clk/Kconfig
··· 218 218 This driver provides the fixed clocks and gates present on Airoha 219 219 ARM silicon. 220 220 221 + config COMMON_CLK_EP93XX 222 + tristate "Clock driver for Cirrus Logic ep93xx SoC" 223 + depends on ARCH_EP93XX || COMPILE_TEST 224 + select AUXILIARY_BUS 225 + select REGMAP_MMIO 226 + help 227 + This driver supports the SoC clocks on the Cirrus Logic ep93xx. 228 + 221 229 config COMMON_CLK_FSL_FLEXSPI 222 230 tristate "Clock driver for FlexSPI on Layerscape SoCs" 223 231 depends on ARCH_LAYERSCAPE || COMPILE_TEST
+1
drivers/clk/Makefile
··· 30 30 obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o 31 31 obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o 32 32 obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o 33 + obj-$(CONFIG_COMMON_CLK_EP93XX) += clk-ep93xx.o 33 34 obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o 34 35 obj-$(CONFIG_COMMON_CLK_EN7523) += clk-en7523.o 35 36 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
+846
drivers/clk/clk-ep93xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 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 ": " fmt 10 + 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 14745600 25 + #define EP93XX_EXT_RTC_RATE 32768 26 + 27 + #define EP93XX_SYSCON_POWER_STATE 0x00 28 + #define EP93XX_SYSCON_PWRCNT 0x04 29 + #define EP93XX_SYSCON_PWRCNT_UARTBAUD BIT(29) 30 + #define EP93XX_SYSCON_PWRCNT_USH_EN 28 31 + #define EP93XX_SYSCON_PWRCNT_DMA_M2M1 27 32 + #define EP93XX_SYSCON_PWRCNT_DMA_M2M0 26 33 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P8 25 34 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P9 24 35 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P6 23 36 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P7 22 37 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P4 21 38 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P5 20 39 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P2 19 40 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P3 18 41 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P0 17 42 + #define EP93XX_SYSCON_PWRCNT_DMA_M2P1 16 43 + #define EP93XX_SYSCON_CLKSET1 0x20 44 + #define EP93XX_SYSCON_CLKSET1_NBYP1 BIT(23) 45 + #define EP93XX_SYSCON_CLKSET2 0x24 46 + #define EP93XX_SYSCON_CLKSET2_NBYP2 BIT(19) 47 + #define EP93XX_SYSCON_CLKSET2_PLL2_EN BIT(18) 48 + #define EP93XX_SYSCON_DEVCFG 0x80 49 + #define EP93XX_SYSCON_DEVCFG_U3EN 24 50 + #define EP93XX_SYSCON_DEVCFG_U2EN 20 51 + #define EP93XX_SYSCON_DEVCFG_U1EN 18 52 + #define EP93XX_SYSCON_VIDCLKDIV 0x84 53 + #define EP93XX_SYSCON_CLKDIV_ENABLE 15 54 + #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 8 58 + #define EP93XX_SYSCON_I2SCLKDIV 0x8c 59 + #define EP93XX_SYSCON_I2SCLKDIV_SENA 31 60 + #define EP93XX_SYSCON_I2SCLKDIV_ORIDE BIT(29) 61 + #define EP93XX_SYSCON_I2SCLKDIV_SPOL BIT(19) 62 + #define EP93XX_SYSCON_KEYTCHCLKDIV 0x90 63 + #define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN 31 64 + #define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV 16 65 + #define EP93XX_SYSCON_KEYTCHCLKDIV_KEN 15 66 + #define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV 0 67 + #define EP93XX_SYSCON_CHIPID 0x94 68 + #define EP93XX_SYSCON_CHIPID_ID 0x9213 69 + 70 + #define EP93XX_FIXED_CLK_COUNT 21 71 + 72 + static const char ep93xx_adc_divisors[] = { 16, 4 }; 73 + static const char ep93xx_sclk_divisors[] = { 2, 4 }; 74 + static const char ep93xx_lrclk_divisors[] = { 32, 64, 128 }; 75 + 76 + struct 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 + 88 + struct 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 + 98 + static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw) 99 + { 100 + return container_of(hw, struct ep93xx_clk, hw); 101 + } 102 + 103 + static 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 + 108 + static 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 + 115 + static 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 + 126 + static 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 + 142 + static 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 + 156 + static 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 + 162 + static 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 + 185 + static 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 + 205 + static 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 + 226 + static 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 + 232 + static 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 multiply 246 + * 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.pdf 250 + * 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 + 283 + static 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 + 300 + static 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 + 342 + static 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 + 353 + static 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 + 376 + static 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 + 392 + static 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 + 411 + static 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 + 435 + static 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 + 444 + static 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 + 474 + struct ep93xx_gate { 475 + unsigned int idx; 476 + unsigned int bit; 477 + const char *name; 478 + }; 479 + 480 + static 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 + 486 + static 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 + else 497 + 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 + 523 + static 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 + 538 + static 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 + 560 + static 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^PS 576 + */ 577 + static 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 + 587 + static 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 + else 605 + 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 + else 644 + 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 + 656 + static 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 zero 763 + * 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 clock 767 + * VDIV - at least 2 768 + */ 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 the 781 + * I2SClkDiv Register settings. LRCLK transitions on the falling SCLK 782 + * 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 + 835 + static 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 + }; 840 + MODULE_DEVICE_TABLE(auxiliary, ep93xx_clk_ids); 841 + 842 + static struct auxiliary_driver ep93xx_clk_driver = { 843 + .probe = ep93xx_clk_probe, 844 + .id_table = ep93xx_clk_ids, 845 + }; 846 + module_auxiliary_driver(ep93xx_clk_driver);