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

clk: ti: Add support for dm814x ADPLL

On dm814x we have 13 ADPLLs with 3 to 4 outputs on each. The
ADPLLs have several dividers and muxes controlled by a shared
control register for each PLL.

Note that for the clocks to work as device drivers for booting on
dm814x, this patch depends on "ARM: OMAP2+: Change core_initcall
levels to postcore_initcall" that has already been merged.

Also note that this patch does not implement clk_set_rate for the
PLL, that will be posted later on when available.

Cc: Stephen Boyd <sboyd@codeaurora.org>
Acked-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Michael Turquette <mturquette@baylibre.com>

authored by

Tony Lindgren and committed by
Michael Turquette
21330497 92e963f5

+1086
+41
Documentation/devicetree/bindings/clock/ti/adpll.txt
··· 1 + Binding for Texas Instruments ADPLL clock. 2 + 3 + Binding status: Unstable - ABI compatibility may be broken in the future 4 + 5 + This binding uses the common clock binding[1]. It assumes a 6 + register-mapped ADPLL with two to three selectable input clocks 7 + and three to four children. 8 + 9 + [1] Documentation/devicetree/bindings/clock/clock-bindings.txt 10 + 11 + Required properties: 12 + - compatible : shall be one of "ti,dm814-adpll-s-clock" or 13 + "ti,dm814-adpll-lj-clock" depending on the type of the ADPLL 14 + - #clock-cells : from common clock binding; shall be set to 1. 15 + - clocks : link phandles of parent clocks clkinp and clkinpulow, note 16 + that the adpll-s-clock also has an optional clkinphif 17 + - reg : address and length of the register set for controlling the ADPLL. 18 + 19 + Examples: 20 + adpll_mpu_ck: adpll@40 { 21 + #clock-cells = <1>; 22 + compatible = "ti,dm814-adpll-s-clock"; 23 + reg = <0x40 0x40>; 24 + clocks = <&devosc_ck &devosc_ck &devosc_ck>; 25 + clock-names = "clkinp", "clkinpulow", "clkinphif"; 26 + clock-output-names = "481c5040.adpll.dcoclkldo", 27 + "481c5040.adpll.clkout", 28 + "481c5040.adpll.clkoutx2", 29 + "481c5040.adpll.clkouthif"; 30 + }; 31 + 32 + adpll_dsp_ck: adpll@80 { 33 + #clock-cells = <1>; 34 + compatible = "ti,dm814-adpll-lj-clock"; 35 + reg = <0x80 0x30>; 36 + clocks = <&devosc_ck &devosc_ck>; 37 + clock-names = "clkinp", "clkinpulow"; 38 + clock-output-names = "481c5080.adpll.dcoclkldo", 39 + "481c5080.adpll.clkout", 40 + "481c5080.adpll.clkoutldo"; 41 + };
+1
drivers/clk/Kconfig
··· 203 203 source "drivers/clk/bcm/Kconfig" 204 204 source "drivers/clk/hisilicon/Kconfig" 205 205 source "drivers/clk/qcom/Kconfig" 206 + source "drivers/clk/ti/Kconfig" 206 207 207 208 endmenu 208 209
+6
drivers/clk/ti/Kconfig
··· 1 + config COMMON_CLK_TI_ADPLL 2 + tristate "Clock driver for dm814x ADPLL" 3 + depends on ARCH_OMAP2PLUS || COMPILE_TEST 4 + default y if SOC_TI81XX 5 + ---help--- 6 + ADPLL clock driver for the dm814x SoC using common clock framework.
+2
drivers/clk/ti/Makefile
··· 18 18 ifdef CONFIG_ATAGS 19 19 obj-$(CONFIG_ARCH_OMAP3) += clk-3xxx-legacy.o 20 20 endif 21 + 22 + obj-$(CONFIG_COMMON_CLK_TI_ADPLL) += adpll.o
+983
drivers/clk/ti/adpll.c
··· 1 + /* 2 + * This program is free software; you can redistribute it and/or 3 + * modify it under the terms of the GNU General Public License as 4 + * published by the Free Software Foundation version 2. 5 + * 6 + * This program is distributed "as is" WITHOUT ANY WARRANTY of any 7 + * kind, whether express or implied; without even the implied warranty 8 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 9 + * GNU General Public License for more details. 10 + */ 11 + 12 + #include <linux/clk.h> 13 + #include <linux/clkdev.h> 14 + #include <linux/clk-provider.h> 15 + #include <linux/delay.h> 16 + #include <linux/err.h> 17 + #include <linux/math64.h> 18 + #include <linux/module.h> 19 + #include <linux/of_device.h> 20 + #include <linux/string.h> 21 + 22 + #define ADPLL_PLLSS_MMR_LOCK_OFFSET 0x00 /* Managed by MPPULL */ 23 + #define ADPLL_PLLSS_MMR_LOCK_ENABLED 0x1f125B64 24 + #define ADPLL_PLLSS_MMR_UNLOCK_MAGIC 0x1eda4c3d 25 + 26 + #define ADPLL_PWRCTRL_OFFSET 0x00 27 + #define ADPLL_PWRCTRL_PONIN 5 28 + #define ADPLL_PWRCTRL_PGOODIN 4 29 + #define ADPLL_PWRCTRL_RET 3 30 + #define ADPLL_PWRCTRL_ISORET 2 31 + #define ADPLL_PWRCTRL_ISOSCAN 1 32 + #define ADPLL_PWRCTRL_OFFMODE 0 33 + 34 + #define ADPLL_CLKCTRL_OFFSET 0x04 35 + #define ADPLL_CLKCTRL_CLKDCOLDOEN 29 36 + #define ADPLL_CLKCTRL_IDLE 23 37 + #define ADPLL_CLKCTRL_CLKOUTEN 20 38 + #define ADPLL_CLKINPHIFSEL_ADPLL_S 19 /* REVISIT: which bit? */ 39 + #define ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ 19 40 + #define ADPLL_CLKCTRL_ULOWCLKEN 18 41 + #define ADPLL_CLKCTRL_CLKDCOLDOPWDNZ 17 42 + #define ADPLL_CLKCTRL_M2PWDNZ 16 43 + #define ADPLL_CLKCTRL_M3PWDNZ_ADPLL_S 15 44 + #define ADPLL_CLKCTRL_LOWCURRSTDBY_ADPLL_S 13 45 + #define ADPLL_CLKCTRL_LPMODE_ADPLL_S 12 46 + #define ADPLL_CLKCTRL_REGM4XEN_ADPLL_S 10 47 + #define ADPLL_CLKCTRL_SELFREQDCO_ADPLL_LJ 10 48 + #define ADPLL_CLKCTRL_TINITZ 0 49 + 50 + #define ADPLL_TENABLE_OFFSET 0x08 51 + #define ADPLL_TENABLEDIV_OFFSET 0x8c 52 + 53 + #define ADPLL_M2NDIV_OFFSET 0x10 54 + #define ADPLL_M2NDIV_M2 16 55 + #define ADPLL_M2NDIV_M2_ADPLL_S_WIDTH 5 56 + #define ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH 7 57 + 58 + #define ADPLL_MN2DIV_OFFSET 0x14 59 + #define ADPLL_MN2DIV_N2 16 60 + 61 + #define ADPLL_FRACDIV_OFFSET 0x18 62 + #define ADPLL_FRACDIV_REGSD 24 63 + #define ADPLL_FRACDIV_FRACTIONALM 0 64 + #define ADPLL_FRACDIV_FRACTIONALM_MASK 0x3ffff 65 + 66 + #define ADPLL_BWCTRL_OFFSET 0x1c 67 + #define ADPLL_BWCTRL_BWCONTROL 1 68 + #define ADPLL_BWCTRL_BW_INCR_DECRZ 0 69 + 70 + #define ADPLL_RESERVED_OFFSET 0x20 71 + 72 + #define ADPLL_STATUS_OFFSET 0x24 73 + #define ADPLL_STATUS_PONOUT 31 74 + #define ADPLL_STATUS_PGOODOUT 30 75 + #define ADPLL_STATUS_LDOPWDN 29 76 + #define ADPLL_STATUS_RECAL_BSTATUS3 28 77 + #define ADPLL_STATUS_RECAL_OPPIN 27 78 + #define ADPLL_STATUS_PHASELOCK 10 79 + #define ADPLL_STATUS_FREQLOCK 9 80 + #define ADPLL_STATUS_BYPASSACK 8 81 + #define ADPLL_STATUS_LOSSREF 6 82 + #define ADPLL_STATUS_CLKOUTENACK 5 83 + #define ADPLL_STATUS_LOCK2 4 84 + #define ADPLL_STATUS_M2CHANGEACK 3 85 + #define ADPLL_STATUS_HIGHJITTER 1 86 + #define ADPLL_STATUS_BYPASS 0 87 + #define ADPLL_STATUS_PREPARED_MASK (BIT(ADPLL_STATUS_PHASELOCK) | \ 88 + BIT(ADPLL_STATUS_FREQLOCK)) 89 + 90 + #define ADPLL_M3DIV_OFFSET 0x28 /* Only on MPUPLL */ 91 + #define ADPLL_M3DIV_M3 0 92 + #define ADPLL_M3DIV_M3_WIDTH 5 93 + #define ADPLL_M3DIV_M3_MASK 0x1f 94 + 95 + #define ADPLL_RAMPCTRL_OFFSET 0x2c /* Only on MPUPLL */ 96 + #define ADPLL_RAMPCTRL_CLKRAMPLEVEL 19 97 + #define ADPLL_RAMPCTRL_CLKRAMPRATE 16 98 + #define ADPLL_RAMPCTRL_RELOCK_RAMP_EN 0 99 + 100 + #define MAX_ADPLL_INPUTS 3 101 + #define MAX_ADPLL_OUTPUTS 4 102 + #define ADPLL_MAX_RETRIES 5 103 + 104 + #define to_dco(_hw) container_of(_hw, struct ti_adpll_dco_data, hw) 105 + #define to_adpll(_hw) container_of(_hw, struct ti_adpll_data, dco) 106 + #define to_clkout(_hw) container_of(_hw, struct ti_adpll_clkout_data, hw) 107 + 108 + enum ti_adpll_clocks { 109 + TI_ADPLL_DCO, 110 + TI_ADPLL_DCO_GATE, 111 + TI_ADPLL_N2, 112 + TI_ADPLL_M2, 113 + TI_ADPLL_M2_GATE, 114 + TI_ADPLL_BYPASS, 115 + TI_ADPLL_HIF, 116 + TI_ADPLL_DIV2, 117 + TI_ADPLL_CLKOUT, 118 + TI_ADPLL_CLKOUT2, 119 + TI_ADPLL_M3, 120 + }; 121 + 122 + #define TI_ADPLL_NR_CLOCKS (TI_ADPLL_M3 + 1) 123 + 124 + enum ti_adpll_inputs { 125 + TI_ADPLL_CLKINP, 126 + TI_ADPLL_CLKINPULOW, 127 + TI_ADPLL_CLKINPHIF, 128 + }; 129 + 130 + enum ti_adpll_s_outputs { 131 + TI_ADPLL_S_DCOCLKLDO, 132 + TI_ADPLL_S_CLKOUT, 133 + TI_ADPLL_S_CLKOUTX2, 134 + TI_ADPLL_S_CLKOUTHIF, 135 + }; 136 + 137 + enum ti_adpll_lj_outputs { 138 + TI_ADPLL_LJ_CLKDCOLDO, 139 + TI_ADPLL_LJ_CLKOUT, 140 + TI_ADPLL_LJ_CLKOUTLDO, 141 + }; 142 + 143 + struct ti_adpll_platform_data { 144 + const bool is_type_s; 145 + const int nr_max_inputs; 146 + const int nr_max_outputs; 147 + const int output_index; 148 + }; 149 + 150 + struct ti_adpll_clock { 151 + struct clk *clk; 152 + struct clk_lookup *cl; 153 + void (*unregister)(struct clk *clk); 154 + }; 155 + 156 + struct ti_adpll_dco_data { 157 + struct clk_hw hw; 158 + }; 159 + 160 + struct ti_adpll_clkout_data { 161 + struct ti_adpll_data *adpll; 162 + struct clk_gate gate; 163 + struct clk_hw hw; 164 + }; 165 + 166 + struct ti_adpll_data { 167 + struct device *dev; 168 + const struct ti_adpll_platform_data *c; 169 + struct device_node *np; 170 + unsigned long pa; 171 + void __iomem *iobase; 172 + void __iomem *regs; 173 + spinlock_t lock; /* For ADPLL shared register access */ 174 + const char *parent_names[MAX_ADPLL_INPUTS]; 175 + struct clk *parent_clocks[MAX_ADPLL_INPUTS]; 176 + struct ti_adpll_clock *clocks; 177 + struct clk_onecell_data outputs; 178 + struct ti_adpll_dco_data dco; 179 + }; 180 + 181 + static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d, 182 + int output_index, 183 + const char *postfix) 184 + { 185 + const char *name; 186 + int err; 187 + 188 + if (output_index >= 0) { 189 + err = of_property_read_string_index(d->np, 190 + "clock-output-names", 191 + output_index, 192 + &name); 193 + if (err) 194 + return NULL; 195 + } else { 196 + const char *base_name = "adpll"; 197 + char *buf; 198 + 199 + buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 + 200 + strlen(postfix), GFP_KERNEL); 201 + if (!buf) 202 + return NULL; 203 + sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix); 204 + name = buf; 205 + } 206 + 207 + return name; 208 + } 209 + 210 + #define ADPLL_MAX_CON_ID 16 /* See MAX_CON_ID */ 211 + 212 + static int ti_adpll_setup_clock(struct ti_adpll_data *d, struct clk *clock, 213 + int index, int output_index, const char *name, 214 + void (*unregister)(struct clk *clk)) 215 + { 216 + struct clk_lookup *cl; 217 + const char *postfix = NULL; 218 + char con_id[ADPLL_MAX_CON_ID]; 219 + 220 + d->clocks[index].clk = clock; 221 + d->clocks[index].unregister = unregister; 222 + 223 + /* Separate con_id in format "pll040dcoclkldo" to fit MAX_CON_ID */ 224 + postfix = strrchr(name, '.'); 225 + if (strlen(postfix) > 1) { 226 + if (strlen(postfix) > ADPLL_MAX_CON_ID) 227 + dev_warn(d->dev, "clock %s con_id lookup may fail\n", 228 + name); 229 + snprintf(con_id, 16, "pll%03lx%s", d->pa & 0xfff, postfix + 1); 230 + cl = clkdev_create(clock, con_id, NULL); 231 + if (!cl) 232 + return -ENOMEM; 233 + d->clocks[index].cl = cl; 234 + } else { 235 + dev_warn(d->dev, "no con_id for clock %s\n", name); 236 + } 237 + 238 + if (output_index < 0) 239 + return 0; 240 + 241 + d->outputs.clks[output_index] = clock; 242 + d->outputs.clk_num++; 243 + 244 + return 0; 245 + } 246 + 247 + static int ti_adpll_init_divider(struct ti_adpll_data *d, 248 + enum ti_adpll_clocks index, 249 + int output_index, char *name, 250 + struct clk *parent_clock, 251 + void __iomem *reg, 252 + u8 shift, u8 width, 253 + u8 clk_divider_flags) 254 + { 255 + const char *child_name; 256 + const char *parent_name; 257 + struct clk *clock; 258 + 259 + child_name = ti_adpll_clk_get_name(d, output_index, name); 260 + if (!child_name) 261 + return -EINVAL; 262 + 263 + parent_name = __clk_get_name(parent_clock); 264 + clock = clk_register_divider(d->dev, child_name, parent_name, 0, 265 + reg, shift, width, clk_divider_flags, 266 + &d->lock); 267 + if (IS_ERR(clock)) { 268 + dev_err(d->dev, "failed to register divider %s: %li\n", 269 + name, PTR_ERR(clock)); 270 + return PTR_ERR(clock); 271 + } 272 + 273 + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, 274 + clk_unregister_divider); 275 + } 276 + 277 + static int ti_adpll_init_mux(struct ti_adpll_data *d, 278 + enum ti_adpll_clocks index, 279 + char *name, struct clk *clk0, 280 + struct clk *clk1, 281 + void __iomem *reg, 282 + u8 shift) 283 + { 284 + const char *child_name; 285 + const char *parents[2]; 286 + struct clk *clock; 287 + 288 + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); 289 + if (!child_name) 290 + return -ENOMEM; 291 + parents[0] = __clk_get_name(clk0); 292 + parents[1] = __clk_get_name(clk1); 293 + clock = clk_register_mux(d->dev, child_name, parents, 2, 0, 294 + reg, shift, 1, 0, &d->lock); 295 + if (IS_ERR(clock)) { 296 + dev_err(d->dev, "failed to register mux %s: %li\n", 297 + name, PTR_ERR(clock)); 298 + return PTR_ERR(clock); 299 + } 300 + 301 + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, 302 + clk_unregister_mux); 303 + } 304 + 305 + static int ti_adpll_init_gate(struct ti_adpll_data *d, 306 + enum ti_adpll_clocks index, 307 + int output_index, char *name, 308 + struct clk *parent_clock, 309 + void __iomem *reg, 310 + u8 bit_idx, 311 + u8 clk_gate_flags) 312 + { 313 + const char *child_name; 314 + const char *parent_name; 315 + struct clk *clock; 316 + 317 + child_name = ti_adpll_clk_get_name(d, output_index, name); 318 + if (!child_name) 319 + return -EINVAL; 320 + 321 + parent_name = __clk_get_name(parent_clock); 322 + clock = clk_register_gate(d->dev, child_name, parent_name, 0, 323 + reg, bit_idx, clk_gate_flags, 324 + &d->lock); 325 + if (IS_ERR(clock)) { 326 + dev_err(d->dev, "failed to register gate %s: %li\n", 327 + name, PTR_ERR(clock)); 328 + return PTR_ERR(clock); 329 + } 330 + 331 + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, 332 + clk_unregister_gate); 333 + } 334 + 335 + static int ti_adpll_init_fixed_factor(struct ti_adpll_data *d, 336 + enum ti_adpll_clocks index, 337 + char *name, 338 + struct clk *parent_clock, 339 + unsigned int mult, 340 + unsigned int div) 341 + { 342 + const char *child_name; 343 + const char *parent_name; 344 + struct clk *clock; 345 + 346 + child_name = ti_adpll_clk_get_name(d, -ENODEV, name); 347 + if (!child_name) 348 + return -ENOMEM; 349 + 350 + parent_name = __clk_get_name(parent_clock); 351 + clock = clk_register_fixed_factor(d->dev, child_name, parent_name, 352 + 0, mult, div); 353 + if (IS_ERR(clock)) 354 + return PTR_ERR(clock); 355 + 356 + return ti_adpll_setup_clock(d, clock, index, -ENODEV, child_name, 357 + clk_unregister); 358 + } 359 + 360 + static void ti_adpll_set_idle_bypass(struct ti_adpll_data *d) 361 + { 362 + unsigned long flags; 363 + u32 v; 364 + 365 + spin_lock_irqsave(&d->lock, flags); 366 + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); 367 + v |= BIT(ADPLL_CLKCTRL_IDLE); 368 + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); 369 + spin_unlock_irqrestore(&d->lock, flags); 370 + } 371 + 372 + static void ti_adpll_clear_idle_bypass(struct ti_adpll_data *d) 373 + { 374 + unsigned long flags; 375 + u32 v; 376 + 377 + spin_lock_irqsave(&d->lock, flags); 378 + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); 379 + v &= ~BIT(ADPLL_CLKCTRL_IDLE); 380 + writel_relaxed(v, d->regs + ADPLL_CLKCTRL_OFFSET); 381 + spin_unlock_irqrestore(&d->lock, flags); 382 + } 383 + 384 + static bool ti_adpll_clock_is_bypass(struct ti_adpll_data *d) 385 + { 386 + u32 v; 387 + 388 + v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); 389 + 390 + return v & BIT(ADPLL_STATUS_BYPASS); 391 + } 392 + 393 + /* 394 + * Locked and bypass are not actually mutually exclusive: if you only care 395 + * about the DCO clock and not CLKOUT you can clear M2PWDNZ before enabling 396 + * the PLL, resulting in status (FREQLOCK | PHASELOCK | BYPASS) after lock. 397 + */ 398 + static bool ti_adpll_is_locked(struct ti_adpll_data *d) 399 + { 400 + u32 v = readl_relaxed(d->regs + ADPLL_STATUS_OFFSET); 401 + 402 + return (v & ADPLL_STATUS_PREPARED_MASK) == ADPLL_STATUS_PREPARED_MASK; 403 + } 404 + 405 + static int ti_adpll_wait_lock(struct ti_adpll_data *d) 406 + { 407 + int retries = ADPLL_MAX_RETRIES; 408 + 409 + do { 410 + if (ti_adpll_is_locked(d)) 411 + return 0; 412 + usleep_range(200, 300); 413 + } while (retries--); 414 + 415 + dev_err(d->dev, "pll failed to lock\n"); 416 + return -ETIMEDOUT; 417 + } 418 + 419 + static int ti_adpll_prepare(struct clk_hw *hw) 420 + { 421 + struct ti_adpll_dco_data *dco = to_dco(hw); 422 + struct ti_adpll_data *d = to_adpll(dco); 423 + 424 + ti_adpll_clear_idle_bypass(d); 425 + ti_adpll_wait_lock(d); 426 + 427 + return 0; 428 + } 429 + 430 + static void ti_adpll_unprepare(struct clk_hw *hw) 431 + { 432 + struct ti_adpll_dco_data *dco = to_dco(hw); 433 + struct ti_adpll_data *d = to_adpll(dco); 434 + 435 + ti_adpll_set_idle_bypass(d); 436 + } 437 + 438 + static int ti_adpll_is_prepared(struct clk_hw *hw) 439 + { 440 + struct ti_adpll_dco_data *dco = to_dco(hw); 441 + struct ti_adpll_data *d = to_adpll(dco); 442 + 443 + return ti_adpll_is_locked(d); 444 + } 445 + 446 + /* 447 + * Note that the DCO clock is never subject to bypass: if the PLL is off, 448 + * dcoclk is low. 449 + */ 450 + static unsigned long ti_adpll_recalc_rate(struct clk_hw *hw, 451 + unsigned long parent_rate) 452 + { 453 + struct ti_adpll_dco_data *dco = to_dco(hw); 454 + struct ti_adpll_data *d = to_adpll(dco); 455 + u32 frac_m, divider, v; 456 + u64 rate; 457 + unsigned long flags; 458 + 459 + if (ti_adpll_clock_is_bypass(d)) 460 + return 0; 461 + 462 + spin_lock_irqsave(&d->lock, flags); 463 + frac_m = readl_relaxed(d->regs + ADPLL_FRACDIV_OFFSET); 464 + frac_m &= ADPLL_FRACDIV_FRACTIONALM_MASK; 465 + rate = readw_relaxed(d->regs + ADPLL_MN2DIV_OFFSET) << 18; 466 + rate += frac_m; 467 + rate *= parent_rate; 468 + divider = (readw_relaxed(d->regs + ADPLL_M2NDIV_OFFSET) + 1) << 18; 469 + spin_unlock_irqrestore(&d->lock, flags); 470 + 471 + do_div(rate, divider); 472 + 473 + if (d->c->is_type_s) { 474 + v = readl_relaxed(d->regs + ADPLL_CLKCTRL_OFFSET); 475 + if (v & BIT(ADPLL_CLKCTRL_REGM4XEN_ADPLL_S)) 476 + rate *= 4; 477 + rate *= 2; 478 + } 479 + 480 + return rate; 481 + } 482 + 483 + /* PLL parent is always clkinp, bypass only affects the children */ 484 + static u8 ti_adpll_get_parent(struct clk_hw *hw) 485 + { 486 + return 0; 487 + } 488 + 489 + static struct clk_ops ti_adpll_ops = { 490 + .prepare = ti_adpll_prepare, 491 + .unprepare = ti_adpll_unprepare, 492 + .is_prepared = ti_adpll_is_prepared, 493 + .recalc_rate = ti_adpll_recalc_rate, 494 + .get_parent = ti_adpll_get_parent, 495 + }; 496 + 497 + static int ti_adpll_init_dco(struct ti_adpll_data *d) 498 + { 499 + struct clk_init_data init; 500 + struct clk *clock; 501 + const char *postfix; 502 + int width, err; 503 + 504 + d->outputs.clks = devm_kzalloc(d->dev, sizeof(struct clk *) * 505 + MAX_ADPLL_OUTPUTS, 506 + GFP_KERNEL); 507 + if (!d->outputs.clks) 508 + return -ENOMEM; 509 + 510 + if (d->c->output_index < 0) 511 + postfix = "dco"; 512 + else 513 + postfix = NULL; 514 + 515 + init.name = ti_adpll_clk_get_name(d, d->c->output_index, postfix); 516 + if (!init.name) 517 + return -EINVAL; 518 + 519 + init.parent_names = d->parent_names; 520 + init.num_parents = d->c->nr_max_inputs; 521 + init.ops = &ti_adpll_ops; 522 + init.flags = CLK_GET_RATE_NOCACHE; 523 + d->dco.hw.init = &init; 524 + 525 + if (d->c->is_type_s) 526 + width = 5; 527 + else 528 + width = 4; 529 + 530 + /* Internal input clock divider N2 */ 531 + err = ti_adpll_init_divider(d, TI_ADPLL_N2, -ENODEV, "n2", 532 + d->parent_clocks[TI_ADPLL_CLKINP], 533 + d->regs + ADPLL_MN2DIV_OFFSET, 534 + ADPLL_MN2DIV_N2, width, 0); 535 + if (err) 536 + return err; 537 + 538 + clock = devm_clk_register(d->dev, &d->dco.hw); 539 + if (IS_ERR(clock)) 540 + return PTR_ERR(clock); 541 + 542 + return ti_adpll_setup_clock(d, clock, TI_ADPLL_DCO, d->c->output_index, 543 + init.name, NULL); 544 + } 545 + 546 + static int ti_adpll_clkout_enable(struct clk_hw *hw) 547 + { 548 + struct ti_adpll_clkout_data *co = to_clkout(hw); 549 + struct clk_hw *gate_hw = &co->gate.hw; 550 + 551 + __clk_hw_set_clk(gate_hw, hw); 552 + 553 + return clk_gate_ops.enable(gate_hw); 554 + } 555 + 556 + static void ti_adpll_clkout_disable(struct clk_hw *hw) 557 + { 558 + struct ti_adpll_clkout_data *co = to_clkout(hw); 559 + struct clk_hw *gate_hw = &co->gate.hw; 560 + 561 + __clk_hw_set_clk(gate_hw, hw); 562 + clk_gate_ops.disable(gate_hw); 563 + } 564 + 565 + static int ti_adpll_clkout_is_enabled(struct clk_hw *hw) 566 + { 567 + struct ti_adpll_clkout_data *co = to_clkout(hw); 568 + struct clk_hw *gate_hw = &co->gate.hw; 569 + 570 + __clk_hw_set_clk(gate_hw, hw); 571 + 572 + return clk_gate_ops.is_enabled(gate_hw); 573 + } 574 + 575 + /* Setting PLL bypass puts clkout and clkoutx2 into bypass */ 576 + static u8 ti_adpll_clkout_get_parent(struct clk_hw *hw) 577 + { 578 + struct ti_adpll_clkout_data *co = to_clkout(hw); 579 + struct ti_adpll_data *d = co->adpll; 580 + 581 + return ti_adpll_clock_is_bypass(d); 582 + } 583 + 584 + static int ti_adpll_init_clkout(struct ti_adpll_data *d, 585 + enum ti_adpll_clocks index, 586 + int output_index, int gate_bit, 587 + char *name, struct clk *clk0, 588 + struct clk *clk1) 589 + { 590 + struct ti_adpll_clkout_data *co; 591 + struct clk_init_data init; 592 + struct clk_ops *ops; 593 + const char *parent_names[2]; 594 + const char *child_name; 595 + struct clk *clock; 596 + int err; 597 + 598 + co = devm_kzalloc(d->dev, sizeof(*co), GFP_KERNEL); 599 + if (!co) 600 + return -ENOMEM; 601 + co->adpll = d; 602 + 603 + err = of_property_read_string_index(d->np, 604 + "clock-output-names", 605 + output_index, 606 + &child_name); 607 + if (err) 608 + return err; 609 + 610 + ops = devm_kzalloc(d->dev, sizeof(*ops), GFP_KERNEL); 611 + if (!ops) 612 + return -ENOMEM; 613 + 614 + init.name = child_name; 615 + init.ops = ops; 616 + init.flags = CLK_IS_BASIC; 617 + co->hw.init = &init; 618 + parent_names[0] = __clk_get_name(clk0); 619 + parent_names[1] = __clk_get_name(clk1); 620 + init.parent_names = parent_names; 621 + init.num_parents = 2; 622 + 623 + ops->get_parent = ti_adpll_clkout_get_parent; 624 + ops->determine_rate = __clk_mux_determine_rate; 625 + if (gate_bit) { 626 + co->gate.lock = &d->lock; 627 + co->gate.reg = d->regs + ADPLL_CLKCTRL_OFFSET; 628 + co->gate.bit_idx = gate_bit; 629 + ops->enable = ti_adpll_clkout_enable; 630 + ops->disable = ti_adpll_clkout_disable; 631 + ops->is_enabled = ti_adpll_clkout_is_enabled; 632 + } 633 + 634 + clock = devm_clk_register(d->dev, &co->hw); 635 + if (IS_ERR(clock)) { 636 + dev_err(d->dev, "failed to register output %s: %li\n", 637 + name, PTR_ERR(clock)); 638 + return PTR_ERR(clock); 639 + } 640 + 641 + return ti_adpll_setup_clock(d, clock, index, output_index, child_name, 642 + NULL); 643 + } 644 + 645 + static int ti_adpll_init_children_adpll_s(struct ti_adpll_data *d) 646 + { 647 + int err; 648 + 649 + if (!d->c->is_type_s) 650 + return 0; 651 + 652 + /* Internal mux, sources from divider N2 or clkinpulow */ 653 + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", 654 + d->clocks[TI_ADPLL_N2].clk, 655 + d->parent_clocks[TI_ADPLL_CLKINPULOW], 656 + d->regs + ADPLL_CLKCTRL_OFFSET, 657 + ADPLL_CLKCTRL_ULOWCLKEN); 658 + if (err) 659 + return err; 660 + 661 + /* Internal divider M2, sources DCO */ 662 + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, "m2", 663 + d->clocks[TI_ADPLL_DCO].clk, 664 + d->regs + ADPLL_M2NDIV_OFFSET, 665 + ADPLL_M2NDIV_M2, 666 + ADPLL_M2NDIV_M2_ADPLL_S_WIDTH, 667 + CLK_DIVIDER_ONE_BASED); 668 + if (err) 669 + return err; 670 + 671 + /* Internal fixed divider, after M2 before clkout */ 672 + err = ti_adpll_init_fixed_factor(d, TI_ADPLL_DIV2, "div2", 673 + d->clocks[TI_ADPLL_M2].clk, 674 + 1, 2); 675 + if (err) 676 + return err; 677 + 678 + /* Output clkout with a mux and gate, sources from div2 or bypass */ 679 + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, 680 + ADPLL_CLKCTRL_CLKOUTEN, "clkout", 681 + d->clocks[TI_ADPLL_DIV2].clk, 682 + d->clocks[TI_ADPLL_BYPASS].clk); 683 + if (err) 684 + return err; 685 + 686 + /* Output clkoutx2 with a mux and gate, sources from M2 or bypass */ 687 + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT2, TI_ADPLL_S_CLKOUTX2, 0, 688 + "clkout2", d->clocks[TI_ADPLL_M2].clk, 689 + d->clocks[TI_ADPLL_BYPASS].clk); 690 + if (err) 691 + return err; 692 + 693 + /* Internal mux, sources from DCO and clkinphif */ 694 + if (d->parent_clocks[TI_ADPLL_CLKINPHIF]) { 695 + err = ti_adpll_init_mux(d, TI_ADPLL_HIF, "hif", 696 + d->clocks[TI_ADPLL_DCO].clk, 697 + d->parent_clocks[TI_ADPLL_CLKINPHIF], 698 + d->regs + ADPLL_CLKCTRL_OFFSET, 699 + ADPLL_CLKINPHIFSEL_ADPLL_S); 700 + if (err) 701 + return err; 702 + } 703 + 704 + /* Output clkouthif with a divider M3, sources from hif */ 705 + err = ti_adpll_init_divider(d, TI_ADPLL_M3, TI_ADPLL_S_CLKOUTHIF, "m3", 706 + d->clocks[TI_ADPLL_HIF].clk, 707 + d->regs + ADPLL_M3DIV_OFFSET, 708 + ADPLL_M3DIV_M3, 709 + ADPLL_M3DIV_M3_WIDTH, 710 + CLK_DIVIDER_ONE_BASED); 711 + if (err) 712 + return err; 713 + 714 + /* Output clock dcoclkldo is the DCO */ 715 + 716 + return 0; 717 + } 718 + 719 + static int ti_adpll_init_children_adpll_lj(struct ti_adpll_data *d) 720 + { 721 + int err; 722 + 723 + if (d->c->is_type_s) 724 + return 0; 725 + 726 + /* Output clkdcoldo, gated output of DCO */ 727 + err = ti_adpll_init_gate(d, TI_ADPLL_DCO_GATE, TI_ADPLL_LJ_CLKDCOLDO, 728 + "clkdcoldo", d->clocks[TI_ADPLL_DCO].clk, 729 + d->regs + ADPLL_CLKCTRL_OFFSET, 730 + ADPLL_CLKCTRL_CLKDCOLDOEN, 0); 731 + if (err) 732 + return err; 733 + 734 + /* Internal divider M2, sources from DCO */ 735 + err = ti_adpll_init_divider(d, TI_ADPLL_M2, -ENODEV, 736 + "m2", d->clocks[TI_ADPLL_DCO].clk, 737 + d->regs + ADPLL_M2NDIV_OFFSET, 738 + ADPLL_M2NDIV_M2, 739 + ADPLL_M2NDIV_M2_ADPLL_LJ_WIDTH, 740 + CLK_DIVIDER_ONE_BASED); 741 + if (err) 742 + return err; 743 + 744 + /* Output clkoutldo, gated output of M2 */ 745 + err = ti_adpll_init_gate(d, TI_ADPLL_M2_GATE, TI_ADPLL_LJ_CLKOUTLDO, 746 + "clkoutldo", d->clocks[TI_ADPLL_M2].clk, 747 + d->regs + ADPLL_CLKCTRL_OFFSET, 748 + ADPLL_CLKCTRL_CLKOUTLDOEN_ADPLL_LJ, 749 + 0); 750 + if (err) 751 + return err; 752 + 753 + /* Internal mux, sources from divider N2 or clkinpulow */ 754 + err = ti_adpll_init_mux(d, TI_ADPLL_BYPASS, "bypass", 755 + d->clocks[TI_ADPLL_N2].clk, 756 + d->parent_clocks[TI_ADPLL_CLKINPULOW], 757 + d->regs + ADPLL_CLKCTRL_OFFSET, 758 + ADPLL_CLKCTRL_ULOWCLKEN); 759 + if (err) 760 + return err; 761 + 762 + /* Output clkout, sources M2 or bypass */ 763 + err = ti_adpll_init_clkout(d, TI_ADPLL_CLKOUT, TI_ADPLL_S_CLKOUT, 764 + ADPLL_CLKCTRL_CLKOUTEN, "clkout", 765 + d->clocks[TI_ADPLL_M2].clk, 766 + d->clocks[TI_ADPLL_BYPASS].clk); 767 + if (err) 768 + return err; 769 + 770 + return 0; 771 + } 772 + 773 + static void ti_adpll_free_resources(struct ti_adpll_data *d) 774 + { 775 + int i; 776 + 777 + for (i = TI_ADPLL_M3; i >= 0; i--) { 778 + struct ti_adpll_clock *ac = &d->clocks[i]; 779 + 780 + if (!ac || IS_ERR_OR_NULL(ac->clk)) 781 + continue; 782 + if (ac->cl) 783 + clkdev_drop(ac->cl); 784 + if (ac->unregister) 785 + ac->unregister(ac->clk); 786 + } 787 + } 788 + 789 + /* MPU PLL manages the lock register for all PLLs */ 790 + static void ti_adpll_unlock_all(void __iomem *reg) 791 + { 792 + u32 v; 793 + 794 + v = readl_relaxed(reg); 795 + if (v == ADPLL_PLLSS_MMR_LOCK_ENABLED) 796 + writel_relaxed(ADPLL_PLLSS_MMR_UNLOCK_MAGIC, reg); 797 + } 798 + 799 + static int ti_adpll_init_registers(struct ti_adpll_data *d) 800 + { 801 + int register_offset = 0; 802 + 803 + if (d->c->is_type_s) { 804 + register_offset = 8; 805 + ti_adpll_unlock_all(d->iobase + ADPLL_PLLSS_MMR_LOCK_OFFSET); 806 + } 807 + 808 + d->regs = d->iobase + register_offset + ADPLL_PWRCTRL_OFFSET; 809 + 810 + return 0; 811 + } 812 + 813 + static int ti_adpll_init_inputs(struct ti_adpll_data *d) 814 + { 815 + const char *error = "need at least %i inputs"; 816 + struct clk *clock; 817 + int nr_inputs; 818 + 819 + nr_inputs = of_clk_get_parent_count(d->np); 820 + if (nr_inputs < d->c->nr_max_inputs) { 821 + dev_err(d->dev, error, nr_inputs); 822 + return -EINVAL; 823 + } 824 + of_clk_parent_fill(d->np, d->parent_names, nr_inputs); 825 + 826 + clock = devm_clk_get(d->dev, d->parent_names[0]); 827 + if (IS_ERR(clock)) { 828 + dev_err(d->dev, "could not get clkinp\n"); 829 + return PTR_ERR(clock); 830 + } 831 + d->parent_clocks[TI_ADPLL_CLKINP] = clock; 832 + 833 + clock = devm_clk_get(d->dev, d->parent_names[1]); 834 + if (IS_ERR(clock)) { 835 + dev_err(d->dev, "could not get clkinpulow clock\n"); 836 + return PTR_ERR(clock); 837 + } 838 + d->parent_clocks[TI_ADPLL_CLKINPULOW] = clock; 839 + 840 + if (d->c->is_type_s) { 841 + clock = devm_clk_get(d->dev, d->parent_names[2]); 842 + if (IS_ERR(clock)) { 843 + dev_err(d->dev, "could not get clkinphif clock\n"); 844 + return PTR_ERR(clock); 845 + } 846 + d->parent_clocks[TI_ADPLL_CLKINPHIF] = clock; 847 + } 848 + 849 + return 0; 850 + } 851 + 852 + static const struct ti_adpll_platform_data ti_adpll_type_s = { 853 + .is_type_s = true, 854 + .nr_max_inputs = MAX_ADPLL_INPUTS, 855 + .nr_max_outputs = MAX_ADPLL_OUTPUTS, 856 + .output_index = TI_ADPLL_S_DCOCLKLDO, 857 + }; 858 + 859 + static const struct ti_adpll_platform_data ti_adpll_type_lj = { 860 + .is_type_s = false, 861 + .nr_max_inputs = MAX_ADPLL_INPUTS - 1, 862 + .nr_max_outputs = MAX_ADPLL_OUTPUTS - 1, 863 + .output_index = -EINVAL, 864 + }; 865 + 866 + static const struct of_device_id ti_adpll_match[] = { 867 + { .compatible = "ti,dm814-adpll-s-clock", &ti_adpll_type_s }, 868 + { .compatible = "ti,dm814-adpll-lj-clock", &ti_adpll_type_lj }, 869 + {}, 870 + }; 871 + MODULE_DEVICE_TABLE(of, ti_adpll_match); 872 + 873 + static int ti_adpll_probe(struct platform_device *pdev) 874 + { 875 + struct device_node *node = pdev->dev.of_node; 876 + struct device *dev = &pdev->dev; 877 + const struct of_device_id *match; 878 + const struct ti_adpll_platform_data *pdata; 879 + struct ti_adpll_data *d; 880 + struct resource *res; 881 + int err; 882 + 883 + match = of_match_device(ti_adpll_match, dev); 884 + if (match) 885 + pdata = match->data; 886 + else 887 + return -ENODEV; 888 + 889 + d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL); 890 + if (!d) 891 + return -ENOMEM; 892 + d->dev = dev; 893 + d->np = node; 894 + d->c = pdata; 895 + dev_set_drvdata(d->dev, d); 896 + spin_lock_init(&d->lock); 897 + 898 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 899 + if (!res) 900 + return -ENODEV; 901 + d->pa = res->start; 902 + 903 + d->iobase = devm_ioremap_resource(dev, res); 904 + if (IS_ERR(d->iobase)) { 905 + dev_err(dev, "could not get IO base: %li\n", 906 + PTR_ERR(d->iobase)); 907 + return PTR_ERR(d->iobase); 908 + } 909 + 910 + err = ti_adpll_init_registers(d); 911 + if (err) 912 + return err; 913 + 914 + err = ti_adpll_init_inputs(d); 915 + if (err) 916 + return err; 917 + 918 + d->clocks = devm_kzalloc(d->dev, sizeof(struct ti_adpll_clock) * 919 + TI_ADPLL_NR_CLOCKS, 920 + GFP_KERNEL); 921 + if (!d->clocks) 922 + goto free; 923 + 924 + err = ti_adpll_init_dco(d); 925 + if (err) { 926 + dev_err(dev, "could not register dco: %i\n", err); 927 + goto free; 928 + } 929 + 930 + err = ti_adpll_init_children_adpll_s(d); 931 + if (err) 932 + goto free; 933 + err = ti_adpll_init_children_adpll_lj(d); 934 + if (err) 935 + goto free; 936 + 937 + err = of_clk_add_provider(d->np, of_clk_src_onecell_get, &d->outputs); 938 + if (err) 939 + goto free; 940 + 941 + return 0; 942 + 943 + free: 944 + WARN_ON(1); 945 + ti_adpll_free_resources(d); 946 + 947 + return err; 948 + } 949 + 950 + static int ti_adpll_remove(struct platform_device *pdev) 951 + { 952 + struct ti_adpll_data *d = dev_get_drvdata(&pdev->dev); 953 + 954 + ti_adpll_free_resources(d); 955 + 956 + return 0; 957 + } 958 + 959 + static struct platform_driver ti_adpll_driver = { 960 + .driver = { 961 + .name = "ti-adpll", 962 + .of_match_table = ti_adpll_match, 963 + }, 964 + .probe = ti_adpll_probe, 965 + .remove = ti_adpll_remove, 966 + }; 967 + 968 + static int __init ti_adpll_init(void) 969 + { 970 + return platform_driver_register(&ti_adpll_driver); 971 + } 972 + core_initcall(ti_adpll_init); 973 + 974 + static void __exit ti_adpll_exit(void) 975 + { 976 + platform_driver_unregister(&ti_adpll_driver); 977 + } 978 + module_exit(ti_adpll_exit); 979 + 980 + MODULE_DESCRIPTION("Clock driver for dm814x ADPLL"); 981 + MODULE_ALIAS("platform:dm814-adpll-clock"); 982 + MODULE_AUTHOR("Tony LIndgren <tony@atomide.com>"); 983 + MODULE_LICENSE("GPL v2");
+53
drivers/clk/ti/clk-814x.c
··· 5 5 */ 6 6 7 7 #include <linux/kernel.h> 8 + #include <linux/clk.h> 8 9 #include <linux/clk-provider.h> 9 10 #include <linux/clk/ti.h> 11 + #include <linux/of_platform.h> 10 12 11 13 #include "clock.h" 12 14 ··· 29 27 { .node_name = NULL }, 30 28 }; 31 29 30 + static bool timer_clocks_initialized; 31 + 32 + int __init dm814x_adpll_early_init(void) 33 + { 34 + struct device_node *np; 35 + 36 + if (!timer_clocks_initialized) 37 + return -ENODEV; 38 + 39 + np = of_find_node_by_name(NULL, "pllss"); 40 + if (!np) { 41 + pr_err("Could not find node for plls\n"); 42 + return -ENODEV; 43 + } 44 + 45 + of_platform_populate(np, NULL, NULL, NULL); 46 + 47 + return 0; 48 + } 49 + core_initcall(dm814x_adpll_early_init); 50 + 51 + static const char * const init_clocks[] = { 52 + "pll040clkout", /* MPU 481c5040.adpll.clkout */ 53 + "pll290clkout", /* DDR 481c5290.adpll.clkout */ 54 + }; 55 + 56 + int __init dm814x_adpll_enable_init_clocks(void) 57 + { 58 + int i, err; 59 + 60 + if (!timer_clocks_initialized) 61 + return -ENODEV; 62 + 63 + for (i = 0; i < ARRAY_SIZE(init_clocks); i++) { 64 + struct clk *clock; 65 + 66 + clock = clk_get(NULL, init_clocks[i]); 67 + if (WARN(IS_ERR(clock), "could not find init clock %s\n", 68 + init_clocks[i])) 69 + continue; 70 + err = clk_prepare_enable(clock); 71 + if (WARN(err, "could not enable init clock %s\n", 72 + init_clocks[i])) 73 + continue; 74 + } 75 + 76 + return 0; 77 + } 78 + postcore_initcall(dm814x_adpll_enable_init_clocks); 79 + 32 80 int __init dm814x_dt_clk_init(void) 33 81 { 34 82 ti_dt_clocks_register(dm814_clks); 35 83 omap2_clk_disable_autoidle_all(); 36 84 omap2_clk_enable_init_clocks(NULL, 0); 85 + timer_clocks_initialized = true; 37 86 38 87 return 0; 39 88 }