Module Name:    src
Committed By:   rkujawa
Date:           Wed May 29 22:35:34 UTC 2013

Modified Files:
        src/sys/arch/arm/marvell: files.marvell
        src/sys/arch/arm/pic: files.pic
Added Files:
        src/sys/arch/arm/marvell: armadaxp.c
        src/sys/arch/arm/pic: armadaxp_splfuncs.c

Log Message:
Add support for Armada XP PIC.

Obtained from Marvell, Semihalf.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/marvell/armadaxp.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/marvell/files.marvell
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/pic/armadaxp_splfuncs.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/pic/files.pic

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/marvell/files.marvell
diff -u src/sys/arch/arm/marvell/files.marvell:1.7 src/sys/arch/arm/marvell/files.marvell:1.8
--- src/sys/arch/arm/marvell/files.marvell:1.7	Wed Aug  1 10:38:41 2012
+++ src/sys/arch/arm/marvell/files.marvell	Wed May 29 22:35:34 2013
@@ -1,4 +1,4 @@
-#       $NetBSD: files.marvell,v 1.7 2012/08/01 10:38:41 kiyohara Exp $
+#       $NetBSD: files.marvell,v 1.8 2013/05/29 22:35:34 rkujawa Exp $
 #
 # Configuration info for Marvell System on Chip support
 #
@@ -15,6 +15,7 @@ file	arch/arm/arm32/irq_dispatch.S
 
 defflag opt_mvsoc.h				ORION KIRKWOOD MV78XX0
 file	arch/arm/marvell/mvsoc_intr.c
+file	arch/arm/marvell/armadaxp.c		armadaxp
 file	arch/arm/marvell/orion.c		orion
 file	arch/arm/marvell/kirkwood.c		kirkwood
 #file	arch/arm/marvell/mv78xx0.c		mv78xx0

Index: src/sys/arch/arm/pic/files.pic
diff -u src/sys/arch/arm/pic/files.pic:1.4 src/sys/arch/arm/pic/files.pic:1.5
--- src/sys/arch/arm/pic/files.pic:1.4	Sat Sep  1 00:00:42 2012
+++ src/sys/arch/arm/pic/files.pic	Wed May 29 22:35:34 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: files.pic,v 1.4 2012/09/01 00:00:42 matt Exp $
+#	$NetBSD: files.pic,v 1.5 2013/05/29 22:35:34 rkujawa Exp $
 #
 # Configuration info for the common PIC code.
 #
@@ -7,5 +7,6 @@ define	pic_splfuncs
 defflag opt_arm_intr_impl.h		__HAVE_PIC_SET_PRIORITY
 defflag opt_arm_intr_impl.h		__HAVE_PIC_SOFTINT
 
-file	arch/arm/pic/pic.c		pic
-file	arch/arm/pic/pic_splfuncs.c	pic & pic_splfuncs
+file	arch/arm/pic/pic.c			pic
+file	arch/arm/pic/pic_splfuncs.c		pic & pic_splfuncs & !armadaxp
+file	arch/arm/pic/armadaxp_splfuncs.c	pic & pic_splfuncs & armadaxp

Added files:

