* [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
@ 2006-08-22 10:07 Zang Roy-r61911
2006-08-22 17:15 ` Adrian Cox
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-22 10:07 UTC (permalink / raw)
To: Paul Mackerras, Benjamin Herrenschmidt
Cc: linuxppc-dev list, Yang Xin-Xin-r48390, Alexandre.Bounine
The patch adds new hardware information table for mpic. This=20
enables mpic code to deal with mpic controller with=20
hardware behavior difference.
CONFIG_MPIC_WEIRD is introduced in the code.
If a board with non standard mpic controller, it can select the
CONFIG_MPIC_WEIRD with board and add its hardware information
in the array mpic_infos.
TSI108/109 PIC takes the first index of weird hardware information=20
table:) . The table can be extended. The Tsi108/109 PIC looks like=20
standard OpenPIC but, in fact, is different in registers mapping and
behavior.
The patch does not affect the behavior of standard mpic.
CONFIG_MPIC_WEIRD
excludes the weird mpic code when building standard mpic.
=20
Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>=20
---
arch/powerpc/Kconfig | 8 +-
arch/powerpc/sysdev/Makefile | 1=20
arch/powerpc/sysdev/mpic.c | 187
+++++++++++++++++++++++++++++-------------
include/asm-powerpc/mpic.h | 114 ++++++++++++++++++++++++++
4 files changed, 252 insertions(+), 58 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index abb325e..c88b647 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -440,11 +440,15 @@ config U3_DART
default n
=20
config MPIC
- depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
- || MPC7448HPC2
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
bool
default y
=20
+config MPIC_WEIRD
+ depends on MPC7448HPC2
+ bool
+ default y
+=09
config PPC_RTAS
bool
default n
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cebfae2..8ae887b 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -3,6 +3,7 @@ EXTRA_CFLAGS +=3D -mno-minimal-toc
endif
=20
obj-$(CONFIG_MPIC) +=3D mpic.o
+obj-$(CONFIG_MPIC_WEIRD) +=3D mpic.o
obj-$(CONFIG_PPC_INDIRECT_PCI) +=3D indirect_pci.o
obj-$(CONFIG_PPC_MPC106) +=3D grackle.o
obj-$(CONFIG_BOOKE) +=3D dcr.o
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 6e0281a..78e0515 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -54,6 +54,55 @@ #define distribute_irqs (0)
#endif
#endif
=20
+#ifdef CONFIG_MPIC_WEIRD
+static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] =3D {
+ [0] =3D { /* Tsi108/109 PIC */
+ TSI108_GREG_BASE,
+ TSI108_GREG_FEATURE_0,
+ TSI108_GREG_GLOBAL_CONF_0,
+ TSI108_GREG_VENDOR_ID,
+ TSI108_GREG_IPI_VECTOR_PRI_0,
+ TSI108_GREG_IPI_STRIDE,
+ TSI108_GREG_SPURIOUS,
+ TSI108_GREG_TIMER_FREQ,
+
+ TSI108_TIMER_BASE,
+ TSI108_TIMER_STRIDE,
+ TSI108_TIMER_CURRENT_CNT,
+ TSI108_TIMER_BASE_CNT,
+ TSI108_TIMER_VECTOR_PRI,
+ TSI108_TIMER_DESTINATION,
+
+ TSI108_CPU_BASE,
+ TSI108_CPU_STRIDE,
+ TSI108_CPU_IPI_DISPATCH_0,
+ TSI108_CPU_IPI_DISPATCH_STRIDE,
+ TSI108_CPU_CURRENT_TASK_PRI,
+ TSI108_CPU_WHOAMI,
+ TSI108_CPU_INTACK,
+ TSI108_CPU_EOI,
+
+ TSI108_IRQ_BASE,
+ TSI108_IRQ_STRIDE,
+ TSI108_IRQ_VECTOR_PRI,
+ TSI108_VECPRI_VECTOR_MASK,
+ TSI108_VECPRI_POLARITY_POSITIVE,
+ TSI108_VECPRI_POLARITY_NEGATIVE,
+ TSI108_VECPRI_SENSE_LEVEL,
+ TSI108_VECPRI_SENSE_EDGE,
+ TSI108_VECPRI_POLARITY_MASK,
+ TSI108_VECPRI_SENSE_MASK,
+ TSI108_IRQ_DESTINATION
+ },
+};
+#endif
+
+#ifdef CONFIG_MPIC_WEIRD
+#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
+#else
+#define MPIC_INFO(name) MPIC_##name
+#endif
+
/*
* Register accessor functions
*/
@@ -80,7 +129,8 @@ static inline void _mpic_write(unsigned=20
static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
unsigned int be =3D (mpic->flags & MPIC_BIG_ENDIAN) !=3D 0;
- unsigned int offset =3D MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset =3D MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
=20
if (mpic->flags & MPIC_BROKEN_IPI)
be =3D !be;
@@ -89,7 +139,8 @@ static inline u32 _mpic_ipi_read(struct=20
=20
static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi,
u32 value)
{
- unsigned int offset =3D MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset =3D MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
=20
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset,
value);
}
@@ -120,7 +171,7 @@ static inline u32 _mpic_irq_read(struct=20
unsigned int idx =3D src_no & mpic->isu_mask;
=20
return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,
mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE));
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)));
}
=20
static inline void _mpic_irq_write(struct mpic *mpic, unsigned int
src_no,
@@ -130,7 +181,7 @@ static inline void _mpic_irq_write(struc
unsigned int idx =3D src_no & mpic->isu_mask;
=20
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE), value);
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
}
=20
#define mpic_read(b,r) _mpic_read(mpic->flags &
MPIC_BIG_ENDIAN,(b),(r))
@@ -156,8 +207,8 @@ static void __init mpic_test_broken_ipi(
{
u32 r;
=20
- mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0,
MPIC_VECPRI_MASK);
- r =3D mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0),
MPIC_VECPRI_MASK);
+ r =3D mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
=20
if (r =3D=3D le32_to_cpu(MPIC_VECPRI_MASK)) {
printk(KERN_INFO "mpic: Detected reversed IPI
registers\n");
@@ -394,8 +445,8 @@ static inline struct mpic * mpic_from_ir
/* Send an EOI */
static inline void mpic_eoi(struct mpic *mpic)
{
- mpic_cpu_write(MPIC_CPU_EOI, 0);
- (void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+ mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
+ (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
}
=20
#ifdef CONFIG_SMP
@@ -419,8 +470,8 @@ static void mpic_unmask_irq(unsigned int
=20
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq,
src);
=20
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -428,7 +479,7 @@ static void mpic_unmask_irq(unsigned int
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
MPIC_VECPRI_MASK);
+ } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
MPIC_VECPRI_MASK);=09
}
=20
static void mpic_mask_irq(unsigned int irq)
@@ -439,8 +490,8 @@ static void mpic_mask_irq(unsigned int i
=20
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
=20
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
MPIC_VECPRI_MASK);
=20
/* make sure mask gets to controller before we return to user */
@@ -449,7 +500,7 @@ static void mpic_mask_irq(unsigned int i
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
MPIC_VECPRI_MASK));
+ } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
MPIC_VECPRI_MASK));
}
=20
static void mpic_end_irq(unsigned int irq)
@@ -560,24 +611,32 @@ static void mpic_set_affinity(unsigned i
=20
cpus_and(tmp, cpumask, cpu_online_map);
=20
- mpic_irq_write(src, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
mpic_physmask(cpus_addr(tmp)[0]));=09
}
=20
+#ifdef CONFIG_MPIC_WEIRD
+static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int
type)
+#else
static unsigned int mpic_type_to_vecpri(unsigned int type)
+#endif
{
/* Now convert sense value */
switch(type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
- return MPIC_VECPRI_SENSE_EDGE |
MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_EDGE_FALLING:
case IRQ_TYPE_EDGE_BOTH:
- return MPIC_VECPRI_SENSE_EDGE |
MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
case IRQ_TYPE_LEVEL_HIGH:
- return MPIC_VECPRI_SENSE_LEVEL |
MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_LEVEL_LOW:
default:
- return MPIC_VECPRI_SENSE_LEVEL |
MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
}
}
=20
@@ -609,13 +668,18 @@ static int mpic_set_irq_type(unsigned in
vecpri =3D MPIC_VECPRI_POLARITY_POSITIVE |
MPIC_VECPRI_SENSE_EDGE;
else
+#ifdef CONFIG_MPIC_WEIRD
+ vecpri =3D mpic_type_to_vecpri(mpic, flow_type);
+#else
vecpri =3D mpic_type_to_vecpri(flow_type);
+#endif=09
=20
- vold =3D mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
- vnew =3D vold & ~(MPIC_VECPRI_POLARITY_MASK |
MPIC_VECPRI_SENSE_MASK);
+ vold =3D mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
+ vnew =3D vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |=20
+ MPIC_INFO(VECPRI_SENSE_MASK));
vnew |=3D vecpri;
if (vold !=3D vnew)
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
=20
return 0;
}
@@ -797,18 +861,23 @@ #endif /* CONFIG_SMP */
mpic->isu_size =3D isu_size;
mpic->irq_count =3D irq_count;
mpic->num_sources =3D 0; /* so far */
+=09
+#ifdef CONFIG_MPIC_WEIRD
+ mpic->hw_set =3D mpic_infos[MPIC_GET_MOD_ID(flags)];
+#endif
=20
/* Map the global registers */
- mpic->gregs =3D ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
- mpic->tmregs =3D mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE)
>> 2);
+ mpic->gregs =3D ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
+ mpic->tmregs =3D mpic->gregs +
+ ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE))
>> 2);
BUG_ON(mpic->gregs =3D=3D NULL);
=20
/* Reset */
if (flags & MPIC_WANTS_RESET) {
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs,
MPIC_GREG_GLOBAL_CONF_0)
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs,
MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_RESET);
- while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ while( mpic_read(mpic->gregs,
MPIC_INFO(GREG_GLOBAL_CONF_0))
& MPIC_GREG_GCONF_RESET)
mb();
}
@@ -817,7 +886,7 @@ #endif /* CONFIG_SMP */
* MPICs, num sources as well. On ISU MPICs, sources are counted
* as ISUs are added
*/
- reg =3D mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
+ reg =3D mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
mpic->num_cpus =3D ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
>> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
if (isu_size =3D=3D 0)
@@ -826,16 +895,16 @@ #endif /* CONFIG_SMP */
=20
/* Map the per-CPU registers */
for (i =3D 0; i < mpic->num_cpus; i++) {
- mpic->cpuregs[i] =3D ioremap(phys_addr + MPIC_CPU_BASE +
- i * MPIC_CPU_STRIDE, 0x1000);
+ mpic->cpuregs[i] =3D ioremap(phys_addr +
MPIC_INFO(CPU_BASE) +
+ i * MPIC_INFO(CPU_STRIDE),
0x1000);
BUG_ON(mpic->cpuregs[i] =3D=3D NULL);
}
=20
/* Initialize main ISU if none provided */
if (mpic->isu_size =3D=3D 0) {
mpic->isu_size =3D mpic->num_sources;
- mpic->isus[0] =3D ioremap(phys_addr + MPIC_IRQ_BASE,
- MPIC_IRQ_STRIDE *
mpic->isu_size);
+ mpic->isus[0] =3D ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
+ MPIC_INFO(IRQ_STRIDE) *
mpic->isu_size);
BUG_ON(mpic->isus[0] =3D=3D NULL);
}
mpic->isu_shift =3D 1 + __ilog2(mpic->isu_size - 1);
@@ -879,7 +948,8 @@ void __init mpic_assign_isu(struct mpic=20
=20
BUG_ON(isu_num >=3D MPIC_MAX_ISU);
=20
- mpic->isus[isu_num] =3D ioremap(phys_addr, MPIC_IRQ_STRIDE *
mpic->isu_size);
+ mpic->isus[isu_num] =3D ioremap(phys_addr,
+ MPIC_INFO(IRQ_STRIDE) *
mpic->isu_size);
if ((isu_first + mpic->isu_size) > mpic->num_sources)
mpic->num_sources =3D isu_first + mpic->isu_size;
}
@@ -904,14 +974,16 @@ void __init mpic_init(struct mpic *mpic)
printk(KERN_INFO "mpic: Initializing for %d sources\n",
mpic->num_sources);
=20
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
=20
/* Initialize timers: just disable them all */
for (i =3D 0; i < 4; i++) {
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE +
MPIC_TIMER_DESTINATION, 0);
+ i * MPIC_INFO(TIMER_STRIDE) +
+ MPIC_INFO(TIMER_DESTINATION), 0);
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE +
MPIC_TIMER_VECTOR_PRI,
+ i * MPIC_INFO(TIMER_STRIDE) +=20
+ MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_VECPRI_MASK |
(MPIC_VEC_TIMER_0 + i));
}
@@ -940,21 +1012,23 @@ void __init mpic_init(struct mpic *mpic)
(8 << MPIC_VECPRI_PRIORITY_SHIFT);
=09
/* init hw */
- mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
1 << hard_smp_processor_id());
}
=09
/* Init spurrious vector */
- mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS),
MPIC_VEC_SPURRIOUS);
=20
- /* Disable 8259 passthrough */
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ /* Disable 8259 passthrough, if supported */
+#ifndef CONFIG_MPIC_WEIRD
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_8259_PTHROU_DIS);
+#endif
=20
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
}
=20
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -997,9 +1071,9 @@ void mpic_irq_set_priority(unsigned int=20
mpic_ipi_write(src - MPIC_VEC_IPI_0,
reg | (pri <<
MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg =3D mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
+ reg =3D mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
& ~MPIC_VECPRI_PRIORITY_MASK;
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
reg | (pri <<
MPIC_VECPRI_PRIORITY_SHIFT));
}
spin_unlock_irqrestore(&mpic_lock, flags);
@@ -1017,7 +1091,7 @@ unsigned int mpic_irq_get_priority(unsig
if (is_ipi)
reg =3D mpic_ipi_read(src =3D MPIC_VEC_IPI_0);
else
- reg =3D mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+ reg =3D mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
spin_unlock_irqrestore(&mpic_lock, flags);
return (reg & MPIC_VECPRI_PRIORITY_MASK) >>
MPIC_VECPRI_PRIORITY_SHIFT;
}
@@ -1043,12 +1117,12 @@ #ifdef CONFIG_SMP
*/
if (distribute_irqs) {
for (i =3D 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) |
msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i,
MPIC_INFO(IRQ_DESTINATION)) | msk);
}
=20
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
=20
spin_unlock_irqrestore(&mpic_lock, flags);
#endif /* CONFIG_SMP */
@@ -1058,7 +1132,7 @@ int mpic_cpu_get_priority(void)
{
struct mpic *mpic =3D mpic_primary;
=20
- return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+ return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
}
=20
void mpic_cpu_set_priority(int prio)
@@ -1066,7 +1140,7 @@ void mpic_cpu_set_priority(int prio)
struct mpic *mpic =3D mpic_primary;
=20
prio &=3D MPIC_CPU_TASKPRI_MASK;
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
}
=20
/*
@@ -1088,11 +1162,11 @@ void mpic_teardown_this_cpu(int secondar
=20
/* let the mpic know we don't want intrs. */
for (i =3D 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) &
~msk);
=20
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
=20
spin_unlock_irqrestore(&mpic_lock, flags);
}
@@ -1108,7 +1182,8 @@ #ifdef DEBUG_IPI
DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
#endif
=20
- mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
+ mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+ ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
mpic_physmask(cpu_mask &
cpus_addr(cpu_online_map)[0]));
}
=20
@@ -1116,7 +1191,7 @@ unsigned int mpic_get_one_irq(struct mpi
{
u32 src;
=20
- src =3D mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
+ src =3D mpic_cpu_read(MPIC_INFO(CPU_INTACK)) &
MPIC_INFO(VECPRI_VECTOR_MASK);
#ifdef DEBUG_LOW
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
#endif
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index eb241c9..faebdf2 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0 0x000
#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0
#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0
#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0
+#define MPIC_GREG_IPI_STRIDE 0x10
#define MPIC_GREG_SPURIOUS 0x000e0
#define MPIC_GREG_TIMER_FREQ 0x000f0
=20
@@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0 0x00040
#define MPIC_CPU_IPI_DISPATCH_1 0x00050
#define MPIC_CPU_IPI_DISPATCH_2 0x00060
#define MPIC_CPU_IPI_DISPATCH_3 0x00070
+#define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010
#define MPIC_CPU_CURRENT_TASK_PRI 0x00080
#define MPIC_CPU_TASKPRI_MASK 0x0000000f
#define MPIC_CPU_WHOAMI 0x00090
@@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2 249
#define MPIC_VEC_TIMER_1 248
#define MPIC_VEC_TIMER_0 247
=20
+#ifdef CONFIG_MPIC_WEIRD
+/*
+ * Tsi108 implementation of MPIC has many differences from the original
one
+ */
+
+/*
+ * Global registers
+ */
+
+#define TSI108_GREG_BASE 0x00000
+#define TSI108_GREG_FEATURE_0 0x00000
+#define TSI108_GREG_GLOBAL_CONF_0 0x00004
+#define TSI108_GREG_VENDOR_ID 0x0000c
+#define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */
+#define TSI108_GREG_IPI_STRIDE 0x0c
+#define TSI108_GREG_SPURIOUS 0x00010
+#define TSI108_GREG_TIMER_FREQ 0x00014
+
+/*
+ * Timer registers
+ */
+#define TSI108_TIMER_BASE 0x0030
+#define TSI108_TIMER_STRIDE 0x10
+#define TSI108_TIMER_CURRENT_CNT 0x00000
+#define TSI108_TIMER_BASE_CNT 0x00004
+#define TSI108_TIMER_VECTOR_PRI 0x00008
+#define TSI108_TIMER_DESTINATION 0x0000c
+
+/*
+ * Per-Processor registers
+ */
+#define TSI108_CPU_BASE 0x00300
+#define TSI108_CPU_STRIDE 0x00040
+#define TSI108_CPU_IPI_DISPATCH_0 0x00200
+#define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000
+#define TSI108_CPU_CURRENT_TASK_PRI 0x00000
+#define TSI108_CPU_WHOAMI 0xffffffff
+#define TSI108_CPU_INTACK 0x00004
+#define TSI108_CPU_EOI 0x00008
+
+/*
+ * Per-source registers
+ */
+#define TSI108_IRQ_BASE 0x00100
+#define TSI108_IRQ_STRIDE 0x00008
+#define TSI108_IRQ_VECTOR_PRI 0x00000
+#define TSI108_VECPRI_VECTOR_MASK 0x000000ff
+#define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000
+#define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000
+#define TSI108_VECPRI_SENSE_LEVEL 0x02000000
+#define TSI108_VECPRI_SENSE_EDGE 0x00000000
+#define TSI108_VECPRI_POLARITY_MASK 0x01000000
+#define TSI108_VECPRI_SENSE_MASK 0x02000000
+#define TSI108_IRQ_DESTINATION 0x00004
+
+/* weird mpic variable index in the HW info array */
+enum MPIC_WEIRD_INDEX {
+ INDEX_GREG_BASE =3D 0, /* Offset of global registers from MPIC
base */
+ INDEX_GREG_FEATURE_0, /* FRR0 offset from base */
+ INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from
base */
+ INDEX_GREG_VENDOR_ID, /* VID register offset from base */
+ INDEX_GREG_IPI_VECTOR_PRI_0, /* IPI Vector/Priority Registers
*/
+ INDEX_GREG_IPI_STRIDE, /* IPI Vector/Priority Registers
spacing */
+ INDEX_GREG_SPURIOUS, /* Spurious Vector Register */
+ INDEX_GREG_TIMER_FREQ, /* Global Timer Frequency Reporting
Register */
+
+ INDEX_TIMER_BASE, /* Global Timer Registers base
*/
+ INDEX_TIMER_STRIDE, /* Global Timer Registers
spacing */
+ INDEX_TIMER_CURRENT_CNT, /* Global Timer Current Count
Register */
+ INDEX_TIMER_BASE_CNT, /* Global Timer Base Count
Register */
+ INDEX_TIMER_VECTOR_PRI, /* Global Timer Vector/Priority
Register */
+ INDEX_TIMER_DESTINATION, /* Global Timer Destination
Register */
+
+ INDEX_CPU_BASE, /* Offset of cpu base */
+ INDEX_CPU_STRIDE, /* Cpu register spacing*/
+ INDEX_CPU_IPI_DISPATCH_0, /* IPI 0 Dispatch Command
Register */
+ INDEX_CPU_IPI_DISPATCH_STRIDE, /* IPI Dispatch spacing */
+ INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority
Register */
+ INDEX_CPU_WHOAMI, /* Who Am I Register */
+ INDEX_CPU_INTACK, /* Interrupt Acknowledge Register */
+ INDEX_CPU_EOI, /* End of Interrupt Register */
+
+ INDEX_IRQ_BASE, /* Interrupt registers base */
+ INDEX_IRQ_STRIDE, /* Interrupt registers spacing */
+ INDEX_IRQ_VECTOR_PRI, /* Interrupt Vector/Priority Register */
+ INDEX_VECPRI_VECTOR_MASK, /* Interrupt Vector Mask */
+ INDEX_VECPRI_POLARITY_POSITIVE, /* Interrupt Positive Polarity
bit */
+ INDEX_VECPRI_POLARITY_NEGATIVE, /* Interrupt Negative Polarity
bit */
+ INDEX_VECPRI_SENSE_LEVEL, /* Interrupt Level Sense bit */
+ INDEX_VECPRI_SENSE_EDGE, /* Interrupt edge Sense bit */
+ INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
+ INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
+ INDEX_IRQ_DESTINATION, /* Interrupt Destination Register */
+ INDEX_MPIC_WEIRD_END /* Size of the hw info array */
+};
+#endif
+
#ifdef CONFIG_MPIC_BROKEN_U3
/* Fixup table entry */
struct mpic_irq_fixup
@@ -170,6 +269,11 @@ #endif
volatile u32 __iomem *tmregs;
volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
volatile u32 __iomem *isus[MPIC_MAX_ISU];
+=09
+#ifdef CONFIG_MPIC_WEIRD
+ /* Pointer to HW info array */
+ u32 *hw_set;
+#endif
=20
/* link */
struct mpic *next;
@@ -189,6 +293,16 @@ #define MPIC_BROKEN_IPI
0x00000008
/* MPIC wants a reset */
#define MPIC_WANTS_RESET 0x00000010
=20
+#ifdef CONFIG_MPIC_WEIRD
+/* Spurious vector requires EOI */
+#define MPIC_SPV_EOI 0x00000020
+/* MPIC HW modification ID */
+#define MPIC_MOD_ID_MASK 0x00000f00
+#define MPIC_MOD_ID(val) (((val) << 8) &
MPIC_MOD_ID_MASK)
+#define MPIC_GET_MOD_ID(flags) (((flags) & MPIC_MOD_ID_MASK) >>
8)
+#define MPIC_ID_TSI108 0 /* Tsi108/109 PIC */
+#endif
+
/* Allocate the controller structure and setup the linux irq descs
* for the range if interrupts passed in. No HW initialization is
* actually performed.
--=20
1.4.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-22 10:07 [PATCH ] powerpc: Add tsi108/9 and non standard mpic support Zang Roy-r61911
@ 2006-08-22 17:15 ` Adrian Cox
2006-08-23 1:20 ` Zang Roy-r61911
2006-08-24 5:42 ` Zang Roy-r61911
2006-08-25 8:43 ` [PATCH ] powerpc: mpc7448hpc2 device tree source file Zang Roy-r61911
2 siblings, 1 reply; 11+ messages in thread
From: Adrian Cox @ 2006-08-22 17:15 UTC (permalink / raw)
To: Zang Roy-r61911
Cc: Yang Xin-Xin-r48390, Paul Mackerras, Alexandre.Bounine,
linuxppc-dev list
On Tue, 2006-08-22 at 18:07 +0800, Zang Roy-r61911 wrote:
> The patch adds new hardware information table for mpic. This
> enables mpic code to deal with mpic controller with
> hardware behavior difference.
> + TSI108_CPU_BASE,
> + TSI108_CPU_STRIDE,
> + TSI108_CPU_IPI_DISPATCH_0,
> + TSI108_CPU_IPI_DISPATCH_STRIDE,
> + TSI108_CPU_CURRENT_TASK_PRI,
This isn't actually enough to get SMP working on a Tsi109, as the Tsi109
mailbox and doorbell registers don't behave like standard MPIC IPIs.
So far I've experimented with a hack that uses the doorbell registers:
Doorbell 0 delivers IPI 0 to processor 0
Doorbell 1 delivers IPI 1 to processor 0
Doorbell 2 delivers IPI 0 to processor 1
Doorbell 3 delivers IPI 1 to processor 1
I don't support IPI 2 and IPI 3, though it would be possible to use the
mailbox registers in a similar scheme. This approach works, but I've not
worked out how to cleanly integrate this with the rest of the MPIC
driver, and won't have any time to do this in the near future.
--
Adrian Cox <adrian@humboldt.co.uk>
^ permalink raw reply [flat|nested] 11+ messages in thread
* RE: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-22 17:15 ` Adrian Cox
@ 2006-08-23 1:20 ` Zang Roy-r61911
0 siblings, 0 replies; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-23 1:20 UTC (permalink / raw)
To: Adrian Cox
Cc: Yang Xin-Xin-r48390, Paul Mackerras, Alexandre.Bounine,
linuxppc-dev list
>=20
> I don't support IPI 2 and IPI 3, though it would be possible=20
> to use the mailbox registers in a similar scheme. This=20
> approach works, but I've not worked out how to cleanly=20
> integrate this with the rest of the MPIC driver, and won't=20
> have any time to do this in the near future.
>=20
It might be better to deal with the tsi108/9 smp support
in a separate file.=20
Roy
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-22 10:07 [PATCH ] powerpc: Add tsi108/9 and non standard mpic support Zang Roy-r61911
2006-08-22 17:15 ` Adrian Cox
@ 2006-08-24 5:42 ` Zang Roy-r61911
2006-08-24 5:54 ` Benjamin Herrenschmidt
2006-08-25 8:43 ` [PATCH ] powerpc: mpc7448hpc2 device tree source file Zang Roy-r61911
2 siblings, 1 reply; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-24 5:42 UTC (permalink / raw)
To: Paul Mackerras; +Cc: Yang Xin-Xin-r48390, linuxppc-dev list
On Tue, 2006-08-22 at 18:07, Zang Roy-r61911 wrote:
> The patch adds new hardware information table for mpic. This
> enables mpic code to deal with mpic controller with
> hardware behavior difference.
>
> CONFIG_MPIC_WEIRD is introduced in the code.
> If a board with non standard mpic controller, it can select the
> CONFIG_MPIC_WEIRD with board and add its hardware information
> in the array mpic_infos.
>
> TSI108/109 PIC takes the first index of weird hardware information
> table:) . The table can be extended. The Tsi108/109 PIC looks like
> standard OpenPIC but, in fact, is different in registers mapping and
> behavior.
>
> The patch does not affect the behavior of standard mpic.
> CONFIG_MPIC_WEIRD
> excludes the weird mpic code when building standard mpic.
>
> Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
>
Repost the patch. Fix the word wrap.
---
arch/powerpc/Kconfig | 8 +-
arch/powerpc/sysdev/Makefile | 1
arch/powerpc/sysdev/mpic.c | 187 +++++++++++++++++++++++++++++-------------
include/asm-powerpc/mpic.h | 114 ++++++++++++++++++++++++++
4 files changed, 252 insertions(+), 58 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index abb325e..c88b647 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -440,11 +440,15 @@ config U3_DART
default n
config MPIC
- depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
- || MPC7448HPC2
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
bool
default y
+config MPIC_WEIRD
+ depends on MPC7448HPC2
+ bool
+ default y
+
config PPC_RTAS
bool
default n
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cebfae2..8ae887b 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -3,6 +3,7 @@ EXTRA_CFLAGS += -mno-minimal-toc
endif
obj-$(CONFIG_MPIC) += mpic.o
+obj-$(CONFIG_MPIC_WEIRD) += mpic.o
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_MPC106) += grackle.o
obj-$(CONFIG_BOOKE) += dcr.o
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 6e0281a..78e0515 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -54,6 +54,55 @@ #define distribute_irqs (0)
#endif
#endif
+#ifdef CONFIG_MPIC_WEIRD
+static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] = {
+ [0] = { /* Tsi108/109 PIC */
+ TSI108_GREG_BASE,
+ TSI108_GREG_FEATURE_0,
+ TSI108_GREG_GLOBAL_CONF_0,
+ TSI108_GREG_VENDOR_ID,
+ TSI108_GREG_IPI_VECTOR_PRI_0,
+ TSI108_GREG_IPI_STRIDE,
+ TSI108_GREG_SPURIOUS,
+ TSI108_GREG_TIMER_FREQ,
+
+ TSI108_TIMER_BASE,
+ TSI108_TIMER_STRIDE,
+ TSI108_TIMER_CURRENT_CNT,
+ TSI108_TIMER_BASE_CNT,
+ TSI108_TIMER_VECTOR_PRI,
+ TSI108_TIMER_DESTINATION,
+
+ TSI108_CPU_BASE,
+ TSI108_CPU_STRIDE,
+ TSI108_CPU_IPI_DISPATCH_0,
+ TSI108_CPU_IPI_DISPATCH_STRIDE,
+ TSI108_CPU_CURRENT_TASK_PRI,
+ TSI108_CPU_WHOAMI,
+ TSI108_CPU_INTACK,
+ TSI108_CPU_EOI,
+
+ TSI108_IRQ_BASE,
+ TSI108_IRQ_STRIDE,
+ TSI108_IRQ_VECTOR_PRI,
+ TSI108_VECPRI_VECTOR_MASK,
+ TSI108_VECPRI_POLARITY_POSITIVE,
+ TSI108_VECPRI_POLARITY_NEGATIVE,
+ TSI108_VECPRI_SENSE_LEVEL,
+ TSI108_VECPRI_SENSE_EDGE,
+ TSI108_VECPRI_POLARITY_MASK,
+ TSI108_VECPRI_SENSE_MASK,
+ TSI108_IRQ_DESTINATION
+ },
+};
+#endif
+
+#ifdef CONFIG_MPIC_WEIRD
+#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
+#else
+#define MPIC_INFO(name) MPIC_##name
+#endif
+
/*
* Register accessor functions
*/
@@ -80,7 +129,8 @@ static inline void _mpic_write(unsigned
static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
if (mpic->flags & MPIC_BROKEN_IPI)
be = !be;
@@ -89,7 +139,8 @@ static inline u32 _mpic_ipi_read(struct
static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
{
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
}
@@ -120,7 +171,7 @@ static inline u32 _mpic_irq_read(struct
unsigned int idx = src_no & mpic->isu_mask;
return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE));
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)));
}
static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -130,7 +181,7 @@ static inline void _mpic_irq_write(struc
unsigned int idx = src_no & mpic->isu_mask;
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE), value);
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
}
#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
@@ -156,8 +207,8 @@ static void __init mpic_test_broken_ipi(
{
u32 r;
- mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
- r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
+ r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
@@ -394,8 +445,8 @@ static inline struct mpic * mpic_from_ir
/* Send an EOI */
static inline void mpic_eoi(struct mpic *mpic)
{
- mpic_cpu_write(MPIC_CPU_EOI, 0);
- (void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+ mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
+ (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
}
#ifdef CONFIG_SMP
@@ -419,8 +470,8 @@ static void mpic_unmask_irq(unsigned int
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -428,7 +479,7 @@ static void mpic_unmask_irq(unsigned int
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
+ } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
}
static void mpic_mask_irq(unsigned int irq)
@@ -439,8 +490,8 @@ static void mpic_mask_irq(unsigned int i
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
@@ -449,7 +500,7 @@ static void mpic_mask_irq(unsigned int i
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
+ } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
}
static void mpic_end_irq(unsigned int irq)
@@ -560,24 +611,32 @@ static void mpic_set_affinity(unsigned i
cpus_and(tmp, cpumask, cpu_online_map);
- mpic_irq_write(src, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
mpic_physmask(cpus_addr(tmp)[0]));
}
+#ifdef CONFIG_MPIC_WEIRD
+static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
+#else
static unsigned int mpic_type_to_vecpri(unsigned int type)
+#endif
{
/* Now convert sense value */
switch(type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
- return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_EDGE_FALLING:
case IRQ_TYPE_EDGE_BOTH:
- return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
case IRQ_TYPE_LEVEL_HIGH:
- return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_LEVEL_LOW:
default:
- return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
}
}
@@ -609,13 +668,18 @@ static int mpic_set_irq_type(unsigned in
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
MPIC_VECPRI_SENSE_EDGE;
else
+#ifdef CONFIG_MPIC_WEIRD
+ vecpri = mpic_type_to_vecpri(mpic, flow_type);
+#else
vecpri = mpic_type_to_vecpri(flow_type);
+#endif
- vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
- vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
+ vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
+ vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
+ MPIC_INFO(VECPRI_SENSE_MASK));
vnew |= vecpri;
if (vold != vnew)
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
return 0;
}
@@ -797,18 +861,23 @@ #endif /* CONFIG_SMP */
mpic->isu_size = isu_size;
mpic->irq_count = irq_count;
mpic->num_sources = 0; /* so far */
+
+#ifdef CONFIG_MPIC_WEIRD
+ mpic->hw_set = mpic_infos[MPIC_GET_MOD_ID(flags)];
+#endif
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
- mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
+ mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
+ mpic->tmregs = mpic->gregs +
+ ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
BUG_ON(mpic->gregs == NULL);
/* Reset */
if (flags & MPIC_WANTS_RESET) {
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_RESET);
- while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
& MPIC_GREG_GCONF_RESET)
mb();
}
@@ -817,7 +886,7 @@ #endif /* CONFIG_SMP */
* MPICs, num sources as well. On ISU MPICs, sources are counted
* as ISUs are added
*/
- reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
+ reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
>> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
if (isu_size == 0)
@@ -826,16 +895,16 @@ #endif /* CONFIG_SMP */
/* Map the per-CPU registers */
for (i = 0; i < mpic->num_cpus; i++) {
- mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
- i * MPIC_CPU_STRIDE, 0x1000);
+ mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
+ i * MPIC_INFO(CPU_STRIDE), 0x1000);
BUG_ON(mpic->cpuregs[i] == NULL);
}
/* Initialize main ISU if none provided */
if (mpic->isu_size == 0) {
mpic->isu_size = mpic->num_sources;
- mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
- MPIC_IRQ_STRIDE * mpic->isu_size);
+ mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
+ MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
BUG_ON(mpic->isus[0] == NULL);
}
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -879,7 +948,8 @@ void __init mpic_assign_isu(struct mpic
BUG_ON(isu_num >= MPIC_MAX_ISU);
- mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
+ mpic->isus[isu_num] = ioremap(phys_addr,
+ MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
if ((isu_first + mpic->isu_size) > mpic->num_sources)
mpic->num_sources = isu_first + mpic->isu_size;
}
@@ -904,14 +974,16 @@ void __init mpic_init(struct mpic *mpic)
printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
/* Initialize timers: just disable them all */
for (i = 0; i < 4; i++) {
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+ i * MPIC_INFO(TIMER_STRIDE) +
+ MPIC_INFO(TIMER_DESTINATION), 0);
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+ i * MPIC_INFO(TIMER_STRIDE) +
+ MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_VECPRI_MASK |
(MPIC_VEC_TIMER_0 + i));
}
@@ -940,21 +1012,23 @@ void __init mpic_init(struct mpic *mpic)
(8 << MPIC_VECPRI_PRIORITY_SHIFT);
/* init hw */
- mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
1 << hard_smp_processor_id());
}
/* Init spurrious vector */
- mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
- /* Disable 8259 passthrough */
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ /* Disable 8259 passthrough, if supported */
+#ifndef CONFIG_MPIC_WEIRD
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_8259_PTHROU_DIS);
+#endif
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
}
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -997,9 +1071,9 @@ void mpic_irq_set_priority(unsigned int
mpic_ipi_write(src - MPIC_VEC_IPI_0,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
+ reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
& ~MPIC_VECPRI_PRIORITY_MASK;
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
spin_unlock_irqrestore(&mpic_lock, flags);
@@ -1017,7 +1091,7 @@ unsigned int mpic_irq_get_priority(unsig
if (is_ipi)
reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
else
- reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+ reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
spin_unlock_irqrestore(&mpic_lock, flags);
return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
}
@@ -1043,12 +1117,12 @@ #ifdef CONFIG_SMP
*/
if (distribute_irqs) {
for (i = 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
}
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
spin_unlock_irqrestore(&mpic_lock, flags);
#endif /* CONFIG_SMP */
@@ -1058,7 +1132,7 @@ int mpic_cpu_get_priority(void)
{
struct mpic *mpic = mpic_primary;
- return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+ return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
}
void mpic_cpu_set_priority(int prio)
@@ -1066,7 +1140,7 @@ void mpic_cpu_set_priority(int prio)
struct mpic *mpic = mpic_primary;
prio &= MPIC_CPU_TASKPRI_MASK;
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
}
/*
@@ -1088,11 +1162,11 @@ void mpic_teardown_this_cpu(int secondar
/* let the mpic know we don't want intrs. */
for (i = 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
spin_unlock_irqrestore(&mpic_lock, flags);
}
@@ -1108,7 +1182,8 @@ #ifdef DEBUG_IPI
DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
#endif
- mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
+ mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+ ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
}
@@ -1116,7 +1191,7 @@ unsigned int mpic_get_one_irq(struct mpi
{
u32 src;
- src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
+ src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
#ifdef DEBUG_LOW
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
#endif
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index eb241c9..faebdf2 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0 0x000
#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0
#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0
#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0
+#define MPIC_GREG_IPI_STRIDE 0x10
#define MPIC_GREG_SPURIOUS 0x000e0
#define MPIC_GREG_TIMER_FREQ 0x000f0
@@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0 0x00040
#define MPIC_CPU_IPI_DISPATCH_1 0x00050
#define MPIC_CPU_IPI_DISPATCH_2 0x00060
#define MPIC_CPU_IPI_DISPATCH_3 0x00070
+#define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010
#define MPIC_CPU_CURRENT_TASK_PRI 0x00080
#define MPIC_CPU_TASKPRI_MASK 0x0000000f
#define MPIC_CPU_WHOAMI 0x00090
@@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2 249
#define MPIC_VEC_TIMER_1 248
#define MPIC_VEC_TIMER_0 247
+#ifdef CONFIG_MPIC_WEIRD
+/*
+ * Tsi108 implementation of MPIC has many differences from the original one
+ */
+
+/*
+ * Global registers
+ */
+
+#define TSI108_GREG_BASE 0x00000
+#define TSI108_GREG_FEATURE_0 0x00000
+#define TSI108_GREG_GLOBAL_CONF_0 0x00004
+#define TSI108_GREG_VENDOR_ID 0x0000c
+#define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */
+#define TSI108_GREG_IPI_STRIDE 0x0c
+#define TSI108_GREG_SPURIOUS 0x00010
+#define TSI108_GREG_TIMER_FREQ 0x00014
+
+/*
+ * Timer registers
+ */
+#define TSI108_TIMER_BASE 0x0030
+#define TSI108_TIMER_STRIDE 0x10
+#define TSI108_TIMER_CURRENT_CNT 0x00000
+#define TSI108_TIMER_BASE_CNT 0x00004
+#define TSI108_TIMER_VECTOR_PRI 0x00008
+#define TSI108_TIMER_DESTINATION 0x0000c
+
+/*
+ * Per-Processor registers
+ */
+#define TSI108_CPU_BASE 0x00300
+#define TSI108_CPU_STRIDE 0x00040
+#define TSI108_CPU_IPI_DISPATCH_0 0x00200
+#define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000
+#define TSI108_CPU_CURRENT_TASK_PRI 0x00000
+#define TSI108_CPU_WHOAMI 0xffffffff
+#define TSI108_CPU_INTACK 0x00004
+#define TSI108_CPU_EOI 0x00008
+
+/*
+ * Per-source registers
+ */
+#define TSI108_IRQ_BASE 0x00100
+#define TSI108_IRQ_STRIDE 0x00008
+#define TSI108_IRQ_VECTOR_PRI 0x00000
+#define TSI108_VECPRI_VECTOR_MASK 0x000000ff
+#define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000
+#define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000
+#define TSI108_VECPRI_SENSE_LEVEL 0x02000000
+#define TSI108_VECPRI_SENSE_EDGE 0x00000000
+#define TSI108_VECPRI_POLARITY_MASK 0x01000000
+#define TSI108_VECPRI_SENSE_MASK 0x02000000
+#define TSI108_IRQ_DESTINATION 0x00004
+
+/* weird mpic variable index in the HW info array */
+enum MPIC_WEIRD_INDEX {
+ INDEX_GREG_BASE = 0, /* Offset of global registers from MPIC base */
+ INDEX_GREG_FEATURE_0, /* FRR0 offset from base */
+ INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from base */
+ INDEX_GREG_VENDOR_ID, /* VID register offset from base */
+ INDEX_GREG_IPI_VECTOR_PRI_0, /* IPI Vector/Priority Registers */
+ INDEX_GREG_IPI_STRIDE, /* IPI Vector/Priority Registers spacing */
+ INDEX_GREG_SPURIOUS, /* Spurious Vector Register */
+ INDEX_GREG_TIMER_FREQ, /* Global Timer Frequency Reporting Register */
+
+ INDEX_TIMER_BASE, /* Global Timer Registers base */
+ INDEX_TIMER_STRIDE, /* Global Timer Registers spacing */
+ INDEX_TIMER_CURRENT_CNT, /* Global Timer Current Count Register */
+ INDEX_TIMER_BASE_CNT, /* Global Timer Base Count Register */
+ INDEX_TIMER_VECTOR_PRI, /* Global Timer Vector/Priority Register */
+ INDEX_TIMER_DESTINATION, /* Global Timer Destination Register */
+
+ INDEX_CPU_BASE, /* Offset of cpu base */
+ INDEX_CPU_STRIDE, /* Cpu register spacing*/
+ INDEX_CPU_IPI_DISPATCH_0, /* IPI 0 Dispatch Command Register */
+ INDEX_CPU_IPI_DISPATCH_STRIDE, /* IPI Dispatch spacing */
+ INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority Register */
+ INDEX_CPU_WHOAMI, /* Who Am I Register */
+ INDEX_CPU_INTACK, /* Interrupt Acknowledge Register */
+ INDEX_CPU_EOI, /* End of Interrupt Register */
+
+ INDEX_IRQ_BASE, /* Interrupt registers base */
+ INDEX_IRQ_STRIDE, /* Interrupt registers spacing */
+ INDEX_IRQ_VECTOR_PRI, /* Interrupt Vector/Priority Register */
+ INDEX_VECPRI_VECTOR_MASK, /* Interrupt Vector Mask */
+ INDEX_VECPRI_POLARITY_POSITIVE, /* Interrupt Positive Polarity bit */
+ INDEX_VECPRI_POLARITY_NEGATIVE, /* Interrupt Negative Polarity bit */
+ INDEX_VECPRI_SENSE_LEVEL, /* Interrupt Level Sense bit */
+ INDEX_VECPRI_SENSE_EDGE, /* Interrupt edge Sense bit */
+ INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
+ INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
+ INDEX_IRQ_DESTINATION, /* Interrupt Destination Register */
+ INDEX_MPIC_WEIRD_END /* Size of the hw info array */
+};
+#endif
+
#ifdef CONFIG_MPIC_BROKEN_U3
/* Fixup table entry */
struct mpic_irq_fixup
@@ -170,6 +269,11 @@ #endif
volatile u32 __iomem *tmregs;
volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
volatile u32 __iomem *isus[MPIC_MAX_ISU];
+
+#ifdef CONFIG_MPIC_WEIRD
+ /* Pointer to HW info array */
+ u32 *hw_set;
+#endif
/* link */
struct mpic *next;
@@ -189,6 +293,16 @@ #define MPIC_BROKEN_IPI 0x00000008
/* MPIC wants a reset */
#define MPIC_WANTS_RESET 0x00000010
+#ifdef CONFIG_MPIC_WEIRD
+/* Spurious vector requires EOI */
+#define MPIC_SPV_EOI 0x00000020
+/* MPIC HW modification ID */
+#define MPIC_MOD_ID_MASK 0x00000f00
+#define MPIC_MOD_ID(val) (((val) << 8) & MPIC_MOD_ID_MASK)
+#define MPIC_GET_MOD_ID(flags) (((flags) & MPIC_MOD_ID_MASK) >> 8)
+#define MPIC_ID_TSI108 0 /* Tsi108/109 PIC */
+#endif
+
/* Allocate the controller structure and setup the linux irq descs
* for the range if interrupts passed in. No HW initialization is
* actually performed.
--
1.4.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 5:42 ` Zang Roy-r61911
@ 2006-08-24 5:54 ` Benjamin Herrenschmidt
2006-08-24 9:52 ` Zang Roy-r61911
0 siblings, 1 reply; 11+ messages in thread
From: Benjamin Herrenschmidt @ 2006-08-24 5:54 UTC (permalink / raw)
To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
On Thu, 2006-08-24 at 13:42 +0800, Zang Roy-r61911 wrote:
> On Tue, 2006-08-22 at 18:07, Zang Roy-r61911 wrote:
> > The patch adds new hardware information table for mpic. This
> > enables mpic code to deal with mpic controller with
> > hardware behavior difference.
> >
> > CONFIG_MPIC_WEIRD is introduced in the code.
> > If a board with non standard mpic controller, it can select the
> > CONFIG_MPIC_WEIRD with board and add its hardware information
> > in the array mpic_infos.
> >
> > TSI108/109 PIC takes the first index of weird hardware information
> > table:) . The table can be extended. The Tsi108/109 PIC looks like
> > standard OpenPIC but, in fact, is different in registers mapping and
> > behavior.
The table should still contain the entries for a normal MPIC. One can
build a kernel that will boot both machines with the "weird" one and
with the normal one. Thus CONFIG_MPIC_WEIRD shall not exclude normal
MPICs, though not having it does exclude weird ones. I thus would
suggest to keep the table as it was in your earlier patches, that is
with the normal MPIC mapping at 0.
I intend to re-use that to handle another weird MPIC from some other
project :)
Cheers,
Ben.
> > The patch does not affect the behavior of standard mpic.
> > CONFIG_MPIC_WEIRD
> > excludes the weird mpic code when building standard mpic.
> >
> > Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>
> > Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
> >
> Repost the patch. Fix the word wrap.
>
> ---
> arch/powerpc/Kconfig | 8 +-
> arch/powerpc/sysdev/Makefile | 1
> arch/powerpc/sysdev/mpic.c | 187 +++++++++++++++++++++++++++++-------------
> include/asm-powerpc/mpic.h | 114 ++++++++++++++++++++++++++
> 4 files changed, 252 insertions(+), 58 deletions(-)
>
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index abb325e..c88b647 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -440,11 +440,15 @@ config U3_DART
> default n
>
> config MPIC
> - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
> - || MPC7448HPC2
> + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
> bool
> default y
>
> +config MPIC_WEIRD
> + depends on MPC7448HPC2
> + bool
> + default y
> +
> config PPC_RTAS
> bool
> default n
> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
> index cebfae2..8ae887b 100644
> --- a/arch/powerpc/sysdev/Makefile
> +++ b/arch/powerpc/sysdev/Makefile
> @@ -3,6 +3,7 @@ EXTRA_CFLAGS += -mno-minimal-toc
> endif
>
> obj-$(CONFIG_MPIC) += mpic.o
> +obj-$(CONFIG_MPIC_WEIRD) += mpic.o
> obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
> obj-$(CONFIG_PPC_MPC106) += grackle.o
> obj-$(CONFIG_BOOKE) += dcr.o
> diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
> index 6e0281a..78e0515 100644
> --- a/arch/powerpc/sysdev/mpic.c
> +++ b/arch/powerpc/sysdev/mpic.c
> @@ -54,6 +54,55 @@ #define distribute_irqs (0)
> #endif
> #endif
>
> +#ifdef CONFIG_MPIC_WEIRD
> +static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] = {
> + [0] = { /* Tsi108/109 PIC */
> + TSI108_GREG_BASE,
> + TSI108_GREG_FEATURE_0,
> + TSI108_GREG_GLOBAL_CONF_0,
> + TSI108_GREG_VENDOR_ID,
> + TSI108_GREG_IPI_VECTOR_PRI_0,
> + TSI108_GREG_IPI_STRIDE,
> + TSI108_GREG_SPURIOUS,
> + TSI108_GREG_TIMER_FREQ,
> +
> + TSI108_TIMER_BASE,
> + TSI108_TIMER_STRIDE,
> + TSI108_TIMER_CURRENT_CNT,
> + TSI108_TIMER_BASE_CNT,
> + TSI108_TIMER_VECTOR_PRI,
> + TSI108_TIMER_DESTINATION,
> +
> + TSI108_CPU_BASE,
> + TSI108_CPU_STRIDE,
> + TSI108_CPU_IPI_DISPATCH_0,
> + TSI108_CPU_IPI_DISPATCH_STRIDE,
> + TSI108_CPU_CURRENT_TASK_PRI,
> + TSI108_CPU_WHOAMI,
> + TSI108_CPU_INTACK,
> + TSI108_CPU_EOI,
> +
> + TSI108_IRQ_BASE,
> + TSI108_IRQ_STRIDE,
> + TSI108_IRQ_VECTOR_PRI,
> + TSI108_VECPRI_VECTOR_MASK,
> + TSI108_VECPRI_POLARITY_POSITIVE,
> + TSI108_VECPRI_POLARITY_NEGATIVE,
> + TSI108_VECPRI_SENSE_LEVEL,
> + TSI108_VECPRI_SENSE_EDGE,
> + TSI108_VECPRI_POLARITY_MASK,
> + TSI108_VECPRI_SENSE_MASK,
> + TSI108_IRQ_DESTINATION
> + },
> +};
> +#endif
> +
> +#ifdef CONFIG_MPIC_WEIRD
> +#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
> +#else
> +#define MPIC_INFO(name) MPIC_##name
> +#endif
> +
> /*
> * Register accessor functions
> */
> @@ -80,7 +129,8 @@ static inline void _mpic_write(unsigned
> static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
> {
> unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
> - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> + unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
> + (ipi * MPIC_INFO(GREG_IPI_STRIDE));
>
> if (mpic->flags & MPIC_BROKEN_IPI)
> be = !be;
> @@ -89,7 +139,8 @@ static inline u32 _mpic_ipi_read(struct
>
> static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
> {
> - unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
> + unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
> + (ipi * MPIC_INFO(GREG_IPI_STRIDE));
>
> _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
> }
> @@ -120,7 +171,7 @@ static inline u32 _mpic_irq_read(struct
> unsigned int idx = src_no & mpic->isu_mask;
>
> return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
> - reg + (idx * MPIC_IRQ_STRIDE));
> + reg + (idx * MPIC_INFO(IRQ_STRIDE)));
> }
>
> static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
> @@ -130,7 +181,7 @@ static inline void _mpic_irq_write(struc
> unsigned int idx = src_no & mpic->isu_mask;
>
> _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
> - reg + (idx * MPIC_IRQ_STRIDE), value);
> + reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
> }
>
> #define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
> @@ -156,8 +207,8 @@ static void __init mpic_test_broken_ipi(
> {
> u32 r;
>
> - mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
> - r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
> + mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
> + r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
>
> if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
> printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
> @@ -394,8 +445,8 @@ static inline struct mpic * mpic_from_ir
> /* Send an EOI */
> static inline void mpic_eoi(struct mpic *mpic)
> {
> - mpic_cpu_write(MPIC_CPU_EOI, 0);
> - (void)mpic_cpu_read(MPIC_CPU_WHOAMI);
> + mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
> + (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
> }
>
> #ifdef CONFIG_SMP
> @@ -419,8 +470,8 @@ static void mpic_unmask_irq(unsigned int
>
> DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
>
> - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
> + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> + mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
> ~MPIC_VECPRI_MASK);
> /* make sure mask gets to controller before we return to user */
> do {
> @@ -428,7 +479,7 @@ static void mpic_unmask_irq(unsigned int
> printk(KERN_ERR "mpic_enable_irq timeout\n");
> break;
> }
> - } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
> + } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
> }
>
> static void mpic_mask_irq(unsigned int irq)
> @@ -439,8 +490,8 @@ static void mpic_mask_irq(unsigned int i
>
> DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
>
> - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> - mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
> + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> + mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
> MPIC_VECPRI_MASK);
>
> /* make sure mask gets to controller before we return to user */
> @@ -449,7 +500,7 @@ static void mpic_mask_irq(unsigned int i
> printk(KERN_ERR "mpic_enable_irq timeout\n");
> break;
> }
> - } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
> + } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
> }
>
> static void mpic_end_irq(unsigned int irq)
> @@ -560,24 +611,32 @@ static void mpic_set_affinity(unsigned i
>
> cpus_and(tmp, cpumask, cpu_online_map);
>
> - mpic_irq_write(src, MPIC_IRQ_DESTINATION,
> + mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
> mpic_physmask(cpus_addr(tmp)[0]));
> }
>
> +#ifdef CONFIG_MPIC_WEIRD
> +static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
> +#else
> static unsigned int mpic_type_to_vecpri(unsigned int type)
> +#endif
> {
> /* Now convert sense value */
> switch(type & IRQ_TYPE_SENSE_MASK) {
> case IRQ_TYPE_EDGE_RISING:
> - return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
> + return MPIC_INFO(VECPRI_SENSE_EDGE) |
> + MPIC_INFO(VECPRI_POLARITY_POSITIVE);
> case IRQ_TYPE_EDGE_FALLING:
> case IRQ_TYPE_EDGE_BOTH:
> - return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
> + return MPIC_INFO(VECPRI_SENSE_EDGE) |
> + MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
> case IRQ_TYPE_LEVEL_HIGH:
> - return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
> + return MPIC_INFO(VECPRI_SENSE_LEVEL) |
> + MPIC_INFO(VECPRI_POLARITY_POSITIVE);
> case IRQ_TYPE_LEVEL_LOW:
> default:
> - return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
> + return MPIC_INFO(VECPRI_SENSE_LEVEL) |
> + MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
> }
> }
>
> @@ -609,13 +668,18 @@ static int mpic_set_irq_type(unsigned in
> vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
> MPIC_VECPRI_SENSE_EDGE;
> else
> +#ifdef CONFIG_MPIC_WEIRD
> + vecpri = mpic_type_to_vecpri(mpic, flow_type);
> +#else
> vecpri = mpic_type_to_vecpri(flow_type);
> +#endif
>
> - vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
> - vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
> + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
> + vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
> + MPIC_INFO(VECPRI_SENSE_MASK));
> vnew |= vecpri;
> if (vold != vnew)
> - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
> + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
>
> return 0;
> }
> @@ -797,18 +861,23 @@ #endif /* CONFIG_SMP */
> mpic->isu_size = isu_size;
> mpic->irq_count = irq_count;
> mpic->num_sources = 0; /* so far */
> +
> +#ifdef CONFIG_MPIC_WEIRD
> + mpic->hw_set = mpic_infos[MPIC_GET_MOD_ID(flags)];
> +#endif
>
> /* Map the global registers */
> - mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
> - mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
> + mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
> + mpic->tmregs = mpic->gregs +
> + ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
> BUG_ON(mpic->gregs == NULL);
>
> /* Reset */
> if (flags & MPIC_WANTS_RESET) {
> - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
> - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> + mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
> + mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
> | MPIC_GREG_GCONF_RESET);
> - while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> + while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
> & MPIC_GREG_GCONF_RESET)
> mb();
> }
> @@ -817,7 +886,7 @@ #endif /* CONFIG_SMP */
> * MPICs, num sources as well. On ISU MPICs, sources are counted
> * as ISUs are added
> */
> - reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
> + reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
> mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
> >> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
> if (isu_size == 0)
> @@ -826,16 +895,16 @@ #endif /* CONFIG_SMP */
>
> /* Map the per-CPU registers */
> for (i = 0; i < mpic->num_cpus; i++) {
> - mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
> - i * MPIC_CPU_STRIDE, 0x1000);
> + mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
> + i * MPIC_INFO(CPU_STRIDE), 0x1000);
> BUG_ON(mpic->cpuregs[i] == NULL);
> }
>
> /* Initialize main ISU if none provided */
> if (mpic->isu_size == 0) {
> mpic->isu_size = mpic->num_sources;
> - mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
> - MPIC_IRQ_STRIDE * mpic->isu_size);
> + mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
> + MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
> BUG_ON(mpic->isus[0] == NULL);
> }
> mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
> @@ -879,7 +948,8 @@ void __init mpic_assign_isu(struct mpic
>
> BUG_ON(isu_num >= MPIC_MAX_ISU);
>
> - mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
> + mpic->isus[isu_num] = ioremap(phys_addr,
> + MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
> if ((isu_first + mpic->isu_size) > mpic->num_sources)
> mpic->num_sources = isu_first + mpic->isu_size;
> }
> @@ -904,14 +974,16 @@ void __init mpic_init(struct mpic *mpic)
> printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
>
> /* Set current processor priority to max */
> - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
> + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
>
> /* Initialize timers: just disable them all */
> for (i = 0; i < 4; i++) {
> mpic_write(mpic->tmregs,
> - i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
> + i * MPIC_INFO(TIMER_STRIDE) +
> + MPIC_INFO(TIMER_DESTINATION), 0);
> mpic_write(mpic->tmregs,
> - i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
> + i * MPIC_INFO(TIMER_STRIDE) +
> + MPIC_INFO(TIMER_VECTOR_PRI),
> MPIC_VECPRI_MASK |
> (MPIC_VEC_TIMER_0 + i));
> }
> @@ -940,21 +1012,23 @@ void __init mpic_init(struct mpic *mpic)
> (8 << MPIC_VECPRI_PRIORITY_SHIFT);
>
> /* init hw */
> - mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
> - mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> + mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
> + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
> 1 << hard_smp_processor_id());
> }
>
> /* Init spurrious vector */
> - mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
> + mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
>
> - /* Disable 8259 passthrough */
> - mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
> - mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
> + /* Disable 8259 passthrough, if supported */
> +#ifndef CONFIG_MPIC_WEIRD
> + mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
> + mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
> | MPIC_GREG_GCONF_8259_PTHROU_DIS);
> +#endif
>
> /* Set current processor priority to 0 */
> - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
> + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
> }
>
> void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
> @@ -997,9 +1071,9 @@ void mpic_irq_set_priority(unsigned int
> mpic_ipi_write(src - MPIC_VEC_IPI_0,
> reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
> } else {
> - reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
> + reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
> & ~MPIC_VECPRI_PRIORITY_MASK;
> - mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
> + mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
> reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
> }
> spin_unlock_irqrestore(&mpic_lock, flags);
> @@ -1017,7 +1091,7 @@ unsigned int mpic_irq_get_priority(unsig
> if (is_ipi)
> reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
> else
> - reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
> + reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
> spin_unlock_irqrestore(&mpic_lock, flags);
> return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
> }
> @@ -1043,12 +1117,12 @@ #ifdef CONFIG_SMP
> */
> if (distribute_irqs) {
> for (i = 0; i < mpic->num_sources ; i++)
> - mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> - mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
> + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
> + mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
> }
>
> /* Set current processor priority to 0 */
> - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
> + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
>
> spin_unlock_irqrestore(&mpic_lock, flags);
> #endif /* CONFIG_SMP */
> @@ -1058,7 +1132,7 @@ int mpic_cpu_get_priority(void)
> {
> struct mpic *mpic = mpic_primary;
>
> - return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
> + return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
> }
>
> void mpic_cpu_set_priority(int prio)
> @@ -1066,7 +1140,7 @@ void mpic_cpu_set_priority(int prio)
> struct mpic *mpic = mpic_primary;
>
> prio &= MPIC_CPU_TASKPRI_MASK;
> - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
> + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
> }
>
> /*
> @@ -1088,11 +1162,11 @@ void mpic_teardown_this_cpu(int secondar
>
> /* let the mpic know we don't want intrs. */
> for (i = 0; i < mpic->num_sources ; i++)
> - mpic_irq_write(i, MPIC_IRQ_DESTINATION,
> - mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
> + mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
> + mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
>
> /* Set current processor priority to max */
> - mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
> + mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
>
> spin_unlock_irqrestore(&mpic_lock, flags);
> }
> @@ -1108,7 +1182,8 @@ #ifdef DEBUG_IPI
> DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
> #endif
>
> - mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
> + mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
> + ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
> mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
> }
>
> @@ -1116,7 +1191,7 @@ unsigned int mpic_get_one_irq(struct mpi
> {
> u32 src;
>
> - src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
> + src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
> #ifdef DEBUG_LOW
> DBG("%s: get_one_irq(): %d\n", mpic->name, src);
> #endif
> diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
> index eb241c9..faebdf2 100644
> --- a/include/asm-powerpc/mpic.h
> +++ b/include/asm-powerpc/mpic.h
> @@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0 0x000
> #define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0
> #define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0
> #define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0
> +#define MPIC_GREG_IPI_STRIDE 0x10
> #define MPIC_GREG_SPURIOUS 0x000e0
> #define MPIC_GREG_TIMER_FREQ 0x000f0
>
> @@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0 0x00040
> #define MPIC_CPU_IPI_DISPATCH_1 0x00050
> #define MPIC_CPU_IPI_DISPATCH_2 0x00060
> #define MPIC_CPU_IPI_DISPATCH_3 0x00070
> +#define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010
> #define MPIC_CPU_CURRENT_TASK_PRI 0x00080
> #define MPIC_CPU_TASKPRI_MASK 0x0000000f
> #define MPIC_CPU_WHOAMI 0x00090
> @@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2 249
> #define MPIC_VEC_TIMER_1 248
> #define MPIC_VEC_TIMER_0 247
>
> +#ifdef CONFIG_MPIC_WEIRD
> +/*
> + * Tsi108 implementation of MPIC has many differences from the original one
> + */
> +
> +/*
> + * Global registers
> + */
> +
> +#define TSI108_GREG_BASE 0x00000
> +#define TSI108_GREG_FEATURE_0 0x00000
> +#define TSI108_GREG_GLOBAL_CONF_0 0x00004
> +#define TSI108_GREG_VENDOR_ID 0x0000c
> +#define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */
> +#define TSI108_GREG_IPI_STRIDE 0x0c
> +#define TSI108_GREG_SPURIOUS 0x00010
> +#define TSI108_GREG_TIMER_FREQ 0x00014
> +
> +/*
> + * Timer registers
> + */
> +#define TSI108_TIMER_BASE 0x0030
> +#define TSI108_TIMER_STRIDE 0x10
> +#define TSI108_TIMER_CURRENT_CNT 0x00000
> +#define TSI108_TIMER_BASE_CNT 0x00004
> +#define TSI108_TIMER_VECTOR_PRI 0x00008
> +#define TSI108_TIMER_DESTINATION 0x0000c
> +
> +/*
> + * Per-Processor registers
> + */
> +#define TSI108_CPU_BASE 0x00300
> +#define TSI108_CPU_STRIDE 0x00040
> +#define TSI108_CPU_IPI_DISPATCH_0 0x00200
> +#define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000
> +#define TSI108_CPU_CURRENT_TASK_PRI 0x00000
> +#define TSI108_CPU_WHOAMI 0xffffffff
> +#define TSI108_CPU_INTACK 0x00004
> +#define TSI108_CPU_EOI 0x00008
> +
> +/*
> + * Per-source registers
> + */
> +#define TSI108_IRQ_BASE 0x00100
> +#define TSI108_IRQ_STRIDE 0x00008
> +#define TSI108_IRQ_VECTOR_PRI 0x00000
> +#define TSI108_VECPRI_VECTOR_MASK 0x000000ff
> +#define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000
> +#define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000
> +#define TSI108_VECPRI_SENSE_LEVEL 0x02000000
> +#define TSI108_VECPRI_SENSE_EDGE 0x00000000
> +#define TSI108_VECPRI_POLARITY_MASK 0x01000000
> +#define TSI108_VECPRI_SENSE_MASK 0x02000000
> +#define TSI108_IRQ_DESTINATION 0x00004
> +
> +/* weird mpic variable index in the HW info array */
> +enum MPIC_WEIRD_INDEX {
> + INDEX_GREG_BASE = 0, /* Offset of global registers from MPIC base */
> + INDEX_GREG_FEATURE_0, /* FRR0 offset from base */
> + INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from base */
> + INDEX_GREG_VENDOR_ID, /* VID register offset from base */
> + INDEX_GREG_IPI_VECTOR_PRI_0, /* IPI Vector/Priority Registers */
> + INDEX_GREG_IPI_STRIDE, /* IPI Vector/Priority Registers spacing */
> + INDEX_GREG_SPURIOUS, /* Spurious Vector Register */
> + INDEX_GREG_TIMER_FREQ, /* Global Timer Frequency Reporting Register */
> +
> + INDEX_TIMER_BASE, /* Global Timer Registers base */
> + INDEX_TIMER_STRIDE, /* Global Timer Registers spacing */
> + INDEX_TIMER_CURRENT_CNT, /* Global Timer Current Count Register */
> + INDEX_TIMER_BASE_CNT, /* Global Timer Base Count Register */
> + INDEX_TIMER_VECTOR_PRI, /* Global Timer Vector/Priority Register */
> + INDEX_TIMER_DESTINATION, /* Global Timer Destination Register */
> +
> + INDEX_CPU_BASE, /* Offset of cpu base */
> + INDEX_CPU_STRIDE, /* Cpu register spacing*/
> + INDEX_CPU_IPI_DISPATCH_0, /* IPI 0 Dispatch Command Register */
> + INDEX_CPU_IPI_DISPATCH_STRIDE, /* IPI Dispatch spacing */
> + INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority Register */
> + INDEX_CPU_WHOAMI, /* Who Am I Register */
> + INDEX_CPU_INTACK, /* Interrupt Acknowledge Register */
> + INDEX_CPU_EOI, /* End of Interrupt Register */
> +
> + INDEX_IRQ_BASE, /* Interrupt registers base */
> + INDEX_IRQ_STRIDE, /* Interrupt registers spacing */
> + INDEX_IRQ_VECTOR_PRI, /* Interrupt Vector/Priority Register */
> + INDEX_VECPRI_VECTOR_MASK, /* Interrupt Vector Mask */
> + INDEX_VECPRI_POLARITY_POSITIVE, /* Interrupt Positive Polarity bit */
> + INDEX_VECPRI_POLARITY_NEGATIVE, /* Interrupt Negative Polarity bit */
> + INDEX_VECPRI_SENSE_LEVEL, /* Interrupt Level Sense bit */
> + INDEX_VECPRI_SENSE_EDGE, /* Interrupt edge Sense bit */
> + INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
> + INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
> + INDEX_IRQ_DESTINATION, /* Interrupt Destination Register */
> + INDEX_MPIC_WEIRD_END /* Size of the hw info array */
> +};
> +#endif
> +
> #ifdef CONFIG_MPIC_BROKEN_U3
> /* Fixup table entry */
> struct mpic_irq_fixup
> @@ -170,6 +269,11 @@ #endif
> volatile u32 __iomem *tmregs;
> volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
> volatile u32 __iomem *isus[MPIC_MAX_ISU];
> +
> +#ifdef CONFIG_MPIC_WEIRD
> + /* Pointer to HW info array */
> + u32 *hw_set;
> +#endif
>
> /* link */
> struct mpic *next;
> @@ -189,6 +293,16 @@ #define MPIC_BROKEN_IPI 0x00000008
> /* MPIC wants a reset */
> #define MPIC_WANTS_RESET 0x00000010
>
> +#ifdef CONFIG_MPIC_WEIRD
> +/* Spurious vector requires EOI */
> +#define MPIC_SPV_EOI 0x00000020
> +/* MPIC HW modification ID */
> +#define MPIC_MOD_ID_MASK 0x00000f00
> +#define MPIC_MOD_ID(val) (((val) << 8) & MPIC_MOD_ID_MASK)
> +#define MPIC_GET_MOD_ID(flags) (((flags) & MPIC_MOD_ID_MASK) >> 8)
> +#define MPIC_ID_TSI108 0 /* Tsi108/109 PIC */
> +#endif
> +
> /* Allocate the controller structure and setup the linux irq descs
> * for the range if interrupts passed in. No HW initialization is
> * actually performed.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 5:54 ` Benjamin Herrenschmidt
@ 2006-08-24 9:52 ` Zang Roy-r61911
2006-08-24 10:54 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-24 9:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
On Thu, 2006-08-24 at 13:54, Benjamin Herrenschmidt wrote:
> On Thu, 2006-08-24 at 13:42 +0800, Zang Roy-r61911 wrote:
> > On Tue, 2006-08-22 at 18:07, Zang Roy-r61911 wrote:
> > > The patch adds new hardware information table for mpic. This
> > > enables mpic code to deal with mpic controller with
> > > hardware behavior difference.
> > >
> > > CONFIG_MPIC_WEIRD is introduced in the code.
> > > If a board with non standard mpic controller, it can select the
> > > CONFIG_MPIC_WEIRD with board and add its hardware information
> > > in the array mpic_infos.
> > >
> > > TSI108/109 PIC takes the first index of weird hardware
> information
> > > table:) . The table can be extended. The Tsi108/109 PIC looks
> like
> > > standard OpenPIC but, in fact, is different in registers mapping
> and
> > > behavior.
>
> The table should still contain the entries for a normal MPIC. One can
> build a kernel that will boot both machines with the "weird" one and
> with the normal one. Thus CONFIG_MPIC_WEIRD shall not exclude normal
> MPICs, though not having it does exclude weird ones. I thus would
> suggest to keep the table as it was in your earlier patches, that is
> with the normal MPIC mapping at 0.
>
> I intend to re-use that to handle another weird MPIC from some other
> project :)
That is also my target. I hope the imported mpic_info table can support
more non-standard mpic structure.
The following patch adds the standard MPIC entry to the table.
I post it here.
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
---
arch/powerpc/Kconfig | 8 +
arch/powerpc/sysdev/Makefile | 1
arch/powerpc/sysdev/mpic.c | 225 ++++++++++++++++++++++++++++++++----------
include/asm-powerpc/mpic.h | 115 +++++++++++++++++++++
4 files changed, 291 insertions(+), 58 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index abb325e..c88b647 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -440,11 +440,15 @@ config U3_DART
default n
config MPIC
- depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \
- || MPC7448HPC2
+ depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP
bool
default y
+config MPIC_WEIRD
+ depends on MPC7448HPC2
+ bool
+ default y
+
config PPC_RTAS
bool
default n
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index cebfae2..8ae887b 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -3,6 +3,7 @@ EXTRA_CFLAGS += -mno-minimal-toc
endif
obj-$(CONFIG_MPIC) += mpic.o
+obj-$(CONFIG_MPIC_WEIRD) += mpic.o
obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
obj-$(CONFIG_PPC_MPC106) += grackle.o
obj-$(CONFIG_BOOKE) += dcr.o
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 6e0281a..9a2ad1f 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -54,6 +54,93 @@ #define distribute_irqs (0)
#endif
#endif
+#ifdef CONFIG_MPIC_WEIRD
+static u32 mpic_infos[][INDEX_MPIC_WEIRD_END] = {
+ [0] = { /* Original OpenPIC compatible MPIC */
+ MPIC_GREG_BASE,
+ MPIC_GREG_FEATURE_0,
+ MPIC_GREG_GLOBAL_CONF_0,
+ MPIC_GREG_VENDOR_ID,
+ MPIC_GREG_IPI_VECTOR_PRI_0,
+ MPIC_GREG_IPI_STRIDE,
+ MPIC_GREG_SPURIOUS,
+ MPIC_GREG_TIMER_FREQ,
+
+ MPIC_TIMER_BASE,
+ MPIC_TIMER_STRIDE,
+ MPIC_TIMER_CURRENT_CNT,
+ MPIC_TIMER_BASE_CNT,
+ MPIC_TIMER_VECTOR_PRI,
+ MPIC_TIMER_DESTINATION,
+
+ MPIC_CPU_BASE,
+ MPIC_CPU_STRIDE,
+ MPIC_CPU_IPI_DISPATCH_0,
+ MPIC_CPU_IPI_DISPATCH_STRIDE,
+ MPIC_CPU_CURRENT_TASK_PRI,
+ MPIC_CPU_WHOAMI,
+ MPIC_CPU_INTACK,
+ MPIC_CPU_EOI,
+
+ MPIC_IRQ_BASE,
+ MPIC_IRQ_STRIDE,
+ MPIC_IRQ_VECTOR_PRI,
+ MPIC_VECPRI_VECTOR_MASK,
+ MPIC_VECPRI_POLARITY_POSITIVE,
+ MPIC_VECPRI_POLARITY_NEGATIVE,
+ MPIC_VECPRI_SENSE_LEVEL,
+ MPIC_VECPRI_SENSE_EDGE,
+ MPIC_VECPRI_POLARITY_MASK,
+ MPIC_VECPRI_SENSE_MASK,
+ MPIC_IRQ_DESTINATION
+ },
+ [1] = { /* Tsi108/109 PIC */
+ TSI108_GREG_BASE,
+ TSI108_GREG_FEATURE_0,
+ TSI108_GREG_GLOBAL_CONF_0,
+ TSI108_GREG_VENDOR_ID,
+ TSI108_GREG_IPI_VECTOR_PRI_0,
+ TSI108_GREG_IPI_STRIDE,
+ TSI108_GREG_SPURIOUS,
+ TSI108_GREG_TIMER_FREQ,
+
+ TSI108_TIMER_BASE,
+ TSI108_TIMER_STRIDE,
+ TSI108_TIMER_CURRENT_CNT,
+ TSI108_TIMER_BASE_CNT,
+ TSI108_TIMER_VECTOR_PRI,
+ TSI108_TIMER_DESTINATION,
+
+ TSI108_CPU_BASE,
+ TSI108_CPU_STRIDE,
+ TSI108_CPU_IPI_DISPATCH_0,
+ TSI108_CPU_IPI_DISPATCH_STRIDE,
+ TSI108_CPU_CURRENT_TASK_PRI,
+ TSI108_CPU_WHOAMI,
+ TSI108_CPU_INTACK,
+ TSI108_CPU_EOI,
+
+ TSI108_IRQ_BASE,
+ TSI108_IRQ_STRIDE,
+ TSI108_IRQ_VECTOR_PRI,
+ TSI108_VECPRI_VECTOR_MASK,
+ TSI108_VECPRI_POLARITY_POSITIVE,
+ TSI108_VECPRI_POLARITY_NEGATIVE,
+ TSI108_VECPRI_SENSE_LEVEL,
+ TSI108_VECPRI_SENSE_EDGE,
+ TSI108_VECPRI_POLARITY_MASK,
+ TSI108_VECPRI_SENSE_MASK,
+ TSI108_IRQ_DESTINATION
+ },
+};
+#endif
+
+#ifdef CONFIG_MPIC_WEIRD
+#define MPIC_INFO(name) mpic->hw_set[INDEX_##name]
+#else
+#define MPIC_INFO(name) MPIC_##name
+#endif
+
/*
* Register accessor functions
*/
@@ -80,7 +167,8 @@ static inline void _mpic_write(unsigned
static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
{
unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0;
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
if (mpic->flags & MPIC_BROKEN_IPI)
be = !be;
@@ -89,7 +177,8 @@ static inline u32 _mpic_ipi_read(struct
static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
{
- unsigned int offset = MPIC_GREG_IPI_VECTOR_PRI_0 + (ipi * 0x10);
+ unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
+ (ipi * MPIC_INFO(GREG_IPI_STRIDE));
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value);
}
@@ -120,7 +209,7 @@ static inline u32 _mpic_irq_read(struct
unsigned int idx = src_no & mpic->isu_mask;
return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE));
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)));
}
static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
@@ -130,7 +219,7 @@ static inline void _mpic_irq_write(struc
unsigned int idx = src_no & mpic->isu_mask;
_mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu],
- reg + (idx * MPIC_IRQ_STRIDE), value);
+ reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
}
#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r))
@@ -156,8 +245,8 @@ static void __init mpic_test_broken_ipi(
{
u32 r;
- mpic_write(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0, MPIC_VECPRI_MASK);
- r = mpic_read(mpic->gregs, MPIC_GREG_IPI_VECTOR_PRI_0);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0), MPIC_VECPRI_MASK);
+ r = mpic_read(mpic->gregs, MPIC_INFO(GREG_IPI_VECTOR_PRI_0));
if (r == le32_to_cpu(MPIC_VECPRI_MASK)) {
printk(KERN_INFO "mpic: Detected reversed IPI registers\n");
@@ -394,8 +483,8 @@ static inline struct mpic * mpic_from_ir
/* Send an EOI */
static inline void mpic_eoi(struct mpic *mpic)
{
- mpic_cpu_write(MPIC_CPU_EOI, 0);
- (void)mpic_cpu_read(MPIC_CPU_WHOAMI);
+ mpic_cpu_write(MPIC_INFO(CPU_EOI), 0);
+ (void)mpic_cpu_read(MPIC_INFO(CPU_WHOAMI));
}
#ifdef CONFIG_SMP
@@ -419,8 +508,8 @@ static void mpic_unmask_irq(unsigned int
DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, irq, src);
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) &
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) &
~MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
do {
@@ -428,7 +517,7 @@ static void mpic_unmask_irq(unsigned int
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK);
+ } while(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK);
}
static void mpic_mask_irq(unsigned int irq)
@@ -439,8 +528,8 @@ static void mpic_mask_irq(unsigned int i
DBG("%s: disable_irq: %d (src %d)\n", mpic->name, irq, src);
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
- mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) |
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
+ mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) |
MPIC_VECPRI_MASK);
/* make sure mask gets to controller before we return to user */
@@ -449,7 +538,7 @@ static void mpic_mask_irq(unsigned int i
printk(KERN_ERR "mpic_enable_irq timeout\n");
break;
}
- } while(!(mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI) & MPIC_VECPRI_MASK));
+ } while(!(mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)) & MPIC_VECPRI_MASK));
}
static void mpic_end_irq(unsigned int irq)
@@ -560,24 +649,32 @@ static void mpic_set_affinity(unsigned i
cpus_and(tmp, cpumask, cpu_online_map);
- mpic_irq_write(src, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
mpic_physmask(cpus_addr(tmp)[0]));
}
+#ifdef CONFIG_MPIC_WEIRD
+static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
+#else
static unsigned int mpic_type_to_vecpri(unsigned int type)
+#endif
{
/* Now convert sense value */
switch(type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
- return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_EDGE_FALLING:
case IRQ_TYPE_EDGE_BOTH:
- return MPIC_VECPRI_SENSE_EDGE | MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_EDGE) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
case IRQ_TYPE_LEVEL_HIGH:
- return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_POSITIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_POSITIVE);
case IRQ_TYPE_LEVEL_LOW:
default:
- return MPIC_VECPRI_SENSE_LEVEL | MPIC_VECPRI_POLARITY_NEGATIVE;
+ return MPIC_INFO(VECPRI_SENSE_LEVEL) |
+ MPIC_INFO(VECPRI_POLARITY_NEGATIVE);
}
}
@@ -609,13 +706,18 @@ static int mpic_set_irq_type(unsigned in
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
MPIC_VECPRI_SENSE_EDGE;
else
+#ifdef CONFIG_MPIC_WEIRD
+ vecpri = mpic_type_to_vecpri(mpic, flow_type);
+#else
vecpri = mpic_type_to_vecpri(flow_type);
+#endif
- vold = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
- vnew = vold & ~(MPIC_VECPRI_POLARITY_MASK | MPIC_VECPRI_SENSE_MASK);
+ vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
+ vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) |
+ MPIC_INFO(VECPRI_SENSE_MASK));
vnew |= vecpri;
if (vold != vnew)
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI, vnew);
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
return 0;
}
@@ -797,18 +899,23 @@ #endif /* CONFIG_SMP */
mpic->isu_size = isu_size;
mpic->irq_count = irq_count;
mpic->num_sources = 0; /* so far */
+
+#ifdef CONFIG_MPIC_WEIRD
+ mpic->hw_set = mpic_infos[MPIC_GET_MOD_ID(flags)];
+#endif
/* Map the global registers */
- mpic->gregs = ioremap(phys_addr + MPIC_GREG_BASE, 0x1000);
- mpic->tmregs = mpic->gregs + ((MPIC_TIMER_BASE - MPIC_GREG_BASE) >> 2);
+ mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000);
+ mpic->tmregs = mpic->gregs +
+ ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
BUG_ON(mpic->gregs == NULL);
/* Reset */
if (flags & MPIC_WANTS_RESET) {
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_RESET);
- while( mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ while( mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
& MPIC_GREG_GCONF_RESET)
mb();
}
@@ -817,7 +924,7 @@ #endif /* CONFIG_SMP */
* MPICs, num sources as well. On ISU MPICs, sources are counted
* as ISUs are added
*/
- reg = mpic_read(mpic->gregs, MPIC_GREG_FEATURE_0);
+ reg = mpic_read(mpic->gregs, MPIC_INFO(GREG_FEATURE_0));
mpic->num_cpus = ((reg & MPIC_GREG_FEATURE_LAST_CPU_MASK)
>> MPIC_GREG_FEATURE_LAST_CPU_SHIFT) + 1;
if (isu_size == 0)
@@ -826,16 +933,16 @@ #endif /* CONFIG_SMP */
/* Map the per-CPU registers */
for (i = 0; i < mpic->num_cpus; i++) {
- mpic->cpuregs[i] = ioremap(phys_addr + MPIC_CPU_BASE +
- i * MPIC_CPU_STRIDE, 0x1000);
+ mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) +
+ i * MPIC_INFO(CPU_STRIDE), 0x1000);
BUG_ON(mpic->cpuregs[i] == NULL);
}
/* Initialize main ISU if none provided */
if (mpic->isu_size == 0) {
mpic->isu_size = mpic->num_sources;
- mpic->isus[0] = ioremap(phys_addr + MPIC_IRQ_BASE,
- MPIC_IRQ_STRIDE * mpic->isu_size);
+ mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE),
+ MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
BUG_ON(mpic->isus[0] == NULL);
}
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
@@ -879,7 +986,8 @@ void __init mpic_assign_isu(struct mpic
BUG_ON(isu_num >= MPIC_MAX_ISU);
- mpic->isus[isu_num] = ioremap(phys_addr, MPIC_IRQ_STRIDE * mpic->isu_size);
+ mpic->isus[isu_num] = ioremap(phys_addr,
+ MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
if ((isu_first + mpic->isu_size) > mpic->num_sources)
mpic->num_sources = isu_first + mpic->isu_size;
}
@@ -904,14 +1012,16 @@ void __init mpic_init(struct mpic *mpic)
printk(KERN_INFO "mpic: Initializing for %d sources\n", mpic->num_sources);
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
/* Initialize timers: just disable them all */
for (i = 0; i < 4; i++) {
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_DESTINATION, 0);
+ i * MPIC_INFO(TIMER_STRIDE) +
+ MPIC_INFO(TIMER_DESTINATION), 0);
mpic_write(mpic->tmregs,
- i * MPIC_TIMER_STRIDE + MPIC_TIMER_VECTOR_PRI,
+ i * MPIC_INFO(TIMER_STRIDE) +
+ MPIC_INFO(TIMER_VECTOR_PRI),
MPIC_VECPRI_MASK |
(MPIC_VEC_TIMER_0 + i));
}
@@ -940,21 +1050,23 @@ void __init mpic_init(struct mpic *mpic)
(8 << MPIC_VECPRI_PRIORITY_SHIFT);
/* init hw */
- mpic_irq_write(i, MPIC_IRQ_VECTOR_PRI, vecpri);
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
+ mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
1 << hard_smp_processor_id());
}
/* Init spurrious vector */
- mpic_write(mpic->gregs, MPIC_GREG_SPURIOUS, MPIC_VEC_SPURRIOUS);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_SPURIOUS), MPIC_VEC_SPURRIOUS);
- /* Disable 8259 passthrough */
- mpic_write(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0,
- mpic_read(mpic->gregs, MPIC_GREG_GLOBAL_CONF_0)
+ /* Disable 8259 passthrough, if supported */
+#ifndef CONFIG_MPIC_WEIRD
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0),
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0))
| MPIC_GREG_GCONF_8259_PTHROU_DIS);
+#endif
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
}
void __init mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio)
@@ -997,9 +1109,9 @@ void mpic_irq_set_priority(unsigned int
mpic_ipi_write(src - MPIC_VEC_IPI_0,
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
} else {
- reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI)
+ reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
& ~MPIC_VECPRI_PRIORITY_MASK;
- mpic_irq_write(src, MPIC_IRQ_VECTOR_PRI,
+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI),
reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
}
spin_unlock_irqrestore(&mpic_lock, flags);
@@ -1017,7 +1129,7 @@ unsigned int mpic_irq_get_priority(unsig
if (is_ipi)
reg = mpic_ipi_read(src = MPIC_VEC_IPI_0);
else
- reg = mpic_irq_read(src, MPIC_IRQ_VECTOR_PRI);
+ reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
spin_unlock_irqrestore(&mpic_lock, flags);
return (reg & MPIC_VECPRI_PRIORITY_MASK) >> MPIC_VECPRI_PRIORITY_SHIFT;
}
@@ -1043,12 +1155,12 @@ #ifdef CONFIG_SMP
*/
if (distribute_irqs) {
for (i = 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) | msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) | msk);
}
/* Set current processor priority to 0 */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0);
spin_unlock_irqrestore(&mpic_lock, flags);
#endif /* CONFIG_SMP */
@@ -1058,7 +1170,7 @@ int mpic_cpu_get_priority(void)
{
struct mpic *mpic = mpic_primary;
- return mpic_cpu_read(MPIC_CPU_CURRENT_TASK_PRI);
+ return mpic_cpu_read(MPIC_INFO(CPU_CURRENT_TASK_PRI));
}
void mpic_cpu_set_priority(int prio)
@@ -1066,7 +1178,7 @@ void mpic_cpu_set_priority(int prio)
struct mpic *mpic = mpic_primary;
prio &= MPIC_CPU_TASKPRI_MASK;
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, prio);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), prio);
}
/*
@@ -1088,11 +1200,11 @@ void mpic_teardown_this_cpu(int secondar
/* let the mpic know we don't want intrs. */
for (i = 0; i < mpic->num_sources ; i++)
- mpic_irq_write(i, MPIC_IRQ_DESTINATION,
- mpic_irq_read(i, MPIC_IRQ_DESTINATION) & ~msk);
+ mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
+ mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION)) & ~msk);
/* Set current processor priority to max */
- mpic_cpu_write(MPIC_CPU_CURRENT_TASK_PRI, 0xf);
+ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
spin_unlock_irqrestore(&mpic_lock, flags);
}
@@ -1108,7 +1220,8 @@ #ifdef DEBUG_IPI
DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
#endif
- mpic_cpu_write(MPIC_CPU_IPI_DISPATCH_0 + ipi_no * 0x10,
+ mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+ ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
}
@@ -1116,7 +1229,7 @@ unsigned int mpic_get_one_irq(struct mpi
{
u32 src;
- src = mpic_cpu_read(MPIC_CPU_INTACK) & MPIC_VECPRI_VECTOR_MASK;
+ src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK);
#ifdef DEBUG_LOW
DBG("%s: get_one_irq(): %d\n", mpic->name, src);
#endif
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index eb241c9..a70ef57 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -41,6 +41,7 @@ #define MPIC_GREG_IPI_VECTOR_PRI_0 0x000
#define MPIC_GREG_IPI_VECTOR_PRI_1 0x000b0
#define MPIC_GREG_IPI_VECTOR_PRI_2 0x000c0
#define MPIC_GREG_IPI_VECTOR_PRI_3 0x000d0
+#define MPIC_GREG_IPI_STRIDE 0x10
#define MPIC_GREG_SPURIOUS 0x000e0
#define MPIC_GREG_TIMER_FREQ 0x000f0
@@ -68,6 +69,7 @@ #define MPIC_CPU_IPI_DISPATCH_0 0x00040
#define MPIC_CPU_IPI_DISPATCH_1 0x00050
#define MPIC_CPU_IPI_DISPATCH_2 0x00060
#define MPIC_CPU_IPI_DISPATCH_3 0x00070
+#define MPIC_CPU_IPI_DISPATCH_STRIDE 0x00010
#define MPIC_CPU_CURRENT_TASK_PRI 0x00080
#define MPIC_CPU_TASKPRI_MASK 0x0000000f
#define MPIC_CPU_WHOAMI 0x00090
@@ -114,6 +116,103 @@ #define MPIC_VEC_TIMER_2 249
#define MPIC_VEC_TIMER_1 248
#define MPIC_VEC_TIMER_0 247
+#ifdef CONFIG_MPIC_WEIRD
+/*
+ * Tsi108 implementation of MPIC has many differences from the original one
+ */
+
+/*
+ * Global registers
+ */
+
+#define TSI108_GREG_BASE 0x00000
+#define TSI108_GREG_FEATURE_0 0x00000
+#define TSI108_GREG_GLOBAL_CONF_0 0x00004
+#define TSI108_GREG_VENDOR_ID 0x0000c
+#define TSI108_GREG_IPI_VECTOR_PRI_0 0x00204 /* Doorbell 0 */
+#define TSI108_GREG_IPI_STRIDE 0x0c
+#define TSI108_GREG_SPURIOUS 0x00010
+#define TSI108_GREG_TIMER_FREQ 0x00014
+
+/*
+ * Timer registers
+ */
+#define TSI108_TIMER_BASE 0x0030
+#define TSI108_TIMER_STRIDE 0x10
+#define TSI108_TIMER_CURRENT_CNT 0x00000
+#define TSI108_TIMER_BASE_CNT 0x00004
+#define TSI108_TIMER_VECTOR_PRI 0x00008
+#define TSI108_TIMER_DESTINATION 0x0000c
+
+/*
+ * Per-Processor registers
+ */
+#define TSI108_CPU_BASE 0x00300
+#define TSI108_CPU_STRIDE 0x00040
+#define TSI108_CPU_IPI_DISPATCH_0 0x00200
+#define TSI108_CPU_IPI_DISPATCH_STRIDE 0x00000
+#define TSI108_CPU_CURRENT_TASK_PRI 0x00000
+#define TSI108_CPU_WHOAMI 0xffffffff
+#define TSI108_CPU_INTACK 0x00004
+#define TSI108_CPU_EOI 0x00008
+
+/*
+ * Per-source registers
+ */
+#define TSI108_IRQ_BASE 0x00100
+#define TSI108_IRQ_STRIDE 0x00008
+#define TSI108_IRQ_VECTOR_PRI 0x00000
+#define TSI108_VECPRI_VECTOR_MASK 0x000000ff
+#define TSI108_VECPRI_POLARITY_POSITIVE 0x01000000
+#define TSI108_VECPRI_POLARITY_NEGATIVE 0x00000000
+#define TSI108_VECPRI_SENSE_LEVEL 0x02000000
+#define TSI108_VECPRI_SENSE_EDGE 0x00000000
+#define TSI108_VECPRI_POLARITY_MASK 0x01000000
+#define TSI108_VECPRI_SENSE_MASK 0x02000000
+#define TSI108_IRQ_DESTINATION 0x00004
+
+/* weird mpic variable index in the HW info array */
+enum MPIC_WEIRD_INDEX {
+ INDEX_GREG_BASE = 0, /* Offset of global registers from MPIC base */
+ INDEX_GREG_FEATURE_0, /* FRR0 offset from base */
+ INDEX_GREG_GLOBAL_CONF_0, /* Global Config register offset from base */
+ INDEX_GREG_VENDOR_ID, /* VID register offset from base */
+ INDEX_GREG_IPI_VECTOR_PRI_0, /* IPI Vector/Priority Registers */
+ INDEX_GREG_IPI_STRIDE, /* IPI Vector/Priority Registers spacing */
+ INDEX_GREG_SPURIOUS, /* Spurious Vector Register */
+ INDEX_GREG_TIMER_FREQ, /* Global Timer Frequency Reporting Register */
+
+ INDEX_TIMER_BASE, /* Global Timer Registers base */
+ INDEX_TIMER_STRIDE, /* Global Timer Registers spacing */
+ INDEX_TIMER_CURRENT_CNT, /* Global Timer Current Count Register */
+ INDEX_TIMER_BASE_CNT, /* Global Timer Base Count Register */
+ INDEX_TIMER_VECTOR_PRI, /* Global Timer Vector/Priority Register */
+ INDEX_TIMER_DESTINATION, /* Global Timer Destination Register */
+
+ INDEX_CPU_BASE, /* Offset of cpu base */
+ INDEX_CPU_STRIDE, /* Cpu register spacing*/
+ INDEX_CPU_IPI_DISPATCH_0, /* IPI 0 Dispatch Command Register */
+ INDEX_CPU_IPI_DISPATCH_STRIDE, /* IPI Dispatch spacing */
+ INDEX_CPU_CURRENT_TASK_PRI,/* Processor Current Task Priority Register */
+ INDEX_CPU_WHOAMI, /* Who Am I Register */
+ INDEX_CPU_INTACK, /* Interrupt Acknowledge Register */
+ INDEX_CPU_EOI, /* End of Interrupt Register */
+
+ INDEX_IRQ_BASE, /* Interrupt registers base */
+ INDEX_IRQ_STRIDE, /* Interrupt registers spacing */
+ INDEX_IRQ_VECTOR_PRI, /* Interrupt Vector/Priority Register */
+ INDEX_VECPRI_VECTOR_MASK, /* Interrupt Vector Mask */
+ INDEX_VECPRI_POLARITY_POSITIVE, /* Interrupt Positive Polarity bit */
+ INDEX_VECPRI_POLARITY_NEGATIVE, /* Interrupt Negative Polarity bit */
+ INDEX_VECPRI_SENSE_LEVEL, /* Interrupt Level Sense bit */
+ INDEX_VECPRI_SENSE_EDGE, /* Interrupt edge Sense bit */
+ INDEX_VECPRI_POLARITY_MASK, /* Interrupt Polarity mask */
+ INDEX_VECPRI_SENSE_MASK, /* Interrupt sense mask */
+ INDEX_IRQ_DESTINATION, /* Interrupt Destination Register */
+ INDEX_MPIC_WEIRD_END /* Size of the hw info array */
+};
+#endif
+
#ifdef CONFIG_MPIC_BROKEN_U3
/* Fixup table entry */
struct mpic_irq_fixup
@@ -170,6 +269,11 @@ #endif
volatile u32 __iomem *tmregs;
volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS];
volatile u32 __iomem *isus[MPIC_MAX_ISU];
+
+#ifdef CONFIG_MPIC_WEIRD
+ /* Pointer to HW info array */
+ u32 *hw_set;
+#endif
/* link */
struct mpic *next;
@@ -189,6 +293,17 @@ #define MPIC_BROKEN_IPI 0x00000008
/* MPIC wants a reset */
#define MPIC_WANTS_RESET 0x00000010
+#ifdef CONFIG_MPIC_WEIRD
+/* Spurious vector requires EOI */
+#define MPIC_SPV_EOI 0x00000020
+/* MPIC HW modification ID */
+#define MPIC_MOD_ID_MASK 0x00000f00
+#define MPIC_MOD_ID(val) (((val) << 8) & MPIC_MOD_ID_MASK)
+#define MPIC_GET_MOD_ID(flags) (((flags) & MPIC_MOD_ID_MASK) >> 8)
+#define MPIC_ID_MPIC 0 /* Original MPIC */
+#define MPIC_ID_TSI108 1 /* Tsi108/109 PIC */
+#endif
+
/* Allocate the controller structure and setup the linux irq descs
* for the range if interrupts passed in. No HW initialization is
* actually performed.
--
1.4.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 9:52 ` Zang Roy-r61911
@ 2006-08-24 10:54 ` Benjamin Herrenschmidt
2006-08-24 11:04 ` Zang Roy-r61911
0 siblings, 1 reply; 11+ messages in thread
From: Benjamin Herrenschmidt @ 2006-08-24 10:54 UTC (permalink / raw)
To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
> > The table should still contain the entries for a normal MPIC. One can
> > build a kernel that will boot both machines with the "weird" one and
> > with the normal one. Thus CONFIG_MPIC_WEIRD shall not exclude normal
> > MPICs, though not having it does exclude weird ones. I thus would
> > suggest to keep the table as it was in your earlier patches, that is
> > with the normal MPIC mapping at 0.
> >
> > I intend to re-use that to handle another weird MPIC from some other
> > project :)
>
> That is also my target. I hope the imported mpic_info table can support
> more non-standard mpic structure.
> The following patch adds the standard MPIC entry to the table.
> I post it here.
Looks good. I still need to test it, hopefully tomorrow, then it can go
in though I'm not sure it can get into 2.6.18, we'll see.
Ben.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 10:54 ` Benjamin Herrenschmidt
@ 2006-08-24 11:04 ` Zang Roy-r61911
2006-08-24 11:13 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-24 11:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
On Thu, 2006-08-24 at 18:54, Benjamin Herrenschmidt wrote:
> > > The table should still contain the entries for a normal MPIC. One
> can
> > > build a kernel that will boot both machines with the "weird" one
> and
> > > with the normal one. Thus CONFIG_MPIC_WEIRD shall not exclude
> normal
> > > MPICs, though not having it does exclude weird ones. I thus would
> > > suggest to keep the table as it was in your earlier patches, that
> is
> > > with the normal MPIC mapping at 0.
> > >
> > > I intend to re-use that to handle another weird MPIC from some
> other
> > > project :)
> >
> > That is also my target. I hope the imported mpic_info table can
> support
> > more non-standard mpic structure.
> > The following patch adds the standard MPIC entry to the table.
> > I post it here.
>
> Looks good. I still need to test it, hopefully tomorrow, then it can
> go
> in though I'm not sure it can get into 2.6.18, we'll see.
>
I have tested on mpc8641hpcn board with CONFIG_MPIC.
Hope to see it in 2.6.18.
Roy
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 11:04 ` Zang Roy-r61911
@ 2006-08-24 11:13 ` Benjamin Herrenschmidt
2006-08-25 1:37 ` Zang Roy-r61911
0 siblings, 1 reply; 11+ messages in thread
From: Benjamin Herrenschmidt @ 2006-08-24 11:13 UTC (permalink / raw)
To: Zang Roy-r61911; +Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
> I have tested on mpc8641hpcn board with CONFIG_MPIC.
I need to test it with normal MPIC machines and CONFIG_MPIC_WEIRD
enabled
> Hope to see it in 2.6.18.
This is not my call unfortunately though I reckon that it could go in
since it's been sitting around for a while. We'll see.
Ben.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH ] powerpc: Add tsi108/9 and non standard mpic support
2006-08-24 11:13 ` Benjamin Herrenschmidt
@ 2006-08-25 1:37 ` Zang Roy-r61911
0 siblings, 0 replies; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-25 1:37 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Paul Mackerras, Yang Xin-Xin-r48390
On Thu, 2006-08-24 at 19:13, Benjamin Herrenschmidt wrote:
> > I have tested on mpc8641hpcn board with CONFIG_MPIC.
>
> I need to test it with normal MPIC machines and CONFIG_MPIC_WEIRD
> enabled
>
For my design, it should have the same behavior just as CONFIG_MPIC, if
you pass MPIC_ID_MPIC flag.
We can see your result.
Roy
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH ] powerpc: mpc7448hpc2 device tree source file
2006-08-22 10:07 [PATCH ] powerpc: Add tsi108/9 and non standard mpic support Zang Roy-r61911
2006-08-22 17:15 ` Adrian Cox
2006-08-24 5:42 ` Zang Roy-r61911
@ 2006-08-25 8:43 ` Zang Roy-r61911
2 siblings, 0 replies; 11+ messages in thread
From: Zang Roy-r61911 @ 2006-08-25 8:43 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev list, Yang Xin-Xin-r48390
This patch adds the mpc7448hpc2 device tree source file.
Signed-off-by: Roy Zang <tie-fei.zang@freescale.com>
---
arch/powerpc/boot/dts/mpc7448hpc2.dts | 190 +++++++++++++++++++++++++++++++++
1 files changed, 190 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
new file mode 100644
index 0000000..d7b985e
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -0,0 +1,190 @@
+/*
+ * MPC7448HPC2 (Taiga) board Device Tree Source
+ *
+ * Copyright 2006 Freescale Semiconductor Inc.
+ * 2006 Roy Zang <Roy Zang at freescale.com>.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+/ {
+ model = "mpc7448hpc2";
+ compatible = "mpc74xx";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ linux,phandle = <100>;
+
+ cpus {
+ #cpus = <1>;
+ #address-cells = <1>;
+ #size-cells =<0>;
+ linux,phandle = <200>;
+
+ PowerPC,7448@0 {
+ device_type = "cpu";
+ reg = <0>;
+ d-cache-line-size = <20>; // 32 bytes
+ i-cache-line-size = <20>; // 32 bytes
+ d-cache-size = <8000>; // L1, 32K bytes
+ i-cache-size = <8000>; // L1, 32K bytes
+ timebase-frequency = <0>; // 33 MHz, from uboot
+ clock-frequency = <0>; // From U-Boot
+ bus-frequency = <0>; // From U-Boot
+ 32-bit;
+ linux,phandle = <201>;
+ linux,boot-cpu;
+ };
+ };
+
+ memory {
+ device_type = "memory";
+ linux,phandle = <300>;
+ reg = <00000000 20000000 // DDR2 512M at 0
+ >;
+ };
+
+ tsi108@c0000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #interrupt-cells = <2>;
+ device_type = "tsi-bridge";
+ ranges = <00000000 c0000000 00010000>;
+ reg = <c0000000 00010000>;
+ bus-frequency = <0>;
+
+ i2c@7000 {
+ interrupt-parent = <7400>;
+ interrupts = <E 0>;
+ reg = <7000 400>;
+ device_type = "i2c";
+ compatible = "tsi-i2c";
+ };
+
+ mdio@6000 {
+ device_type = "mdio";
+ compatible = "tsi-ethernet";
+
+ ethernet-phy@6000 {
+ linux,phandle = <6000>;
+ interrupt-parent = <7400>;
+ interrupts = <2 1>;
+ reg = <6000 50>;
+ phy-id = <8>;
+ device_type = "ethernet-phy";
+ };
+
+ ethernet-phy@6400 {
+ linux,phandle = <6400>;
+ interrupt-parent = <7400>;
+ interrupts = <2 1>;
+ reg = <6000 50>;
+ phy-id = <9>;
+ device_type = "ethernet-phy";
+ };
+
+ };
+
+ ethernet@6200 {
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSI-ETH";
+ compatible = "tsi-ethernet";
+ reg = <6000 200>;
+ address = [ 00 06 D2 00 00 01 ];
+ interrupts = <10 2>;
+ interrupt-parent = <7400>;
+ phy-handle = <6000>;
+ };
+
+ ethernet@6600 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ device_type = "network";
+ model = "TSI-ETH";
+ compatible = "tsi-ethernet";
+ reg = <6400 200>;
+ address = [ 00 06 D2 00 00 02 ];
+ interrupts = <11 2>;
+ interrupt-parent = <7400>;
+ phy-handle = <6400>;
+ };
+
+ serial@7808 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7808 200>;
+ clock-frequency = <3f6b5a00>;
+ interrupts = <c 0>;
+ interrupt-parent = <7400>;
+ };
+
+ serial@7c08 {
+ device_type = "serial";
+ compatible = "ns16550";
+ reg = <7c08 200>;
+ clock-frequency = <3f6b5a00>;
+ interrupts = <d 0>;
+ interrupt-parent = <7400>;
+ };
+
+ pic@7400 {
+ linux,phandle = <7400>;
+ clock-frequency = <0>;
+ interrupt-controller;
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <7400 400>;
+ built-in;
+ compatible = "chrp,open-pic";
+ device_type = "open-pic";
+ big-endian;
+ };
+ pci@1000 {
+ compatible = "tsi10x";
+ device_type = "pci";
+ linux,phandle = <1000>;
+ #interrupt-cells = <1>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ reg = <1000 1000>;
+ bus-range = <0 0>;
+ ranges = <02000000 0 e0000000 e0000000 0 1A000000
+ 01000000 0 00000000 fa000000 0 00010000>;
+ clock-frequency = <7f28154>;
+ interrupt-parent = <7400>;
+ interrupts = <17 2>;
+ interrupt-map-mask = <f800 0 0 7>;
+ interrupt-map = <
+
+ /* IDSEL 0x11 */
+ 0800 0 0 1 7400 24 0
+ 0800 0 0 2 7400 25 0
+ 0800 0 0 3 7400 26 0
+ 0800 0 0 4 7400 27 0
+
+ /* IDSEL 0x12 */
+ 1000 0 0 1 7400 25 0
+ 1000 0 0 2 7400 26 0
+ 1000 0 0 3 7400 27 0
+ 1000 0 0 4 7400 24 0
+
+ /* IDSEL 0x13 */
+ 1800 0 0 1 7400 26 0
+ 1800 0 0 2 7400 27 0
+ 1800 0 0 3 7400 24 0
+ 1800 0 0 4 7400 25 0
+
+ /* IDSEL 0x14 */
+ 2000 0 0 1 7400 27 0
+ 2000 0 0 2 7400 24 0
+ 2000 0 0 3 7400 25 0
+ 2000 0 0 4 7400 26 0
+ >;
+ };
+ };
+
+};
--
1.4.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2006-08-25 8:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-22 10:07 [PATCH ] powerpc: Add tsi108/9 and non standard mpic support Zang Roy-r61911
2006-08-22 17:15 ` Adrian Cox
2006-08-23 1:20 ` Zang Roy-r61911
2006-08-24 5:42 ` Zang Roy-r61911
2006-08-24 5:54 ` Benjamin Herrenschmidt
2006-08-24 9:52 ` Zang Roy-r61911
2006-08-24 10:54 ` Benjamin Herrenschmidt
2006-08-24 11:04 ` Zang Roy-r61911
2006-08-24 11:13 ` Benjamin Herrenschmidt
2006-08-25 1:37 ` Zang Roy-r61911
2006-08-25 8:43 ` [PATCH ] powerpc: mpc7448hpc2 device tree source file Zang Roy-r61911
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).