aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVarun Sethi <Varun.Sethi@freescale.com>2012-07-09 04:45:42 -0400
committerKumar Gala <galak@kernel.crashing.org>2012-09-12 15:57:07 -0400
commit03bcb7e35f7e5f759fe03f10a12cd4060dabe60d (patch)
treeda831db282105b46a434db47143b51d4a274909f
parent34f84b5b5bc83f4fc208cc278f572e6d926f976b (diff)
powerpc/mpic: finish supporting timer group B on Freescale chips
Previously, these interrupts would be mapped, but the offset calculation was broken, and only the first group was initialized. Signed-off-by: Varun Sethi <Varun.Sethi@freescale.com> Signed-off-by: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/mpic.h5
-rw-r--r--arch/powerpc/sysdev/mpic.c58
2 files changed, 47 insertions, 16 deletions
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index c9f698a994be..e14d35d572af 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -63,6 +63,7 @@
63 */ 63 */
64#define MPIC_TIMER_BASE 0x01100 64#define MPIC_TIMER_BASE 0x01100
65#define MPIC_TIMER_STRIDE 0x40 65#define MPIC_TIMER_STRIDE 0x40
66#define MPIC_TIMER_GROUP_STRIDE 0x1000
66 67
67#define MPIC_TIMER_CURRENT_CNT 0x00000 68#define MPIC_TIMER_CURRENT_CNT 0x00000
68#define MPIC_TIMER_BASE_CNT 0x00010 69#define MPIC_TIMER_BASE_CNT 0x00010
@@ -110,6 +111,9 @@
110#define MPIC_VECPRI_SENSE_MASK 0x00400000 111#define MPIC_VECPRI_SENSE_MASK 0x00400000
111#define MPIC_IRQ_DESTINATION 0x00010 112#define MPIC_IRQ_DESTINATION 0x00010
112 113
114#define MPIC_FSL_BRR1 0x00000
115#define MPIC_FSL_BRR1_VER 0x0000ffff
116
113#define MPIC_MAX_IRQ_SOURCES 2048 117#define MPIC_MAX_IRQ_SOURCES 2048
114#define MPIC_MAX_CPUS 32 118#define MPIC_MAX_CPUS 32
115#define MPIC_MAX_ISU 32 119#define MPIC_MAX_ISU 32
@@ -296,6 +300,7 @@ struct mpic
296 phys_addr_t paddr; 300 phys_addr_t paddr;
297 301
298 /* The various ioremap'ed bases */ 302 /* The various ioremap'ed bases */
303 struct mpic_reg_bank thiscpuregs;
299 struct mpic_reg_bank gregs; 304 struct mpic_reg_bank gregs;
300 struct mpic_reg_bank tmregs; 305 struct mpic_reg_bank tmregs;
301 struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS]; 306 struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index bfc6211e5422..7e32db7e7b0d 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -6,7 +6,7 @@
6 * with various broken implementations of this HW. 6 * with various broken implementations of this HW.
7 * 7 *
8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. 8 * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
9 * Copyright 2010-2011 Freescale Semiconductor, Inc. 9 * Copyright 2010-2012 Freescale Semiconductor, Inc.
10 * 10 *
11 * This file is subject to the terms and conditions of the GNU General Public 11 * This file is subject to the terms and conditions of the GNU General Public
12 * License. See the file COPYING in the main directory of this archive 12 * License. See the file COPYING in the main directory of this archive
@@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
221 _mpic_write(mpic->reg_type, &mpic->gregs, offset, value); 221 _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
222} 222}
223 223
224static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm) 224static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
225{ 225{
226 unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + 226 return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
227 ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); 227 (tm & 3) * MPIC_INFO(TIMER_STRIDE);
228}
228 229
229 if (tm >= 4) 230static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
230 offset += 0x1000 / 4; 231{
232 unsigned int offset = mpic_tm_offset(mpic, tm) +
233 MPIC_INFO(TIMER_VECTOR_PRI);
231 234
232 return _mpic_read(mpic->reg_type, &mpic->tmregs, offset); 235 return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
233} 236}
234 237
235static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value) 238static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
236{ 239{
237 unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + 240 unsigned int offset = mpic_tm_offset(mpic, tm) +
238 ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); 241 MPIC_INFO(TIMER_VECTOR_PRI);
239
240 if (tm >= 4)
241 offset += 0x1000 / 4;
242 242
243 _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value); 243 _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
244} 244}
@@ -1301,6 +1301,16 @@ struct mpic * __init mpic_alloc(struct device_node *node,
1301 mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); 1301 mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
1302 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); 1302 mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
1303 1303
1304 if (mpic->flags & MPIC_FSL) {
1305 /*
1306 * Yes, Freescale really did put global registers in the
1307 * magic per-cpu area -- and they don't even show up in the
1308 * non-magic per-cpu copies that this driver normally uses.
1309 */
1310 mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
1311 MPIC_CPU_THISBASE, 0x1000);
1312 }
1313
1304 /* Reset */ 1314 /* Reset */
1305 1315
1306 /* When using a device-node, reset requests are only honored if the MPIC 1316 /* When using a device-node, reset requests are only honored if the MPIC
@@ -1440,6 +1450,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
1440void __init mpic_init(struct mpic *mpic) 1450void __init mpic_init(struct mpic *mpic)
1441{ 1451{
1442 int i, cpu; 1452 int i, cpu;
1453 int num_timers = 4;
1443 1454
1444 BUG_ON(mpic->num_sources == 0); 1455 BUG_ON(mpic->num_sources == 0);
1445 1456
@@ -1448,15 +1459,30 @@ void __init mpic_init(struct mpic *mpic)
1448 /* Set current processor priority to max */ 1459 /* Set current processor priority to max */
1449 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); 1460 mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
1450 1461
1462 if (mpic->flags & MPIC_FSL) {
1463 u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
1464 MPIC_FSL_BRR1);
1465 u32 version = brr1 & MPIC_FSL_BRR1_VER;
1466
1467 /*
1468 * Timer group B is present at the latest in MPIC 3.1 (e.g.
1469 * mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544).
1470 * I don't know about the status of intermediate versions (or
1471 * whether they even exist).
1472 */
1473 if (version >= 0x0301)
1474 num_timers = 8;
1475 }
1476
1451 /* Initialize timers to our reserved vectors and mask them for now */ 1477 /* Initialize timers to our reserved vectors and mask them for now */
1452 for (i = 0; i < 4; i++) { 1478 for (i = 0; i < num_timers; i++) {
1479 unsigned int offset = mpic_tm_offset(mpic, i);
1480
1453 mpic_write(mpic->tmregs, 1481 mpic_write(mpic->tmregs,
1454 i * MPIC_INFO(TIMER_STRIDE) + 1482 offset + MPIC_INFO(TIMER_DESTINATION),
1455 MPIC_INFO(TIMER_DESTINATION),
1456 1 << hard_smp_processor_id()); 1483 1 << hard_smp_processor_id());
1457 mpic_write(mpic->tmregs, 1484 mpic_write(mpic->tmregs,
1458 i * MPIC_INFO(TIMER_STRIDE) + 1485 offset + MPIC_INFO(TIMER_VECTOR_PRI),
1459 MPIC_INFO(TIMER_VECTOR_PRI),
1460 MPIC_VECPRI_MASK | 1486 MPIC_VECPRI_MASK |
1461 (9 << MPIC_VECPRI_PRIORITY_SHIFT) | 1487 (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
1462 (mpic->timer_vecs[0] + i)); 1488 (mpic->timer_vecs[0] + i));