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