prcmu.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. static int prcmu_is_ready(void)
  40. {
  41. int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
  42. if (!ready)
  43. printf("PRCMU firmware not ready\n");
  44. return ready;
  45. }
  46. static int _wait_for_req_complete(int num)
  47. {
  48. int timeout = 1000;
  49. /* checking any already on-going transaction */
  50. while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
  51. timeout--;
  52. timeout = 1000;
  53. /* Set an interrupt to XP70 */
  54. writel(1 << num, PRCM_MBOX_CPU_SET);
  55. while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout)
  56. timeout--;
  57. if (!timeout) {
  58. printf("PRCMU operation timed out\n");
  59. return -1;
  60. }
  61. return 0;
  62. }
  63. /**
  64. * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
  65. * @reg: - db8500 register bank to be accessed
  66. * @slave: - db8500 register to be accessed
  67. * Returns: ACK_MB5 value containing the status
  68. */
  69. int prcmu_i2c_read(u8 reg, u16 slave)
  70. {
  71. uint8_t i2c_status;
  72. uint8_t i2c_val;
  73. if (!prcmu_is_ready())
  74. return -1;
  75. debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
  76. reg, slave);
  77. /* prepare the data for mailbox 5 */
  78. writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
  79. writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
  80. writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
  81. writeb(0, PRCM_REQ_MB5_I2CVAL);
  82. _wait_for_req_complete(REQ_MB5);
  83. /* retrieve values */
  84. debug("ack-mb5:transfer status = %x\n",
  85. readb(PRCM_ACK_MB5_STATUS));
  86. debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
  87. debug("ack-mb5:slave_add = %x\n",
  88. readb(PRCM_ACK_MB5_SLAVE));
  89. debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
  90. i2c_status = readb(PRCM_ACK_MB5_STATUS);
  91. i2c_val = readb(PRCM_ACK_MB5_VAL);
  92. if (i2c_status == I2C_RD_OK)
  93. return i2c_val;
  94. else {
  95. printf("prcmu_i2c_read:read return status= %d\n",
  96. i2c_status);
  97. return -1;
  98. }
  99. }
  100. /**
  101. * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
  102. * @reg: - db8500 register bank to be accessed
  103. * @slave: - db800 register to be written to
  104. * @reg_data: - the data to write
  105. * Returns: ACK_MB5 value containing the status
  106. */
  107. int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
  108. {
  109. uint8_t i2c_status;
  110. if (!prcmu_is_ready())
  111. return -1;
  112. debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
  113. reg, slave);
  114. /* prepare the data for mailbox 5 */
  115. writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
  116. writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
  117. writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
  118. writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
  119. debug("\ncpu_is_u8500v11\n");
  120. _wait_for_req_complete(REQ_MB5);
  121. /* retrieve values */
  122. debug("ack-mb5:transfer status = %x\n",
  123. readb(PRCM_ACK_MB5_STATUS));
  124. debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
  125. debug("ack-mb5:slave_add = %x\n",
  126. readb(PRCM_ACK_MB5_SLAVE));
  127. debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
  128. i2c_status = readb(PRCM_ACK_MB5_STATUS);
  129. debug("\ni2c_status = %x\n", i2c_status);
  130. if (i2c_status == I2C_WR_OK)
  131. return 0;
  132. else {
  133. printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
  134. return -1;
  135. }
  136. }