Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-block.git] / arch / arm / mach-ux500 / prcmu.c
CommitLineData
e3726fcf 1/*
e0befb23
MP
2 * Copyright (C) STMicroelectronics 2009
3 * Copyright (C) ST-Ericsson SA 2010
e3726fcf
LW
4 *
5 * License Terms: GNU General Public License v2
e0befb23
MP
6 * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
7 * Author: Sundar Iyer <sundar.iyer@stericsson.com>
e3726fcf
LW
8 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
9 *
e0befb23
MP
10 * U8500 PRCM Unit interface driver
11 *
e3726fcf
LW
12 */
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/errno.h>
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/mutex.h>
19#include <linux/completion.h>
20#include <linux/jiffies.h>
21#include <linux/bitops.h>
22#include <linux/interrupt.h>
23
24#include <mach/hardware.h>
25#include <mach/prcmu-regs.h>
e0befb23 26#include <mach/prcmu-defs.h>
e3726fcf 27
fcbd458e
MW
28/* Global var to runtime determine TCDM base for v2 or v1 */
29static __iomem void *tcdm_base;
e3726fcf 30
e0befb23
MP
31#define _MBOX_HEADER (tcdm_base + 0xFE8)
32#define MBOX_HEADER_REQ_MB0 (_MBOX_HEADER + 0x0)
33
34#define REQ_MB1 (tcdm_base + 0xFD0)
fcbd458e 35#define REQ_MB5 (tcdm_base + 0xE44)
e0befb23
MP
36
37#define REQ_MB1_ARMOPP (REQ_MB1 + 0x0)
38#define REQ_MB1_APEOPP (REQ_MB1 + 0x1)
39#define REQ_MB1_BOOSTOPP (REQ_MB1 + 0x2)
40
41#define ACK_MB1 (tcdm_base + 0xE04)
fcbd458e 42#define ACK_MB5 (tcdm_base + 0xDF4)
e3726fcf 43
e0befb23
MP
44#define ACK_MB1_CURR_ARMOPP (ACK_MB1 + 0x0)
45#define ACK_MB1_CURR_APEOPP (ACK_MB1 + 0x1)
46
e3726fcf
LW
47#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
48#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
49#define REQ_MB5_I2C_REG (REQ_MB5 + 2)
50#define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
51
52#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
53#define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
54
e0befb23
MP
55#define PRCM_AVS_VARM_MAX_OPP (tcdm_base + 0x2E4)
56#define PRCM_AVS_ISMODEENABLE 7
57#define PRCM_AVS_ISMODEENABLE_MASK (1 << PRCM_AVS_ISMODEENABLE)
58
fcbd458e
MW
59#define I2C_WRITE(slave) \
60 (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
61#define I2C_READ(slave) \
62 (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0))
e3726fcf
LW
63#define I2C_STOP_EN BIT(3)
64
e0befb23
MP
65enum mb1_h {
66 MB1H_ARM_OPP = 1,
67 MB1H_APE_OPP,
68 MB1H_ARM_APE_OPP,
69};
70
71static struct {
72 struct mutex lock;
73 struct completion work;
74 struct {
75 u8 arm_opp;
76 u8 ape_opp;
77 u8 arm_status;
78 u8 ape_status;
79 } ack;
80} mb1_transfer;
81
e3726fcf
LW
82enum ack_mb5_status {
83 I2C_WR_OK = 0x01,
84 I2C_RD_OK = 0x02,
85};
86
87#define MBOX_BIT BIT
88#define NUM_MBOX 8
89
90static struct {
91 struct mutex lock;
92 struct completion work;
93 bool failed;
94 struct {
95 u8 status;
96 u8 value;
97 } ack;
98} mb5_transfer;
99
100/**
101 * prcmu_abb_read() - Read register value(s) from the ABB.
102 * @slave: The I2C slave address.
103 * @reg: The (start) register address.
104 * @value: The read out value(s).
105 * @size: The number of registers to read.
106 *
107 * Reads register value(s) from the ABB.
108 * @size has to be 1 for the current firmware version.
109 */
110int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
111{
112 int r;
113
114 if (size != 1)
115 return -EINVAL;
116
117 r = mutex_lock_interruptible(&mb5_transfer.lock);
118 if (r)
119 return r;
120
121 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
122 cpu_relax();
123
124 writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
125 writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
126 writeb(reg, REQ_MB5_I2C_REG);
127
128 writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
129 if (!wait_for_completion_timeout(&mb5_transfer.work,
130 msecs_to_jiffies(500))) {
131 pr_err("prcmu: prcmu_abb_read timed out.\n");
132 r = -EIO;
133 goto unlock_and_return;
134 }
135 r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
136 if (!r)
137 *value = mb5_transfer.ack.value;
138
139unlock_and_return:
140 mutex_unlock(&mb5_transfer.lock);
141 return r;
142}
143EXPORT_SYMBOL(prcmu_abb_read);
144
145/**
146 * prcmu_abb_write() - Write register value(s) to the ABB.
147 * @slave: The I2C slave address.
148 * @reg: The (start) register address.
149 * @value: The value(s) to write.
150 * @size: The number of registers to write.
151 *
152 * Reads register value(s) from the ABB.
153 * @size has to be 1 for the current firmware version.
154 */
155int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
156{
157 int r;
158
159 if (size != 1)
160 return -EINVAL;
161
162 r = mutex_lock_interruptible(&mb5_transfer.lock);
163 if (r)
164 return r;
165
166
167 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
168 cpu_relax();
169
170 writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
171 writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
172 writeb(reg, REQ_MB5_I2C_REG);
173 writeb(*value, REQ_MB5_I2C_VAL);
174
175 writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
176 if (!wait_for_completion_timeout(&mb5_transfer.work,
177 msecs_to_jiffies(500))) {
178 pr_err("prcmu: prcmu_abb_write timed out.\n");
179 r = -EIO;
180 goto unlock_and_return;
181 }
182 r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
183
184unlock_and_return:
185 mutex_unlock(&mb5_transfer.lock);
186 return r;
187}
188EXPORT_SYMBOL(prcmu_abb_write);
189
e0befb23
MP
190static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp,
191 enum prcmu_cpu_opp cpu_opp)
192{
193 bool do_ape;
194 bool do_arm;
195 int err = 0;
196
197 do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP));
198 do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP));
199
200 mutex_lock(&mb1_transfer.lock);
201
202 while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
203 cpu_relax();
204
205 writeb(0, MBOX_HEADER_REQ_MB0);
206 writeb(cpu_opp, REQ_MB1_ARMOPP);
207 writeb(ape_opp, REQ_MB1_APEOPP);
208 writeb(0, REQ_MB1_BOOSTOPP);
209 writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
210 wait_for_completion(&mb1_transfer.work);
211 if ((do_ape) && (mb1_transfer.ack.ape_status != 0))
212 err = -EIO;
213 if ((do_arm) && (mb1_transfer.ack.arm_status != 0))
214 err = -EIO;
215
216 mutex_unlock(&mb1_transfer.lock);
217
218 return err;
219}
220
221/**
222 * prcmu_set_ape_opp() - Set the OPP of the APE.
223 * @opp: The OPP to set.
224 *
225 * This function sets the OPP of the APE.
226 */
227int prcmu_set_ape_opp(enum prcmu_ape_opp opp)
228{
229 return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE);
230}
231EXPORT_SYMBOL(prcmu_set_ape_opp);
232
233/**
234 * prcmu_set_cpu_opp() - Set the OPP of the CPU.
235 * @opp: The OPP to set.
236 *
237 * This function sets the OPP of the CPU.
238 */
239int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp)
240{
241 return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp);
242}
243EXPORT_SYMBOL(prcmu_set_cpu_opp);
244
245/**
246 * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU.
247 * @ape_opp: The APE OPP to set.
248 * @cpu_opp: The CPU OPP to set.
249 *
250 * This function sets the OPPs of the APE and the CPU.
251 */
252int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
253 enum prcmu_cpu_opp cpu_opp)
254{
255 return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp);
256}
257EXPORT_SYMBOL(prcmu_set_ape_cpu_opps);
258
259/**
260 * prcmu_get_ape_opp() - Get the OPP of the APE.
261 *
262 * This function gets the OPP of the APE.
263 */
264enum prcmu_ape_opp prcmu_get_ape_opp(void)
265{
266 return readb(ACK_MB1_CURR_APEOPP);
267}
268EXPORT_SYMBOL(prcmu_get_ape_opp);
269
270/**
271 * prcmu_get_cpu_opp() - Get the OPP of the CPU.
272 *
273 * This function gets the OPP of the CPU. The OPP is specified in %%.
274 * PRCMU_OPP_EXT is a special OPP value, not specified in %%.
275 */
276int prcmu_get_cpu_opp(void)
277{
278 return readb(ACK_MB1_CURR_ARMOPP);
279}
280EXPORT_SYMBOL(prcmu_get_cpu_opp);
281
282bool prcmu_has_arm_maxopp(void)
283{
284 return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK)
285 == PRCM_AVS_ISMODEENABLE_MASK;
286}
287
e3726fcf
LW
288static void read_mailbox_0(void)
289{
290 writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
291}
292
293static void read_mailbox_1(void)
294{
e0befb23
MP
295 mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP);
296 mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP);
297 complete(&mb1_transfer.work);
e3726fcf
LW
298 writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
299}
300
301static void read_mailbox_2(void)
302{
303 writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
304}
305
306static void read_mailbox_3(void)
307{
308 writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
309}
310
311static void read_mailbox_4(void)
312{
313 writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
314}
315
316static void read_mailbox_5(void)
317{
318 mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
319 mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
320 complete(&mb5_transfer.work);
321 writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
322}
323
324static void read_mailbox_6(void)
325{
326 writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
327}
328
329static void read_mailbox_7(void)
330{
331 writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
332}
333
334static void (* const read_mailbox[NUM_MBOX])(void) = {
335 read_mailbox_0,
336 read_mailbox_1,
337 read_mailbox_2,
338 read_mailbox_3,
339 read_mailbox_4,
340 read_mailbox_5,
341 read_mailbox_6,
342 read_mailbox_7
343};
344
345static irqreturn_t prcmu_irq_handler(int irq, void *data)
346{
347 u32 bits;
348 u8 n;
349
350 bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
351 if (unlikely(!bits))
352 return IRQ_NONE;
353
354 for (n = 0; bits; n++) {
355 if (bits & MBOX_BIT(n)) {
356 bits -= MBOX_BIT(n);
357 read_mailbox[n]();
358 }
359 }
360 return IRQ_HANDLED;
361}
362
fcbd458e
MW
363void __init prcmu_early_init(void)
364{
365 if (cpu_is_u8500v11() || cpu_is_u8500ed()) {
366 tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
367 } else if (cpu_is_u8500v2()) {
368 tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
369 } else {
370 pr_err("prcmu: Unsupported chip version\n");
371 BUG();
372 }
373}
374
e3726fcf
LW
375static int __init prcmu_init(void)
376{
e0befb23
MP
377 if (cpu_is_u8500ed()) {
378 pr_err("prcmu: Unsupported chip version\n");
379 return 0;
380 }
381
382 mutex_init(&mb1_transfer.lock);
383 init_completion(&mb1_transfer.work);
e3726fcf
LW
384 mutex_init(&mb5_transfer.lock);
385 init_completion(&mb5_transfer.work);
386
387 /* Clean up the mailbox interrupts after pre-kernel code. */
388 writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
389
22039b7c
RV
390 return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0,
391 "prcmu", NULL);
e3726fcf
LW
392}
393
394arch_initcall(prcmu_init);