Home | History | Annotate | Line # | Download | only in marvell
armadaxp.c revision 1.8.6.1
      1  1.8.6.1     skrll /*	$NetBSD: armadaxp.c,v 1.8.6.1 2015/06/06 14:39:56 skrll Exp $	*/
      2      1.1   rkujawa /*******************************************************************************
      3      1.1   rkujawa Copyright (C) Marvell International Ltd. and its affiliates
      4      1.1   rkujawa 
      5      1.1   rkujawa Developed by Semihalf
      6      1.1   rkujawa 
      7      1.1   rkujawa ********************************************************************************
      8      1.1   rkujawa Marvell BSD License
      9      1.1   rkujawa 
     10      1.1   rkujawa If you received this File from Marvell, you may opt to use, redistribute and/or
     11      1.1   rkujawa modify this File under the following licensing terms.
     12      1.1   rkujawa Redistribution and use in source and binary forms, with or without modification,
     13      1.1   rkujawa are permitted provided that the following conditions are met:
     14      1.1   rkujawa 
     15      1.1   rkujawa     *   Redistributions of source code must retain the above copyright notice,
     16      1.1   rkujawa             this list of conditions and the following disclaimer.
     17      1.1   rkujawa 
     18      1.1   rkujawa     *   Redistributions in binary form must reproduce the above copyright
     19      1.1   rkujawa         notice, this list of conditions and the following disclaimer in the
     20      1.1   rkujawa         documentation and/or other materials provided with the distribution.
     21      1.1   rkujawa 
     22      1.1   rkujawa     *   Neither the name of Marvell nor the names of its contributors may be
     23      1.1   rkujawa         used to endorse or promote products derived from this software without
     24      1.1   rkujawa         specific prior written permission.
     25      1.1   rkujawa 
     26      1.1   rkujawa THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     27      1.1   rkujawa ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     28      1.1   rkujawa WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     29      1.1   rkujawa DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     30      1.1   rkujawa ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     31      1.1   rkujawa (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     32      1.1   rkujawa LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     33      1.1   rkujawa ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     34      1.1   rkujawa (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     35      1.1   rkujawa SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     36      1.1   rkujawa 
     37      1.1   rkujawa *******************************************************************************/
     38      1.1   rkujawa 
     39      1.1   rkujawa #include <sys/cdefs.h>
     40  1.8.6.1     skrll __KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.8.6.1 2015/06/06 14:39:56 skrll Exp $");
     41      1.1   rkujawa 
     42      1.1   rkujawa #define _INTR_PRIVATE
     43      1.1   rkujawa 
     44      1.1   rkujawa #include "opt_mvsoc.h"
     45      1.1   rkujawa 
     46      1.1   rkujawa #include <sys/param.h>
     47      1.1   rkujawa #include <sys/bus.h>
     48      1.1   rkujawa 
     49      1.1   rkujawa #include <machine/intr.h>
     50      1.1   rkujawa 
     51      1.1   rkujawa #include <arm/pic/picvar.h>
     52      1.1   rkujawa 
     53      1.1   rkujawa #include <arm/armreg.h>
     54      1.1   rkujawa #include <arm/cpu.h>
     55      1.1   rkujawa #include <arm/cpufunc.h>
     56      1.1   rkujawa 
     57      1.1   rkujawa #include <arm/marvell/mvsocreg.h>
     58      1.1   rkujawa #include <arm/marvell/mvsocvar.h>
     59      1.3  kiyohara #include <arm/marvell/armadaxpreg.h>
     60  1.8.6.1     skrll #include <arm/marvell/armadaxpvar.h>
     61      1.1   rkujawa 
     62      1.1   rkujawa #include <dev/marvell/marvellreg.h>
     63      1.1   rkujawa 
     64      1.7  kiyohara #define EXTRACT_XP_CPU_FREQ_FIELD(sar)	(((0x01 & (sar >> 52)) << 3) | \
     65      1.1   rkujawa 					    (0x07 & (sar >> 21)))
     66      1.7  kiyohara #define EXTRACT_XP_FAB_FREQ_FIELD(sar)	(((0x01 & (sar >> 51)) << 4) | \
     67      1.1   rkujawa 					    (0x0F & (sar >> 24)))
     68      1.7  kiyohara #define EXTRACT_370_CPU_FREQ_FIELD(sar)	((sar >> 11) & 0xf)
     69      1.7  kiyohara #define EXTRACT_370_FAB_FREQ_FIELD(sar)	((sar >> 15) & 0x1f)
     70      1.1   rkujawa 
     71      1.1   rkujawa #define	MPIC_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
     72      1.1   rkujawa 					    mpic_handle, reg, val))
     73      1.1   rkujawa #define	MPIC_CPU_WRITE(reg, val)	(bus_space_write_4(&mvsoc_bs_tag, \
     74      1.1   rkujawa 					    mpic_cpu_handle, reg, val))
     75      1.1   rkujawa 
     76      1.1   rkujawa #define	MPIC_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
     77      1.1   rkujawa 					    mpic_handle, reg))
     78      1.1   rkujawa #define	MPIC_CPU_READ(reg)		(bus_space_read_4(&mvsoc_bs_tag, \
     79      1.1   rkujawa 					    mpic_cpu_handle, reg))
     80      1.1   rkujawa 
     81      1.1   rkujawa #define	L2_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
     82      1.1   rkujawa 					    l2_handle, reg, val))
     83      1.1   rkujawa #define	L2_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
     84      1.1   rkujawa 					    l2_handle, reg))
     85      1.1   rkujawa bus_space_handle_t mpic_cpu_handle;
     86      1.1   rkujawa static bus_space_handle_t mpic_handle, l2_handle;
     87      1.1   rkujawa int l2cache_state = 0;
     88      1.1   rkujawa int iocc_state = 0;
     89      1.5  kiyohara #define read_miscreg(r)		(*(volatile uint32_t *)(misc_base + (r)))
     90      1.5  kiyohara vaddr_t misc_base;
     91  1.8.6.1     skrll vaddr_t armadaxp_l2_barrier_reg;
     92      1.1   rkujawa 
     93      1.1   rkujawa extern void (*mvsoc_intr_init)(void);
     94      1.1   rkujawa static void armadaxp_intr_init(void);
     95      1.1   rkujawa 
     96      1.1   rkujawa static void armadaxp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     97      1.1   rkujawa static void armadaxp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     98      1.1   rkujawa static void armadaxp_pic_establish_irq(struct pic_softc *, struct intrsource *);
     99      1.4  kiyohara static void armadaxp_pic_set_priority(struct pic_softc *, int);
    100  1.8.6.1     skrll static void armadaxp_pic_source_name(struct pic_softc *, int, char*, size_t);
    101      1.1   rkujawa 
    102      1.4  kiyohara static int armadaxp_find_pending_irqs(void);
    103      1.4  kiyohara static void armadaxp_pic_block_irq(struct pic_softc *, size_t);
    104  1.8.6.1     skrll 
    105  1.8.6.1     skrll /* handle error cause */
    106  1.8.6.1     skrll static void armadaxp_err_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
    107  1.8.6.1     skrll static void armadaxp_err_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
    108  1.8.6.1     skrll static void armadaxp_err_pic_establish_irq(struct pic_softc *,
    109  1.8.6.1     skrll     struct intrsource *);
    110  1.8.6.1     skrll static void armadaxp_err_pic_source_name(struct pic_softc *,
    111  1.8.6.1     skrll     int, char*, size_t);
    112  1.8.6.1     skrll static int armadaxp_err_pic_pending_irqs(struct pic_softc *);
    113      1.1   rkujawa 
    114      1.1   rkujawa struct vco_freq_ratio {
    115      1.1   rkujawa 	uint8_t	vco_cpu;	/* VCO to CLK0(CPU) clock ratio */
    116      1.1   rkujawa 	uint8_t	vco_l2c;	/* VCO to NB(L2 cache) clock ratio */
    117      1.1   rkujawa 	uint8_t	vco_hcl;	/* VCO to HCLK(DDR controller) clock ratio */
    118      1.1   rkujawa 	uint8_t	vco_ddr;	/* VCO to DR(DDR memory) clock ratio */
    119      1.1   rkujawa };
    120      1.1   rkujawa 
    121  1.8.6.1     skrll /*
    122  1.8.6.1     skrll  * Interrupt names for ARMADA XP
    123  1.8.6.1     skrll  */
    124  1.8.6.1     skrll static const char * const armadaxp_pic_source_names[] = {
    125  1.8.6.1     skrll 	/* Main Interrupt Cause Per-CPU (IRQ 0-29) */
    126  1.8.6.1     skrll 	"InDBLowSum", "InDBHighSum", "OutDBSum", "CFU_LocalSum",
    127  1.8.6.1     skrll 	"SoC_ErrorSum", "LTimer0", "LTimer1", "LWDT", "GbE0_TH_RxTx",
    128  1.8.6.1     skrll 	"GbE0_RxTx", "GbE1_RxTxTh", "GbE1_RxTx", "GbE2_RxTxTh", "GbE2_RxTx",
    129  1.8.6.1     skrll 	"GbE3_RxTxTh", "GbE3_RxTx", "GPIO0_7", "GPIO8_15", "GPIO16_23",
    130  1.8.6.1     skrll 	"GPIO24_31", "GPIO32_39", "GPIO40_47", "GPIO48_55", "GPIO56_63",
    131  1.8.6.1     skrll 	"GPIO64_66", "SCNT", "PCNT", "Reserved27", "VCNT", "Reserved29",
    132  1.8.6.1     skrll 	/* Main Interrupt Cause Global-Shared (IRQ 30-115) */
    133  1.8.6.1     skrll 	"SPI0", "I2C0", "I2C1", "IDMA0", "IDMA1", "IDMA2", "IDMA3", "GTimer0",
    134  1.8.6.1     skrll 	"GTimer1", "GTimer2", "GTimer3", "UART0", "UART1", "UART2", "UART3",
    135  1.8.6.1     skrll 	"USB0", "USB1", "USB2", "CESA0", "CESA1", "RTC", "XOR0_Ch0",
    136  1.8.6.1     skrll 	"XOR0_Ch1", "BM", "SDIO", "SATA0", "TDM", "SATA1", "PEX0_0", "PEX0_1",
    137  1.8.6.1     skrll 	"PEX0_2", "PEX0_3", "PEX1_0", "PEX1_1", "PEX1_2", "PEX1_3",
    138  1.8.6.1     skrll 	"GbE0_Sum", "GbE0_Rx", "GbE0_Tx", "GbE0_Misc", "GbE1_Sum", "GbE1_Rx",
    139  1.8.6.1     skrll 	"GbE1_Tx", "GbE1_Misc", "GbE2_Sum", "GbE2_Rx", "GbE2_Tx", "GbE2_Misc",
    140  1.8.6.1     skrll 	"GbE3_Sum", "GbE3_Rx", "GbE3_Tx", "GbE3_Misc", "GPIO0_7", "GPIO8_15",
    141  1.8.6.1     skrll 	"GPIO16_23", "GPIO24_31", "Reserved86", "GPIO32_39", "GPIO40_47",
    142  1.8.6.1     skrll 	"GPIO48_55", "GPIO56_63", "GPIO64_66", "SPI1", "WDT", "XOR1_Ch2",
    143  1.8.6.1     skrll 	"XOR1_Ch3", "SharedDB1Sum", "SharedDB2Sum", "SharedDB3Sum", "PEX2_0",
    144  1.8.6.1     skrll 	"Reserved100", "Reserved101", "Reserved102", "PEX3_0", "Reserved104",
    145  1.8.6.1     skrll 	"Reserved105", "Reserved106", "PMU", "DRAM", "GbE0_Wakeup",
    146  1.8.6.1     skrll 	"GbE1_Wakeup", "GbE2_Wakeup", "GbE3_Wakeup", "NAND", "Reserved114",
    147  1.8.6.1     skrll 	"Reserved115"
    148  1.8.6.1     skrll };
    149  1.8.6.1     skrll static const char * const armadaxp_err_pic_source_names[] = {
    150  1.8.6.1     skrll 	/*
    151  1.8.6.1     skrll 	 * IRQ 120-151 (bit 0-31 in SoC Error Interrupt Cause register)
    152  1.8.6.1     skrll 	 * connected to SoC_ErrorSum in Main Interrupt Cause
    153  1.8.6.1     skrll 	 */
    154  1.8.6.1     skrll 	"ERR_CESA0", "ERR_DevBus", "ERR_IDMA", "ERR_XOR1",
    155  1.8.6.1     skrll 	"ERR_PEX0", "ERR_PEX1", "ERR_GbE", "ERR_CESA1",
    156  1.8.6.1     skrll 	"ERR_USB", "ERR_DRAM", "ERR_XOR0", "ERR_Reserved11",
    157  1.8.6.1     skrll 	"ERR_BM", "ERR_CIB", "ERR_Reserved14", "ERR_PEX2",
    158  1.8.6.1     skrll 	"ERR_PEX3", "ERR_SATA0", "ERR_SATA1", "ERR_Reserved19",
    159  1.8.6.1     skrll 	"ERR_TDM", "ERR_NAND", "ERR_Reserved22",
    160  1.8.6.1     skrll 	"ERR_Reserved23", "ERR_Reserved24", "ERR_Reserved25",
    161  1.8.6.1     skrll 	"ERR_Reserved26", "ERR_Reserved27", "ERR_Reserved28",
    162  1.8.6.1     skrll 	"ERR_Reserved29", "ERR_Reserved30", "ERR_Reserved31",
    163  1.8.6.1     skrll };
    164  1.8.6.1     skrll 
    165  1.8.6.1     skrll /*
    166  1.8.6.1     skrll  * Mbus Target and Attribute bindings for ARMADA XP
    167  1.8.6.1     skrll  */
    168  1.8.6.1     skrll static struct mbus_description {
    169  1.8.6.1     skrll 	uint8_t target;
    170  1.8.6.1     skrll 	uint8_t attr;
    171  1.8.6.1     skrll 	const char *string;
    172  1.8.6.1     skrll } mbus_desc[] = {
    173  1.8.6.1     skrll 	/* DDR */
    174  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0,
    175  1.8.6.1     skrll 	       	"DDR(M_CS[0])" },
    176  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS1,
    177  1.8.6.1     skrll 	       	"DDR(M_CS[1])" },
    178  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS2,
    179  1.8.6.1     skrll 	       	"DDR(M_CS[2])" },
    180  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS3,
    181  1.8.6.1     skrll 	       	"DDR(M_CS[3])" },
    182  1.8.6.1     skrll 
    183  1.8.6.1     skrll 	/* DEVBUS */
    184  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0,
    185  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS0)" },
    186  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS1,
    187  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS1)" },
    188  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS2,
    189  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS2)" },
    190  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS3,
    191  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS3)" },
    192  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS4,
    193  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS4)" },
    194  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS5,
    195  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS5)" },
    196  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS6,
    197  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS6)" },
    198  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS7,
    199  1.8.6.1     skrll 	       	"DEVBUS(SPI0 CS7)" },
    200  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS0,
    201  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS0)" },
    202  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS1,
    203  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS1)" },
    204  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS2,
    205  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS2)" },
    206  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS3,
    207  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS3)" },
    208  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS4,
    209  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS4)" },
    210  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS5,
    211  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS5)" },
    212  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS6,
    213  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS6)" },
    214  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS7,
    215  1.8.6.1     skrll 	       	"DEVBUS(SPI1 CS7)" },
    216  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0,
    217  1.8.6.1     skrll 	       	"DEVBUS(DevCS[0])" },
    218  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1,
    219  1.8.6.1     skrll 	       	"DEVBUS(DevCS[1])" },
    220  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2,
    221  1.8.6.1     skrll 	       	"DEVBUS(DevCS[2])" },
    222  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS3,
    223  1.8.6.1     skrll 	       	"DEVBUS(DevCS[3])" },
    224  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS,
    225  1.8.6.1     skrll 	       	"DEVBUS(BootCS)" },
    226  1.8.6.1     skrll 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM,
    227  1.8.6.1     skrll 	       	"DEVBUS(BootROM)" },
    228  1.8.6.1     skrll 
    229  1.8.6.1     skrll 	/* GbE */
    230  1.8.6.1     skrll 	{ ARMADAXP_UNITID_GBE0, ARMADAXP_ATTR_GBE_RESERVED,
    231  1.8.6.1     skrll 	       	"GBE0 GBE1" },
    232  1.8.6.1     skrll 	{ ARMADAXP_UNITID_GBE2, ARMADAXP_ATTR_GBE_RESERVED,
    233  1.8.6.1     skrll 	       	"GBE2 GBE3" },
    234  1.8.6.1     skrll 
    235  1.8.6.1     skrll 	/* PEX(PCIe) */
    236  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM,
    237  1.8.6.1     skrll 	       	"PEX0(Lane0, Memory)" },
    238  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM,
    239  1.8.6.1     skrll 	       	"PEX0(Lane1, Memory)" },
    240  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM,
    241  1.8.6.1     skrll 	       	"PEX0(Lane2, Memory)" },
    242  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM,
    243  1.8.6.1     skrll 	       	"PEX0(Lane3, Memory)" },
    244  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEX2_MEM,
    245  1.8.6.1     skrll 	       	"PEX2(Lane0, Memory)" },
    246  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM,
    247  1.8.6.1     skrll 	       	"PEX1(Lane0, Memory)" },
    248  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_MEM,
    249  1.8.6.1     skrll 	       	"PEX1(Lane1, Memory)" },
    250  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_MEM,
    251  1.8.6.1     skrll 	       	"PEX1(Lane2, Memory)" },
    252  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_MEM,
    253  1.8.6.1     skrll 	       	"PEX1(Lane3, Memory)" },
    254  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEX2_MEM,
    255  1.8.6.1     skrll 	       	"PEX3(Lane0, Memory)" },
    256  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO,
    257  1.8.6.1     skrll 	       	"PEX0(Lane0, I/O)" },
    258  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_IO,
    259  1.8.6.1     skrll 	       	"PEX0(Lane1, I/O)" },
    260  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_IO,
    261  1.8.6.1     skrll 	       	"PEX0(Lane2, I/O)" },
    262  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_IO,
    263  1.8.6.1     skrll 	       	"PEX0(Lane3, I/O)" },
    264  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEX2_IO,
    265  1.8.6.1     skrll 	       	"PEX2(Lane0, I/O)" },
    266  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_IO,
    267  1.8.6.1     skrll 	       	"PEX1(Lane0, I/O)" },
    268  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_IO,
    269  1.8.6.1     skrll 	       	"PEX1(Lane1, I/O)" },
    270  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_IO,
    271  1.8.6.1     skrll 	       	"PEX1(Lane2, I/O)" },
    272  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_IO,
    273  1.8.6.1     skrll 	       	"PEX1(Lane3, I/O)" },
    274  1.8.6.1     skrll 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEX2_IO,
    275  1.8.6.1     skrll 	       	"PEX3(Lane0, I/O)" },
    276  1.8.6.1     skrll 
    277  1.8.6.1     skrll 	/* CRYPT */
    278  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP,
    279  1.8.6.1     skrll 	       	"CESA0(No swap)" },
    280  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE,
    281  1.8.6.1     skrll 	       	"CESA0(Byte swap)" },
    282  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE_WORD,
    283  1.8.6.1     skrll 	       	"CESA0(Byte and word swap)" },
    284  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_WORD,
    285  1.8.6.1     skrll 	       	"CESA0(Word swap)" },
    286  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP,
    287  1.8.6.1     skrll 	       	"CESA1(No swap)" },
    288  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE,
    289  1.8.6.1     skrll 	       	"CESA1(Byte swap)" },
    290  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE_WORD,
    291  1.8.6.1     skrll 	       	"CESA1(Byte and word swap)" },
    292  1.8.6.1     skrll 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_WORD,
    293  1.8.6.1     skrll 	       	"CESA1(Word swap)" },
    294  1.8.6.1     skrll 
    295  1.8.6.1     skrll 	/* BM */
    296  1.8.6.1     skrll 	{ ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED,
    297  1.8.6.1     skrll 		"BM" },
    298  1.8.6.1     skrll 
    299  1.8.6.1     skrll 	/* NAND */
    300  1.8.6.1     skrll 	{ ARMADAXP_UNITID_NAND, ARMADAXP_ATTR_NAND_RESERVED,
    301  1.8.6.1     skrll 		"NAND" },
    302  1.8.6.1     skrll };
    303  1.8.6.1     skrll 
    304  1.8.6.1     skrll /*
    305  1.8.6.1     skrll  * Default Mbus addrss decoding table for ARMADA XP
    306  1.8.6.1     skrll  * this table may changed by device drivers.
    307  1.8.6.1     skrll  *
    308  1.8.6.1     skrll  * NOTE: some version of u-boot is broken. it writes old decoding table.
    309  1.8.6.1     skrll  *       probably, it's designed for Kirkwood SoC or older. we need to restore
    310  1.8.6.1     skrll  *       ARMADA XP's parameter set.
    311  1.8.6.1     skrll  */
    312  1.8.6.1     skrll static struct mbus_table_def {
    313  1.8.6.1     skrll 	int window;	/* index of address decoding window registers */
    314  1.8.6.1     skrll 	uint32_t base;	/* base address of the window */
    315  1.8.6.1     skrll 	uint32_t size;	/* size of the window */
    316  1.8.6.1     skrll 	uint8_t target;	/* target unit of the window */
    317  1.8.6.1     skrll 	uint8_t attr;	/* target attribute of the window */
    318  1.8.6.1     skrll } mbus_table[] = {
    319  1.8.6.1     skrll 	/*
    320  1.8.6.1     skrll 	 * based on 'default address mapping' described in Marvell's document
    321  1.8.6.1     skrll 	 * 'ARMADA XP Functional Specifications.'
    322  1.8.6.1     skrll 	 *
    323  1.8.6.1     skrll 	 * some windows are modified to get compatibility with old codes.
    324  1.8.6.1     skrll 	 */
    325  1.8.6.1     skrll 	{
    326  1.8.6.1     skrll 		/* PCIe 0 lane0 MEM */
    327  1.8.6.1     skrll 		/* MODIFIED (moved to MARVELL_PEXMEM_PBASE) */
    328  1.8.6.1     skrll 		 0, 0xe0000000, 0x01000000,
    329  1.8.6.1     skrll 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM
    330  1.8.6.1     skrll 	},
    331  1.8.6.1     skrll 	{
    332  1.8.6.1     skrll 		/* PCIe 0 lane1 MEM */
    333  1.8.6.1     skrll 		 1, 0x88000000, 0x08000000,
    334  1.8.6.1     skrll 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM
    335  1.8.6.1     skrll 	},
    336  1.8.6.1     skrll 	{
    337  1.8.6.1     skrll 		/* PCIe 0 lane2 MEM */
    338  1.8.6.1     skrll 		 2, 0x90000000, 0x08000000,
    339  1.8.6.1     skrll 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM
    340  1.8.6.1     skrll 	},
    341  1.8.6.1     skrll 	{
    342  1.8.6.1     skrll 		/* PCIe 0 lane3 MEM */
    343  1.8.6.1     skrll 		 3, 0x98000000, 0x08000000,
    344  1.8.6.1     skrll 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM
    345  1.8.6.1     skrll 	},
    346  1.8.6.1     skrll 	{
    347  1.8.6.1     skrll 		/* PCIe 1 lane0 MEM */
    348  1.8.6.1     skrll 		 4, 0xa0000000, 0x08000000,
    349  1.8.6.1     skrll 		 ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM
    350  1.8.6.1     skrll 	},
    351  1.8.6.1     skrll 	{	5, 0, 0, 0, 0 /* disabled */ },
    352  1.8.6.1     skrll 	{	6, 0, 0, 0, 0 /* disabled */ },
    353  1.8.6.1     skrll 	{	7, 0, 0, 0, 0 /* disabled */ },
    354  1.8.6.1     skrll 	{
    355  1.8.6.1     skrll 		/* Security Accelerator SRAM, Engine 0, no data swap */
    356  1.8.6.1     skrll 		 8, 0xc8010000, 0x00010000,
    357  1.8.6.1     skrll 		 ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP,
    358  1.8.6.1     skrll 	},
    359  1.8.6.1     skrll 	{
    360  1.8.6.1     skrll 		/* Device bus, BOOT_CS */
    361  1.8.6.1     skrll 		 9, 0xd8000000, 0x08000000,
    362  1.8.6.1     skrll 		 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS,
    363  1.8.6.1     skrll 	},
    364  1.8.6.1     skrll 	{
    365  1.8.6.1     skrll 		/* Device bus, DEV_CS[0] */
    366  1.8.6.1     skrll 		/* MODIFIED (moved, conflict to MARVELL_PEXMEM_PBASE here.) */
    367  1.8.6.1     skrll 		10, 0x80000000, 0x08000000,
    368  1.8.6.1     skrll 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0
    369  1.8.6.1     skrll 	},
    370  1.8.6.1     skrll 	{
    371  1.8.6.1     skrll 		/* Device bus, DEV_CS[1] */
    372  1.8.6.1     skrll 		11, 0xe8000000, 0x08000000,
    373  1.8.6.1     skrll 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1
    374  1.8.6.1     skrll 	},
    375  1.8.6.1     skrll 	{
    376  1.8.6.1     skrll 		/* Device bus, DEV_CS[2] */
    377  1.8.6.1     skrll 		/* MODIFIED: (disabled, conflict to MARVELL_PEXIO_PBASE) */
    378  1.8.6.1     skrll 		12, 0xf0000000, 0x00000000,
    379  1.8.6.1     skrll 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2
    380  1.8.6.1     skrll 	},
    381  1.8.6.1     skrll 	{
    382  1.8.6.1     skrll 		/* Device bus, BOOT_ROM */
    383  1.8.6.1     skrll 		13, 0xf8000000, 0x08000000,
    384  1.8.6.1     skrll 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM
    385  1.8.6.1     skrll 	},
    386  1.8.6.1     skrll 	{
    387  1.8.6.1     skrll 		/* Device bus, SPI0_CS[0] */
    388  1.8.6.1     skrll 		14, 0xd4000000, 0x04000000,
    389  1.8.6.1     skrll 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0
    390  1.8.6.1     skrll 	},
    391  1.8.6.1     skrll 	{
    392  1.8.6.1     skrll 		/* Security Accelerator SRAM, Engine 1, no data swap */
    393  1.8.6.1     skrll 		/* MODIFIED (added, 0xd0300000-0xd030ffff) */
    394  1.8.6.1     skrll 		15, 0xd0300000, 0x00010000,
    395  1.8.6.1     skrll 	       	ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP
    396  1.8.6.1     skrll 	},
    397  1.8.6.1     skrll 	{
    398  1.8.6.1     skrll 		/* PCIe 0 lane 0 I/O */
    399  1.8.6.1     skrll 		/* MODIFIED (added, MARVELL_PEXIO_PBASE) */
    400  1.8.6.1     skrll 		16, 0xf2000000, 0x00100000,
    401  1.8.6.1     skrll 	       	ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO
    402  1.8.6.1     skrll        	},
    403  1.8.6.1     skrll 	{	17, 0xd0320000, 0, 0, 0 /* disabled */ },
    404  1.8.6.1     skrll 	{
    405  1.8.6.1     skrll 		/* Buffer Manamgement unit */
    406  1.8.6.1     skrll 		18, 0xd3800000, 0x00800000,
    407  1.8.6.1     skrll 		ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED
    408  1.8.6.1     skrll 	},
    409  1.8.6.1     skrll 	{
    410  1.8.6.1     skrll 		/* DDR */
    411  1.8.6.1     skrll 		/* MODIFIED (up to 2GB memory space) */
    412  1.8.6.1     skrll 		19, 0x00000000, 0x80000000,
    413  1.8.6.1     skrll 		ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0
    414  1.8.6.1     skrll 	},
    415  1.8.6.1     skrll 
    416  1.8.6.1     skrll };
    417  1.8.6.1     skrll 
    418      1.1   rkujawa static struct vco_freq_ratio freq_conf_table[] = {
    419      1.1   rkujawa /*00*/	{ 1, 1,	 4,  2 },
    420      1.1   rkujawa /*01*/	{ 1, 2,	 2,  2 },
    421      1.1   rkujawa /*02*/	{ 2, 2,	 6,  3 },
    422      1.1   rkujawa /*03*/	{ 2, 2,	 3,  3 },
    423      1.1   rkujawa /*04*/	{ 1, 2,	 3,  3 },
    424      1.1   rkujawa /*05*/	{ 1, 2,	 4,  2 },
    425      1.1   rkujawa /*06*/	{ 1, 1,	 2,  2 },
    426      1.1   rkujawa /*07*/	{ 2, 3,	 6,  6 },
    427      1.1   rkujawa /*08*/	{ 2, 3,	 5,  5 },
    428      1.1   rkujawa /*09*/	{ 1, 2,	 6,  3 },
    429      1.1   rkujawa /*10*/	{ 2, 4,	10,  5 },
    430      1.1   rkujawa /*11*/	{ 1, 3,	 6,  6 },
    431      1.1   rkujawa /*12*/	{ 1, 2,	 5,  5 },
    432      1.1   rkujawa /*13*/	{ 1, 3,	 6,  3 },
    433      1.1   rkujawa /*14*/	{ 1, 2,	 5,  5 },
    434      1.1   rkujawa /*15*/	{ 2, 2,	 5,  5 },
    435      1.1   rkujawa /*16*/	{ 1, 1,	 3,  3 },
    436      1.1   rkujawa /*17*/	{ 2, 5,	10, 10 },
    437      1.1   rkujawa /*18*/	{ 1, 3,	 8,  4 },
    438      1.1   rkujawa /*19*/	{ 1, 1,	 2,  1 },
    439      1.1   rkujawa /*20*/	{ 2, 3,	 6,  3 },
    440      1.1   rkujawa /*21*/	{ 1, 2,	 8,  4 },
    441      1.1   rkujawa /*22*/	{ 2, 5,	10,  5 }
    442      1.1   rkujawa };
    443      1.1   rkujawa 
    444      1.7  kiyohara static uint16_t clock_table_xp[] = {
    445      1.7  kiyohara 	1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000,
    446      1.7  kiyohara 	 600,  667,  800, 1600, 2133, 2200, 2400
    447      1.7  kiyohara };
    448      1.7  kiyohara static uint16_t clock_table_370[] = {
    449      1.7  kiyohara 	 400,  533,  667,  800, 1000, 1067, 1200, 1333,
    450      1.7  kiyohara 	1500, 1600, 1667, 1800, 2000,  333,  600,  900,
    451      1.7  kiyohara 	   0
    452      1.7  kiyohara };
    453      1.1   rkujawa 
    454      1.1   rkujawa static struct pic_ops armadaxp_picops = {
    455      1.1   rkujawa 	.pic_unblock_irqs = armadaxp_pic_unblock_irqs,
    456      1.1   rkujawa 	.pic_block_irqs = armadaxp_pic_block_irqs,
    457      1.1   rkujawa 	.pic_establish_irq = armadaxp_pic_establish_irq,
    458      1.4  kiyohara 	.pic_set_priority = armadaxp_pic_set_priority,
    459  1.8.6.1     skrll 	.pic_source_name = armadaxp_pic_source_name,
    460      1.1   rkujawa };
    461      1.1   rkujawa 
    462      1.1   rkujawa static struct pic_softc armadaxp_pic = {
    463      1.1   rkujawa 	.pic_ops = &armadaxp_picops,
    464      1.1   rkujawa 	.pic_name = "armadaxp",
    465      1.1   rkujawa };
    466      1.1   rkujawa 
    467  1.8.6.1     skrll static struct pic_ops armadaxp_err_picops = {
    468  1.8.6.1     skrll 	.pic_unblock_irqs = armadaxp_err_pic_unblock_irqs,
    469  1.8.6.1     skrll 	.pic_block_irqs = armadaxp_err_pic_block_irqs,
    470  1.8.6.1     skrll 	.pic_establish_irq = armadaxp_err_pic_establish_irq,
    471  1.8.6.1     skrll 	.pic_find_pending_irqs = armadaxp_err_pic_pending_irqs,
    472  1.8.6.1     skrll 	.pic_source_name = armadaxp_err_pic_source_name,
    473  1.8.6.1     skrll };
    474  1.8.6.1     skrll 
    475  1.8.6.1     skrll static struct pic_softc armadaxp_err_pic = {
    476  1.8.6.1     skrll 	.pic_ops = &armadaxp_err_picops,
    477  1.8.6.1     skrll 	.pic_name = "armadaxp_err",
    478  1.8.6.1     skrll };
    479  1.8.6.1     skrll 
    480      1.6  kiyohara static struct {
    481      1.6  kiyohara 	bus_size_t offset;
    482      1.6  kiyohara 	uint32_t bits;
    483      1.6  kiyohara } clkgatings[]= {
    484      1.6  kiyohara 	{ ARMADAXP_GBE3_BASE,	(1 << 1) },
    485      1.6  kiyohara 	{ ARMADAXP_GBE2_BASE,	(1 << 2) },
    486      1.6  kiyohara 	{ ARMADAXP_GBE1_BASE,	(1 << 3) },
    487      1.6  kiyohara 	{ ARMADAXP_GBE0_BASE,	(1 << 4) },
    488      1.6  kiyohara 	{ MVSOC_PEX_BASE,	(1 << 5) },
    489      1.6  kiyohara 	{ ARMADAXP_PEX01_BASE,	(1 << 6) },
    490      1.6  kiyohara 	{ ARMADAXP_PEX02_BASE,	(1 << 7) },
    491      1.6  kiyohara 	{ ARMADAXP_PEX03_BASE,	(1 << 8) },
    492      1.6  kiyohara 	{ ARMADAXP_PEX10_BASE,	(1 << 9) },
    493      1.6  kiyohara 	{ ARMADAXP_PEX11_BASE,	(1 << 10) },
    494      1.6  kiyohara 	{ ARMADAXP_PEX12_BASE,	(1 << 11) },
    495      1.6  kiyohara 	{ ARMADAXP_PEX13_BASE,	(1 << 12) },
    496      1.6  kiyohara #if 0
    497      1.6  kiyohara 	{ NetA, (1 << 13) },
    498      1.6  kiyohara #endif
    499      1.6  kiyohara 	{ ARMADAXP_SATAHC_BASE,	(1 << 14) | (1 << 15) | (1 << 29) | (1 << 30) },
    500      1.6  kiyohara 	{ ARMADAXP_LCD_BASE,	(1 << 16) },
    501      1.6  kiyohara 	{ ARMADAXP_SDIO_BASE,	(1 << 17) },
    502      1.6  kiyohara 	{ ARMADAXP_USB1_BASE,	(1 << 19) },
    503      1.6  kiyohara 	{ ARMADAXP_USB2_BASE,	(1 << 20) },
    504  1.8.6.1     skrll 	{ ARMADAXP_CESA0_BASE,	(1 << 23) },
    505  1.8.6.1     skrll 	{ ARMADAXP_CESA1_BASE,	(1 << 23) },
    506      1.6  kiyohara 	{ ARMADAXP_PEX2_BASE,	(1 << 26) },
    507      1.6  kiyohara 	{ ARMADAXP_PEX3_BASE,	(1 << 27) },
    508      1.6  kiyohara #if 0
    509      1.6  kiyohara 	{ DDR, (1 << 28) },
    510      1.6  kiyohara #endif
    511      1.6  kiyohara };
    512      1.6  kiyohara 
    513      1.1   rkujawa /*
    514      1.1   rkujawa  * armadaxp_intr_bootstrap:
    515      1.1   rkujawa  *
    516      1.1   rkujawa  *	Initialize the rest of the interrupt subsystem, making it
    517      1.1   rkujawa  *	ready to handle interrupts from devices.
    518      1.1   rkujawa  */
    519      1.1   rkujawa void
    520      1.3  kiyohara armadaxp_intr_bootstrap(bus_addr_t pbase)
    521      1.1   rkujawa {
    522      1.1   rkujawa 	int i;
    523      1.1   rkujawa 
    524      1.1   rkujawa 	/* Map MPIC base and MPIC percpu base registers */
    525      1.3  kiyohara 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_BASE,
    526      1.3  kiyohara 	    0x500, 0, &mpic_handle) != 0)
    527      1.1   rkujawa 		panic("%s: Could not map MPIC registers", __func__);
    528      1.3  kiyohara 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_CPU_BASE,
    529      1.3  kiyohara 	    0x800, 0, &mpic_cpu_handle) != 0)
    530      1.1   rkujawa 		panic("%s: Could not map MPIC percpu registers", __func__);
    531      1.1   rkujawa 
    532      1.1   rkujawa 	/* Disable all interrupts */
    533  1.8.6.1     skrll 	for (i = 0; i < ARMADAXP_IRQ_SOURCES; i++)
    534      1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, i);
    535      1.1   rkujawa 
    536      1.1   rkujawa 	mvsoc_intr_init = armadaxp_intr_init;
    537      1.1   rkujawa }
    538      1.1   rkujawa 
    539      1.1   rkujawa static void
    540      1.1   rkujawa armadaxp_intr_init(void)
    541      1.1   rkujawa {
    542      1.1   rkujawa 	int ctrl;
    543  1.8.6.1     skrll 	void *ih __diagused;
    544      1.1   rkujawa 
    545      1.1   rkujawa 	/* Get max interrupts */
    546      1.1   rkujawa 	armadaxp_pic.pic_maxsources =
    547      1.1   rkujawa 	    ((MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL) >> 2) & 0x7FF);
    548      1.1   rkujawa 
    549      1.1   rkujawa 	if (!armadaxp_pic.pic_maxsources)
    550  1.8.6.1     skrll 		armadaxp_pic.pic_maxsources = ARMADAXP_IRQ_SOURCES;
    551      1.1   rkujawa 
    552      1.1   rkujawa 	pic_add(&armadaxp_pic, 0);
    553      1.1   rkujawa 
    554  1.8.6.1     skrll 	/* Chain error interrupts controller */
    555  1.8.6.1     skrll 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, 0);
    556  1.8.6.1     skrll 	armadaxp_err_pic.pic_maxsources = ARMADAXP_IRQ_ERROR_SOURCES;
    557  1.8.6.1     skrll 	pic_add(&armadaxp_err_pic, ARMADAXP_IRQ_ERROR_BASE);
    558  1.8.6.1     skrll 	ih = intr_establish(ARMADAXP_IRQ_ERR_SUMMARY, IPL_HIGH, IST_LEVEL_HIGH,
    559  1.8.6.1     skrll 	    pic_handle_intr, &armadaxp_err_pic);
    560  1.8.6.1     skrll 	KASSERT(ih != NULL);
    561  1.8.6.1     skrll 
    562      1.1   rkujawa 	ctrl = MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL);
    563      1.1   rkujawa 	/* Enable IRQ prioritization */
    564      1.1   rkujawa 	ctrl |= (1 << 0);
    565      1.1   rkujawa 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_CTRL, ctrl);
    566      1.4  kiyohara 
    567      1.4  kiyohara 	find_pending_irqs = armadaxp_find_pending_irqs;
    568      1.1   rkujawa }
    569      1.1   rkujawa 
    570      1.1   rkujawa static void
    571      1.1   rkujawa armadaxp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    572      1.1   rkujawa     uint32_t irq_mask)
    573      1.1   rkujawa {
    574      1.1   rkujawa 	int n;
    575      1.1   rkujawa 
    576      1.1   rkujawa 	while (irq_mask != 0) {
    577      1.1   rkujawa 		n = ffs(irq_mask) - 1;
    578      1.1   rkujawa 		KASSERT(pic->pic_maxsources >= n + irqbase);
    579      1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISE, n + irqbase);
    580      1.1   rkujawa 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ICM, n + irqbase);
    581      1.1   rkujawa 		if ((n + irqbase) == 0)
    582      1.1   rkujawa 			MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_DOORBELL_MASK,
    583      1.1   rkujawa 			    0xffffffff);
    584      1.1   rkujawa 		irq_mask &= ~__BIT(n);
    585      1.1   rkujawa 	}
    586      1.1   rkujawa }
    587      1.1   rkujawa 
    588      1.1   rkujawa static void
    589      1.1   rkujawa armadaxp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
    590      1.1   rkujawa     uint32_t irq_mask)
    591      1.1   rkujawa {
    592      1.1   rkujawa 	int n;
    593      1.1   rkujawa 
    594      1.1   rkujawa 	while (irq_mask != 0) {
    595      1.1   rkujawa 		n = ffs(irq_mask) - 1;
    596      1.1   rkujawa 		KASSERT(pic->pic_maxsources >= n + irqbase);
    597      1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, n + irqbase);
    598      1.1   rkujawa 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, n + irqbase);
    599      1.1   rkujawa 		irq_mask &= ~__BIT(n);
    600      1.1   rkujawa 	}
    601      1.1   rkujawa }
    602      1.1   rkujawa 
    603      1.1   rkujawa static void
    604      1.1   rkujawa armadaxp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    605      1.1   rkujawa {
    606      1.1   rkujawa 	int tmp;
    607      1.1   rkujawa 	KASSERT(pic->pic_maxsources >= is->is_irq);
    608      1.1   rkujawa 	tmp = MPIC_READ(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4);
    609      1.1   rkujawa 	/* Clear previous priority */
    610      1.1   rkujawa 	tmp &= ~(0xf << MPIC_ISCR_SHIFT);
    611      1.1   rkujawa 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4,
    612      1.1   rkujawa 	    tmp | (is->is_ipl << MPIC_ISCR_SHIFT));
    613      1.1   rkujawa }
    614      1.1   rkujawa 
    615      1.4  kiyohara static void
    616      1.4  kiyohara armadaxp_pic_set_priority(struct pic_softc *pic, int ipl)
    617      1.4  kiyohara {
    618      1.4  kiyohara 	int ctp;
    619      1.4  kiyohara 
    620      1.4  kiyohara 	ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
    621      1.4  kiyohara 	ctp &= ~(0xf << MPIC_CTP_SHIFT);
    622      1.4  kiyohara 	ctp |= (ipl << MPIC_CTP_SHIFT);
    623      1.4  kiyohara 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
    624      1.4  kiyohara }
    625      1.4  kiyohara 
    626  1.8.6.1     skrll static void
    627  1.8.6.1     skrll armadaxp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
    628  1.8.6.1     skrll {
    629  1.8.6.1     skrll 	if (irq > __arraycount(armadaxp_pic_source_names)) {
    630  1.8.6.1     skrll 		snprintf(buf, len, "Unknown IRQ %d", irq);
    631  1.8.6.1     skrll 		return;
    632  1.8.6.1     skrll 	}
    633  1.8.6.1     skrll 	strlcpy(buf, armadaxp_pic_source_names[irq], len);
    634  1.8.6.1     skrll }
    635  1.8.6.1     skrll 
    636      1.4  kiyohara static int
    637      1.4  kiyohara armadaxp_find_pending_irqs(void)
    638      1.1   rkujawa {
    639      1.1   rkujawa 	struct intrsource *is;
    640      1.1   rkujawa 	int irq;
    641      1.1   rkujawa 
    642      1.1   rkujawa 	irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff;
    643      1.1   rkujawa 
    644      1.1   rkujawa 	/* Is it a spurious interrupt ?*/
    645      1.1   rkujawa 	if (irq == 0x3ff)
    646      1.4  kiyohara 		return 0;
    647      1.1   rkujawa 	is = armadaxp_pic.pic_sources[irq];
    648      1.4  kiyohara 	if (is == NULL) {
    649      1.4  kiyohara 		printf("stray interrupt: %d\n", irq);
    650      1.4  kiyohara 		return 0;
    651      1.1   rkujawa 	}
    652      1.4  kiyohara 
    653      1.4  kiyohara 	armadaxp_pic_block_irq(&armadaxp_pic, irq);
    654      1.4  kiyohara 	pic_mark_pending(&armadaxp_pic, irq);
    655      1.4  kiyohara 
    656      1.4  kiyohara 	return is->is_ipl;
    657      1.4  kiyohara }
    658      1.4  kiyohara 
    659      1.4  kiyohara static void
    660      1.4  kiyohara armadaxp_pic_block_irq(struct pic_softc *pic, size_t irq)
    661      1.4  kiyohara {
    662      1.4  kiyohara 
    663      1.4  kiyohara 	KASSERT(pic->pic_maxsources >= irq);
    664      1.4  kiyohara 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, irq);
    665      1.4  kiyohara 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, irq);
    666      1.1   rkujawa }
    667      1.1   rkujawa 
    668  1.8.6.1     skrll static void
    669  1.8.6.1     skrll armadaxp_err_pic_source_name(struct pic_softc *pic, int irq,
    670  1.8.6.1     skrll     char *buf, size_t len)
    671  1.8.6.1     skrll {
    672  1.8.6.1     skrll 	if (irq > __arraycount(armadaxp_err_pic_source_names)) {
    673  1.8.6.1     skrll 		snprintf(buf, len, "Unknown IRQ %d", irq);
    674  1.8.6.1     skrll 		return;
    675  1.8.6.1     skrll 	}
    676  1.8.6.1     skrll 	strlcpy(buf, armadaxp_err_pic_source_names[irq], len);
    677  1.8.6.1     skrll }
    678  1.8.6.1     skrll 
    679  1.8.6.1     skrll 
    680  1.8.6.1     skrll /*
    681  1.8.6.1     skrll  * ARMADAXP_MLMB_MPIC_ERR_CAUSE
    682  1.8.6.1     skrll  */
    683  1.8.6.1     skrll static void
    684  1.8.6.1     skrll armadaxp_err_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    685  1.8.6.1     skrll     uint32_t irq_mask)
    686  1.8.6.1     skrll {
    687  1.8.6.1     skrll 	uint32_t reg;
    688  1.8.6.1     skrll 
    689  1.8.6.1     skrll 	KASSERT(irqbase == 0); /* XXX: support offset */
    690  1.8.6.1     skrll 
    691  1.8.6.1     skrll 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
    692  1.8.6.1     skrll 	reg |= irq_mask;
    693  1.8.6.1     skrll 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
    694  1.8.6.1     skrll }
    695  1.8.6.1     skrll 
    696  1.8.6.1     skrll static void
    697  1.8.6.1     skrll armadaxp_err_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
    698  1.8.6.1     skrll     uint32_t irq_mask)
    699  1.8.6.1     skrll {
    700  1.8.6.1     skrll 	uint32_t reg;
    701  1.8.6.1     skrll 
    702  1.8.6.1     skrll 	KASSERT(irqbase == 0); /* XXX: support offset */
    703  1.8.6.1     skrll 
    704  1.8.6.1     skrll 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
    705  1.8.6.1     skrll 	reg &= ~irq_mask;
    706  1.8.6.1     skrll 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
    707  1.8.6.1     skrll }
    708  1.8.6.1     skrll 
    709  1.8.6.1     skrll static void
    710  1.8.6.1     skrll armadaxp_err_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    711  1.8.6.1     skrll {
    712  1.8.6.1     skrll 	uint32_t reg;
    713  1.8.6.1     skrll 
    714  1.8.6.1     skrll 	KASSERT(pic->pic_maxsources >= is->is_irq);
    715  1.8.6.1     skrll 
    716  1.8.6.1     skrll 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
    717  1.8.6.1     skrll 	reg |= ARMADAXP_IRQ_ERROR_BIT(is->is_irq);
    718  1.8.6.1     skrll 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
    719  1.8.6.1     skrll }
    720  1.8.6.1     skrll 
    721  1.8.6.1     skrll static int
    722  1.8.6.1     skrll armadaxp_err_pic_pending_irqs(struct pic_softc *pic)
    723  1.8.6.1     skrll {
    724  1.8.6.1     skrll 	struct intrsource *is;
    725  1.8.6.1     skrll 	uint32_t reg;
    726  1.8.6.1     skrll 	int irq;
    727  1.8.6.1     skrll 
    728  1.8.6.1     skrll 	reg = MPIC_READ(ARMADAXP_MLMB_MPIC_ERR_CAUSE);
    729  1.8.6.1     skrll 	irq = ffs(reg);
    730  1.8.6.1     skrll 	if (irq == 0)
    731  1.8.6.1     skrll 		return 0;
    732  1.8.6.1     skrll 	irq--; /* bit number to index */
    733  1.8.6.1     skrll 
    734  1.8.6.1     skrll 	is = pic->pic_sources[irq];
    735  1.8.6.1     skrll 	if (is == NULL) {
    736  1.8.6.1     skrll 		printf("stray interrupt: %d\n", irq);
    737  1.8.6.1     skrll 		return 0;
    738  1.8.6.1     skrll 	}
    739  1.8.6.1     skrll 	return pic_mark_pending_sources(pic, 0, irq);
    740  1.8.6.1     skrll }
    741  1.8.6.1     skrll 
    742  1.8.6.1     skrll 
    743      1.1   rkujawa /*
    744      1.1   rkujawa  * Clock functions
    745      1.1   rkujawa  */
    746      1.1   rkujawa 
    747      1.1   rkujawa void
    748      1.1   rkujawa armadaxp_getclks(void)
    749      1.1   rkujawa {
    750      1.1   rkujawa 	uint64_t sar_reg;
    751      1.7  kiyohara 	uint8_t  sar_cpu_freq, sar_fab_freq;
    752      1.1   rkujawa 
    753      1.1   rkujawa 	if (cputype == CPU_ID_MV88SV584X_V7)
    754      1.1   rkujawa 		mvTclk = 250000000; /* 250 MHz */
    755      1.1   rkujawa 	else
    756      1.1   rkujawa 		mvTclk = 200000000; /* 200 MHz */
    757      1.1   rkujawa 
    758      1.1   rkujawa 	sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) |
    759      1.1   rkujawa 	    read_miscreg(ARMADAXP_MISC_SAR_LO);
    760      1.1   rkujawa 
    761      1.7  kiyohara 	sar_cpu_freq = EXTRACT_XP_CPU_FREQ_FIELD(sar_reg);
    762      1.7  kiyohara 	sar_fab_freq = EXTRACT_XP_FAB_FREQ_FIELD(sar_reg);
    763      1.1   rkujawa 
    764      1.1   rkujawa 	/* Check if CPU frequency field has correct value */
    765      1.7  kiyohara 	if (sar_cpu_freq >= __arraycount(clock_table_xp))
    766      1.1   rkujawa 		panic("Reserved value in cpu frequency configuration field: "
    767      1.1   rkujawa 		    "%d", sar_cpu_freq);
    768      1.1   rkujawa 
    769      1.1   rkujawa 	/* Check if fabric frequency field has correct value */
    770      1.7  kiyohara 	if (sar_fab_freq >= __arraycount(freq_conf_table))
    771      1.1   rkujawa 		panic("Reserved value in fabric frequency configuration field: "
    772      1.1   rkujawa 		    "%d", sar_fab_freq);
    773      1.1   rkujawa 
    774      1.1   rkujawa 	/* Get CPU clock frequency */
    775      1.7  kiyohara 	mvPclk = clock_table_xp[sar_cpu_freq] *
    776      1.1   rkujawa 	    freq_conf_table[sar_fab_freq].vco_cpu;
    777      1.1   rkujawa 
    778      1.1   rkujawa 	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
    779      1.1   rkujawa 	mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c;
    780      1.1   rkujawa 
    781      1.1   rkujawa 	/* Round mvSysclk value to integer MHz */
    782      1.1   rkujawa 	if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
    783      1.1   rkujawa 	    freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
    784      1.1   rkujawa 		mvSysclk++;
    785      1.1   rkujawa 
    786      1.7  kiyohara 	mvPclk *= 1000000;
    787      1.7  kiyohara 	mvSysclk *= 1000000;
    788      1.8      matt 
    789      1.8      matt 	curcpu()->ci_data.cpu_cc_freq = mvPclk;
    790      1.7  kiyohara }
    791      1.7  kiyohara 
    792      1.7  kiyohara void
    793      1.7  kiyohara armada370_getclks(void)
    794      1.7  kiyohara {
    795      1.7  kiyohara 	uint32_t sar;
    796      1.7  kiyohara 	uint8_t  cpu_freq, fab_freq;
    797      1.7  kiyohara 
    798      1.7  kiyohara 	sar = read_miscreg(ARMADAXP_MISC_SAR_LO);
    799      1.7  kiyohara 	if (sar & 0x00100000)
    800      1.7  kiyohara 		mvTclk = 200000000; /* 200 MHz */
    801      1.7  kiyohara 	else
    802      1.7  kiyohara 		mvTclk = 166666667; /* 166 MHz */
    803      1.7  kiyohara 
    804      1.7  kiyohara 	cpu_freq = EXTRACT_370_CPU_FREQ_FIELD(sar);
    805      1.7  kiyohara 	fab_freq = EXTRACT_370_FAB_FREQ_FIELD(sar);
    806      1.7  kiyohara 
    807      1.7  kiyohara 	/* Check if CPU frequency field has correct value */
    808      1.7  kiyohara 	if (cpu_freq >= __arraycount(clock_table_370))
    809      1.7  kiyohara 		panic("Reserved value in cpu frequency configuration field: "
    810      1.7  kiyohara 		    "%d", cpu_freq);
    811      1.7  kiyohara 
    812      1.7  kiyohara 	/* Check if fabric frequency field has correct value */
    813      1.7  kiyohara 	if (fab_freq >= __arraycount(freq_conf_table))
    814      1.7  kiyohara 		panic("Reserved value in fabric frequency configuration field: "
    815      1.7  kiyohara 		    "%d", fab_freq);
    816      1.7  kiyohara 
    817      1.7  kiyohara 	/* Get CPU clock frequency */
    818      1.7  kiyohara 	mvPclk = clock_table_370[cpu_freq] *
    819      1.7  kiyohara 	    freq_conf_table[fab_freq].vco_cpu;
    820      1.7  kiyohara 
    821      1.7  kiyohara 	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
    822      1.7  kiyohara 	mvSysclk = mvPclk / freq_conf_table[fab_freq].vco_l2c;
    823      1.7  kiyohara 
    824      1.7  kiyohara 	/* Round mvSysclk value to integer MHz */
    825      1.7  kiyohara 	if (((mvPclk % freq_conf_table[fab_freq].vco_l2c) * 10 /
    826      1.7  kiyohara 	    freq_conf_table[fab_freq].vco_l2c) >= 5)
    827      1.7  kiyohara 		mvSysclk++;
    828      1.7  kiyohara 
    829      1.7  kiyohara 	mvPclk *= 1000000;
    830      1.7  kiyohara 	mvSysclk *= 1000000;
    831      1.1   rkujawa }
    832      1.1   rkujawa 
    833      1.1   rkujawa /*
    834      1.1   rkujawa  * L2 Cache initialization
    835      1.1   rkujawa  */
    836      1.1   rkujawa 
    837      1.1   rkujawa int
    838      1.3  kiyohara armadaxp_l2_init(bus_addr_t pbase)
    839      1.1   rkujawa {
    840      1.1   rkujawa 	u_int32_t reg;
    841      1.1   rkujawa 	int ret;
    842      1.1   rkujawa 
    843      1.1   rkujawa 	/* Map L2 space */
    844      1.3  kiyohara 	ret = bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_L2_BASE,
    845      1.3  kiyohara 	    0x1000, 0, &l2_handle);
    846      1.1   rkujawa 	if (ret) {
    847      1.1   rkujawa 		printf("%s: Cannot map L2 register space, ret:%d\n",
    848      1.1   rkujawa 		    __func__, ret);
    849      1.1   rkujawa 		return (-1);
    850      1.1   rkujawa 	}
    851      1.1   rkujawa 
    852  1.8.6.1     skrll 	/* Variables for cpufunc_asm_pj4b.S */
    853  1.8.6.1     skrll 	/* XXX: per cpu register. need to support SMP */
    854  1.8.6.1     skrll 	armadaxp_l2_barrier_reg = mlmb_base + MVSOC_MLMB_CIB_BARRIER(0);
    855  1.8.6.1     skrll 
    856      1.1   rkujawa 	/* Set L2 policy */
    857      1.1   rkujawa 	reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
    858  1.8.6.1     skrll 	reg &= ~(L2_AUX_WBWT_MODE_MASK);
    859  1.8.6.1     skrll 	reg &= ~(L2_AUX_REP_STRAT_MASK);
    860  1.8.6.1     skrll 	reg |= L2_AUX_ECC_ENABLE;
    861  1.8.6.1     skrll 	reg |= L2_AUX_PARITY_ENABLE;
    862  1.8.6.1     skrll 	reg |= L2_AUX_WBWT_MODE_BY_ATTR;
    863  1.8.6.1     skrll 	reg |= L2_AUX_FORCE_WA_BY_ATTR;
    864  1.8.6.1     skrll 	reg |= L2_AUX_REP_STRAT_SEMIPLRU;
    865      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
    866      1.1   rkujawa 
    867      1.1   rkujawa 	/* Invalidate L2 cache */
    868      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
    869      1.1   rkujawa 
    870      1.1   rkujawa 	/* Clear pending L2 interrupts */
    871      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff);
    872      1.1   rkujawa 
    873      1.1   rkujawa 	/* Enable Cache and TLB maintenance broadcast */
    874      1.1   rkujawa 	__asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg));
    875      1.1   rkujawa 	reg |= (1 << 8);
    876      1.1   rkujawa 	__asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg));
    877      1.1   rkujawa 
    878      1.1   rkujawa 	/*
    879      1.1   rkujawa 	 * Set the Point of Coherency and Point of Unification to DRAM.
    880      1.1   rkujawa 	 * This is a reset value but anyway, configure this just in case.
    881      1.1   rkujawa 	 */
    882      1.1   rkujawa 	reg = read_mlmbreg(ARMADAXP_L2_CFU);
    883      1.1   rkujawa 	reg |= (1 << 17) | (1 << 18);
    884      1.1   rkujawa 	write_mlmbreg(ARMADAXP_L2_CFU, reg);
    885      1.1   rkujawa 
    886      1.1   rkujawa 	/* Enable L2 cache */
    887      1.1   rkujawa 	reg = L2_READ(ARMADAXP_L2_CTRL);
    888  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_CTRL_ENABLE);
    889      1.1   rkujawa 
    890      1.1   rkujawa 	/* Mark as enabled */
    891      1.1   rkujawa 	l2cache_state = 1;
    892      1.1   rkujawa 
    893      1.1   rkujawa #ifdef DEBUG
    894      1.1   rkujawa 	/* Configure and enable counter */
    895      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
    896      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
    897      1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303);
    898      1.1   rkujawa #endif
    899      1.1   rkujawa 
    900      1.1   rkujawa 	return (0);
    901      1.1   rkujawa }
    902      1.1   rkujawa 
    903      1.1   rkujawa void
    904  1.8.6.1     skrll armadaxp_sdcache_inv_all(void)
    905  1.8.6.1     skrll {
    906  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
    907  1.8.6.1     skrll }
    908  1.8.6.1     skrll 
    909  1.8.6.1     skrll void
    910  1.8.6.1     skrll armadaxp_sdcache_wb_all(void)
    911  1.8.6.1     skrll {
    912  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_WB_WAY, L2_ALL_WAYS);
    913  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
    914  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
    915  1.8.6.1     skrll }
    916  1.8.6.1     skrll 
    917  1.8.6.1     skrll void
    918  1.8.6.1     skrll armadaxp_sdcache_wbinv_all(void)
    919  1.8.6.1     skrll {
    920  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_WBINV_WAY, L2_ALL_WAYS);
    921  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
    922  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
    923  1.8.6.1     skrll }
    924  1.8.6.1     skrll 
    925  1.8.6.1     skrll static paddr_t
    926  1.8.6.1     skrll armadaxp_sdcache_wbalign_base(vaddr_t va, paddr_t pa, psize_t sz)
    927  1.8.6.1     skrll {
    928  1.8.6.1     skrll 	paddr_t line_start = pa & ~ARMADAXP_L2_ALIGN;
    929  1.8.6.1     skrll 	vaddr_t save_start;
    930  1.8.6.1     skrll 	uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
    931  1.8.6.1     skrll 	size_t unalign;
    932  1.8.6.1     skrll 
    933  1.8.6.1     skrll 	unalign = va & ARMADAXP_L2_ALIGN;
    934  1.8.6.1     skrll 	if (unalign == 0)
    935  1.8.6.1     skrll 		return line_start;  /* request is aligned to cache line size */
    936  1.8.6.1     skrll 
    937  1.8.6.1     skrll 	/* save data that is not intended to invalidate */
    938  1.8.6.1     skrll 	save_start = va & ~ARMADAXP_L2_ALIGN;
    939  1.8.6.1     skrll 	memcpy(save_buf, (void *)save_start, unalign);
    940  1.8.6.1     skrll 
    941  1.8.6.1     skrll 	/* invalidate include saved data */
    942  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
    943  1.8.6.1     skrll 
    944  1.8.6.1     skrll 	/* write back saved data */
    945  1.8.6.1     skrll 	memcpy((void *)save_start, save_buf, unalign);
    946  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
    947  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
    948  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
    949  1.8.6.1     skrll 
    950  1.8.6.1     skrll 	return line_start;
    951  1.8.6.1     skrll }
    952  1.8.6.1     skrll 
    953  1.8.6.1     skrll static paddr_t
    954  1.8.6.1     skrll armadaxp_sdcache_wbalign_end(vaddr_t va, paddr_t pa, psize_t sz)
    955  1.8.6.1     skrll {
    956  1.8.6.1     skrll 	paddr_t line_start = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
    957  1.8.6.1     skrll 	vaddr_t save_start = va + sz;
    958  1.8.6.1     skrll 	uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
    959  1.8.6.1     skrll 	size_t save_len;
    960  1.8.6.1     skrll 	size_t unalign;
    961  1.8.6.1     skrll 
    962  1.8.6.1     skrll 	unalign = save_start & ARMADAXP_L2_ALIGN;
    963  1.8.6.1     skrll 	if (unalign == 0)
    964  1.8.6.1     skrll 		return line_start; /* request is aligned to cache line size */
    965  1.8.6.1     skrll 
    966  1.8.6.1     skrll 	/* save data that is not intended to invalidate */
    967  1.8.6.1     skrll 	save_len = ARMADAXP_L2_LINE_SIZE - unalign;
    968  1.8.6.1     skrll 	memcpy(save_buf, (void *)save_start, save_len);
    969  1.8.6.1     skrll 
    970  1.8.6.1     skrll 	/* invalidate include saved data */
    971  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
    972  1.8.6.1     skrll 
    973  1.8.6.1     skrll 	/* write back saved data */
    974  1.8.6.1     skrll 	memcpy((void *)save_start, save_buf, save_len);
    975  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
    976  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
    977  1.8.6.1     skrll 
    978  1.8.6.1     skrll 	return line_start;
    979  1.8.6.1     skrll }
    980  1.8.6.1     skrll 
    981  1.8.6.1     skrll void
    982  1.8.6.1     skrll armadaxp_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t sz)
    983  1.8.6.1     skrll {
    984  1.8.6.1     skrll 	paddr_t pa_base;
    985  1.8.6.1     skrll 	paddr_t pa_end;
    986  1.8.6.1     skrll 
    987  1.8.6.1     skrll 	/* align and write-back the boundary */
    988  1.8.6.1     skrll 	pa_base = armadaxp_sdcache_wbalign_base(va, pa, sz);
    989  1.8.6.1     skrll 	pa_end = armadaxp_sdcache_wbalign_end(va, pa, sz);
    990  1.8.6.1     skrll 
    991  1.8.6.1     skrll 	/* invalidate other cache */
    992  1.8.6.1     skrll 	if (pa_base == pa_end) {
    993  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_INV_PHYS, pa_base);
    994  1.8.6.1     skrll 		return;
    995  1.8.6.1     skrll 	}
    996  1.8.6.1     skrll 
    997  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
    998  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_INV_RANGE, pa_end);
    999  1.8.6.1     skrll }
   1000  1.8.6.1     skrll 
   1001  1.8.6.1     skrll void
   1002  1.8.6.1     skrll armadaxp_sdcache_wb_range(vaddr_t va, paddr_t pa, psize_t sz)
   1003  1.8.6.1     skrll {
   1004  1.8.6.1     skrll 	paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;
   1005  1.8.6.1     skrll 	paddr_t pa_end  = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
   1006  1.8.6.1     skrll 
   1007  1.8.6.1     skrll 	if (pa_base == pa_end)
   1008  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_WB_PHYS, pa_base);
   1009  1.8.6.1     skrll 	else {
   1010  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
   1011  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_WB_RANGE, pa_end);
   1012  1.8.6.1     skrll 	}
   1013  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
   1014  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
   1015  1.8.6.1     skrll }
   1016  1.8.6.1     skrll 
   1017  1.8.6.1     skrll void
   1018  1.8.6.1     skrll armadaxp_sdcache_wbinv_range(vaddr_t va, paddr_t pa, psize_t sz)
   1019  1.8.6.1     skrll {
   1020  1.8.6.1     skrll 	paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;;
   1021  1.8.6.1     skrll 	paddr_t pa_end  = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
   1022  1.8.6.1     skrll 
   1023  1.8.6.1     skrll 	if (pa_base == pa_end)
   1024  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_WBINV_PHYS, pa_base);
   1025  1.8.6.1     skrll 	else {
   1026  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
   1027  1.8.6.1     skrll 		L2_WRITE(ARMADAXP_L2_WBINV_RANGE, pa_end);
   1028  1.8.6.1     skrll 	}
   1029  1.8.6.1     skrll 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
   1030  1.8.6.1     skrll 	__asm__ __volatile__("dsb");
   1031  1.8.6.1     skrll }
   1032  1.8.6.1     skrll 
   1033  1.8.6.1     skrll void
   1034      1.1   rkujawa armadaxp_io_coherency_init(void)
   1035      1.1   rkujawa {
   1036      1.1   rkujawa 	uint32_t reg;
   1037      1.1   rkujawa 
   1038      1.1   rkujawa 	/* set CIB read snoop command to ReadUnique */
   1039      1.1   rkujawa 	reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG);
   1040  1.8.6.1     skrll 	reg |= MVSOC_MLMB_CIB_CTRL_CFG_WB_EN;
   1041      1.1   rkujawa 	write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg);
   1042  1.8.6.1     skrll 
   1043      1.1   rkujawa 	/* enable CPUs in SMP group on Fabric coherency */
   1044  1.8.6.1     skrll 	reg = read_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL);
   1045  1.8.6.1     skrll 	reg |= MVSOC_MLMB_CFU_FAB_CTRL_SNOOP_CPU0;
   1046  1.8.6.1     skrll 	write_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL, reg);
   1047  1.8.6.1     skrll 
   1048  1.8.6.1     skrll 	/* send all snoop request to L2 cache */
   1049  1.8.6.1     skrll 	reg = read_mlmbreg(MVSOC_MLMB_CFU_CFG);
   1050  1.8.6.1     skrll #ifdef L2CACHE_ENABLE
   1051  1.8.6.1     skrll 	reg |= MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
   1052  1.8.6.1     skrll #else
   1053  1.8.6.1     skrll 	reg &= ~MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
   1054  1.8.6.1     skrll #endif
   1055  1.8.6.1     skrll 	write_mlmbreg(MVSOC_MLMB_CFU_CFG, reg);
   1056      1.1   rkujawa 
   1057      1.1   rkujawa 	/* Mark as enabled */
   1058      1.1   rkujawa 	iocc_state = 1;
   1059      1.1   rkujawa }
   1060      1.6  kiyohara 
   1061      1.7  kiyohara int
   1062      1.6  kiyohara armadaxp_clkgating(struct marvell_attach_args *mva)
   1063      1.6  kiyohara {
   1064      1.6  kiyohara 	uint32_t val;
   1065      1.6  kiyohara 	int i;
   1066      1.6  kiyohara 
   1067      1.6  kiyohara 	for (i = 0; i < __arraycount(clkgatings); i++) {
   1068      1.6  kiyohara 		if (clkgatings[i].offset == mva->mva_offset) {
   1069      1.6  kiyohara 			val = read_miscreg(ARMADAXP_MISC_PMCGC);
   1070      1.6  kiyohara 			if ((val & clkgatings[i].bits) == clkgatings[i].bits)
   1071      1.6  kiyohara 				/* Clock enabled */
   1072      1.7  kiyohara 				return 0;
   1073      1.6  kiyohara 			return 1;
   1074      1.6  kiyohara 		}
   1075      1.7  kiyohara 	}
   1076      1.6  kiyohara 	/* Clock Gating not support */
   1077      1.6  kiyohara 	return 0;
   1078      1.6  kiyohara }
   1079  1.8.6.1     skrll 
   1080  1.8.6.1     skrll int
   1081  1.8.6.1     skrll armadaxp_init_mbus(void)
   1082  1.8.6.1     skrll {
   1083  1.8.6.1     skrll 	struct mbus_table_def *def;
   1084  1.8.6.1     skrll 	uint32_t reg;
   1085  1.8.6.1     skrll 	int i;
   1086  1.8.6.1     skrll 
   1087  1.8.6.1     skrll 	for (i = 0; i < nwindow; i++) {
   1088  1.8.6.1     skrll 		/* disable all windows */
   1089  1.8.6.1     skrll 		reg = read_mlmbreg(MVSOC_MLMB_WCR(i));
   1090  1.8.6.1     skrll 		reg &= ~MVSOC_MLMB_WCR_WINEN;
   1091  1.8.6.1     skrll 		write_mlmbreg(MVSOC_MLMB_WCR(i), reg);
   1092  1.8.6.1     skrll 		write_mlmbreg(MVSOC_MLMB_WBR(i), 0);
   1093  1.8.6.1     skrll 	}
   1094  1.8.6.1     skrll 
   1095  1.8.6.1     skrll 	for (i = 0; i < __arraycount(mbus_table); i++) {
   1096  1.8.6.1     skrll 		def = &mbus_table[i];
   1097  1.8.6.1     skrll 		if (def->window >= nwindow)
   1098  1.8.6.1     skrll 			continue;
   1099  1.8.6.1     skrll 		if (def->size == 0)
   1100  1.8.6.1     skrll 			continue;
   1101  1.8.6.1     skrll 
   1102  1.8.6.1     skrll 		/* restore window base */
   1103  1.8.6.1     skrll 		reg = def->base & MVSOC_MLMB_WBR_BASE_MASK;
   1104  1.8.6.1     skrll 		write_mlmbreg(MVSOC_MLMB_WBR(def->window), reg);
   1105  1.8.6.1     skrll 
   1106  1.8.6.1     skrll 		/* restore window configuration */
   1107  1.8.6.1     skrll 		reg  = MVSOC_MLMB_WCR_SIZE(def->size);
   1108  1.8.6.1     skrll 		reg |= MVSOC_MLMB_WCR_TARGET(def->target);
   1109  1.8.6.1     skrll 		reg |= MVSOC_MLMB_WCR_ATTR(def->attr);
   1110  1.8.6.1     skrll #ifdef AURORA_IO_CACHE_COHERENCY
   1111  1.8.6.1     skrll 		reg |= MVSOC_MLMB_WCR_SYNC; /* enbale I/O coherency barrior */
   1112  1.8.6.1     skrll #endif
   1113  1.8.6.1     skrll 		reg |= MVSOC_MLMB_WCR_WINEN;
   1114  1.8.6.1     skrll 		write_mlmbreg(MVSOC_MLMB_WCR(def->window), reg);
   1115  1.8.6.1     skrll 	}
   1116  1.8.6.1     skrll 
   1117  1.8.6.1     skrll 	return 0;
   1118  1.8.6.1     skrll }
   1119  1.8.6.1     skrll 
   1120  1.8.6.1     skrll int
   1121  1.8.6.1     skrll armadaxp_attr_dump(struct mvsoc_softc *sc, uint32_t target, uint32_t attr)
   1122  1.8.6.1     skrll {
   1123  1.8.6.1     skrll 	struct mbus_description *desc;
   1124  1.8.6.1     skrll 	int i;
   1125  1.8.6.1     skrll 
   1126  1.8.6.1     skrll 	for (i = 0; i < __arraycount(mbus_desc); i++) {
   1127  1.8.6.1     skrll 		desc = &mbus_desc[i];
   1128  1.8.6.1     skrll 		if (desc->target != target)
   1129  1.8.6.1     skrll 			continue;
   1130  1.8.6.1     skrll 		if (desc->attr != attr)
   1131  1.8.6.1     skrll 			continue;
   1132  1.8.6.1     skrll 		aprint_verbose_dev(sc->sc_dev, "%s", desc->string);
   1133  1.8.6.1     skrll 		return 0;
   1134  1.8.6.1     skrll 	}
   1135  1.8.6.1     skrll 
   1136  1.8.6.1     skrll 	/* unknown decoding target/attribute pair */
   1137  1.8.6.1     skrll 	aprint_verbose_dev(sc->sc_dev, "target 0x%x(attr 0x%x)", target, attr);
   1138  1.8.6.1     skrll 	return -1;
   1139  1.8.6.1     skrll }
   1140