Home | History | Annotate | Line # | Download | only in marvell
      1  1.7       rin /*	$NetBSD: orion.c,v 1.7 2021/08/30 00:04:30 rin Exp $	*/
      2  1.1  kiyohara /*
      3  1.1  kiyohara  * Copyright (c) 2010 KIYOHARA Takashi
      4  1.1  kiyohara  * All rights reserved.
      5  1.1  kiyohara  *
      6  1.1  kiyohara  * Redistribution and use in source and binary forms, with or without
      7  1.1  kiyohara  * modification, are permitted provided that the following conditions
      8  1.1  kiyohara  * are met:
      9  1.1  kiyohara  * 1. Redistributions of source code must retain the above copyright
     10  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer.
     11  1.1  kiyohara  * 2. Redistributions in binary form must reproduce the above copyright
     12  1.1  kiyohara  *    notice, this list of conditions and the following disclaimer in the
     13  1.1  kiyohara  *    documentation and/or other materials provided with the distribution.
     14  1.1  kiyohara  *
     15  1.1  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  1.1  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17  1.1  kiyohara  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18  1.1  kiyohara  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
     19  1.1  kiyohara  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     20  1.1  kiyohara  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21  1.1  kiyohara  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22  1.1  kiyohara  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     23  1.1  kiyohara  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     24  1.1  kiyohara  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  1.1  kiyohara  * POSSIBILITY OF SUCH DAMAGE.
     26  1.1  kiyohara  */
     27  1.1  kiyohara 
     28  1.1  kiyohara #include <sys/cdefs.h>
     29  1.7       rin __KERNEL_RCSID(0, "$NetBSD: orion.c,v 1.7 2021/08/30 00:04:30 rin Exp $");
     30  1.1  kiyohara 
     31  1.1  kiyohara #define _INTR_PRIVATE
     32  1.1  kiyohara 
     33  1.1  kiyohara #include "mvsocgpp.h"
     34  1.1  kiyohara 
     35  1.1  kiyohara #include <sys/param.h>
     36  1.1  kiyohara #include <sys/bus.h>
     37  1.1  kiyohara 
     38  1.1  kiyohara #include <machine/intr.h>
     39  1.1  kiyohara 
     40  1.1  kiyohara #include <arm/pic/picvar.h>
     41  1.1  kiyohara #include <arm/pic/picvar.h>
     42  1.1  kiyohara 
     43  1.1  kiyohara #include <arm/marvell/mvsocreg.h>
     44  1.1  kiyohara #include <arm/marvell/mvsocvar.h>
     45  1.1  kiyohara #include <arm/marvell/orionreg.h>
     46  1.1  kiyohara 
     47  1.1  kiyohara #include <dev/marvell/marvellreg.h>
     48  1.1  kiyohara 
     49  1.1  kiyohara 
     50  1.1  kiyohara static void orion_intr_init(void);
     51  1.1  kiyohara 
     52  1.1  kiyohara static void orion_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     53  1.1  kiyohara static void orion_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     54  1.1  kiyohara static void orion_pic_establish_irq(struct pic_softc *, struct intrsource *);
     55  1.1  kiyohara static void orion_pic_source_name(struct pic_softc *, int, char *, size_t);
     56  1.1  kiyohara 
     57  1.1  kiyohara static int orion_find_pending_irqs(void);
     58  1.1  kiyohara 
     59  1.6  kiyohara static void orion_getclks(vaddr_t);
     60  1.6  kiyohara 
     61  1.1  kiyohara static const char * const sources[64] = {
     62  1.1  kiyohara     "Bridge(0)",       "Host2CPU DB(1)",  "CPU2Host DB(2)",  "UART0(3)",
     63  1.1  kiyohara     "UART1(4)",        "TWSI(5)",         "GPIO7_0(6)",      "GPIO15_8(7)",
     64  1.1  kiyohara     "GPIO23_16(8)",    "GPIO31_24(9)",    "PEX0Err(10)",     "PEX0INT(11)",
     65  1.1  kiyohara     "PEX1Err/USBCnt1", "PEX1INT(13)",     "DEVErr(14)",      "PCIErr(15)",
     66  1.1  kiyohara     "USBBr(16)",       "USBCnt0(17)",     "GbERx(18)",       "GbETx(19)",
     67  1.1  kiyohara     "GbEMisc(20)",     "GbESum(21)",      "GbEErr(22)",      "DMAErr(23)",
     68  1.1  kiyohara     "IDMA0(24)",       "IDMA1(25)",       "IDMA2(26)",       "IDMA3(27)",
     69  1.1  kiyohara     "SecIntr(28)",     "SataIntr(29)",    "XOR0(30)",        "XOR1(31)"
     70  1.1  kiyohara };
     71  1.1  kiyohara 
     72  1.1  kiyohara static struct pic_ops orion_picops = {
     73  1.1  kiyohara 	.pic_unblock_irqs = orion_pic_unblock_irqs,
     74  1.1  kiyohara 	.pic_block_irqs = orion_pic_block_irqs,
     75  1.1  kiyohara 	.pic_establish_irq = orion_pic_establish_irq,
     76  1.1  kiyohara 	.pic_source_name = orion_pic_source_name,
     77  1.1  kiyohara };
     78  1.1  kiyohara static struct pic_softc orion_pic = {
     79  1.1  kiyohara 	.pic_ops = &orion_picops,
     80  1.1  kiyohara 	.pic_maxsources = 32,
     81  1.1  kiyohara 	.pic_name = "orion_pic",
     82  1.1  kiyohara };
     83  1.1  kiyohara 
     84  1.1  kiyohara 
     85  1.1  kiyohara /*
     86  1.6  kiyohara  * orion_bootstrap:
     87  1.1  kiyohara  *
     88  1.6  kiyohara  *	Initialize the rest of the Orion dependences, making it
     89  1.1  kiyohara  *	ready to handle interrupts from devices.
     90  1.1  kiyohara  */
     91  1.1  kiyohara void
     92  1.6  kiyohara orion_bootstrap(vaddr_t iobase)
     93  1.1  kiyohara {
     94  1.1  kiyohara 
     95  1.1  kiyohara 	/* disable all interrupts */
     96  1.1  kiyohara 	write_mlmbreg(ORION_MLMB_MIRQIMR, 0);
     97  1.1  kiyohara 
     98  1.1  kiyohara 	/* disable all bridge interrupts */
     99  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_MLMBIMR, 0);
    100  1.1  kiyohara 
    101  1.1  kiyohara 	mvsoc_intr_init = orion_intr_init;
    102  1.1  kiyohara 
    103  1.1  kiyohara #if NMVSOCGPP > 0
    104  1.1  kiyohara 	gpp_npins = 32;
    105  1.1  kiyohara 	gpp_irqbase = 64;	/* Main(32) + Bridge(32) */
    106  1.1  kiyohara #endif
    107  1.6  kiyohara 
    108  1.6  kiyohara 	orion_getclks(iobase);
    109  1.1  kiyohara }
    110  1.1  kiyohara 
    111  1.1  kiyohara static void
    112  1.1  kiyohara orion_intr_init(void)
    113  1.1  kiyohara {
    114  1.1  kiyohara 	extern struct pic_softc mvsoc_bridge_pic;
    115  1.5    martin 	void *ih __diagused;
    116  1.1  kiyohara 
    117  1.1  kiyohara 	pic_add(&orion_pic, 0);
    118  1.1  kiyohara 
    119  1.1  kiyohara 	pic_add(&mvsoc_bridge_pic, 32);
    120  1.1  kiyohara 	ih = intr_establish(ORION_IRQ_BRIDGE, IPL_HIGH, IST_LEVEL_HIGH,
    121  1.1  kiyohara 	    pic_handle_intr, &mvsoc_bridge_pic);
    122  1.1  kiyohara 	KASSERT(ih != NULL);
    123  1.1  kiyohara 
    124  1.1  kiyohara 	find_pending_irqs = orion_find_pending_irqs;
    125  1.1  kiyohara }
    126  1.1  kiyohara 
    127  1.1  kiyohara /* ARGSUSED */
    128  1.1  kiyohara static void
    129  1.1  kiyohara orion_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
    130  1.1  kiyohara {
    131  1.1  kiyohara 
    132  1.1  kiyohara 	write_mlmbreg(ORION_MLMB_MIRQIMR,
    133  1.1  kiyohara 	    read_mlmbreg(ORION_MLMB_MIRQIMR) | irq_mask);
    134  1.1  kiyohara }
    135  1.1  kiyohara 
    136  1.1  kiyohara /* ARGSUSED */
    137  1.1  kiyohara static void
    138  1.1  kiyohara orion_pic_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
    139  1.1  kiyohara {
    140  1.1  kiyohara 
    141  1.1  kiyohara 	write_mlmbreg(ORION_MLMB_MIRQIMR,
    142  1.1  kiyohara 	    read_mlmbreg(ORION_MLMB_MIRQIMR) & ~irq_mask);
    143  1.1  kiyohara }
    144  1.1  kiyohara 
    145  1.1  kiyohara /* ARGSUSED */
    146  1.1  kiyohara static void
    147  1.1  kiyohara orion_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    148  1.1  kiyohara {
    149  1.1  kiyohara 	/* Nothing */
    150  1.1  kiyohara }
    151  1.1  kiyohara 
    152  1.1  kiyohara static void
    153  1.1  kiyohara orion_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
    154  1.1  kiyohara {
    155  1.1  kiyohara 
    156  1.1  kiyohara 	strlcpy(buf, sources[pic->pic_irqbase + irq], len);
    157  1.1  kiyohara }
    158  1.1  kiyohara 
    159  1.1  kiyohara /*
    160  1.1  kiyohara  * Called with interrupts disabled
    161  1.1  kiyohara  */
    162  1.1  kiyohara static int
    163  1.1  kiyohara orion_find_pending_irqs(void)
    164  1.1  kiyohara {
    165  1.1  kiyohara 	uint32_t pending;
    166  1.1  kiyohara 
    167  1.1  kiyohara 	pending =
    168  1.1  kiyohara 	    read_mlmbreg(ORION_MLMB_MICR) & read_mlmbreg(ORION_MLMB_MIRQIMR);
    169  1.1  kiyohara 	if (pending == 0)
    170  1.1  kiyohara 		return 0;
    171  1.1  kiyohara 
    172  1.1  kiyohara 	return pic_mark_pending_sources(&orion_pic, 0, pending);
    173  1.1  kiyohara }
    174  1.1  kiyohara 
    175  1.1  kiyohara /*
    176  1.1  kiyohara  * Clock functions
    177  1.1  kiyohara  */
    178  1.1  kiyohara 
    179  1.6  kiyohara static void
    180  1.6  kiyohara orion_getclks(vaddr_t iobase)
    181  1.1  kiyohara {
    182  1.2  jakllsch 	static const struct {
    183  1.1  kiyohara 		int armddrclkval;
    184  1.1  kiyohara 		uint32_t pclk;
    185  1.1  kiyohara 		uint32_t sysclk;
    186  1.1  kiyohara 	} sysclktbl[] = {
    187  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_333_167, 333000000, 166666667 },
    188  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_400_200, 400000000, 200000000 },
    189  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_400_133, 400000000, 133333334 },
    190  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_500_167, 500000000, 166666667 },
    191  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_533_133, 533000000, 133333334 },
    192  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_600_200, 600000000, 200000000 },
    193  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_667_167, 667000000, 166666667 },
    194  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_800_200, 800000000, 200000000 },
    195  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_480_160, 480000000, 160000000 },
    196  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_550_183, 550000000, 183333334 },
    197  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_525_175, 525000000, 175000000 },
    198  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_466_233, 466000000, 233000000 },
    199  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_500_250, 500000000, 250000000 },
    200  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_533_266, 533000000, 266000000 },
    201  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_600_300, 600000000, 300000000 },
    202  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_450_150, 450000000, 150000000 },
    203  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_533_178, 533000000, 178000000 },
    204  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_575_192, 575000000, 192000000 },
    205  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_700_175, 700000000, 175000000 },
    206  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_733_183, 733000000, 183333334 },
    207  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_750_187, 750000000, 187000000 },
    208  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_775_194, 775000000, 194000000 },
    209  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_500_125, 500000000, 125000000 },
    210  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_500_100, 500000000, 100000000 },
    211  1.1  kiyohara 		{ ORION_PMISMPL_ARMDDRCLK_600_150, 600000000, 150000000 },
    212  1.1  kiyohara 	};
    213  1.1  kiyohara 	uint32_t reg, armddrclk, tclk;
    214  1.1  kiyohara 	uint16_t model;
    215  1.1  kiyohara 	int armddrclk_shift, tclk_shift, i;
    216  1.1  kiyohara 
    217  1.1  kiyohara 	model = mvsoc_model();
    218  1.1  kiyohara 	if (model == MARVELL_ORION_1_88F1181 ||
    219  1.1  kiyohara 	    model == MARVELL_ORION_2_88F1281) {
    220  1.1  kiyohara 		armddrclk_shift = 6;
    221  1.1  kiyohara 		tclk_shift = 10;
    222  1.1  kiyohara 	} else {
    223  1.1  kiyohara 		armddrclk_shift = 4;
    224  1.1  kiyohara 		tclk_shift = 8;
    225  1.1  kiyohara 	}
    226  1.1  kiyohara 
    227  1.7       rin 	reg = le32toh(*(volatile uint32_t *)(iobase + ORION_PMI_BASE +
    228  1.7       rin 	    ORION_PMI_SAMPLE_AT_RESET));
    229  1.1  kiyohara 	armddrclk = (reg >> armddrclk_shift) & ORION_PMISMPL_ARMDDRCLK_MASK;
    230  1.1  kiyohara 	if (model == PCI_PRODUCT_MARVELL_88F5281)
    231  1.1  kiyohara 		if (reg & ORION_PMISMPL_ARMDDRCLK_H_MASK)
    232  1.1  kiyohara 			armddrclk |= 0x00000010;	/* set to bit4 */
    233  1.2  jakllsch 	for (i = 0; i < __arraycount(sysclktbl); i++)
    234  1.1  kiyohara 		if (armddrclk == sysclktbl[i].armddrclkval) {
    235  1.1  kiyohara 			mvPclk = sysclktbl[i].pclk;
    236  1.1  kiyohara 			mvSysclk = sysclktbl[i].sysclk;
    237  1.1  kiyohara 			break;
    238  1.1  kiyohara 		}
    239  1.1  kiyohara 
    240  1.1  kiyohara 	tclk = (reg >> tclk_shift) & ORION_PMISMPL_TCLK_MASK;
    241  1.1  kiyohara 	switch (tclk) {
    242  1.1  kiyohara 	case ORION_PMISMPL_TCLK_133:
    243  1.3  jakllsch 		mvTclk = 133333333;	/* 133MHz */
    244  1.1  kiyohara 		break;
    245  1.1  kiyohara 
    246  1.1  kiyohara 	case ORION_PMISMPL_TCLK_150:
    247  1.1  kiyohara 		mvTclk = 150000000;	/* 150MHz */
    248  1.1  kiyohara 		break;
    249  1.1  kiyohara 
    250  1.1  kiyohara 	case ORION_PMISMPL_TCLK_166:
    251  1.1  kiyohara 		mvTclk = 166666667;	/* 166MHz */
    252  1.1  kiyohara 		break;
    253  1.1  kiyohara 
    254  1.1  kiyohara 	default:
    255  1.1  kiyohara 		mvTclk = 100000000;	/* 100MHz */
    256  1.1  kiyohara 		break;
    257  1.1  kiyohara 	}
    258  1.1  kiyohara }
    259