root/arch/unicore32/kernel/clock.c

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

DEFINITIONS

This source file includes following definitions.
  1. clk_get
  2. clk_put
  3. clk_enable
  4. clk_disable
  5. clk_get_rate
  6. clk_set_rate
  7. clk_register
  8. clk_unregister
  9. clk_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * linux/arch/unicore32/kernel/clock.c
   4  *
   5  * Code specific to PKUnity SoC and UniCore ISA
   6  *
   7  *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
   8  *      Copyright (C) 2001-2010 Guan Xuetao
   9  */
  10 #include <linux/module.h>
  11 #include <linux/kernel.h>
  12 #include <linux/device.h>
  13 #include <linux/list.h>
  14 #include <linux/errno.h>
  15 #include <linux/err.h>
  16 #include <linux/string.h>
  17 #include <linux/clk.h>
  18 #include <linux/mutex.h>
  19 #include <linux/delay.h>
  20 #include <linux/io.h>
  21 
  22 #include <mach/hardware.h>
  23 
  24 /*
  25  * Very simple clock implementation
  26  */
  27 struct clk {
  28         struct list_head        node;
  29         unsigned long           rate;
  30         const char              *name;
  31 };
  32 
  33 static struct clk clk_ost_clk = {
  34         .name           = "OST_CLK",
  35         .rate           = CLOCK_TICK_RATE,
  36 };
  37 
  38 static struct clk clk_mclk_clk = {
  39         .name           = "MAIN_CLK",
  40 };
  41 
  42 static struct clk clk_bclk32_clk = {
  43         .name           = "BUS32_CLK",
  44 };
  45 
  46 static struct clk clk_ddr_clk = {
  47         .name           = "DDR_CLK",
  48 };
  49 
  50 static struct clk clk_vga_clk = {
  51         .name           = "VGA_CLK",
  52 };
  53 
  54 static LIST_HEAD(clocks);
  55 static DEFINE_MUTEX(clocks_mutex);
  56 
  57 struct clk *clk_get(struct device *dev, const char *id)
  58 {
  59         struct clk *p, *clk = ERR_PTR(-ENOENT);
  60 
  61         mutex_lock(&clocks_mutex);
  62         list_for_each_entry(p, &clocks, node) {
  63                 if (strcmp(id, p->name) == 0) {
  64                         clk = p;
  65                         break;
  66                 }
  67         }
  68         mutex_unlock(&clocks_mutex);
  69 
  70         return clk;
  71 }
  72 EXPORT_SYMBOL(clk_get);
  73 
  74 void clk_put(struct clk *clk)
  75 {
  76 }
  77 EXPORT_SYMBOL(clk_put);
  78 
  79 int clk_enable(struct clk *clk)
  80 {
  81         return 0;
  82 }
  83 EXPORT_SYMBOL(clk_enable);
  84 
  85 void clk_disable(struct clk *clk)
  86 {
  87 }
  88 EXPORT_SYMBOL(clk_disable);
  89 
  90 unsigned long clk_get_rate(struct clk *clk)
  91 {
  92         return clk->rate;
  93 }
  94 EXPORT_SYMBOL(clk_get_rate);
  95 
  96 struct {
  97         unsigned long rate;
  98         unsigned long cfg;
  99         unsigned long div;
 100 } vga_clk_table[] = {
 101         {.rate =  25175000, .cfg = 0x00002001, .div = 0x9},
 102         {.rate =  31500000, .cfg = 0x00002001, .div = 0x7},
 103         {.rate =  40000000, .cfg = 0x00003801, .div = 0x9},
 104         {.rate =  49500000, .cfg = 0x00003801, .div = 0x7},
 105         {.rate =  65000000, .cfg = 0x00002c01, .div = 0x4},
 106         {.rate =  78750000, .cfg = 0x00002400, .div = 0x7},
 107         {.rate = 108000000, .cfg = 0x00002c01, .div = 0x2},
 108         {.rate = 106500000, .cfg = 0x00003c01, .div = 0x3},
 109         {.rate =  50650000, .cfg = 0x00106400, .div = 0x9},
 110         {.rate =  61500000, .cfg = 0x00106400, .div = 0xa},
 111         {.rate =  85500000, .cfg = 0x00002800, .div = 0x6},
 112 };
 113 
 114 struct {
 115         unsigned long mrate;
 116         unsigned long prate;
 117 } mclk_clk_table[] = {
 118         {.mrate = 500000000, .prate = 0x00109801},
 119         {.mrate = 525000000, .prate = 0x00104C00},
 120         {.mrate = 550000000, .prate = 0x00105000},
 121         {.mrate = 575000000, .prate = 0x00105400},
 122         {.mrate = 600000000, .prate = 0x00105800},
 123         {.mrate = 625000000, .prate = 0x00105C00},
 124         {.mrate = 650000000, .prate = 0x00106000},
 125         {.mrate = 675000000, .prate = 0x00106400},
 126         {.mrate = 700000000, .prate = 0x00106800},
 127         {.mrate = 725000000, .prate = 0x00106C00},
 128         {.mrate = 750000000, .prate = 0x00107000},
 129         {.mrate = 775000000, .prate = 0x00107400},
 130         {.mrate = 800000000, .prate = 0x00107800},
 131 };
 132 
 133 int clk_set_rate(struct clk *clk, unsigned long rate)
 134 {
 135         if (clk == &clk_vga_clk) {
 136                 unsigned long pll_vgacfg, pll_vgadiv;
 137                 int ret, i;
 138 
 139                 /* lookup vga_clk_table */
 140                 ret = -EINVAL;
 141                 for (i = 0; i < ARRAY_SIZE(vga_clk_table); i++) {
 142                         if (rate == vga_clk_table[i].rate) {
 143                                 pll_vgacfg = vga_clk_table[i].cfg;
 144                                 pll_vgadiv = vga_clk_table[i].div;
 145                                 ret = 0;
 146                                 break;
 147                         }
 148                 }
 149 
 150                 if (ret)
 151                         return ret;
 152 
 153                 if (readl(PM_PLLVGACFG) == pll_vgacfg)
 154                         return 0;
 155 
 156                 /* set pll vga cfg reg. */
 157                 writel(pll_vgacfg, PM_PLLVGACFG);
 158 
 159                 writel(PM_PMCR_CFBVGA, PM_PMCR);
 160                 while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_VGADFC)
 161                                 != PM_PLLDFCDONE_VGADFC)
 162                         udelay(100); /* about 1ms */
 163 
 164                 /* set div cfg reg. */
 165                 writel(readl(PM_PCGR) | PM_PCGR_VGACLK, PM_PCGR);
 166 
 167                 writel((readl(PM_DIVCFG) & ~PM_DIVCFG_VGACLK_MASK)
 168                                 | PM_DIVCFG_VGACLK(pll_vgadiv), PM_DIVCFG);
 169 
 170                 writel(readl(PM_SWRESET) | PM_SWRESET_VGADIV, PM_SWRESET);
 171                 while ((readl(PM_SWRESET) & PM_SWRESET_VGADIV)
 172                                 == PM_SWRESET_VGADIV)
 173                         udelay(100); /* 65536 bclk32, about 320us */
 174 
 175                 writel(readl(PM_PCGR) & ~PM_PCGR_VGACLK, PM_PCGR);
 176         }
 177 #ifdef CONFIG_CPU_FREQ
 178         if (clk == &clk_mclk_clk) {
 179                 u32 pll_rate, divstatus = readl(PM_DIVSTATUS);
 180                 int ret, i;
 181 
 182                 /* lookup mclk_clk_table */
 183                 ret = -EINVAL;
 184                 for (i = 0; i < ARRAY_SIZE(mclk_clk_table); i++) {
 185                         if (rate == mclk_clk_table[i].mrate) {
 186                                 pll_rate = mclk_clk_table[i].prate;
 187                                 clk_mclk_clk.rate = mclk_clk_table[i].mrate;
 188                                 ret = 0;
 189                                 break;
 190                         }
 191                 }
 192 
 193                 if (ret)
 194                         return ret;
 195 
 196                 if (clk_mclk_clk.rate)
 197                         clk_bclk32_clk.rate = clk_mclk_clk.rate
 198                                 / (((divstatus & 0x0000f000) >> 12) + 1);
 199 
 200                 /* set pll sys cfg reg. */
 201                 writel(pll_rate, PM_PLLSYSCFG);
 202 
 203                 writel(PM_PMCR_CFBSYS, PM_PMCR);
 204                 while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_SYSDFC)
 205                                 != PM_PLLDFCDONE_SYSDFC)
 206                         udelay(100);
 207                         /* about 1ms */
 208         }
 209 #endif
 210         return 0;
 211 }
 212 EXPORT_SYMBOL(clk_set_rate);
 213 
 214 int clk_register(struct clk *clk)
 215 {
 216         mutex_lock(&clocks_mutex);
 217         list_add(&clk->node, &clocks);
 218         mutex_unlock(&clocks_mutex);
 219         printk(KERN_DEFAULT "PKUnity PM: %s %lu.%02luM\n", clk->name,
 220                 (clk->rate)/1000000, (clk->rate)/10000 % 100);
 221         return 0;
 222 }
 223 EXPORT_SYMBOL(clk_register);
 224 
 225 void clk_unregister(struct clk *clk)
 226 {
 227         mutex_lock(&clocks_mutex);
 228         list_del(&clk->node);
 229         mutex_unlock(&clocks_mutex);
 230 }
 231 EXPORT_SYMBOL(clk_unregister);
 232 
 233 struct {
 234         unsigned long prate;
 235         unsigned long rate;
 236 } pllrate_table[] = {
 237         {.prate = 0x00002001, .rate = 250000000},
 238         {.prate = 0x00104801, .rate = 250000000},
 239         {.prate = 0x00104C01, .rate = 262500000},
 240         {.prate = 0x00002401, .rate = 275000000},
 241         {.prate = 0x00105001, .rate = 275000000},
 242         {.prate = 0x00105401, .rate = 287500000},
 243         {.prate = 0x00002801, .rate = 300000000},
 244         {.prate = 0x00105801, .rate = 300000000},
 245         {.prate = 0x00105C01, .rate = 312500000},
 246         {.prate = 0x00002C01, .rate = 325000000},
 247         {.prate = 0x00106001, .rate = 325000000},
 248         {.prate = 0x00106401, .rate = 337500000},
 249         {.prate = 0x00003001, .rate = 350000000},
 250         {.prate = 0x00106801, .rate = 350000000},
 251         {.prate = 0x00106C01, .rate = 362500000},
 252         {.prate = 0x00003401, .rate = 375000000},
 253         {.prate = 0x00107001, .rate = 375000000},
 254         {.prate = 0x00107401, .rate = 387500000},
 255         {.prate = 0x00003801, .rate = 400000000},
 256         {.prate = 0x00107801, .rate = 400000000},
 257         {.prate = 0x00107C01, .rate = 412500000},
 258         {.prate = 0x00003C01, .rate = 425000000},
 259         {.prate = 0x00108001, .rate = 425000000},
 260         {.prate = 0x00108401, .rate = 437500000},
 261         {.prate = 0x00004001, .rate = 450000000},
 262         {.prate = 0x00108801, .rate = 450000000},
 263         {.prate = 0x00108C01, .rate = 462500000},
 264         {.prate = 0x00004401, .rate = 475000000},
 265         {.prate = 0x00109001, .rate = 475000000},
 266         {.prate = 0x00109401, .rate = 487500000},
 267         {.prate = 0x00004801, .rate = 500000000},
 268         {.prate = 0x00109801, .rate = 500000000},
 269         {.prate = 0x00104C00, .rate = 525000000},
 270         {.prate = 0x00002400, .rate = 550000000},
 271         {.prate = 0x00105000, .rate = 550000000},
 272         {.prate = 0x00105400, .rate = 575000000},
 273         {.prate = 0x00002800, .rate = 600000000},
 274         {.prate = 0x00105800, .rate = 600000000},
 275         {.prate = 0x00105C00, .rate = 625000000},
 276         {.prate = 0x00002C00, .rate = 650000000},
 277         {.prate = 0x00106000, .rate = 650000000},
 278         {.prate = 0x00106400, .rate = 675000000},
 279         {.prate = 0x00003000, .rate = 700000000},
 280         {.prate = 0x00106800, .rate = 700000000},
 281         {.prate = 0x00106C00, .rate = 725000000},
 282         {.prate = 0x00003400, .rate = 750000000},
 283         {.prate = 0x00107000, .rate = 750000000},
 284         {.prate = 0x00107400, .rate = 775000000},
 285         {.prate = 0x00003800, .rate = 800000000},
 286         {.prate = 0x00107800, .rate = 800000000},
 287         {.prate = 0x00107C00, .rate = 825000000},
 288         {.prate = 0x00003C00, .rate = 850000000},
 289         {.prate = 0x00108000, .rate = 850000000},
 290         {.prate = 0x00108400, .rate = 875000000},
 291         {.prate = 0x00004000, .rate = 900000000},
 292         {.prate = 0x00108800, .rate = 900000000},
 293         {.prate = 0x00108C00, .rate = 925000000},
 294         {.prate = 0x00004400, .rate = 950000000},
 295         {.prate = 0x00109000, .rate = 950000000},
 296         {.prate = 0x00109400, .rate = 975000000},
 297         {.prate = 0x00004800, .rate = 1000000000},
 298         {.prate = 0x00109800, .rate = 1000000000},
 299 };
 300 
 301 struct {
 302         unsigned long prate;
 303         unsigned long drate;
 304 } pddr_table[] = {
 305         {.prate = 0x00100800, .drate = 44236800},
 306         {.prate = 0x00100C00, .drate = 66355200},
 307         {.prate = 0x00101000, .drate = 88473600},
 308         {.prate = 0x00101400, .drate = 110592000},
 309         {.prate = 0x00101800, .drate = 132710400},
 310         {.prate = 0x00101C01, .drate = 154828800},
 311         {.prate = 0x00102001, .drate = 176947200},
 312         {.prate = 0x00102401, .drate = 199065600},
 313         {.prate = 0x00102801, .drate = 221184000},
 314         {.prate = 0x00102C01, .drate = 243302400},
 315         {.prate = 0x00103001, .drate = 265420800},
 316         {.prate = 0x00103401, .drate = 287539200},
 317         {.prate = 0x00103801, .drate = 309657600},
 318         {.prate = 0x00103C01, .drate = 331776000},
 319         {.prate = 0x00104001, .drate = 353894400},
 320 };
 321 
 322 static int __init clk_init(void)
 323 {
 324 #ifdef CONFIG_PUV3_PM
 325         u32 pllrate, divstatus = readl(PM_DIVSTATUS);
 326         u32 pcgr_val = readl(PM_PCGR);
 327         int i;
 328 
 329         pcgr_val |= PM_PCGR_BCLKMME | PM_PCGR_BCLKH264E | PM_PCGR_BCLKH264D
 330                         | PM_PCGR_HECLK | PM_PCGR_HDCLK;
 331         writel(pcgr_val, PM_PCGR);
 332 
 333         pllrate = readl(PM_PLLSYSSTATUS);
 334 
 335         /* lookup pmclk_table */
 336         clk_mclk_clk.rate = 0;
 337         for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
 338                 if (pllrate == pllrate_table[i].prate) {
 339                         clk_mclk_clk.rate = pllrate_table[i].rate;
 340                         break;
 341                 }
 342         }
 343 
 344         if (clk_mclk_clk.rate)
 345                 clk_bclk32_clk.rate = clk_mclk_clk.rate /
 346                         (((divstatus & 0x0000f000) >> 12) + 1);
 347 
 348         pllrate = readl(PM_PLLDDRSTATUS);
 349 
 350         /* lookup pddr_table */
 351         clk_ddr_clk.rate = 0;
 352         for (i = 0; i < ARRAY_SIZE(pddr_table); i++) {
 353                 if (pllrate == pddr_table[i].prate) {
 354                         clk_ddr_clk.rate = pddr_table[i].drate;
 355                         break;
 356                 }
 357         }
 358 
 359         pllrate = readl(PM_PLLVGASTATUS);
 360 
 361         /* lookup pvga_table */
 362         clk_vga_clk.rate = 0;
 363         for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
 364                 if (pllrate == pllrate_table[i].prate) {
 365                         clk_vga_clk.rate = pllrate_table[i].rate;
 366                         break;
 367                 }
 368         }
 369 
 370         if (clk_vga_clk.rate)
 371                 clk_vga_clk.rate = clk_vga_clk.rate /
 372                         (((divstatus & 0x00f00000) >> 20) + 1);
 373 
 374         clk_register(&clk_vga_clk);
 375 #endif
 376 #ifdef CONFIG_ARCH_FPGA
 377         clk_ddr_clk.rate = 33000000;
 378         clk_mclk_clk.rate = 33000000;
 379         clk_bclk32_clk.rate = 33000000;
 380 #endif
 381         clk_register(&clk_ddr_clk);
 382         clk_register(&clk_mclk_clk);
 383         clk_register(&clk_bclk32_clk);
 384         clk_register(&clk_ost_clk);
 385         return 0;
 386 }
 387 core_initcall(clk_init);

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