root/arch/c6x/platforms/plldata.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. c6455_setup_clocks
  2. c6457_setup_clocks
  3. c6472_setup_clocks
  4. c6474_setup_clocks
  5. c6678_setup_clocks
  6. c64x_setup_clocks

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Port on Texas Instruments TMS320C6x architecture
   4  *
   5  *  Copyright (C) 2011 Texas Instruments Incorporated
   6  *  Author: Mark Salter <msalter@redhat.com>
   7  */
   8 #include <linux/kernel.h>
   9 #include <linux/delay.h>
  10 #include <linux/errno.h>
  11 #include <linux/string.h>
  12 #include <linux/ioport.h>
  13 #include <linux/clkdev.h>
  14 #include <linux/of.h>
  15 #include <linux/of_address.h>
  16 
  17 #include <asm/clock.h>
  18 #include <asm/setup.h>
  19 #include <asm/special_insns.h>
  20 #include <asm/irq.h>
  21 
  22 /*
  23  * Common SoC clock support.
  24  */
  25 
  26 /* Default input for PLL1 */
  27 struct clk clkin1 = {
  28         .name = "clkin1",
  29         .node = LIST_HEAD_INIT(clkin1.node),
  30         .children = LIST_HEAD_INIT(clkin1.children),
  31         .childnode = LIST_HEAD_INIT(clkin1.childnode),
  32 };
  33 
  34 struct pll_data c6x_soc_pll1 = {
  35         .num       = 1,
  36         .sysclks   = {
  37                 {
  38                         .name = "pll1",
  39                         .parent = &clkin1,
  40                         .pll_data = &c6x_soc_pll1,
  41                         .flags = CLK_PLL,
  42                 },
  43                 {
  44                         .name = "pll1_sysclk1",
  45                         .parent = &c6x_soc_pll1.sysclks[0],
  46                         .flags = CLK_PLL,
  47                 },
  48                 {
  49                         .name = "pll1_sysclk2",
  50                         .parent = &c6x_soc_pll1.sysclks[0],
  51                         .flags = CLK_PLL,
  52                 },
  53                 {
  54                         .name = "pll1_sysclk3",
  55                         .parent = &c6x_soc_pll1.sysclks[0],
  56                         .flags = CLK_PLL,
  57                 },
  58                 {
  59                         .name = "pll1_sysclk4",
  60                         .parent = &c6x_soc_pll1.sysclks[0],
  61                         .flags = CLK_PLL,
  62                 },
  63                 {
  64                         .name = "pll1_sysclk5",
  65                         .parent = &c6x_soc_pll1.sysclks[0],
  66                         .flags = CLK_PLL,
  67                 },
  68                 {
  69                         .name = "pll1_sysclk6",
  70                         .parent = &c6x_soc_pll1.sysclks[0],
  71                         .flags = CLK_PLL,
  72                 },
  73                 {
  74                         .name = "pll1_sysclk7",
  75                         .parent = &c6x_soc_pll1.sysclks[0],
  76                         .flags = CLK_PLL,
  77                 },
  78                 {
  79                         .name = "pll1_sysclk8",
  80                         .parent = &c6x_soc_pll1.sysclks[0],
  81                         .flags = CLK_PLL,
  82                 },
  83                 {
  84                         .name = "pll1_sysclk9",
  85                         .parent = &c6x_soc_pll1.sysclks[0],
  86                         .flags = CLK_PLL,
  87                 },
  88                 {
  89                         .name = "pll1_sysclk10",
  90                         .parent = &c6x_soc_pll1.sysclks[0],
  91                         .flags = CLK_PLL,
  92                 },
  93                 {
  94                         .name = "pll1_sysclk11",
  95                         .parent = &c6x_soc_pll1.sysclks[0],
  96                         .flags = CLK_PLL,
  97                 },
  98                 {
  99                         .name = "pll1_sysclk12",
 100                         .parent = &c6x_soc_pll1.sysclks[0],
 101                         .flags = CLK_PLL,
 102                 },
 103                 {
 104                         .name = "pll1_sysclk13",
 105                         .parent = &c6x_soc_pll1.sysclks[0],
 106                         .flags = CLK_PLL,
 107                 },
 108                 {
 109                         .name = "pll1_sysclk14",
 110                         .parent = &c6x_soc_pll1.sysclks[0],
 111                         .flags = CLK_PLL,
 112                 },
 113                 {
 114                         .name = "pll1_sysclk15",
 115                         .parent = &c6x_soc_pll1.sysclks[0],
 116                         .flags = CLK_PLL,
 117                 },
 118                 {
 119                         .name = "pll1_sysclk16",
 120                         .parent = &c6x_soc_pll1.sysclks[0],
 121                         .flags = CLK_PLL,
 122                 },
 123         },
 124 };
 125 
 126 /* CPU core clock */
 127 struct clk c6x_core_clk = {
 128         .name = "core",
 129 };
 130 
 131 /* miscellaneous IO clocks */
 132 struct clk c6x_i2c_clk = {
 133         .name = "i2c",
 134 };
 135 
 136 struct clk c6x_watchdog_clk = {
 137         .name = "watchdog",
 138 };
 139 
 140 struct clk c6x_mcbsp1_clk = {
 141         .name = "mcbsp1",
 142 };
 143 
 144 struct clk c6x_mcbsp2_clk = {
 145         .name = "mcbsp2",
 146 };
 147 
 148 struct clk c6x_mdio_clk = {
 149         .name = "mdio",
 150 };
 151 
 152 
 153 #ifdef CONFIG_SOC_TMS320C6455
 154 static struct clk_lookup c6455_clks[] = {
 155         CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
 156         CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
 157         CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
 158         CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
 159         CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
 160         CLK(NULL, "core", &c6x_core_clk),
 161         CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
 162         CLK("watchdog", NULL, &c6x_watchdog_clk),
 163         CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
 164         CLK("", NULL, NULL)
 165 };
 166 
 167 
 168 static void __init c6455_setup_clocks(struct device_node *node)
 169 {
 170         struct pll_data *pll = &c6x_soc_pll1;
 171         struct clk *sysclks = pll->sysclks;
 172 
 173         pll->flags = PLL_HAS_PRE | PLL_HAS_MUL;
 174 
 175         sysclks[2].flags |= FIXED_DIV_PLL;
 176         sysclks[2].div = 3;
 177         sysclks[3].flags |= FIXED_DIV_PLL;
 178         sysclks[3].div = 6;
 179         sysclks[4].div = PLLDIV4;
 180         sysclks[5].div = PLLDIV5;
 181 
 182         c6x_core_clk.parent = &sysclks[0];
 183         c6x_i2c_clk.parent = &sysclks[3];
 184         c6x_watchdog_clk.parent = &sysclks[3];
 185         c6x_mdio_clk.parent = &sysclks[3];
 186 
 187         c6x_clks_init(c6455_clks);
 188 }
 189 #endif /* CONFIG_SOC_TMS320C6455 */
 190 
 191 #ifdef CONFIG_SOC_TMS320C6457
 192 static struct clk_lookup c6457_clks[] = {
 193         CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
 194         CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
 195         CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
 196         CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
 197         CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
 198         CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
 199         CLK(NULL, "core", &c6x_core_clk),
 200         CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
 201         CLK("watchdog", NULL, &c6x_watchdog_clk),
 202         CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
 203         CLK("", NULL, NULL)
 204 };
 205 
 206 static void __init c6457_setup_clocks(struct device_node *node)
 207 {
 208         struct pll_data *pll = &c6x_soc_pll1;
 209         struct clk *sysclks = pll->sysclks;
 210 
 211         pll->flags = PLL_HAS_MUL | PLL_HAS_POST;
 212 
 213         sysclks[1].flags |= FIXED_DIV_PLL;
 214         sysclks[1].div = 1;
 215         sysclks[2].flags |= FIXED_DIV_PLL;
 216         sysclks[2].div = 3;
 217         sysclks[3].flags |= FIXED_DIV_PLL;
 218         sysclks[3].div = 6;
 219         sysclks[4].div = PLLDIV4;
 220         sysclks[5].div = PLLDIV5;
 221 
 222         c6x_core_clk.parent = &sysclks[1];
 223         c6x_i2c_clk.parent = &sysclks[3];
 224         c6x_watchdog_clk.parent = &sysclks[5];
 225         c6x_mdio_clk.parent = &sysclks[5];
 226 
 227         c6x_clks_init(c6457_clks);
 228 }
 229 #endif /* CONFIG_SOC_TMS320C6455 */
 230 
 231 #ifdef CONFIG_SOC_TMS320C6472
 232 static struct clk_lookup c6472_clks[] = {
 233         CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
 234         CLK(NULL, "pll1_sysclk1", &c6x_soc_pll1.sysclks[1]),
 235         CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
 236         CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
 237         CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
 238         CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
 239         CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
 240         CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
 241         CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
 242         CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
 243         CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
 244         CLK(NULL, "core", &c6x_core_clk),
 245         CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
 246         CLK("watchdog", NULL, &c6x_watchdog_clk),
 247         CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
 248         CLK("", NULL, NULL)
 249 };
 250 
 251 /* assumptions used for delay loop calculations */
 252 #define MIN_CLKIN1_KHz 15625
 253 #define MAX_CORE_KHz   700000
 254 #define MIN_PLLOUT_KHz MIN_CLKIN1_KHz
 255 
 256 static void __init c6472_setup_clocks(struct device_node *node)
 257 {
 258         struct pll_data *pll = &c6x_soc_pll1;
 259         struct clk *sysclks = pll->sysclks;
 260         int i;
 261 
 262         pll->flags = PLL_HAS_MUL;
 263 
 264         for (i = 1; i <= 6; i++) {
 265                 sysclks[i].flags |= FIXED_DIV_PLL;
 266                 sysclks[i].div = 1;
 267         }
 268 
 269         sysclks[7].flags |= FIXED_DIV_PLL;
 270         sysclks[7].div = 3;
 271         sysclks[8].flags |= FIXED_DIV_PLL;
 272         sysclks[8].div = 6;
 273         sysclks[9].flags |= FIXED_DIV_PLL;
 274         sysclks[9].div = 2;
 275         sysclks[10].div = PLLDIV10;
 276 
 277         c6x_core_clk.parent = &sysclks[get_coreid() + 1];
 278         c6x_i2c_clk.parent = &sysclks[8];
 279         c6x_watchdog_clk.parent = &sysclks[8];
 280         c6x_mdio_clk.parent = &sysclks[5];
 281 
 282         c6x_clks_init(c6472_clks);
 283 }
 284 #endif /* CONFIG_SOC_TMS320C6472 */
 285 
 286 
 287 #ifdef CONFIG_SOC_TMS320C6474
 288 static struct clk_lookup c6474_clks[] = {
 289         CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
 290         CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
 291         CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
 292         CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
 293         CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
 294         CLK(NULL, "pll1_sysclk12", &c6x_soc_pll1.sysclks[12]),
 295         CLK(NULL, "pll1_sysclk13", &c6x_soc_pll1.sysclks[13]),
 296         CLK(NULL, "core", &c6x_core_clk),
 297         CLK("i2c_davinci.1", NULL, &c6x_i2c_clk),
 298         CLK("mcbsp.1", NULL, &c6x_mcbsp1_clk),
 299         CLK("mcbsp.2", NULL, &c6x_mcbsp2_clk),
 300         CLK("watchdog", NULL, &c6x_watchdog_clk),
 301         CLK("2c81800.mdio", NULL, &c6x_mdio_clk),
 302         CLK("", NULL, NULL)
 303 };
 304 
 305 static void __init c6474_setup_clocks(struct device_node *node)
 306 {
 307         struct pll_data *pll = &c6x_soc_pll1;
 308         struct clk *sysclks = pll->sysclks;
 309 
 310         pll->flags = PLL_HAS_MUL;
 311 
 312         sysclks[7].flags |= FIXED_DIV_PLL;
 313         sysclks[7].div = 1;
 314         sysclks[9].flags |= FIXED_DIV_PLL;
 315         sysclks[9].div = 3;
 316         sysclks[10].flags |= FIXED_DIV_PLL;
 317         sysclks[10].div = 6;
 318 
 319         sysclks[11].div = PLLDIV11;
 320 
 321         sysclks[12].flags |= FIXED_DIV_PLL;
 322         sysclks[12].div = 2;
 323 
 324         sysclks[13].div = PLLDIV13;
 325 
 326         c6x_core_clk.parent = &sysclks[7];
 327         c6x_i2c_clk.parent = &sysclks[10];
 328         c6x_watchdog_clk.parent = &sysclks[10];
 329         c6x_mcbsp1_clk.parent = &sysclks[10];
 330         c6x_mcbsp2_clk.parent = &sysclks[10];
 331 
 332         c6x_clks_init(c6474_clks);
 333 }
 334 #endif /* CONFIG_SOC_TMS320C6474 */
 335 
 336 #ifdef CONFIG_SOC_TMS320C6678
 337 static struct clk_lookup c6678_clks[] = {
 338         CLK(NULL, "pll1", &c6x_soc_pll1.sysclks[0]),
 339         CLK(NULL, "pll1_refclk", &c6x_soc_pll1.sysclks[1]),
 340         CLK(NULL, "pll1_sysclk2", &c6x_soc_pll1.sysclks[2]),
 341         CLK(NULL, "pll1_sysclk3", &c6x_soc_pll1.sysclks[3]),
 342         CLK(NULL, "pll1_sysclk4", &c6x_soc_pll1.sysclks[4]),
 343         CLK(NULL, "pll1_sysclk5", &c6x_soc_pll1.sysclks[5]),
 344         CLK(NULL, "pll1_sysclk6", &c6x_soc_pll1.sysclks[6]),
 345         CLK(NULL, "pll1_sysclk7", &c6x_soc_pll1.sysclks[7]),
 346         CLK(NULL, "pll1_sysclk8", &c6x_soc_pll1.sysclks[8]),
 347         CLK(NULL, "pll1_sysclk9", &c6x_soc_pll1.sysclks[9]),
 348         CLK(NULL, "pll1_sysclk10", &c6x_soc_pll1.sysclks[10]),
 349         CLK(NULL, "pll1_sysclk11", &c6x_soc_pll1.sysclks[11]),
 350         CLK(NULL, "core", &c6x_core_clk),
 351         CLK("", NULL, NULL)
 352 };
 353 
 354 static void __init c6678_setup_clocks(struct device_node *node)
 355 {
 356         struct pll_data *pll = &c6x_soc_pll1;
 357         struct clk *sysclks = pll->sysclks;
 358 
 359         pll->flags = PLL_HAS_MUL;
 360 
 361         sysclks[1].flags |= FIXED_DIV_PLL;
 362         sysclks[1].div = 1;
 363 
 364         sysclks[2].div = PLLDIV2;
 365 
 366         sysclks[3].flags |= FIXED_DIV_PLL;
 367         sysclks[3].div = 2;
 368 
 369         sysclks[4].flags |= FIXED_DIV_PLL;
 370         sysclks[4].div = 3;
 371 
 372         sysclks[5].div = PLLDIV5;
 373 
 374         sysclks[6].flags |= FIXED_DIV_PLL;
 375         sysclks[6].div = 64;
 376 
 377         sysclks[7].flags |= FIXED_DIV_PLL;
 378         sysclks[7].div = 6;
 379 
 380         sysclks[8].div = PLLDIV8;
 381 
 382         sysclks[9].flags |= FIXED_DIV_PLL;
 383         sysclks[9].div = 12;
 384 
 385         sysclks[10].flags |= FIXED_DIV_PLL;
 386         sysclks[10].div = 3;
 387 
 388         sysclks[11].flags |= FIXED_DIV_PLL;
 389         sysclks[11].div = 6;
 390 
 391         c6x_core_clk.parent = &sysclks[0];
 392         c6x_i2c_clk.parent = &sysclks[7];
 393 
 394         c6x_clks_init(c6678_clks);
 395 }
 396 #endif /* CONFIG_SOC_TMS320C6678 */
 397 
 398 static struct of_device_id c6x_clkc_match[] __initdata = {
 399 #ifdef CONFIG_SOC_TMS320C6455
 400         { .compatible = "ti,c6455-pll", .data = c6455_setup_clocks },
 401 #endif
 402 #ifdef CONFIG_SOC_TMS320C6457
 403         { .compatible = "ti,c6457-pll", .data = c6457_setup_clocks },
 404 #endif
 405 #ifdef CONFIG_SOC_TMS320C6472
 406         { .compatible = "ti,c6472-pll", .data = c6472_setup_clocks },
 407 #endif
 408 #ifdef CONFIG_SOC_TMS320C6474
 409         { .compatible = "ti,c6474-pll", .data = c6474_setup_clocks },
 410 #endif
 411 #ifdef CONFIG_SOC_TMS320C6678
 412         { .compatible = "ti,c6678-pll", .data = c6678_setup_clocks },
 413 #endif
 414         { .compatible = "ti,c64x+pll" },
 415         {}
 416 };
 417 
 418 void __init c64x_setup_clocks(void)
 419 {
 420         void (*__setup_clocks)(struct device_node *np);
 421         struct pll_data *pll = &c6x_soc_pll1;
 422         struct device_node *node;
 423         const struct of_device_id *id;
 424         int err;
 425         u32 val;
 426 
 427         node = of_find_matching_node(NULL, c6x_clkc_match);
 428         if (!node)
 429                 return;
 430 
 431         pll->base = of_iomap(node, 0);
 432         if (!pll->base)
 433                 goto out;
 434 
 435         err = of_property_read_u32(node, "clock-frequency", &val);
 436         if (err || val == 0) {
 437                 pr_err("%pOF: no clock-frequency found! Using %dMHz\n",
 438                        node, (int)val / 1000000);
 439                 val = 25000000;
 440         }
 441         clkin1.rate = val;
 442 
 443         err = of_property_read_u32(node, "ti,c64x+pll-bypass-delay", &val);
 444         if (err)
 445                 val = 5000;
 446         pll->bypass_delay = val;
 447 
 448         err = of_property_read_u32(node, "ti,c64x+pll-reset-delay", &val);
 449         if (err)
 450                 val = 30000;
 451         pll->reset_delay = val;
 452 
 453         err = of_property_read_u32(node, "ti,c64x+pll-lock-delay", &val);
 454         if (err)
 455                 val = 30000;
 456         pll->lock_delay = val;
 457 
 458         /* id->data is a pointer to SoC-specific setup */
 459         id = of_match_node(c6x_clkc_match, node);
 460         if (id && id->data) {
 461                 __setup_clocks = id->data;
 462                 __setup_clocks(node);
 463         }
 464 
 465 out:
 466         of_node_put(node);
 467 }

/* [<][>][^][v][top][bottom][index][help] */