clksel.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. /*
  2. * linux/arch/arm/mach-w90x900/clksel.c
  3. *
  4. * Copyright (c) 2008 Nuvoton technology corporation
  5. *
  6. * Wan ZongShun <mcuos.com@gmail.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation;version 2 of the License.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/kernel.h>
  14. #include <linux/device.h>
  15. #include <linux/list.h>
  16. #include <linux/errno.h>
  17. #include <linux/err.h>
  18. #include <linux/string.h>
  19. #include <linux/clk.h>
  20. #include <linux/mutex.h>
  21. #include <linux/io.h>
  22. #include <mach/hardware.h>
  23. #include <mach/regs-clock.h>
  24. #define PLL0 0x00
  25. #define PLL1 0x01
  26. #define OTHER 0x02
  27. #define EXT 0x03
  28. #define MSOFFSET 0x0C
  29. #define ATAOFFSET 0x0a
  30. #define LCDOFFSET 0x06
  31. #define AUDOFFSET 0x04
  32. #define CPUOFFSET 0x00
  33. static DEFINE_MUTEX(clksel_sem);
  34. static void clock_source_select(const char *dev_id, unsigned int clkval)
  35. {
  36. unsigned int clksel, offset;
  37. clksel = __raw_readl(REG_CLKSEL);
  38. if (strcmp(dev_id, "nuc900-ms") == 0)
  39. offset = MSOFFSET;
  40. else if (strcmp(dev_id, "nuc900-atapi") == 0)
  41. offset = ATAOFFSET;
  42. else if (strcmp(dev_id, "nuc900-lcd") == 0)
  43. offset = LCDOFFSET;
  44. else if (strcmp(dev_id, "nuc900-ac97") == 0)
  45. offset = AUDOFFSET;
  46. else
  47. offset = CPUOFFSET;
  48. clksel &= ~(0x03 << offset);
  49. clksel |= (clkval << offset);
  50. __raw_writel(clksel, REG_CLKSEL);
  51. }
  52. void nuc900_clock_source(struct device *dev, unsigned char *src)
  53. {
  54. unsigned int clkval;
  55. const char *dev_id;
  56. BUG_ON(!src);
  57. clkval = 0;
  58. mutex_lock(&clksel_sem);
  59. if (dev)
  60. dev_id = dev_name(dev);
  61. else
  62. dev_id = "cpufreq";
  63. if (strcmp(src, "pll0") == 0)
  64. clkval = PLL0;
  65. else if (strcmp(src, "pll1") == 0)
  66. clkval = PLL1;
  67. else if (strcmp(src, "ext") == 0)
  68. clkval = EXT;
  69. else if (strcmp(src, "oth") == 0)
  70. clkval = OTHER;
  71. clock_source_select(dev_id, clkval);
  72. mutex_unlock(&clksel_sem);
  73. }
  74. EXPORT_SYMBOL(nuc900_clock_source);