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
+}
+