Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

powerpc/mpic: finish supporting timer group B on Freescale chips



Previously, these interrupts would be mapped, but the offset calculation
was broken, and only the first group was initialized.

Signed-off-by: default avatarVarun Sethi <Varun.Sethi@freescale.com>
Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 34f84b5b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
 */
#define MPIC_TIMER_BASE			0x01100
#define MPIC_TIMER_STRIDE		0x40
#define MPIC_TIMER_GROUP_STRIDE		0x1000

#define MPIC_TIMER_CURRENT_CNT		0x00000
#define MPIC_TIMER_BASE_CNT		0x00010
@@ -110,6 +111,9 @@
#define 	MPIC_VECPRI_SENSE_MASK			0x00400000
#define MPIC_IRQ_DESTINATION		0x00010

#define MPIC_FSL_BRR1			0x00000
#define 	MPIC_FSL_BRR1_VER			0x0000ffff

#define MPIC_MAX_IRQ_SOURCES	2048
#define MPIC_MAX_CPUS		32
#define MPIC_MAX_ISU		32
@@ -296,6 +300,7 @@ struct mpic
	phys_addr_t paddr;

	/* The various ioremap'ed bases */
	struct mpic_reg_bank	thiscpuregs;
	struct mpic_reg_bank	gregs;
	struct mpic_reg_bank	tmregs;
	struct mpic_reg_bank	cpuregs[MPIC_MAX_CPUS];
+42 −16
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
 *  with various broken implementations of this HW.
 *
 *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
 *  Copyright 2010-2011 Freescale Semiconductor, Inc.
 *  Copyright 2010-2012 Freescale Semiconductor, Inc.
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of this archive
@@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
	_mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
}

static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm)
{
	unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
			      ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
	return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE +
	       (tm & 3) * MPIC_INFO(TIMER_STRIDE);
}

	if (tm >= 4)
		offset += 0x1000 / 4;
static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
{
	unsigned int offset = mpic_tm_offset(mpic, tm) +
			      MPIC_INFO(TIMER_VECTOR_PRI);

	return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
}

static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
{
	unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
			      ((tm & 3) * MPIC_INFO(TIMER_STRIDE));

	if (tm >= 4)
		offset += 0x1000 / 4;
	unsigned int offset = mpic_tm_offset(mpic, tm) +
			      MPIC_INFO(TIMER_VECTOR_PRI);

	_mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
}
@@ -1301,6 +1301,16 @@ struct mpic * __init mpic_alloc(struct device_node *node,
	mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
	mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);

	if (mpic->flags & MPIC_FSL) {
		/*
		 * Yes, Freescale really did put global registers in the
		 * magic per-cpu area -- and they don't even show up in the
		 * non-magic per-cpu copies that this driver normally uses.
		 */
		mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs,
			 MPIC_CPU_THISBASE, 0x1000);
	}

	/* Reset */

	/* When using a device-node, reset requests are only honored if the MPIC
@@ -1440,6 +1450,7 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
void __init mpic_init(struct mpic *mpic)
{
	int i, cpu;
	int num_timers = 4;

	BUG_ON(mpic->num_sources == 0);

@@ -1448,15 +1459,30 @@ void __init mpic_init(struct mpic *mpic)
	/* Set current processor priority to max */
	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);

	if (mpic->flags & MPIC_FSL) {
		u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs,
				      MPIC_FSL_BRR1);
		u32 version = brr1 & MPIC_FSL_BRR1_VER;

		/*
		 * Timer group B is present at the latest in MPIC 3.1 (e.g.
		 * mpc8536).  It is not present in MPIC 2.0 (e.g. mpc8544).
		 * I don't know about the status of intermediate versions (or
		 * whether they even exist).
		 */
		if (version >= 0x0301)
			num_timers = 8;
	}

	/* Initialize timers to our reserved vectors and mask them for now */
	for (i = 0; i < 4; i++) {
	for (i = 0; i < num_timers; i++) {
		unsigned int offset = mpic_tm_offset(mpic, i);

		mpic_write(mpic->tmregs,
			   i * MPIC_INFO(TIMER_STRIDE) +
			   MPIC_INFO(TIMER_DESTINATION),
			   offset + MPIC_INFO(TIMER_DESTINATION),
			   1 << hard_smp_processor_id());
		mpic_write(mpic->tmregs,
			   i * MPIC_INFO(TIMER_STRIDE) +
			   MPIC_INFO(TIMER_VECTOR_PRI),
			   offset + MPIC_INFO(TIMER_VECTOR_PRI),
			   MPIC_VECPRI_MASK |
			   (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
			   (mpic->timer_vecs[0] + i));