blob: 63de9448c74e224fd157d83b0106cd06fb1b7281 [file] [log] [blame]
Taniya Dasfcb35002012-03-09 15:28:12 +05301/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/bitops.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/delay.h>
18#include <linux/types.h>
19#include <linux/init.h>
20#include <linux/interrupt.h>
21#include <linux/io.h>
22#include <linux/irq.h>
23#include <linux/spinlock.h>
24
25#include <asm/hardware/gic.h>
26#include <mach/msm_smsm.h>
27
28#define NUM_REGS_ENABLE 2
29/* (NR_MSM_IRQS/32) 96 max irqs supported */
30#define NUM_REGS_DISABLE 3
31#define GIC_IRQ_MASK(irq) BIT(irq % 32)
32#define GIC_IRQ_INDEX(irq) (irq / 32)
33
34#ifdef CONFIG_PM
35u32 saved_spi_enable[DIV_ROUND_UP(256, 32)];
36u32 saved_spi_conf[DIV_ROUND_UP(256, 16)];
37u32 saved_spi_target[DIV_ROUND_UP(256, 4)];
38u32 __percpu *saved_ppi_enable;
39u32 __percpu *saved_ppi_conf;
40#endif
41
42enum {
43 IRQ_DEBUG_SLEEP_INT_TRIGGER = BIT(0),
44 IRQ_DEBUG_SLEEP_INT = BIT(1),
45 IRQ_DEBUG_SLEEP_ABORT = BIT(2),
46 IRQ_DEBUG_SLEEP = BIT(3),
47 IRQ_DEBUG_SLEEP_REQUEST = BIT(4)
48};
49
50static int msm_gic_irq_debug_mask;
51module_param_named(debug_mask, msm_gic_irq_debug_mask, int,
52 S_IRUGO | S_IWUSR | S_IWGRP);
53
54static uint32_t msm_gic_irq_smsm_wake_enable[NUM_REGS_ENABLE];
55static uint32_t msm_gic_irq_idle_disable[NUM_REGS_DISABLE];
56
57static DEFINE_RAW_SPINLOCK(gic_controller_lock);
58static void __iomem *dist_base, *cpu_base;
59static unsigned int max_irqs;
60
61 /*
62 * Some of the interrupts which will not be considered as wake capable
63 * should be marked as FAKE.
64 * Interrupts: GPIO, Timers etc..
65 */
66#define SMSM_FAKE_IRQ (0xff)
67
68 /* msm_gic_irq_to_smsm: IRQ's those will be monitored by Modem */
69static uint8_t msm_gic_irq_to_smsm[NR_IRQS] = {
70 [MSM8625_INT_USB_OTG] = 4,
71 [MSM8625_INT_PWB_I2C] = 5,
72 [MSM8625_INT_SDC1_0] = 6,
73 [MSM8625_INT_SDC1_1] = 7,
74 [MSM8625_INT_SDC2_0] = 8,
75 [MSM8625_INT_SDC2_1] = 9,
76 [MSM8625_INT_ADSP_A9_A11] = 10,
77 [MSM8625_INT_UART1] = 11,
78 [MSM8625_INT_UART2] = 12,
79 [MSM8625_INT_UART3] = 13,
80 [MSM8625_INT_UART1_RX] = 14,
81 [MSM8625_INT_UART2_RX] = 15,
82 [MSM8625_INT_UART3_RX] = 16,
83 [MSM8625_INT_UART1DM_IRQ] = 17,
84 [MSM8625_INT_UART1DM_RX] = 18,
85 [MSM8625_INT_KEYSENSE] = 19,
86 [MSM8625_INT_AD_HSSD] = 20,
87 [MSM8625_INT_NAND_WR_ER_DONE] = 21,
88 [MSM8625_INT_NAND_OP_DONE] = 22,
89 [MSM8625_INT_TCHSCRN1] = 23,
90 [MSM8625_INT_TCHSCRN2] = 24,
91 [MSM8625_INT_TCHSCRN_SSBI] = 25,
92 [MSM8625_INT_USB_HS] = 26,
93 [MSM8625_INT_UART2DM_RX] = 27,
94 [MSM8625_INT_UART2DM_IRQ] = 28,
95 [MSM8625_INT_SDC4_1] = 29,
96 [MSM8625_INT_SDC4_0] = 30,
97 [MSM8625_INT_SDC3_1] = 31,
98 [MSM8625_INT_SDC3_0] = 32,
99
100 /* fake wakeup interrupts */
101 [MSM8625_INT_GPIO_GROUP1] = SMSM_FAKE_IRQ,
102 [MSM8625_INT_GPIO_GROUP2] = SMSM_FAKE_IRQ,
103 [MSM8625_INT_A9_M2A_0] = SMSM_FAKE_IRQ,
104 [MSM8625_INT_A9_M2A_1] = SMSM_FAKE_IRQ,
105 [MSM8625_INT_A9_M2A_5] = SMSM_FAKE_IRQ,
106 [MSM8625_INT_GP_TIMER_EXP] = SMSM_FAKE_IRQ,
107 [MSM8625_INT_DEBUG_TIMER_EXP] = SMSM_FAKE_IRQ,
108 [MSM8625_INT_ADSP_A11] = SMSM_FAKE_IRQ,
109};
110
111static void msm_gic_mask_irq(struct irq_data *d)
112{
113 unsigned int index = GIC_IRQ_INDEX(d->irq);
114 uint32_t mask;
115 int smsm_irq = msm_gic_irq_to_smsm[d->irq];
116
117 mask = GIC_IRQ_MASK(d->irq);
118
119 if (smsm_irq == 0) {
120 msm_gic_irq_idle_disable[index] &= ~mask;
121 } else {
122 mask = GIC_IRQ_MASK(smsm_irq - 1);
123 msm_gic_irq_smsm_wake_enable[0] &= ~mask;
124 }
125}
126
127static void msm_gic_unmask_irq(struct irq_data *d)
128{
129 unsigned int index = GIC_IRQ_INDEX(d->irq);
130 uint32_t mask;
131 int smsm_irq = msm_gic_irq_to_smsm[d->irq];
132
133 mask = GIC_IRQ_MASK(d->irq);
134
135 if (smsm_irq == 0) {
136 msm_gic_irq_idle_disable[index] |= mask;
137 } else {
138 mask = GIC_IRQ_MASK(smsm_irq - 1);
139 msm_gic_irq_smsm_wake_enable[0] |= mask;
140 }
141}
142
143static int msm_gic_set_irq_wake(struct irq_data *d, unsigned int on)
144{
145 uint32_t mask;
146 int smsm_irq = msm_gic_irq_to_smsm[d->irq];
147
148 if (smsm_irq == 0) {
149 pr_err("bad wake up irq %d\n", d->irq);
150 return -EINVAL;
151 }
152
153 if (smsm_irq == SMSM_FAKE_IRQ)
154 return 0;
155
156 mask = GIC_IRQ_MASK(smsm_irq - 1);
157 if (on)
158 msm_gic_irq_smsm_wake_enable[1] |= mask;
159 else
160 msm_gic_irq_smsm_wake_enable[1] &= ~mask;
161
162 return 0;
163}
164
165#ifdef CONFIG_PM
166static void __init msm_gic_pm_init(void)
167{
168 saved_ppi_enable = __alloc_percpu(DIV_ROUND_UP(32, 32) * 4,
169 sizeof(u32));
170 BUG_ON(!saved_ppi_enable);
171
172 saved_ppi_conf = __alloc_percpu(DIV_ROUND_UP(32, 16) * 4,
173 sizeof(u32));
174 BUG_ON(!saved_ppi_conf);
175}
176#endif
177
178void msm_gic_irq_extn_init(void __iomem *db, void __iomem *cb)
179{
180 dist_base = db;
181 cpu_base = cb;
182 max_irqs = readl_relaxed(dist_base + GIC_DIST_CTR) & 0x11f;
183 max_irqs = (max_irqs + 1) * 32;
184
185 gic_arch_extn.irq_mask = msm_gic_mask_irq;
186 gic_arch_extn.irq_unmask = msm_gic_unmask_irq;
187 gic_arch_extn.irq_disable = msm_gic_mask_irq;
188 gic_arch_extn.irq_set_wake = msm_gic_set_irq_wake;
189
190#ifdef CONFIG_PM
191 msm_gic_pm_init();
192#endif
193}
194
195/* GIC APIs */
196
197 /*
198 * Save the GIC cpu and distributor context before PC and
199 * restor it back after coming out of PC.
200 */
201static void msm_gic_save(void)
202{
203 int i;
204 u32 *ptr;
205
206 /* Save the Per CPU PPI's */
207 ptr = __this_cpu_ptr(saved_ppi_enable);
208 /* 0 - 31 the SGI and PPI */
209 ptr[0] = readl_relaxed(dist_base + GIC_DIST_ENABLE_SET);
210
211 ptr = __this_cpu_ptr(saved_ppi_conf);
212 for (i = 0; i < 2; i++)
213 ptr[i] = readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
214
215 /* Save the SPIs */
216 for (i = 0; (i * 16) < max_irqs; i++)
217 saved_spi_conf[i] =
218 readl_relaxed(dist_base + GIC_DIST_CONFIG + i * 4);
219
220 for (i = 0; (i * 4) < max_irqs; i++)
221 saved_spi_target[i] =
222 readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4);
223
224 for (i = 0; (i * 32) < max_irqs; i++)
225 saved_spi_enable[i] =
226 readl_relaxed(dist_base + GIC_DIST_ENABLE_SET + i * 4);
227}
228
229static void msm_gic_restore(void)
230{
231 int i;
232 u32 *ptr;
233
234 /* restore CPU Interface */
235 /* Per CPU SGIs and PPIs */
236 ptr = __this_cpu_ptr(saved_ppi_enable);
237 writel_relaxed(ptr[0], dist_base + GIC_DIST_ENABLE_SET);
238
239 ptr = __this_cpu_ptr(saved_ppi_conf);
240 for (i = 0; i < 2; i++)
241 writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4);
242
243 for (i = 0; (i * 4) < max_irqs; i++)
244 writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
245
246 writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
247 writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
248
249 /* restore Distributor */
250 writel_relaxed(0, dist_base + GIC_DIST_CTRL);
251
252 for (i = 0; (i * 16) < max_irqs; i++)
253 writel_relaxed(saved_spi_conf[i],
254 dist_base + GIC_DIST_CONFIG + i * 4);
255
256 for (i = 0; (i * 4) < max_irqs; i++)
257 writel_relaxed(0xa0a0a0a0,
258 dist_base + GIC_DIST_PRI + i * 4);
259
260 for (i = 0; (i * 4) < max_irqs; i++)
261 writel_relaxed(saved_spi_target[i],
262 dist_base + GIC_DIST_TARGET + i * 4);
263
264 for (i = 0; (i * 32) < max_irqs; i++)
265 writel_relaxed(saved_spi_enable[i],
266 dist_base + GIC_DIST_ENABLE_SET + i * 4);
267
268 writel_relaxed(1, dist_base + GIC_DIST_CTRL);
269
270 mb();
271}
272
273/* Power APIs */
274
275 /*
276 * Check for any interrupts which are enabled are pending
277 * in the pending set or not.
278 * Return :
279 * 0 : No pending interrupts
280 * 1 : Pending interrupts other than A9_M2A_5
281 */
282unsigned int msm_gic_spi_ppi_pending(void)
283{
284 unsigned int i, bit = 0;
285 unsigned int pending_enb = 0, pending = 0;
286 unsigned long value = 0;
287
288 raw_spin_lock(&gic_controller_lock);
289 /*
290 * PPI and SGI to be included.
291 * MSM8625_INT_A9_M2A_5 needs to be ignored, as A9_M2A_5
292 * requesting sleep triggers it
293 */
294 for (i = 0; (i * 32) < max_irqs; i++) {
295 pending = readl_relaxed(dist_base +
296 GIC_DIST_PENDING_SET + i * 4);
297 pending_enb = readl_relaxed(dist_base +
298 GIC_DIST_ENABLE_SET + i * 4);
299 value = pending & pending_enb;
300
301 if (value) {
302 for (bit = 0; bit < 32; bit++) {
303 bit = find_next_bit(&value, 32, bit);
304 if ((bit + 32 * i) != MSM8625_INT_A9_M2A_5) {
305 raw_spin_unlock(&gic_controller_lock);
306 return 1;
307 }
308 }
309 }
310 }
311 raw_spin_unlock(&gic_controller_lock);
312
313 return 0;
314}
315
316 /*
317 * Iterate over the disable list
318 */
319
320int msm_gic_irq_idle_sleep_allowed(void)
321{
322 uint32_t i, disable = 0;
323
324 for (i = 0; i < NUM_REGS_DISABLE; i++)
325 disable |= msm_gic_irq_idle_disable[i];
326
327 return !disable;
328}
329
330 /*
331 * Prepare interrupt subsystem for entering sleep -- phase 1
332 * If modem_wake is true, return currently enabled interrupt
333 * mask in *irq_mask
334 */
335void msm_gic_irq_enter_sleep1(bool modem_wake, int from_idle, uint32_t
336 *irq_mask)
337{
338 if (modem_wake) {
339 *irq_mask = msm_gic_irq_smsm_wake_enable[!from_idle];
340 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
341 pr_info("%s irq_mask %x\n", __func__, *irq_mask);
342 }
343}
344
345 /*
346 * Prepare interrupt susbsytem for entering sleep -- phase 2
347 * Detect any pending interrupts and configure interrupt hardware.
348 * Return value:
349 * -EAGAIN: there are pending interrupt(s); interrupt configuration is not
350 * changed
351 * 0: Success
352 */
353int msm_gic_irq_enter_sleep2(bool modem_wake, int from_idle)
354{
355
356 if (from_idle && !modem_wake)
357 return 0;
358
359 /* edge triggered interrupt may get lost if this mode is used */
360 WARN_ON_ONCE(!modem_wake && !from_idle);
361
362 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
363 pr_info("%s interrupts pending\n", __func__);
364
365 /* check the pending interrupts */
366 if (msm_gic_spi_ppi_pending()) {
367 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP_ABORT)
368 pr_info("%s aborted....\n", __func__);
369 return -EAGAIN;
370 }
371
372 if (modem_wake) {
373 irq_set_irq_type(MSM8625_INT_A9_M2A_6, IRQF_TRIGGER_RISING);
374 /* save the contents of GIC CPU interface and Distributor */
375 msm_gic_save();
376 enable_irq(MSM8625_INT_A9_M2A_6);
377 pr_info("%s Good to go for sleep now\n", __func__);
378 }
379
380 return 0;
381}
382
383 /*
384 * Restore interrupt subsystem from sleep -- phase 1
385 * Configure the interrupt hardware.
386 */
387void msm_gic_irq_exit_sleep1(uint32_t irq_mask, uint32_t wakeup_reason,
388 uint32_t pending_irqs)
389{
390 /* Restore GIC contents, which were saved */
391 msm_gic_restore();
392
393 /* Disable A9_M2A_6 */
394 disable_irq(MSM8625_INT_A9_M2A_6);
395
396 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
397 pr_info("%s %x %x %x now\n", __func__, irq_mask,
398 pending_irqs, wakeup_reason);
399}
400
401 /*
402 * Restore interrupt subsystem from sleep -- phase 2
403 * Poke the specified pending interrupts into interrupt hardware.
404 */
405void msm_gic_irq_exit_sleep2(uint32_t irq_mask, uint32_t wakeup_reason,
406 uint32_t pending)
407{
408 int i, smsm_irq, smsm_mask;
409 struct irq_desc *desc;
410
411 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
412 pr_info("%s %x %x %x now\n", __func__, irq_mask,
413 pending, wakeup_reason);
414
415 for (i = 0; pending && i < ARRAY_SIZE(msm_gic_irq_to_smsm); i++) {
416 smsm_irq = msm_gic_irq_to_smsm[i];
417
418 if (smsm_irq == 0)
419 continue;
420
421 smsm_mask = BIT(smsm_irq - 1);
422 if (!(pending & smsm_mask))
423 continue;
424
425 pending &= ~smsm_mask;
426
427 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP_INT)
428 pr_info("%s, irq %d, still pending %x now\n",
429 __func__, i, pending);
430 /* Peding IRQ */
431 desc = i ? irq_to_desc(i) : NULL;
432
433 /* Check if the pending */
434 if (desc && !irqd_is_level_type(&desc->irq_data)) {
435 /* Mark the IRQ as pending, if not Level */
436 irq_set_pending(i);
437 check_irq_resend(desc, i);
438 }
439 }
440}
441
442 /*
443 * Restore interrupt subsystem from sleep -- phase 3
444 * Print debug information
445 */
446void msm_gic_irq_exit_sleep3(uint32_t irq_mask, uint32_t wakeup_reason,
447 uint32_t pending_irqs)
448{
449 if (msm_gic_irq_debug_mask & IRQ_DEBUG_SLEEP)
450 pr_info("%s, irq_mask %x pending_irqs %x, wakeup_reason %x,"
451 "state %x now\n", __func__, irq_mask,
452 pending_irqs, wakeup_reason,
453 smsm_get_state(SMSM_MODEM_STATE));
454}