Index: src/sys/arch/arm/marvell/armadaxp.c
diff -u /dev/null src/sys/arch/arm/marvell/armadaxp.c:1.1
--- /dev/null	Wed May 29 22:35:34 2013
+++ src/sys/arch/arm/marvell/armadaxp.c	Wed May 29 22:35:34 2013
@@ -0,0 +1,399 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Developed by Semihalf
+
+********************************************************************************
+Marvell BSD License
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+            this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+        used to endorse or promote products derived from this software without
+        specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.1 2013/05/29 22:35:34 rkujawa Exp $");
+
+#define _INTR_PRIVATE
+
+#include "opt_mvsoc.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <machine/intr.h>
+
+#include <arm/pic/picvar.h>
+#include <arm/pic/picvar.h>
+
+#include <arm/armreg.h>
+#include <arm/cpu.h>
+#include <arm/cpufunc.h>
+
+#include <arm/marvell/mvsocreg.h>
+#include <arm/marvell/mvsocvar.h>
+#include <evbarm/armadaxp/armadaxpreg.h>
+
+#include <evbarm/marvell/marvellreg.h>
+#include <dev/marvell/marvellreg.h>
+
+#define EXTRACT_CPU_FREQ_FIELD(sar)	(((0x01 & (sar >> 52)) << 3) | \
+					    (0x07 & (sar >> 21)))
+#define EXTRACT_FAB_FREQ_FIELD(sar)	(((0x01 & (sar >> 51)) << 4) | \
+					    (0x0F & (sar >> 24)))
+
+#define	MPIC_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
+					    mpic_handle, reg, val))
+#define	MPIC_CPU_WRITE(reg, val)	(bus_space_write_4(&mvsoc_bs_tag, \
+					    mpic_cpu_handle, reg, val))
+
+#define	MPIC_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
+					    mpic_handle, reg))
+#define	MPIC_CPU_READ(reg)		(bus_space_read_4(&mvsoc_bs_tag, \
+					    mpic_cpu_handle, reg))
+
+#define	L2_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
+					    l2_handle, reg, val))
+#define	L2_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
+					    l2_handle, reg))
+bus_space_handle_t mpic_cpu_handle;
+static bus_space_handle_t mpic_handle, l2_handle;
+int l2cache_state = 0;
+int iocc_state = 0;
+
+extern void (*mvsoc_intr_init)(void);
+static void armadaxp_intr_init(void);
+
+static void armadaxp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
+static void armadaxp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
+static void armadaxp_pic_establish_irq(struct pic_softc *, struct intrsource *);
+
+void armadaxp_handle_irq(void *);
+void armadaxp_io_coherency_init(void);
+int armadaxp_l2_init(void);
+
+struct vco_freq_ratio {
+	uint8_t	vco_cpu;	/* VCO to CLK0(CPU) clock ratio */
+	uint8_t	vco_l2c;	/* VCO to NB(L2 cache) clock ratio */
+	uint8_t	vco_hcl;	/* VCO to HCLK(DDR controller) clock ratio */
+	uint8_t	vco_ddr;	/* VCO to DR(DDR memory) clock ratio */
+};
+
+static struct vco_freq_ratio freq_conf_table[] = {
+/*00*/	{ 1, 1,	 4,  2 },
+/*01*/	{ 1, 2,	 2,  2 },
+/*02*/	{ 2, 2,	 6,  3 },
+/*03*/	{ 2, 2,	 3,  3 },
+/*04*/	{ 1, 2,	 3,  3 },
+/*05*/	{ 1, 2,	 4,  2 },
+/*06*/	{ 1, 1,	 2,  2 },
+/*07*/	{ 2, 3,	 6,  6 },
+/*08*/	{ 2, 3,	 5,  5 },
+/*09*/	{ 1, 2,	 6,  3 },
+/*10*/	{ 2, 4,	10,  5 },
+/*11*/	{ 1, 3,	 6,  6 },
+/*12*/	{ 1, 2,	 5,  5 },
+/*13*/	{ 1, 3,	 6,  3 },
+/*14*/	{ 1, 2,	 5,  5 },
+/*15*/	{ 2, 2,	 5,  5 },
+/*16*/	{ 1, 1,	 3,  3 },
+/*17*/	{ 2, 5,	10, 10 },
+/*18*/	{ 1, 3,	 8,  4 },
+/*19*/	{ 1, 1,	 2,  1 },
+/*20*/	{ 2, 3,	 6,  3 },
+/*21*/	{ 1, 2,	 8,  4 },
+/*22*/	{ 2, 5,	10,  5 }
+};
+
+static uint16_t	cpu_clock_table[] = {
+    1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 600,  667,  800,  1600,
+    2133, 2200, 2400 };
+
+static struct pic_ops armadaxp_picops = {
+	.pic_unblock_irqs = armadaxp_pic_unblock_irqs,
+	.pic_block_irqs = armadaxp_pic_block_irqs,
+	.pic_establish_irq = armadaxp_pic_establish_irq,
+};
+
+static struct pic_softc armadaxp_pic = {
+	.pic_ops = &armadaxp_picops,
+	.pic_name = "armadaxp",
+};
+
+/*
+ * armadaxp_intr_bootstrap:
+ *
+ *	Initialize the rest of the interrupt subsystem, making it
+ *	ready to handle interrupts from devices.
+ */
+void
+armadaxp_intr_bootstrap(void)
+{
+	int i;
+
+	/* Map MPIC base and MPIC percpu base registers */
+	if (bus_space_map(&mvsoc_bs_tag, MARVELL_INTERREGS_PBASE +
+	    ARMADAXP_MLMB_MPIC_BASE, 0x500, 0, &mpic_handle) != 0)
+		panic("%s: Could not map MPIC registers", __func__);
+	if (bus_space_map(&mvsoc_bs_tag, MARVELL_INTERREGS_PBASE +
+	    ARMADAXP_MLMB_MPIC_CPU_BASE, 0x800, 0, &mpic_cpu_handle) != 0)
+		panic("%s: Could not map MPIC percpu registers", __func__);
+
+	/* Disable all interrupts */
+	for (i = 0; i < 116; i++)
+		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, i);
+
+	mvsoc_intr_init = armadaxp_intr_init;
+}
+
+static void
+armadaxp_intr_init(void)
+{
+	int ctrl;
+
+	/* Get max interrupts */
+	armadaxp_pic.pic_maxsources =
+	    ((MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL) >> 2) & 0x7FF);
+
+	if (!armadaxp_pic.pic_maxsources)
+		armadaxp_pic.pic_maxsources = 116;
+
+	pic_add(&armadaxp_pic, 0);
+
+	ctrl = MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL);
+	/* Enable IRQ prioritization */
+	ctrl |= (1 << 0);
+	MPIC_WRITE(ARMADAXP_MLMB_MPIC_CTRL, ctrl);
+	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, curcpl() << MPIC_CTP_SHIFT);
+}
+
+static void
+armadaxp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
+    uint32_t irq_mask)
+{
+	int n;
+
+	while (irq_mask != 0) {
+		n = ffs(irq_mask) - 1;
+		KASSERT(pic->pic_maxsources >= n + irqbase);
+		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISE, n + irqbase);
+		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ICM, n + irqbase);
+		if ((n + irqbase) == 0)
+			MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_DOORBELL_MASK,
+			    0xffffffff);
+		irq_mask &= ~__BIT(n);
+	}
+}
+
+static void
+armadaxp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
+    uint32_t irq_mask)
+{
+	int n;
+
+	while (irq_mask != 0) {
+		n = ffs(irq_mask) - 1;
+		KASSERT(pic->pic_maxsources >= n + irqbase);
+		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, n + irqbase);
+		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, n + irqbase);
+		irq_mask &= ~__BIT(n);
+	}
+}
+
+static void
+armadaxp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
+{
+	int tmp;
+	KASSERT(pic->pic_maxsources >= is->is_irq);
+	tmp = MPIC_READ(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4);
+	/* Clear previous priority */
+	tmp &= ~(0xf << MPIC_ISCR_SHIFT);
+	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4,
+	    tmp | (is->is_ipl << MPIC_ISCR_SHIFT));
+}
+
+void
+armadaxp_handle_irq(void *frame)
+{
+	struct intrsource *is;
+	int irq;
+	u_int irqstate;
+
+	irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff;
+
+	/* Is it a spurious interrupt ?*/
+	if (irq == 0x3ff)
+		return;
+
+	is = armadaxp_pic.pic_sources[irq];
+	if (is != NULL)  {
+		KASSERT(is->is_ipl > curcpu()->ci_cpl);
+		/* Dispatch irq */
+		irqstate = disable_interrupts(I32_bit);
+		pic_dispatch(is, frame);
+		restore_interrupts(irqstate);
+	}
+#ifdef __HAVE_FAST_SOFTINTS
+	cpu_dosoftints();
+#endif
+}
+
+/*
+ * Clock functions
+ */
+
+void
+armadaxp_getclks(void)
+{
+	uint64_t sar_reg;
+	uint8_t  sar_cpu_freq, sar_fab_freq, array_size;
+
+	if (cputype == CPU_ID_MV88SV584X_V7)
+		mvTclk = 250000000; /* 250 MHz */
+	else
+		mvTclk = 200000000; /* 200 MHz */
+
+	sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) |
+	    read_miscreg(ARMADAXP_MISC_SAR_LO);
+
+	sar_cpu_freq = EXTRACT_CPU_FREQ_FIELD(sar_reg);
+	sar_fab_freq = EXTRACT_FAB_FREQ_FIELD(sar_reg);
+
+	/* Check if CPU frequency field has correct value */
+	array_size = sizeof(cpu_clock_table) / sizeof(cpu_clock_table[0]);
+	if (sar_cpu_freq >= array_size)
+		panic("Reserved value in cpu frequency configuration field: "
+		    "%d", sar_cpu_freq);
+
+	/* Check if fabric frequency field has correct value */
+	array_size = sizeof(freq_conf_table) / sizeof(freq_conf_table[0]);
+	if (sar_fab_freq >= array_size)
+		panic("Reserved value in fabric frequency configuration field: "
+		    "%d", sar_fab_freq);
+
+	/* Get CPU clock frequency */
+	mvPclk = cpu_clock_table[sar_cpu_freq] *
+	    freq_conf_table[sar_fab_freq].vco_cpu;
+
+	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
+	mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c;
+
+	/* Round mvSysclk value to integer MHz */
+	if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
+	    freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
+		mvSysclk++;
+
+	mvPclk = mvPclk * 1000000;
+	mvSysclk = mvSysclk * 1000000;
+}
+
+/*
+ * L2 Cache initialization
+ */
+
+int
+armadaxp_l2_init(void)
+{
+	u_int32_t reg;
+	int ret;
+
+	/* Map L2 space */
+	ret = bus_space_map(&mvsoc_bs_tag, MARVELL_INTERREGS_PBASE +
+	    ARMADAXP_L2_BASE, 0x1000, 0, &l2_handle);
+	if (ret) {
+		printf("%s: Cannot map L2 register space, ret:%d\n",
+		    __func__, ret);
+		return (-1);
+	}
+
+	/* Set L2 policy */
+	reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
+	reg &= ~(L2_WBWT_MODE_MASK);
+	reg &= ~(L2_REP_STRAT_MASK);
+	reg |= L2_REP_STRAT_SEMIPLRU;
+	L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
+
+	/* Invalidate L2 cache */
+	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
+
+	/* Clear pending L2 interrupts */
+	L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff);
+
+	/* Enable Cache and TLB maintenance broadcast */
+	__asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg));
+	reg |= (1 << 8);
+	__asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg));
+
+	/*
+	 * Set the Point of Coherency and Point of Unification to DRAM.
+	 * This is a reset value but anyway, configure this just in case.
+	 */
+	reg = read_mlmbreg(ARMADAXP_L2_CFU);
+	reg |= (1 << 17) | (1 << 18);
+	write_mlmbreg(ARMADAXP_L2_CFU, reg);
+
+	/* Enable L2 cache */
+	reg = L2_READ(ARMADAXP_L2_CTRL);
+	L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_ENABLE);
+
+	/* Mark as enabled */
+	l2cache_state = 1;
+
+#ifdef DEBUG
+	/* Configure and enable counter */
+	L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
+	L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
+	L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303);
+#endif
+
+	return (0);
+}
+
+void
+armadaxp_io_coherency_init(void)
+{
+	uint32_t reg;
+
+	/* set CIB read snoop command to ReadUnique */
+	reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG);
+	reg &= ~(7 << 16);
+	reg |= (7 << 16);
+	write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg);
+	/* enable CPUs in SMP group on Fabric coherency */
+	reg = read_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CTRL);
+	reg &= ~(0x3 << 24);
+	reg |= (1 << 24);
+	write_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CTRL, reg);
+
+	reg = read_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CFG);
+	reg &= ~(0x3 << 24);
+	reg |= (1 << 24);
+	write_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CFG, reg);
+
+	/* Mark as enabled */
+	iocc_state = 1;
+}

