ARM: ux500: prcmu db8500 v2 support
[pandora-kernel.git] / arch / arm / mach-ux500 / prcmu.c
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
20 #include <mach/hardware.h>
21 #include <mach/prcmu-regs.h>
22
23 /* Global var to runtime determine TCDM base for v2 or v1 */
24 static __iomem void *tcdm_base;
25
26 #define REQ_MB5 (tcdm_base + 0xE44)
27 #define ACK_MB5 (tcdm_base + 0xDF4)
28
29 #define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
30 #define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
31 #define REQ_MB5_I2C_REG (REQ_MB5 + 2)
32 #define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
33
34 #define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
35 #define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
36
37 #define I2C_WRITE(slave) \
38         (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
39 #define I2C_READ(slave) \
40         (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0))
41 #define I2C_STOP_EN BIT(3)
42
43 enum ack_mb5_status {
44         I2C_WR_OK = 0x01,
45         I2C_RD_OK = 0x02,
46 };
47
48 #define MBOX_BIT BIT
49 #define NUM_MBOX 8
50
51 static struct {
52         struct mutex lock;
53         struct completion work;
54         bool failed;
55         struct {
56                 u8 status;
57                 u8 value;
58         } ack;
59 } mb5_transfer;
60
61 /**
62  * prcmu_abb_read() - Read register value(s) from the ABB.
63  * @slave:      The I2C slave address.
64  * @reg:        The (start) register address.
65  * @value:      The read out value(s).
66  * @size:       The number of registers to read.
67  *
68  * Reads register value(s) from the ABB.
69  * @size has to be 1 for the current firmware version.
70  */
71 int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
72 {
73         int r;
74
75         if (size != 1)
76                 return -EINVAL;
77
78         r = mutex_lock_interruptible(&mb5_transfer.lock);
79         if (r)
80                 return r;
81
82         while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
83                 cpu_relax();
84
85         writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
86         writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
87         writeb(reg, REQ_MB5_I2C_REG);
88
89         writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
90         if (!wait_for_completion_timeout(&mb5_transfer.work,
91                         msecs_to_jiffies(500))) {
92                 pr_err("prcmu: prcmu_abb_read timed out.\n");
93                 r = -EIO;
94                 goto unlock_and_return;
95         }
96         r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
97         if (!r)
98                 *value = mb5_transfer.ack.value;
99
100 unlock_and_return:
101         mutex_unlock(&mb5_transfer.lock);
102         return r;
103 }
104 EXPORT_SYMBOL(prcmu_abb_read);
105
106 /**
107  * prcmu_abb_write() - Write register value(s) to the ABB.
108  * @slave:      The I2C slave address.
109  * @reg:        The (start) register address.
110  * @value:      The value(s) to write.
111  * @size:       The number of registers to write.
112  *
113  * Reads register value(s) from the ABB.
114  * @size has to be 1 for the current firmware version.
115  */
116 int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
117 {
118         int r;
119
120         if (size != 1)
121                 return -EINVAL;
122
123         r = mutex_lock_interruptible(&mb5_transfer.lock);
124         if (r)
125                 return r;
126
127
128         while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
129                 cpu_relax();
130
131         writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
132         writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
133         writeb(reg, REQ_MB5_I2C_REG);
134         writeb(*value, REQ_MB5_I2C_VAL);
135
136         writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
137         if (!wait_for_completion_timeout(&mb5_transfer.work,
138                         msecs_to_jiffies(500))) {
139                 pr_err("prcmu: prcmu_abb_write timed out.\n");
140                 r = -EIO;
141                 goto unlock_and_return;
142         }
143         r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
144
145 unlock_and_return:
146         mutex_unlock(&mb5_transfer.lock);
147         return r;
148 }
149 EXPORT_SYMBOL(prcmu_abb_write);
150
151 static void read_mailbox_0(void)
152 {
153         writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
154 }
155
156 static void read_mailbox_1(void)
157 {
158         writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
159 }
160
161 static void read_mailbox_2(void)
162 {
163         writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
164 }
165
166 static void read_mailbox_3(void)
167 {
168         writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
169 }
170
171 static void read_mailbox_4(void)
172 {
173         writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
174 }
175
176 static void read_mailbox_5(void)
177 {
178         mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
179         mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
180         complete(&mb5_transfer.work);
181         writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
182 }
183
184 static void read_mailbox_6(void)
185 {
186         writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
187 }
188
189 static void read_mailbox_7(void)
190 {
191         writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
192 }
193
194 static void (* const read_mailbox[NUM_MBOX])(void) = {
195         read_mailbox_0,
196         read_mailbox_1,
197         read_mailbox_2,
198         read_mailbox_3,
199         read_mailbox_4,
200         read_mailbox_5,
201         read_mailbox_6,
202         read_mailbox_7
203 };
204
205 static irqreturn_t prcmu_irq_handler(int irq, void *data)
206 {
207         u32 bits;
208         u8 n;
209
210         bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
211         if (unlikely(!bits))
212                 return IRQ_NONE;
213
214         for (n = 0; bits; n++) {
215                 if (bits & MBOX_BIT(n)) {
216                         bits -= MBOX_BIT(n);
217                         read_mailbox[n]();
218                 }
219         }
220         return IRQ_HANDLED;
221 }
222
223 void __init prcmu_early_init(void)
224 {
225         if (cpu_is_u8500v11() || cpu_is_u8500ed()) {
226                 tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
227         } else if (cpu_is_u8500v2()) {
228                 tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
229         } else {
230                 pr_err("prcmu: Unsupported chip version\n");
231                 BUG();
232         }
233 }
234
235 static int __init prcmu_init(void)
236 {
237         mutex_init(&mb5_transfer.lock);
238         init_completion(&mb5_transfer.work);
239
240         /* Clean up the mailbox interrupts after pre-kernel code. */
241         writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
242
243         return request_irq(IRQ_PRCMU, prcmu_irq_handler, 0, "prcmu", NULL);
244 }
245
246 arch_initcall(prcmu_init);