Commit 03bcb7e3 authored by Varun Sethi's avatar Varun Sethi Committed by Kumar Gala

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: default avatarVarun Sethi <Varun.Sethi@freescale.com>
Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 34f84b5b
...@@ -63,6 +63,7 @@ ...@@ -63,6 +63,7 @@
*/ */
#define MPIC_TIMER_BASE 0x01100 #define MPIC_TIMER_BASE 0x01100
#define MPIC_TIMER_STRIDE 0x40 #define MPIC_TIMER_STRIDE 0x40
#define MPIC_TIMER_GROUP_STRIDE 0x1000
#define MPIC_TIMER_CURRENT_CNT 0x00000 #define MPIC_TIMER_CURRENT_CNT 0x00000
#define MPIC_TIMER_BASE_CNT 0x00010 #define MPIC_TIMER_BASE_CNT 0x00010
...@@ -110,6 +111,9 @@ ...@@ -110,6 +111,9 @@
#define MPIC_VECPRI_SENSE_MASK 0x00400000 #define MPIC_VECPRI_SENSE_MASK 0x00400000
#define MPIC_IRQ_DESTINATION 0x00010 #define MPIC_IRQ_DESTINATION 0x00010
#define MPIC_FSL_BRR1 0x00000
#define MPIC_FSL_BRR1_VER 0x0000ffff
#define MPIC_MAX_IRQ_SOURCES 2048 #define MPIC_MAX_IRQ_SOURCES 2048
#define MPIC_MAX_CPUS 32 #define MPIC_MAX_CPUS 32
#define MPIC_MAX_ISU 32 #define MPIC_MAX_ISU 32
...@@ -296,6 +300,7 @@ struct mpic ...@@ -296,6 +300,7 @@ struct mpic
phys_addr_t paddr; phys_addr_t paddr;
/* The various ioremap'ed bases */ /* The various ioremap'ed bases */
struct mpic_reg_bank thiscpuregs;
struct mpic_reg_bank gregs; struct mpic_reg_bank gregs;
struct mpic_reg_bank tmregs; struct mpic_reg_bank tmregs;
struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS]; struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* with various broken implementations of this HW. * with various broken implementations of this HW.
* *
* Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
* Copyright 2010-2011 Freescale Semiconductor, Inc. * Copyright 2010-2012 Freescale Semiconductor, Inc.
* *
* This file is subject to the terms and conditions of the GNU General Public * This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive * 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,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
_mpic_write(mpic->reg_type, &mpic->gregs, offset, value); _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
} }
static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm) static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
{ {
unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
((tm & 3) * MPIC_INFO(TIMER_STRIDE)); (tm & 3) * MPIC_INFO(TIMER_STRIDE);
}
if (tm >= 4) static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
offset += 0x1000 / 4; {
unsigned int offset = mpic_tm_offset(mpic, tm) +
MPIC_INFO(TIMER_VECTOR_PRI);
return _mpic_read(mpic->reg_type, &mpic->tmregs, offset); return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
} }
static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value) static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
{ {
unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + unsigned int offset = mpic_tm_offset(mpic, tm) +
((tm & 3) * MPIC_INFO(TIMER_STRIDE)); MPIC_INFO(TIMER_VECTOR_PRI);
if (tm >= 4)
offset += 0x1000 / 4;
_mpic_write(mpic->reg_type, &mpic->tmregs, offset, value); _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
} }
...@@ -1301,6 +1301,16 @@ struct mpic * __init mpic_alloc(struct device_node *node, ...@@ -1301,6 +1301,16 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
if (mpic->flags & MPIC_FSL) {
/*
* Yes, Freescale really did put global registers in the
* magic per-cpu area -- and they don't even show up in the
* non-magic per-cpu copies that this driver normally uses.
*/
mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
MPIC_CPU_THISBASE, 0x1000);
}
/* Reset */ /* Reset */
/* When using a device-node, reset requests are only honored if the MPIC /* 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, ...@@ -1440,6 +1450,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
void __init mpic_init(struct mpic *mpic) void __init mpic_init(struct mpic *mpic)
{ {
int i, cpu; int i, cpu;
int num_timers = 4;
BUG_ON(mpic->num_sources == 0); BUG_ON(mpic->num_sources == 0);
...@@ -1448,15 +1459,30 @@ void __init mpic_init(struct mpic *mpic) ...@@ -1448,15 +1459,30 @@ void __init mpic_init(struct mpic *mpic)
/* Set current processor priority to max */ /* Set current processor priority to max */
mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
if (mpic->flags & MPIC_FSL) {
u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
MPIC_FSL_BRR1);
u32 version = brr1 & MPIC_FSL_BRR1_VER;
/*
* Timer group B is present at the latest in MPIC 3.1 (e.g.
* mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544).
* I don't know about the status of intermediate versions (or
* whether they even exist).
*/
if (version >= 0x0301)
num_timers = 8;
}
/* Initialize timers to our reserved vectors and mask them for now */ /* Initialize timers to our reserved vectors and mask them for now */
for (i = 0; i < 4; i++) { for (i = 0; i < num_timers; i++) {
unsigned int offset = mpic_tm_offset(mpic, i);
mpic_write(mpic->tmregs, mpic_write(mpic->tmregs,
i * MPIC_INFO(TIMER_STRIDE) + offset + MPIC_INFO(TIMER_DESTINATION),
MPIC_INFO(TIMER_DESTINATION),
1 << hard_smp_processor_id()); 1 << hard_smp_processor_id());
mpic_write(mpic->tmregs, mpic_write(mpic->tmregs,
i * MPIC_INFO(TIMER_STRIDE) + offset + MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_VECPRI_MASK | MPIC_VECPRI_MASK |
(9 << MPIC_VECPRI_PRIORITY_SHIFT) | (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
(mpic->timer_vecs[0] + i)); (mpic->timer_vecs[0] + i));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment