Home | History | Annotate | Line # | Download | only in marvell
armadaxp.c revision 1.3
      1  1.3  kiyohara /*	$NetBSD: armadaxp.c,v 1.3 2013/09/30 13:03:25 kiyohara 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.3  kiyohara __KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.3 2013/09/30 13:03:25 kiyohara 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 #include <arm/pic/picvar.h>
     53  1.1   rkujawa 
     54  1.1   rkujawa #include <arm/armreg.h>
     55  1.1   rkujawa #include <arm/cpu.h>
     56  1.1   rkujawa #include <arm/cpufunc.h>
     57  1.1   rkujawa 
     58  1.1   rkujawa #include <arm/marvell/mvsocreg.h>
     59  1.1   rkujawa #include <arm/marvell/mvsocvar.h>
     60  1.3  kiyohara #include <arm/marvell/armadaxpreg.h>
     61  1.1   rkujawa 
     62  1.1   rkujawa #include <dev/marvell/marvellreg.h>
     63  1.1   rkujawa 
     64  1.1   rkujawa #define EXTRACT_CPU_FREQ_FIELD(sar)	(((0x01 & (sar >> 52)) << 3) | \
     65  1.1   rkujawa 					    (0x07 & (sar >> 21)))
     66  1.1   rkujawa #define EXTRACT_FAB_FREQ_FIELD(sar)	(((0x01 & (sar >> 51)) << 4) | \
     67  1.1   rkujawa 					    (0x0F & (sar >> 24)))
     68  1.1   rkujawa 
     69  1.1   rkujawa #define	MPIC_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
     70  1.1   rkujawa 					    mpic_handle, reg, val))
     71  1.1   rkujawa #define	MPIC_CPU_WRITE(reg, val)	(bus_space_write_4(&mvsoc_bs_tag, \
     72  1.1   rkujawa 					    mpic_cpu_handle, reg, val))
     73  1.1   rkujawa 
     74  1.1   rkujawa #define	MPIC_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
     75  1.1   rkujawa 					    mpic_handle, reg))
     76  1.1   rkujawa #define	MPIC_CPU_READ(reg)		(bus_space_read_4(&mvsoc_bs_tag, \
     77  1.1   rkujawa 					    mpic_cpu_handle, reg))
     78  1.1   rkujawa 
     79  1.1   rkujawa #define	L2_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
     80  1.1   rkujawa 					    l2_handle, reg, val))
     81  1.1   rkujawa #define	L2_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
     82  1.1   rkujawa 					    l2_handle, reg))
     83  1.1   rkujawa bus_space_handle_t mpic_cpu_handle;
     84  1.1   rkujawa static bus_space_handle_t mpic_handle, l2_handle;
     85  1.1   rkujawa int l2cache_state = 0;
     86  1.1   rkujawa int iocc_state = 0;
     87  1.1   rkujawa 
     88  1.1   rkujawa extern void (*mvsoc_intr_init)(void);
     89  1.1   rkujawa static void armadaxp_intr_init(void);
     90  1.1   rkujawa 
     91  1.1   rkujawa static void armadaxp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     92  1.1   rkujawa static void armadaxp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     93  1.1   rkujawa static void armadaxp_pic_establish_irq(struct pic_softc *, struct intrsource *);
     94  1.1   rkujawa 
     95  1.1   rkujawa void armadaxp_handle_irq(void *);
     96  1.1   rkujawa void armadaxp_io_coherency_init(void);
     97  1.3  kiyohara int armadaxp_l2_init(bus_addr_t);
     98  1.1   rkujawa 
     99  1.1   rkujawa struct vco_freq_ratio {
    100  1.1   rkujawa 	uint8_t	vco_cpu;	/* VCO to CLK0(CPU) clock ratio */
    101  1.1   rkujawa 	uint8_t	vco_l2c;	/* VCO to NB(L2 cache) clock ratio */
    102  1.1   rkujawa 	uint8_t	vco_hcl;	/* VCO to HCLK(DDR controller) clock ratio */
    103  1.1   rkujawa 	uint8_t	vco_ddr;	/* VCO to DR(DDR memory) clock ratio */
    104  1.1   rkujawa };
    105  1.1   rkujawa 
    106  1.1   rkujawa static struct vco_freq_ratio freq_conf_table[] = {
    107  1.1   rkujawa /*00*/	{ 1, 1,	 4,  2 },
    108  1.1   rkujawa /*01*/	{ 1, 2,	 2,  2 },
    109  1.1   rkujawa /*02*/	{ 2, 2,	 6,  3 },
    110  1.1   rkujawa /*03*/	{ 2, 2,	 3,  3 },
    111  1.1   rkujawa /*04*/	{ 1, 2,	 3,  3 },
    112  1.1   rkujawa /*05*/	{ 1, 2,	 4,  2 },
    113  1.1   rkujawa /*06*/	{ 1, 1,	 2,  2 },
    114  1.1   rkujawa /*07*/	{ 2, 3,	 6,  6 },
    115  1.1   rkujawa /*08*/	{ 2, 3,	 5,  5 },
    116  1.1   rkujawa /*09*/	{ 1, 2,	 6,  3 },
    117  1.1   rkujawa /*10*/	{ 2, 4,	10,  5 },
    118  1.1   rkujawa /*11*/	{ 1, 3,	 6,  6 },
    119  1.1   rkujawa /*12*/	{ 1, 2,	 5,  5 },
    120  1.1   rkujawa /*13*/	{ 1, 3,	 6,  3 },
    121  1.1   rkujawa /*14*/	{ 1, 2,	 5,  5 },
    122  1.1   rkujawa /*15*/	{ 2, 2,	 5,  5 },
    123  1.1   rkujawa /*16*/	{ 1, 1,	 3,  3 },
    124  1.1   rkujawa /*17*/	{ 2, 5,	10, 10 },
    125  1.1   rkujawa /*18*/	{ 1, 3,	 8,  4 },
    126  1.1   rkujawa /*19*/	{ 1, 1,	 2,  1 },
    127  1.1   rkujawa /*20*/	{ 2, 3,	 6,  3 },
    128  1.1   rkujawa /*21*/	{ 1, 2,	 8,  4 },
    129  1.1   rkujawa /*22*/	{ 2, 5,	10,  5 }
    130  1.1   rkujawa };
    131  1.1   rkujawa 
    132  1.1   rkujawa static uint16_t	cpu_clock_table[] = {
    133  1.1   rkujawa     1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000, 600,  667,  800,  1600,
    134  1.1   rkujawa     2133, 2200, 2400 };
    135  1.1   rkujawa 
    136  1.1   rkujawa static struct pic_ops armadaxp_picops = {
    137  1.1   rkujawa 	.pic_unblock_irqs = armadaxp_pic_unblock_irqs,
    138  1.1   rkujawa 	.pic_block_irqs = armadaxp_pic_block_irqs,
    139  1.1   rkujawa 	.pic_establish_irq = armadaxp_pic_establish_irq,
    140  1.1   rkujawa };
    141  1.1   rkujawa 
    142  1.1   rkujawa static struct pic_softc armadaxp_pic = {
    143  1.1   rkujawa 	.pic_ops = &armadaxp_picops,
    144  1.1   rkujawa 	.pic_name = "armadaxp",
    145  1.1   rkujawa };
    146  1.1   rkujawa 
    147  1.1   rkujawa /*
    148  1.1   rkujawa  * armadaxp_intr_bootstrap:
    149  1.1   rkujawa  *
    150  1.1   rkujawa  *	Initialize the rest of the interrupt subsystem, making it
    151  1.1   rkujawa  *	ready to handle interrupts from devices.
    152  1.1   rkujawa  */
    153  1.1   rkujawa void
    154  1.3  kiyohara armadaxp_intr_bootstrap(bus_addr_t pbase)
    155  1.1   rkujawa {
    156  1.1   rkujawa 	int i;
    157  1.1   rkujawa 
    158  1.1   rkujawa 	/* Map MPIC base and MPIC percpu base registers */
    159  1.3  kiyohara 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_BASE,
    160  1.3  kiyohara 	    0x500, 0, &mpic_handle) != 0)
    161  1.1   rkujawa 		panic("%s: Could not map MPIC registers", __func__);
    162  1.3  kiyohara 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_CPU_BASE,
    163  1.3  kiyohara 	    0x800, 0, &mpic_cpu_handle) != 0)
    164  1.1   rkujawa 		panic("%s: Could not map MPIC percpu registers", __func__);
    165  1.1   rkujawa 
    166  1.1   rkujawa 	/* Disable all interrupts */
    167  1.1   rkujawa 	for (i = 0; i < 116; i++)
    168  1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, i);
    169  1.1   rkujawa 
    170  1.1   rkujawa 	mvsoc_intr_init = armadaxp_intr_init;
    171  1.1   rkujawa }
    172  1.1   rkujawa 
    173  1.1   rkujawa static void
    174  1.1   rkujawa armadaxp_intr_init(void)
    175  1.1   rkujawa {
    176  1.1   rkujawa 	int ctrl;
    177  1.1   rkujawa 
    178  1.1   rkujawa 	/* Get max interrupts */
    179  1.1   rkujawa 	armadaxp_pic.pic_maxsources =
    180  1.1   rkujawa 	    ((MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL) >> 2) & 0x7FF);
    181  1.1   rkujawa 
    182  1.1   rkujawa 	if (!armadaxp_pic.pic_maxsources)
    183  1.1   rkujawa 		armadaxp_pic.pic_maxsources = 116;
    184  1.1   rkujawa 
    185  1.1   rkujawa 	pic_add(&armadaxp_pic, 0);
    186  1.1   rkujawa 
    187  1.1   rkujawa 	ctrl = MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL);
    188  1.1   rkujawa 	/* Enable IRQ prioritization */
    189  1.1   rkujawa 	ctrl |= (1 << 0);
    190  1.1   rkujawa 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_CTRL, ctrl);
    191  1.1   rkujawa 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, curcpl() << MPIC_CTP_SHIFT);
    192  1.1   rkujawa }
    193  1.1   rkujawa 
    194  1.1   rkujawa static void
    195  1.1   rkujawa armadaxp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    196  1.1   rkujawa     uint32_t irq_mask)
    197  1.1   rkujawa {
    198  1.1   rkujawa 	int n;
    199  1.1   rkujawa 
    200  1.1   rkujawa 	while (irq_mask != 0) {
    201  1.1   rkujawa 		n = ffs(irq_mask) - 1;
    202  1.1   rkujawa 		KASSERT(pic->pic_maxsources >= n + irqbase);
    203  1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISE, n + irqbase);
    204  1.1   rkujawa 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ICM, n + irqbase);
    205  1.1   rkujawa 		if ((n + irqbase) == 0)
    206  1.1   rkujawa 			MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_DOORBELL_MASK,
    207  1.1   rkujawa 			    0xffffffff);
    208  1.1   rkujawa 		irq_mask &= ~__BIT(n);
    209  1.1   rkujawa 	}
    210  1.1   rkujawa }
    211  1.1   rkujawa 
    212  1.1   rkujawa static void
    213  1.1   rkujawa armadaxp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
    214  1.1   rkujawa     uint32_t irq_mask)
    215  1.1   rkujawa {
    216  1.1   rkujawa 	int n;
    217  1.1   rkujawa 
    218  1.1   rkujawa 	while (irq_mask != 0) {
    219  1.1   rkujawa 		n = ffs(irq_mask) - 1;
    220  1.1   rkujawa 		KASSERT(pic->pic_maxsources >= n + irqbase);
    221  1.1   rkujawa 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, n + irqbase);
    222  1.1   rkujawa 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, n + irqbase);
    223  1.1   rkujawa 		irq_mask &= ~__BIT(n);
    224  1.1   rkujawa 	}
    225  1.1   rkujawa }
    226  1.1   rkujawa 
    227  1.1   rkujawa static void
    228  1.1   rkujawa armadaxp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    229  1.1   rkujawa {
    230  1.1   rkujawa 	int tmp;
    231  1.1   rkujawa 	KASSERT(pic->pic_maxsources >= is->is_irq);
    232  1.1   rkujawa 	tmp = MPIC_READ(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4);
    233  1.1   rkujawa 	/* Clear previous priority */
    234  1.1   rkujawa 	tmp &= ~(0xf << MPIC_ISCR_SHIFT);
    235  1.1   rkujawa 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4,
    236  1.1   rkujawa 	    tmp | (is->is_ipl << MPIC_ISCR_SHIFT));
    237  1.1   rkujawa }
    238  1.1   rkujawa 
    239  1.1   rkujawa void
    240  1.1   rkujawa armadaxp_handle_irq(void *frame)
    241  1.1   rkujawa {
    242  1.1   rkujawa 	struct intrsource *is;
    243  1.1   rkujawa 	int irq;
    244  1.1   rkujawa 	u_int irqstate;
    245  1.1   rkujawa 
    246  1.1   rkujawa 	irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff;
    247  1.1   rkujawa 
    248  1.1   rkujawa 	/* Is it a spurious interrupt ?*/
    249  1.1   rkujawa 	if (irq == 0x3ff)
    250  1.1   rkujawa 		return;
    251  1.1   rkujawa 
    252  1.1   rkujawa 	is = armadaxp_pic.pic_sources[irq];
    253  1.1   rkujawa 	if (is != NULL)  {
    254  1.1   rkujawa 		KASSERT(is->is_ipl > curcpu()->ci_cpl);
    255  1.1   rkujawa 		/* Dispatch irq */
    256  1.1   rkujawa 		irqstate = disable_interrupts(I32_bit);
    257  1.1   rkujawa 		pic_dispatch(is, frame);
    258  1.1   rkujawa 		restore_interrupts(irqstate);
    259  1.1   rkujawa 	}
    260  1.1   rkujawa #ifdef __HAVE_FAST_SOFTINTS
    261  1.1   rkujawa 	cpu_dosoftints();
    262  1.1   rkujawa #endif
    263  1.1   rkujawa }
    264  1.1   rkujawa 
    265  1.1   rkujawa /*
    266  1.1   rkujawa  * Clock functions
    267  1.1   rkujawa  */
    268  1.1   rkujawa 
    269  1.1   rkujawa void
    270  1.1   rkujawa armadaxp_getclks(void)
    271  1.1   rkujawa {
    272  1.1   rkujawa 	uint64_t sar_reg;
    273  1.1   rkujawa 	uint8_t  sar_cpu_freq, sar_fab_freq, array_size;
    274  1.1   rkujawa 
    275  1.1   rkujawa 	if (cputype == CPU_ID_MV88SV584X_V7)
    276  1.1   rkujawa 		mvTclk = 250000000; /* 250 MHz */
    277  1.1   rkujawa 	else
    278  1.1   rkujawa 		mvTclk = 200000000; /* 200 MHz */
    279  1.1   rkujawa 
    280  1.1   rkujawa 	sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) |
    281  1.1   rkujawa 	    read_miscreg(ARMADAXP_MISC_SAR_LO);
    282  1.1   rkujawa 
    283  1.1   rkujawa 	sar_cpu_freq = EXTRACT_CPU_FREQ_FIELD(sar_reg);
    284  1.1   rkujawa 	sar_fab_freq = EXTRACT_FAB_FREQ_FIELD(sar_reg);
    285  1.1   rkujawa 
    286  1.1   rkujawa 	/* Check if CPU frequency field has correct value */
    287  1.1   rkujawa 	array_size = sizeof(cpu_clock_table) / sizeof(cpu_clock_table[0]);
    288  1.1   rkujawa 	if (sar_cpu_freq >= array_size)
    289  1.1   rkujawa 		panic("Reserved value in cpu frequency configuration field: "
    290  1.1   rkujawa 		    "%d", sar_cpu_freq);
    291  1.1   rkujawa 
    292  1.1   rkujawa 	/* Check if fabric frequency field has correct value */
    293  1.1   rkujawa 	array_size = sizeof(freq_conf_table) / sizeof(freq_conf_table[0]);
    294  1.1   rkujawa 	if (sar_fab_freq >= array_size)
    295  1.1   rkujawa 		panic("Reserved value in fabric frequency configuration field: "
    296  1.1   rkujawa 		    "%d", sar_fab_freq);
    297  1.1   rkujawa 
    298  1.1   rkujawa 	/* Get CPU clock frequency */
    299  1.1   rkujawa 	mvPclk = cpu_clock_table[sar_cpu_freq] *
    300  1.1   rkujawa 	    freq_conf_table[sar_fab_freq].vco_cpu;
    301  1.1   rkujawa 
    302  1.1   rkujawa 	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
    303  1.1   rkujawa 	mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c;
    304  1.1   rkujawa 
    305  1.1   rkujawa 	/* Round mvSysclk value to integer MHz */
    306  1.1   rkujawa 	if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
    307  1.1   rkujawa 	    freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
    308  1.1   rkujawa 		mvSysclk++;
    309  1.1   rkujawa 
    310  1.1   rkujawa 	mvPclk = mvPclk * 1000000;
    311  1.1   rkujawa 	mvSysclk = mvSysclk * 1000000;
    312  1.1   rkujawa }
    313  1.1   rkujawa 
    314  1.1   rkujawa /*
    315  1.1   rkujawa  * L2 Cache initialization
    316  1.1   rkujawa  */
    317  1.1   rkujawa 
    318  1.1   rkujawa int
    319  1.3  kiyohara armadaxp_l2_init(bus_addr_t pbase)
    320  1.1   rkujawa {
    321  1.1   rkujawa 	u_int32_t reg;
    322  1.1   rkujawa 	int ret;
    323  1.1   rkujawa 
    324  1.1   rkujawa 	/* Map L2 space */
    325  1.3  kiyohara 	ret = bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_L2_BASE,
    326  1.3  kiyohara 	    0x1000, 0, &l2_handle);
    327  1.1   rkujawa 	if (ret) {
    328  1.1   rkujawa 		printf("%s: Cannot map L2 register space, ret:%d\n",
    329  1.1   rkujawa 		    __func__, ret);
    330  1.1   rkujawa 		return (-1);
    331  1.1   rkujawa 	}
    332  1.1   rkujawa 
    333  1.1   rkujawa 	/* Set L2 policy */
    334  1.1   rkujawa 	reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
    335  1.1   rkujawa 	reg &= ~(L2_WBWT_MODE_MASK);
    336  1.1   rkujawa 	reg &= ~(L2_REP_STRAT_MASK);
    337  1.1   rkujawa 	reg |= L2_REP_STRAT_SEMIPLRU;
    338  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
    339  1.1   rkujawa 
    340  1.1   rkujawa 	/* Invalidate L2 cache */
    341  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
    342  1.1   rkujawa 
    343  1.1   rkujawa 	/* Clear pending L2 interrupts */
    344  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff);
    345  1.1   rkujawa 
    346  1.1   rkujawa 	/* Enable Cache and TLB maintenance broadcast */
    347  1.1   rkujawa 	__asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg));
    348  1.1   rkujawa 	reg |= (1 << 8);
    349  1.1   rkujawa 	__asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg));
    350  1.1   rkujawa 
    351  1.1   rkujawa 	/*
    352  1.1   rkujawa 	 * Set the Point of Coherency and Point of Unification to DRAM.
    353  1.1   rkujawa 	 * This is a reset value but anyway, configure this just in case.
    354  1.1   rkujawa 	 */
    355  1.1   rkujawa 	reg = read_mlmbreg(ARMADAXP_L2_CFU);
    356  1.1   rkujawa 	reg |= (1 << 17) | (1 << 18);
    357  1.1   rkujawa 	write_mlmbreg(ARMADAXP_L2_CFU, reg);
    358  1.1   rkujawa 
    359  1.1   rkujawa 	/* Enable L2 cache */
    360  1.1   rkujawa 	reg = L2_READ(ARMADAXP_L2_CTRL);
    361  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_ENABLE);
    362  1.1   rkujawa 
    363  1.1   rkujawa 	/* Mark as enabled */
    364  1.1   rkujawa 	l2cache_state = 1;
    365  1.1   rkujawa 
    366  1.1   rkujawa #ifdef DEBUG
    367  1.1   rkujawa 	/* Configure and enable counter */
    368  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
    369  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
    370  1.1   rkujawa 	L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303);
    371  1.1   rkujawa #endif
    372  1.1   rkujawa 
    373  1.1   rkujawa 	return (0);
    374  1.1   rkujawa }
    375  1.1   rkujawa 
    376  1.1   rkujawa void
    377  1.1   rkujawa armadaxp_io_coherency_init(void)
    378  1.1   rkujawa {
    379  1.1   rkujawa 	uint32_t reg;
    380  1.1   rkujawa 
    381  1.1   rkujawa 	/* set CIB read snoop command to ReadUnique */
    382  1.1   rkujawa 	reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG);
    383  1.1   rkujawa 	reg &= ~(7 << 16);
    384  1.1   rkujawa 	reg |= (7 << 16);
    385  1.1   rkujawa 	write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg);
    386  1.1   rkujawa 	/* enable CPUs in SMP group on Fabric coherency */
    387  1.1   rkujawa 	reg = read_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CTRL);
    388  1.1   rkujawa 	reg &= ~(0x3 << 24);
    389  1.1   rkujawa 	reg |= (1 << 24);
    390  1.1   rkujawa 	write_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CTRL, reg);
    391  1.1   rkujawa 
    392  1.1   rkujawa 	reg = read_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CFG);
    393  1.1   rkujawa 	reg &= ~(0x3 << 24);
    394  1.1   rkujawa 	reg |= (1 << 24);
    395  1.1   rkujawa 	write_mlmbreg(MVSOC_MLMB_COHERENCY_FABRIC_CFG, reg);
    396  1.1   rkujawa 
    397  1.1   rkujawa 	/* Mark as enabled */
    398  1.1   rkujawa 	iocc_state = 1;
    399  1.1   rkujawa }
    400