prcmu.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (C) ST Ericsson SA 2010
  3. *
  4. * License Terms: GNU General Public License v2
  5. * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
  6. *
  7. * U8500 PRCMU driver.
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/errno.h>
  12. #include <linux/err.h>
  13. #include <linux/io.h>
  14. #include <linux/mutex.h>
  15. #include <linux/completion.h>
  16. #include <linux/jiffies.h>
  17. #include <linux/bitops.h>
  18. #include <linux/interrupt.h>
  19. #include <mach/hardware.h>
  20. #include <mach/prcmu-regs.h>
  21. #define PRCMU_TCDM_BASE __io_address(U8500_PRCMU_TCDM_BASE)
  22. #define REQ_MB5 (PRCMU_TCDM_BASE + 0xE44)
  23. #define ACK_MB5 (PRCMU_TCDM_BASE + 0xDF4)
  24. #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
  25. #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
  26. #define REQ_MB5_I2C_REG (REQ_MB5 + 2)
  27. #define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
  28. #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
  29. #define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
  30. #define I2C_WRITE(slave) ((slave) << 1)
  31. #define I2C_READ(slave) (((slave) << 1) | BIT(0))
  32. #define I2C_STOP_EN BIT(3)
  33. enum ack_mb5_status {
  34. I2C_WR_OK = 0x01,
  35. I2C_RD_OK = 0x02,
  36. };
  37. #define MBOX_BIT BIT
  38. #define NUM_MBOX 8
  39. static struct {
  40. struct mutex lock;
  41. struct completion work;
  42. bool failed;
  43. struct {
  44. u8 status;
  45. u8 value;
  46. } ack;
  47. } mb5_transfer;
  48. /**
  49. * prcmu_abb_read() - Read register value(s) from the ABB.
  50. * @slave: The I2C slave address.
  51. * @reg: The (start) register address.
  52. * @value: The read out value(s).
  53. * @size: The number of registers to read.
  54. *
  55. * Reads register value(s) from the ABB.
  56. * @size has to be 1 for the current firmware version.
  57. */
  58. int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
  59. {
  60. int r;
  61. if (size != 1)
  62. return -EINVAL;
  63. r = mutex_lock_interruptible(&mb5_transfer.lock);
  64. if (r)
  65. return r;
  66. while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
  67. cpu_relax();
  68. writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
  69. writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
  70. writeb(reg, REQ_MB5_I2C_REG);
  71. writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
  72. if (!wait_for_completion_timeout(&mb5_transfer.work,
  73. msecs_to_jiffies(500))) {
  74. pr_err("prcmu: prcmu_abb_read timed out.\n");
  75. r = -EIO;
  76. goto unlock_and_return;
  77. }
  78. r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
  79. if (!r)
  80. *value = mb5_transfer.ack.value;
  81. unlock_and_return:
  82. mutex_unlock(&mb5_transfer.lock);
  83. return r;
  84. }
  85. EXPORT_SYMBOL(prcmu_abb_read);
  86. /**
  87. * prcmu_abb_write() - Write register value(s) to the ABB.
  88. * @slave: The I2C slave address.
  89. * @reg: The (start) register address.
  90. * @value: The value(s) to write.
  91. * @size: The number of registers to write.
  92. *
  93. * Reads register value(s) from the ABB.
  94. * @size has to be 1 for the current firmware version.
  95. */
  96. int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
  97. {
  98. int r;
  99. if (size != 1)
  100. return -EINVAL;
  101. r = mutex_lock_interruptible(&mb5_transfer.lock);
  102. if (r)
  103. return r;
  104. while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
  105. cpu_relax();
  106. writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
  107. writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
  108. writeb(reg, REQ_MB5_I2C_REG);
  109. writeb(*value, REQ_MB5_I2C_VAL);
  110. writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
  111. if (!wait_for_completion_timeout(&mb5_transfer.work,
  112. msecs_to_jiffies(500))) {
  113. pr_err("prcmu: prcmu_abb_write timed out.\n");
  114. r = -EIO;
  115. goto unlock_and_return;
  116. }
  117. r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
  118. unlock_and_return:
  119. mutex_unlock(&mb5_transfer.lock);
  120. return r;
  121. }
  122. EXPORT_SYMBOL(prcmu_abb_write);
  123. static void read_mailbox_0(void)
  124. {
  125. writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
  126. }
  127. static void read_mailbox_1(void)
  128. {
  129. writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
  130. }
  131. static void read_mailbox_2(void)
  132. {
  133. writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
  134. }
  135. static void read_mailbox_3(void)
  136. {
  137. writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
  138. }
  139. static void read_mailbox_4(void)
  140. {
  141. writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
  142. }
  143. static void read_mailbox_5(void)
  144. {
  145. mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
  146. mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
  147. complete(&mb5_transfer.work);
  148. writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
  149. }
  150. static void read_mailbox_6(void)
  151. {
  152. writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
  153. }
  154. static void read_mailbox_7(void)
  155. {
  156. writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
  157. }
  158. static void (* const read_mailbox[NUM_MBOX])(void) = {
  159. read_mailbox_0,
  160. read_mailbox_1,
  161. read_mailbox_2,
  162. read_mailbox_3,
  163. read_mailbox_4,
  164. read_mailbox_5,
  165. read_mailbox_6,
  166. read_mailbox_7
  167. };
  168. static irqreturn_t prcmu_irq_handler(int irq, void *data)
  169. {
  170. u32 bits;
  171. u8 n;
  172. bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
  173. if (unlikely(!bits))
  174. return IRQ_NONE;
  175. for (n = 0; bits; n++) {
  176. if (bits & MBOX_BIT(n)) {
  177. bits -= MBOX_BIT(n);
  178. read_mailbox[n]();
  179. }
  180. }
  181. return IRQ_HANDLED;
  182. }
  183. static int __init prcmu_init(void)
  184. {
  185. mutex_init(&mb5_transfer.lock);
  186. init_completion(&mb5_transfer.work);
  187. /* Clean up the mailbox interrupts after pre-kernel code. */
  188. writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
  189. return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL);
  190. }
  191. arch_initcall(prcmu_init);