cpu.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /*
  2. * Copyright (C) 2012 Linaro Limited
  3. * Mathieu Poirier <mathieu.poirier@linaro.org>
  4. *
  5. * Based on original code from Joakim Axelsson at ST-Ericsson
  6. * (C) Copyright 2010 ST-Ericsson
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <asm/io.h>
  28. #include <asm/arch/prcmu.h>
  29. #include <asm/arch/clock.h>
  30. #include <asm/arch/hardware.h>
  31. #include <asm/arch/hardware.h>
  32. #define CPUID_DB8500V1 0x411fc091
  33. #define CPUID_DB8500V2 0x412fc091
  34. #define ASICID_DB8500V11 0x008500A1
  35. static unsigned int read_asicid(void);
  36. static inline unsigned int read_cpuid(void)
  37. {
  38. unsigned int val;
  39. /* Main ID register (MIDR) */
  40. asm("mrc p15, 0, %0, c0, c0, 0"
  41. : "=r" (val)
  42. :
  43. : "cc");
  44. return val;
  45. }
  46. static int cpu_is_u8500v11(void)
  47. {
  48. return read_asicid() == ASICID_DB8500V11;
  49. }
  50. static int cpu_is_u8500v2(void)
  51. {
  52. return read_cpuid() == CPUID_DB8500V2;
  53. }
  54. static unsigned int read_asicid(void)
  55. {
  56. unsigned int *address;
  57. if (cpu_is_u8500v2())
  58. address = (void *) U8500_ASIC_ID_LOC_V2;
  59. else
  60. address = (void *) U8500_ASIC_ID_LOC_ED_V1;
  61. return readl(address);
  62. }
  63. #ifdef CONFIG_ARCH_CPU_INIT
  64. /*
  65. * SOC specific cpu init
  66. */
  67. int arch_cpu_init(void)
  68. {
  69. db8500_prcmu_init();
  70. db8500_clocks_init();
  71. return 0;
  72. }
  73. #endif /* CONFIG_ARCH_CPU_INIT */
  74. #ifdef CONFIG_MMC
  75. int u8500_mmc_power_init(void)
  76. {
  77. int ret;
  78. int enable, voltage;
  79. int ab8500_revision;
  80. if (!cpu_is_u8500v11() && !cpu_is_u8500v2())
  81. return 0;
  82. /* Get AB8500 revision */
  83. ret = ab8500_read(AB8500_MISC, AB8500_REV_REG);
  84. if (ret < 0)
  85. goto out;
  86. ab8500_revision = ret;
  87. /*
  88. * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
  89. * card to work. This is done by enabling the regulators in the AB8500
  90. * via PRCMU I2C transactions.
  91. *
  92. * This code is derived from the handling of AB8500_LDO_VAUX3 in
  93. * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
  94. *
  95. * Turn off and delay is required to have it work across soft reboots.
  96. */
  97. /* Turn off (read-modify-write) */
  98. ret = ab8500_read(AB8500_REGU_CTRL2,
  99. AB8500_REGU_VRF1VAUX3_REGU_REG);
  100. if (ret < 0)
  101. goto out;
  102. enable = ret;
  103. /* Turn off */
  104. ret = ab8500_write(AB8500_REGU_CTRL2,
  105. AB8500_REGU_VRF1VAUX3_REGU_REG,
  106. enable & ~LDO_VAUX3_ENABLE_MASK);
  107. if (ret < 0)
  108. goto out;
  109. udelay(10 * 1000);
  110. /* Set the voltage to 2.91 V or 2.9 V without overriding VRF1 value */
  111. ret = ab8500_read(AB8500_REGU_CTRL2,
  112. AB8500_REGU_VRF1VAUX3_SEL_REG);
  113. if (ret < 0)
  114. goto out;
  115. voltage = ret;
  116. if (ab8500_revision < 0x20) {
  117. voltage &= ~LDO_VAUX3_SEL_MASK;
  118. voltage |= LDO_VAUX3_SEL_2V9;
  119. } else {
  120. voltage &= ~LDO_VAUX3_V2_SEL_MASK;
  121. voltage |= LDO_VAUX3_V2_SEL_2V91;
  122. }
  123. ret = ab8500_write(AB8500_REGU_CTRL2,
  124. AB8500_REGU_VRF1VAUX3_SEL_REG, voltage);
  125. if (ret < 0)
  126. goto out;
  127. /* Turn on the supply */
  128. enable &= ~LDO_VAUX3_ENABLE_MASK;
  129. enable |= LDO_VAUX3_ENABLE_VAL;
  130. ret = ab8500_write(AB8500_REGU_CTRL2,
  131. AB8500_REGU_VRF1VAUX3_REGU_REG, enable);
  132. out:
  133. return ret;
  134. }
  135. #endif /* CONFIG_MMC */