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