Index: src/sys/arch/arm/pic/armadaxp_splfuncs.c
diff -u /dev/null src/sys/arch/arm/pic/armadaxp_splfuncs.c:1.1
--- /dev/null	Wed May 29 22:35:34 2013
+++ src/sys/arch/arm/pic/armadaxp_splfuncs.c	Wed May 29 22:35:34 2013
@@ -0,0 +1,156 @@
+/*******************************************************************************
+Copyright (C) Marvell International Ltd. and its affiliates
+
+Developed by Semihalf
+
+********************************************************************************
+Marvell BSD License
+
+If you received this File from Marvell, you may opt to use, redistribute and/or
+modify this File under the following licensing terms.
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+    *   Redistributions of source code must retain the above copyright notice,
+            this list of conditions and the following disclaimer.
+
+    *   Redistributions in binary form must reproduce the above copyright
+        notice, this list of conditions and the following disclaimer in the
+        documentation and/or other materials provided with the distribution.
+
+    *   Neither the name of Marvell nor the names of its contributors may be
+        used to endorse or promote products derived from this software without
+        specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: armadaxp_splfuncs.c,v 1.1 2013/05/29 22:35:34 rkujawa Exp $");
+
+#define _INTR_PRIVATE
+
+#include "opt_mvsoc.h"
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <machine/intr.h>
+
+#include <arm/pic/picvar.h>
+
+#include <arm/armreg.h>
+#include <arm/cpu.h>
+#include <arm/cpufunc.h>
+
+#include <arm/marvell/mvsocreg.h>
+#include <arm/marvell/mvsocvar.h>
+#include <evbarm/armadaxp/armadaxpreg.h>
+
+#include <evbarm/marvell/marvellreg.h>
+#include <dev/marvell/marvellreg.h>
+
+extern bus_space_handle_t mpic_cpu_handle;
+
+#define	MPIC_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
+					    mpic_handle, reg, val))
+#define	MPIC_CPU_WRITE(reg, val)	(bus_space_write_4(&mvsoc_bs_tag, \
+					    mpic_cpu_handle, reg, val))
+
+#define	MPIC_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
+					    mpic_handle, reg))
+#define	MPIC_CPU_READ(reg)		(bus_space_read_4(&mvsoc_bs_tag, \
+					    mpic_cpu_handle, reg))
+
+int
+_splraise(int newipl)
+{
+	struct cpu_info * const ci = curcpu();
+	const int oldipl = ci->ci_cpl;
+	int ctp;
+
+	/*
+	 * Disable interrupts in order to avoid disrupt 
+	 * while changing the priority level that may cause
+	 * mismatch between CTP and ci_cpl values.
+	 */
+	register_t psw = disable_interrupts(I32_bit);
+	KASSERT(newipl < NIPL);
+	if (newipl > ci->ci_cpl) {
+		ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
+		ctp &= ~(0xf << MPIC_CTP_SHIFT);
+		ctp |= (newipl << MPIC_CTP_SHIFT);
+		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
+		ci->ci_cpl = newipl;
+	}
+	restore_interrupts(psw);
+
+	return oldipl;
+}
+
+int
+_spllower(int newipl)
+{
+	struct cpu_info * const ci = curcpu();
+	const int oldipl = ci->ci_cpl;
+	int ctp;
+
+	/*
+	 * Disable interrupts in order to avoid disrupt 
+	 * while changing the priority level that may cause
+	 * mismatch between CTP and ci_cpl values.
+	 */
+	register_t psw = disable_interrupts(I32_bit);
+	KASSERT(newipl <= ci->ci_cpl);
+	if (newipl < ci->ci_cpl) {
+		ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
+		ctp &= ~(0xf << MPIC_CTP_SHIFT);
+		ctp |= (newipl << MPIC_CTP_SHIFT);
+		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
+		ci->ci_cpl = newipl;
+	}
+	restore_interrupts(psw);
+
+#ifdef __HAVE_FAST_SOFTINTS
+	cpu_dosoftints();
+#endif
+	return oldipl;
+}
+
+void
+splx(int savedipl)
+{
+	struct cpu_info * const ci = curcpu();
+	int ctp;
+
+	/*
+	 * Disable interrupts in order to avoid disrupt 
+	 * while changing the priority level that may cause
+	 * mismatch between CTP and ci_cpl values.
+	 */
+	register_t psw = disable_interrupts(I32_bit);
+	KASSERT(savedipl < NIPL);
+	if (savedipl != ci->ci_cpl) {
+		ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
+		ctp &= ~(0xf << MPIC_CTP_SHIFT);
+		ctp |= (savedipl << MPIC_CTP_SHIFT);
+		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
+		ci->ci_cpl = savedipl;
+	}
+	restore_interrupts(psw);
+
+#ifdef __HAVE_FAST_SOFTINTS
+	cpu_dosoftints();
+#endif
+}
+

Reply via email to