root/arch/mips/bcm63xx/clk.c

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

DEFINITIONS

This source file includes following definitions.
  1. clk_enable_unlocked
  2. clk_disable_unlocked
  3. bcm_hwclock_set
  4. enet_misc_set
  5. enetx_set
  6. ephy_set
  7. swpkt_sar_set
  8. swpkt_usb_set
  9. enetsw_set
  10. pcm_set
  11. usbh_set
  12. usbd_set
  13. spi_set
  14. hsspi_set
  15. xtm_set
  16. ipsec_set
  17. pcie_set
  18. clk_enable
  19. clk_disable
  20. clk_get_rate
  21. clk_set_rate
  22. clk_round_rate
  23. bcm63xx_clk_init

   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
   7  */
   8 
   9 #include <linux/init.h>
  10 #include <linux/export.h>
  11 #include <linux/mutex.h>
  12 #include <linux/err.h>
  13 #include <linux/clk.h>
  14 #include <linux/clkdev.h>
  15 #include <linux/delay.h>
  16 #include <bcm63xx_cpu.h>
  17 #include <bcm63xx_io.h>
  18 #include <bcm63xx_regs.h>
  19 #include <bcm63xx_reset.h>
  20 
  21 struct clk {
  22         void            (*set)(struct clk *, int);
  23         unsigned int    rate;
  24         unsigned int    usage;
  25         int             id;
  26 };
  27 
  28 static DEFINE_MUTEX(clocks_mutex);
  29 
  30 
  31 static void clk_enable_unlocked(struct clk *clk)
  32 {
  33         if (clk->set && (clk->usage++) == 0)
  34                 clk->set(clk, 1);
  35 }
  36 
  37 static void clk_disable_unlocked(struct clk *clk)
  38 {
  39         if (clk->set && (--clk->usage) == 0)
  40                 clk->set(clk, 0);
  41 }
  42 
  43 static void bcm_hwclock_set(u32 mask, int enable)
  44 {
  45         u32 reg;
  46 
  47         reg = bcm_perf_readl(PERF_CKCTL_REG);
  48         if (enable)
  49                 reg |= mask;
  50         else
  51                 reg &= ~mask;
  52         bcm_perf_writel(reg, PERF_CKCTL_REG);
  53 }
  54 
  55 /*
  56  * Ethernet MAC "misc" clock: dma clocks and main clock on 6348
  57  */
  58 static void enet_misc_set(struct clk *clk, int enable)
  59 {
  60         u32 mask;
  61 
  62         if (BCMCPU_IS_6338())
  63                 mask = CKCTL_6338_ENET_EN;
  64         else if (BCMCPU_IS_6345())
  65                 mask = CKCTL_6345_ENET_EN;
  66         else if (BCMCPU_IS_6348())
  67                 mask = CKCTL_6348_ENET_EN;
  68         else
  69                 /* BCMCPU_IS_6358 */
  70                 mask = CKCTL_6358_EMUSB_EN;
  71         bcm_hwclock_set(mask, enable);
  72 }
  73 
  74 static struct clk clk_enet_misc = {
  75         .set    = enet_misc_set,
  76 };
  77 
  78 /*
  79  * Ethernet MAC clocks: only revelant on 6358, silently enable misc
  80  * clocks
  81  */
  82 static void enetx_set(struct clk *clk, int enable)
  83 {
  84         if (enable)
  85                 clk_enable_unlocked(&clk_enet_misc);
  86         else
  87                 clk_disable_unlocked(&clk_enet_misc);
  88 
  89         if (BCMCPU_IS_3368() || BCMCPU_IS_6358()) {
  90                 u32 mask;
  91 
  92                 if (clk->id == 0)
  93                         mask = CKCTL_6358_ENET0_EN;
  94                 else
  95                         mask = CKCTL_6358_ENET1_EN;
  96                 bcm_hwclock_set(mask, enable);
  97         }
  98 }
  99 
 100 static struct clk clk_enet0 = {
 101         .id     = 0,
 102         .set    = enetx_set,
 103 };
 104 
 105 static struct clk clk_enet1 = {
 106         .id     = 1,
 107         .set    = enetx_set,
 108 };
 109 
 110 /*
 111  * Ethernet PHY clock
 112  */
 113 static void ephy_set(struct clk *clk, int enable)
 114 {
 115         if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
 116                 bcm_hwclock_set(CKCTL_6358_EPHY_EN, enable);
 117 }
 118 
 119 
 120 static struct clk clk_ephy = {
 121         .set    = ephy_set,
 122 };
 123 
 124 /*
 125  * Ethernet switch SAR clock
 126  */
 127 static void swpkt_sar_set(struct clk *clk, int enable)
 128 {
 129         if (BCMCPU_IS_6368())
 130                 bcm_hwclock_set(CKCTL_6368_SWPKT_SAR_EN, enable);
 131         else
 132                 return;
 133 }
 134 
 135 static struct clk clk_swpkt_sar = {
 136         .set    = swpkt_sar_set,
 137 };
 138 
 139 /*
 140  * Ethernet switch USB clock
 141  */
 142 static void swpkt_usb_set(struct clk *clk, int enable)
 143 {
 144         if (BCMCPU_IS_6368())
 145                 bcm_hwclock_set(CKCTL_6368_SWPKT_USB_EN, enable);
 146         else
 147                 return;
 148 }
 149 
 150 static struct clk clk_swpkt_usb = {
 151         .set    = swpkt_usb_set,
 152 };
 153 
 154 /*
 155  * Ethernet switch clock
 156  */
 157 static void enetsw_set(struct clk *clk, int enable)
 158 {
 159         if (BCMCPU_IS_6328()) {
 160                 bcm_hwclock_set(CKCTL_6328_ROBOSW_EN, enable);
 161         } else if (BCMCPU_IS_6362()) {
 162                 bcm_hwclock_set(CKCTL_6362_ROBOSW_EN, enable);
 163         } else if (BCMCPU_IS_6368()) {
 164                 if (enable) {
 165                         clk_enable_unlocked(&clk_swpkt_sar);
 166                         clk_enable_unlocked(&clk_swpkt_usb);
 167                 } else {
 168                         clk_disable_unlocked(&clk_swpkt_usb);
 169                         clk_disable_unlocked(&clk_swpkt_sar);
 170                 }
 171                 bcm_hwclock_set(CKCTL_6368_ROBOSW_EN, enable);
 172         } else {
 173                 return;
 174         }
 175 
 176         if (enable) {
 177                 /* reset switch core afer clock change */
 178                 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
 179                 msleep(10);
 180                 bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 0);
 181                 msleep(10);
 182         }
 183 }
 184 
 185 static struct clk clk_enetsw = {
 186         .set    = enetsw_set,
 187 };
 188 
 189 /*
 190  * PCM clock
 191  */
 192 static void pcm_set(struct clk *clk, int enable)
 193 {
 194         if (BCMCPU_IS_3368())
 195                 bcm_hwclock_set(CKCTL_3368_PCM_EN, enable);
 196         if (BCMCPU_IS_6358())
 197                 bcm_hwclock_set(CKCTL_6358_PCM_EN, enable);
 198 }
 199 
 200 static struct clk clk_pcm = {
 201         .set    = pcm_set,
 202 };
 203 
 204 /*
 205  * USB host clock
 206  */
 207 static void usbh_set(struct clk *clk, int enable)
 208 {
 209         if (BCMCPU_IS_6328())
 210                 bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
 211         else if (BCMCPU_IS_6348())
 212                 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
 213         else if (BCMCPU_IS_6362())
 214                 bcm_hwclock_set(CKCTL_6362_USBH_EN, enable);
 215         else if (BCMCPU_IS_6368())
 216                 bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
 217 }
 218 
 219 static struct clk clk_usbh = {
 220         .set    = usbh_set,
 221 };
 222 
 223 /*
 224  * USB device clock
 225  */
 226 static void usbd_set(struct clk *clk, int enable)
 227 {
 228         if (BCMCPU_IS_6328())
 229                 bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
 230         else if (BCMCPU_IS_6362())
 231                 bcm_hwclock_set(CKCTL_6362_USBD_EN, enable);
 232         else if (BCMCPU_IS_6368())
 233                 bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
 234 }
 235 
 236 static struct clk clk_usbd = {
 237         .set    = usbd_set,
 238 };
 239 
 240 /*
 241  * SPI clock
 242  */
 243 static void spi_set(struct clk *clk, int enable)
 244 {
 245         u32 mask;
 246 
 247         if (BCMCPU_IS_6338())
 248                 mask = CKCTL_6338_SPI_EN;
 249         else if (BCMCPU_IS_6348())
 250                 mask = CKCTL_6348_SPI_EN;
 251         else if (BCMCPU_IS_3368() || BCMCPU_IS_6358())
 252                 mask = CKCTL_6358_SPI_EN;
 253         else if (BCMCPU_IS_6362())
 254                 mask = CKCTL_6362_SPI_EN;
 255         else
 256                 /* BCMCPU_IS_6368 */
 257                 mask = CKCTL_6368_SPI_EN;
 258         bcm_hwclock_set(mask, enable);
 259 }
 260 
 261 static struct clk clk_spi = {
 262         .set    = spi_set,
 263 };
 264 
 265 /*
 266  * HSSPI clock
 267  */
 268 static void hsspi_set(struct clk *clk, int enable)
 269 {
 270         u32 mask;
 271 
 272         if (BCMCPU_IS_6328())
 273                 mask = CKCTL_6328_HSSPI_EN;
 274         else if (BCMCPU_IS_6362())
 275                 mask = CKCTL_6362_HSSPI_EN;
 276         else
 277                 return;
 278 
 279         bcm_hwclock_set(mask, enable);
 280 }
 281 
 282 static struct clk clk_hsspi = {
 283         .set    = hsspi_set,
 284 };
 285 
 286 /*
 287  * HSSPI PLL
 288  */
 289 static struct clk clk_hsspi_pll;
 290 
 291 /*
 292  * XTM clock
 293  */
 294 static void xtm_set(struct clk *clk, int enable)
 295 {
 296         if (!BCMCPU_IS_6368())
 297                 return;
 298 
 299         if (enable)
 300                 clk_enable_unlocked(&clk_swpkt_sar);
 301         else
 302                 clk_disable_unlocked(&clk_swpkt_sar);
 303 
 304         bcm_hwclock_set(CKCTL_6368_SAR_EN, enable);
 305 
 306         if (enable) {
 307                 /* reset sar core afer clock change */
 308                 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 1);
 309                 mdelay(1);
 310                 bcm63xx_core_set_reset(BCM63XX_RESET_SAR, 0);
 311                 mdelay(1);
 312         }
 313 }
 314 
 315 
 316 static struct clk clk_xtm = {
 317         .set    = xtm_set,
 318 };
 319 
 320 /*
 321  * IPsec clock
 322  */
 323 static void ipsec_set(struct clk *clk, int enable)
 324 {
 325         if (BCMCPU_IS_6362())
 326                 bcm_hwclock_set(CKCTL_6362_IPSEC_EN, enable);
 327         else if (BCMCPU_IS_6368())
 328                 bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
 329 }
 330 
 331 static struct clk clk_ipsec = {
 332         .set    = ipsec_set,
 333 };
 334 
 335 /*
 336  * PCIe clock
 337  */
 338 
 339 static void pcie_set(struct clk *clk, int enable)
 340 {
 341         if (BCMCPU_IS_6328())
 342                 bcm_hwclock_set(CKCTL_6328_PCIE_EN, enable);
 343         else if (BCMCPU_IS_6362())
 344                 bcm_hwclock_set(CKCTL_6362_PCIE_EN, enable);
 345 }
 346 
 347 static struct clk clk_pcie = {
 348         .set    = pcie_set,
 349 };
 350 
 351 /*
 352  * Internal peripheral clock
 353  */
 354 static struct clk clk_periph = {
 355         .rate   = (50 * 1000 * 1000),
 356 };
 357 
 358 
 359 /*
 360  * Linux clock API implementation
 361  */
 362 int clk_enable(struct clk *clk)
 363 {
 364         mutex_lock(&clocks_mutex);
 365         clk_enable_unlocked(clk);
 366         mutex_unlock(&clocks_mutex);
 367         return 0;
 368 }
 369 
 370 EXPORT_SYMBOL(clk_enable);
 371 
 372 void clk_disable(struct clk *clk)
 373 {
 374         if (!clk)
 375                 return;
 376 
 377         mutex_lock(&clocks_mutex);
 378         clk_disable_unlocked(clk);
 379         mutex_unlock(&clocks_mutex);
 380 }
 381 
 382 EXPORT_SYMBOL(clk_disable);
 383 
 384 unsigned long clk_get_rate(struct clk *clk)
 385 {
 386         if (!clk)
 387                 return 0;
 388 
 389         return clk->rate;
 390 }
 391 
 392 EXPORT_SYMBOL(clk_get_rate);
 393 
 394 int clk_set_rate(struct clk *clk, unsigned long rate)
 395 {
 396         return 0;
 397 }
 398 EXPORT_SYMBOL_GPL(clk_set_rate);
 399 
 400 long clk_round_rate(struct clk *clk, unsigned long rate)
 401 {
 402         return 0;
 403 }
 404 EXPORT_SYMBOL_GPL(clk_round_rate);
 405 
 406 static struct clk_lookup bcm3368_clks[] = {
 407         /* fixed rate clocks */
 408         CLKDEV_INIT(NULL, "periph", &clk_periph),
 409         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 410         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
 411         /* gated clocks */
 412         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
 413         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
 414         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
 415         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 416         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 417         CLKDEV_INIT(NULL, "spi", &clk_spi),
 418         CLKDEV_INIT(NULL, "pcm", &clk_pcm),
 419         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
 420         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
 421 };
 422 
 423 static struct clk_lookup bcm6328_clks[] = {
 424         /* fixed rate clocks */
 425         CLKDEV_INIT(NULL, "periph", &clk_periph),
 426         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 427         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
 428         CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
 429         /* gated clocks */
 430         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
 431         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 432         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 433         CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
 434         CLKDEV_INIT(NULL, "pcie", &clk_pcie),
 435 };
 436 
 437 static struct clk_lookup bcm6338_clks[] = {
 438         /* fixed rate clocks */
 439         CLKDEV_INIT(NULL, "periph", &clk_periph),
 440         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 441         /* gated clocks */
 442         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
 443         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
 444         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
 445         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 446         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 447         CLKDEV_INIT(NULL, "spi", &clk_spi),
 448         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
 449 };
 450 
 451 static struct clk_lookup bcm6345_clks[] = {
 452         /* fixed rate clocks */
 453         CLKDEV_INIT(NULL, "periph", &clk_periph),
 454         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 455         /* gated clocks */
 456         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
 457         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
 458         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
 459         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 460         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 461         CLKDEV_INIT(NULL, "spi", &clk_spi),
 462         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
 463 };
 464 
 465 static struct clk_lookup bcm6348_clks[] = {
 466         /* fixed rate clocks */
 467         CLKDEV_INIT(NULL, "periph", &clk_periph),
 468         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 469         /* gated clocks */
 470         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
 471         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
 472         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
 473         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 474         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 475         CLKDEV_INIT(NULL, "spi", &clk_spi),
 476         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet_misc),
 477         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet_misc),
 478 };
 479 
 480 static struct clk_lookup bcm6358_clks[] = {
 481         /* fixed rate clocks */
 482         CLKDEV_INIT(NULL, "periph", &clk_periph),
 483         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 484         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
 485         /* gated clocks */
 486         CLKDEV_INIT(NULL, "enet0", &clk_enet0),
 487         CLKDEV_INIT(NULL, "enet1", &clk_enet1),
 488         CLKDEV_INIT(NULL, "ephy", &clk_ephy),
 489         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 490         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 491         CLKDEV_INIT(NULL, "spi", &clk_spi),
 492         CLKDEV_INIT(NULL, "pcm", &clk_pcm),
 493         CLKDEV_INIT(NULL, "swpkt_sar", &clk_swpkt_sar),
 494         CLKDEV_INIT(NULL, "swpkt_usb", &clk_swpkt_usb),
 495         CLKDEV_INIT("bcm63xx_enet.0", "enet", &clk_enet0),
 496         CLKDEV_INIT("bcm63xx_enet.1", "enet", &clk_enet1),
 497 };
 498 
 499 static struct clk_lookup bcm6362_clks[] = {
 500         /* fixed rate clocks */
 501         CLKDEV_INIT(NULL, "periph", &clk_periph),
 502         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 503         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
 504         CLKDEV_INIT("bcm63xx-hsspi.0", "pll", &clk_hsspi_pll),
 505         /* gated clocks */
 506         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
 507         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 508         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 509         CLKDEV_INIT(NULL, "spi", &clk_spi),
 510         CLKDEV_INIT(NULL, "hsspi", &clk_hsspi),
 511         CLKDEV_INIT(NULL, "pcie", &clk_pcie),
 512         CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
 513 };
 514 
 515 static struct clk_lookup bcm6368_clks[] = {
 516         /* fixed rate clocks */
 517         CLKDEV_INIT(NULL, "periph", &clk_periph),
 518         CLKDEV_INIT("bcm63xx_uart.0", "refclk", &clk_periph),
 519         CLKDEV_INIT("bcm63xx_uart.1", "refclk", &clk_periph),
 520         /* gated clocks */
 521         CLKDEV_INIT(NULL, "enetsw", &clk_enetsw),
 522         CLKDEV_INIT(NULL, "usbh", &clk_usbh),
 523         CLKDEV_INIT(NULL, "usbd", &clk_usbd),
 524         CLKDEV_INIT(NULL, "spi", &clk_spi),
 525         CLKDEV_INIT(NULL, "xtm", &clk_xtm),
 526         CLKDEV_INIT(NULL, "ipsec", &clk_ipsec),
 527 };
 528 
 529 #define HSSPI_PLL_HZ_6328       133333333
 530 #define HSSPI_PLL_HZ_6362       400000000
 531 
 532 static int __init bcm63xx_clk_init(void)
 533 {
 534         switch (bcm63xx_get_cpu_id()) {
 535         case BCM3368_CPU_ID:
 536                 clkdev_add_table(bcm3368_clks, ARRAY_SIZE(bcm3368_clks));
 537                 break;
 538         case BCM6328_CPU_ID:
 539                 clk_hsspi_pll.rate = HSSPI_PLL_HZ_6328;
 540                 clkdev_add_table(bcm6328_clks, ARRAY_SIZE(bcm6328_clks));
 541                 break;
 542         case BCM6338_CPU_ID:
 543                 clkdev_add_table(bcm6338_clks, ARRAY_SIZE(bcm6338_clks));
 544                 break;
 545         case BCM6345_CPU_ID:
 546                 clkdev_add_table(bcm6345_clks, ARRAY_SIZE(bcm6345_clks));
 547                 break;
 548         case BCM6348_CPU_ID:
 549                 clkdev_add_table(bcm6348_clks, ARRAY_SIZE(bcm6348_clks));
 550                 break;
 551         case BCM6358_CPU_ID:
 552                 clkdev_add_table(bcm6358_clks, ARRAY_SIZE(bcm6358_clks));
 553                 break;
 554         case BCM6362_CPU_ID:
 555                 clk_hsspi_pll.rate = HSSPI_PLL_HZ_6362;
 556                 clkdev_add_table(bcm6362_clks, ARRAY_SIZE(bcm6362_clks));
 557                 break;
 558         case BCM6368_CPU_ID:
 559                 clkdev_add_table(bcm6368_clks, ARRAY_SIZE(bcm6368_clks));
 560                 break;
 561         }
 562 
 563         return 0;
 564 }
 565 arch_initcall(bcm63xx_clk_init);

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