psc.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * TI DaVinci Power and Sleep Controller (PSC)
  3. *
  4. * Copyright (C) 2006 Texas Instruments.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. */
  21. #include <linux/kernel.h>
  22. #include <linux/module.h>
  23. #include <linux/init.h>
  24. #include <asm/io.h>
  25. #include <asm/hardware.h>
  26. #include <asm/arch/psc.h>
  27. #include <asm/arch/mux.h>
  28. /* PSC register offsets */
  29. #define EPCPR 0x070
  30. #define PTCMD 0x120
  31. #define PTSTAT 0x128
  32. #define PDSTAT 0x200
  33. #define PDCTL1 0x304
  34. #define MDSTAT 0x800
  35. #define MDCTL 0xA00
  36. /* System control register offsets */
  37. #define VDD3P3V_PWDN 0x48
  38. static void davinci_psc_mux(unsigned int id)
  39. {
  40. switch (id) {
  41. case DAVINCI_LPSC_ATA:
  42. davinci_mux_peripheral(DAVINCI_MUX_HDIREN, 1);
  43. davinci_mux_peripheral(DAVINCI_MUX_ATAEN, 1);
  44. break;
  45. case DAVINCI_LPSC_MMC_SD:
  46. /* VDD power manupulations are done in U-Boot for CPMAC
  47. * so applies to MMC as well
  48. */
  49. /*Set up the pull regiter for MMC */
  50. davinci_writel(0, DAVINCI_SYSTEM_MODULE_BASE + VDD3P3V_PWDN);
  51. davinci_mux_peripheral(DAVINCI_MUX_MSTK, 0);
  52. break;
  53. case DAVINCI_LPSC_I2C:
  54. davinci_mux_peripheral(DAVINCI_MUX_I2C, 1);
  55. break;
  56. case DAVINCI_LPSC_McBSP:
  57. davinci_mux_peripheral(DAVINCI_MUX_ASP, 1);
  58. break;
  59. default:
  60. break;
  61. }
  62. }
  63. /* Enable or disable a PSC domain */
  64. void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
  65. {
  66. u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
  67. if (id < 0)
  68. return;
  69. mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
  70. if (enable)
  71. mdctl |= 0x00000003; /* Enable Module */
  72. else
  73. mdctl &= 0xFFFFFFF2; /* Disable Module */
  74. davinci_writel(mdctl, DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
  75. pdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDSTAT);
  76. if ((pdstat & 0x00000001) == 0) {
  77. pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
  78. pdctl1 |= 0x1;
  79. davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
  80. ptcmd = 1 << domain;
  81. davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
  82. do {
  83. epcpr = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
  84. EPCPR);
  85. } while ((((epcpr >> domain) & 1) == 0));
  86. pdctl1 = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
  87. pdctl1 |= 0x100;
  88. davinci_writel(pdctl1, DAVINCI_PWR_SLEEP_CNTRL_BASE + PDCTL1);
  89. do {
  90. ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
  91. PTSTAT);
  92. } while (!(((ptstat >> domain) & 1) == 0));
  93. } else {
  94. ptcmd = 1 << domain;
  95. davinci_writel(ptcmd, DAVINCI_PWR_SLEEP_CNTRL_BASE + PTCMD);
  96. do {
  97. ptstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
  98. PTSTAT);
  99. } while (!(((ptstat >> domain) & 1) == 0));
  100. }
  101. if (enable)
  102. mdstat_mask = 0x3;
  103. else
  104. mdstat_mask = 0x2;
  105. do {
  106. mdstat = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE +
  107. MDSTAT + 4 * id);
  108. } while (!((mdstat & 0x0000001F) == mdstat_mask));
  109. if (enable)
  110. davinci_psc_mux(id);
  111. }
  112. void __init davinci_psc_init(void)
  113. {
  114. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSMSTR, 1);
  115. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_VPSSSLV, 1);
  116. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPCC, 1);
  117. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC0, 1);
  118. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TPTC1, 1);
  119. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_GPIO, 1);
  120. /* Turn on WatchDog timer LPSC. Needed for RESET to work */
  121. davinci_psc_config(DAVINCI_GPSC_ARMDOMAIN, DAVINCI_LPSC_TIMER2, 1);
  122. }