prcmu.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright (C) 2009 ST-Ericsson SA
  3. *
  4. * Adapted from the Linux version:
  5. * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. * This program is free software; you can redistribute it and/or modify
  21. * it under the terms of the GNU General Public License version 2
  22. * as published by the Free Software Foundation.
  23. */
  24. /*
  25. * NOTE: This currently does not support the I2C workaround access method.
  26. */
  27. #include <common.h>
  28. #include <config.h>
  29. #include <asm/io.h>
  30. #include <asm/arch/hardware.h>
  31. #include <asm/types.h>
  32. #include <asm/io.h>
  33. #include <asm/errno.h>
  34. #include <asm/arch/prcmu.h>
  35. /* CPU mailbox registers */
  36. #define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
  37. #define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
  38. #define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
  39. #define I2C_MBOX_BIT (1 << 5)
  40. static int prcmu_is_ready(void)
  41. {
  42. int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
  43. if (!ready)
  44. printf("PRCMU firmware not ready\n");
  45. return ready;
  46. }
  47. static int _wait_for_req_complete(int num)
  48. {
  49. int timeout = 1000;
  50. /* checking any already on-going transaction */
  51. while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
  52. timeout--;
  53. timeout = 1000;
  54. /* Set an interrupt to XP70 */
  55. writel(1 << num, PRCM_MBOX_CPU_SET);
  56. while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
  57. timeout--;
  58. if (!timeout) {
  59. printf("PRCMU operation timed out\n");
  60. return -1;
  61. }
  62. return 0;
  63. }
  64. /**
  65. * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
  66. * @reg: - db8500 register bank to be accessed
  67. * @slave: - db8500 register to be accessed
  68. * Returns: ACK_MB5 value containing the status
  69. */
  70. int prcmu_i2c_read(u8 reg, u16 slave)
  71. {
  72. uint8_t i2c_status;
  73. uint8_t i2c_val;
  74. if (!prcmu_is_ready())
  75. return -1;
  76. debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
  77. reg, slave);
  78. /* prepare the data for mailbox 5 */
  79. writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
  80. writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
  81. writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
  82. writeb(0, PRCM_REQ_MB5_I2CVAL);
  83. _wait_for_req_complete(REQ_MB5);
  84. /* retrieve values */
  85. debug("ack-mb5:transfer status = %x\n",
  86. readb(PRCM_ACK_MB5_STATUS));
  87. debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
  88. debug("ack-mb5:slave_add = %x\n",
  89. readb(PRCM_ACK_MB5_SLAVE));
  90. debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
  91. i2c_status = readb(PRCM_ACK_MB5_STATUS);
  92. i2c_val = readb(PRCM_ACK_MB5_VAL);
  93. if (i2c_status == I2C_RD_OK)
  94. return i2c_val;
  95. else {
  96. printf("prcmu_i2c_read:read return status= %d\n",
  97. i2c_status);
  98. return -1;
  99. }
  100. }
  101. /**
  102. * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
  103. * @reg: - db8500 register bank to be accessed
  104. * @slave: - db800 register to be written to
  105. * @reg_data: - the data to write
  106. * Returns: ACK_MB5 value containing the status
  107. */
  108. int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
  109. {
  110. uint8_t i2c_status;
  111. if (!prcmu_is_ready())
  112. return -1;
  113. debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
  114. reg, slave);
  115. /* prepare the data for mailbox 5 */
  116. writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
  117. writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
  118. writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
  119. writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
  120. debug("\ncpu_is_u8500v11\n");
  121. _wait_for_req_complete(REQ_MB5);
  122. /* retrieve values */
  123. debug("ack-mb5:transfer status = %x\n",
  124. readb(PRCM_ACK_MB5_STATUS));
  125. debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
  126. debug("ack-mb5:slave_add = %x\n",
  127. readb(PRCM_ACK_MB5_SLAVE));
  128. debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
  129. i2c_status = readb(PRCM_ACK_MB5_STATUS);
  130. debug("\ni2c_status = %x\n", i2c_status);
  131. if (i2c_status == I2C_WR_OK)
  132. return 0;
  133. else {
  134. printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
  135. return -1;
  136. }
  137. }
  138. void u8500_prcmu_enable(u32 *reg)
  139. {
  140. writel(readl(reg) | (1 << 8), reg);
  141. }
  142. void db8500_prcmu_init(void)
  143. {
  144. /* Enable timers */
  145. writel(1 << 17, PRCM_TCR);
  146. u8500_prcmu_enable((u32 *)PRCM_PER1CLK_MGT_REG);
  147. u8500_prcmu_enable((u32 *)PRCM_PER2CLK_MGT_REG);
  148. u8500_prcmu_enable((u32 *)PRCM_PER3CLK_MGT_REG);
  149. /* PER4CLK does not exist */
  150. u8500_prcmu_enable((u32 *)PRCM_PER5CLK_MGT_REG);
  151. u8500_prcmu_enable((u32 *)PRCM_PER6CLK_MGT_REG);
  152. /* Only exists in ED but is always ok to write to */
  153. u8500_prcmu_enable((u32 *)PRCM_PER7CLK_MGT_REG);
  154. u8500_prcmu_enable((u32 *)PRCM_UARTCLK_MGT_REG);
  155. u8500_prcmu_enable((u32 *)PRCM_I2CCLK_MGT_REG);
  156. u8500_prcmu_enable((u32 *)PRCM_SDMMCCLK_MGT_REG);
  157. /* Clean up the mailbox interrupts after pre-u-boot code. */
  158. writel(I2C_MBOX_BIT, PRCM_ARM_IT1_CLEAR);
  159. }