Home | History | Annotate | Line # | Download | only in marvell
      1  1.3       rin /*	$NetBSD: mv78xx0.c,v 1.3 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.3       rin __KERNEL_RCSID(0, "$NetBSD: mv78xx0.c,v 1.3 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 #include <sys/cpu.h>
     38  1.1  kiyohara 
     39  1.1  kiyohara #include <machine/intr.h>
     40  1.1  kiyohara 
     41  1.1  kiyohara #include <arm/pic/picvar.h>
     42  1.1  kiyohara #include <arm/pic/picvar.h>
     43  1.1  kiyohara 
     44  1.1  kiyohara #include <arm/marvell/mvsocreg.h>
     45  1.1  kiyohara #include <arm/marvell/mvsocvar.h>
     46  1.1  kiyohara #include <arm/marvell/mv78xx0reg.h>
     47  1.1  kiyohara 
     48  1.1  kiyohara #include <dev/marvell/marvellreg.h>
     49  1.1  kiyohara 
     50  1.1  kiyohara #define MV78XX0_ICI_MICR(g)	(MV78XX0_ICI_MICLR + ((g) << 2))
     51  1.1  kiyohara #define MV78XX0_ICI_IRQIMR(g)	(MV78XX0_ICI_IRQIMLR + ((g) << 2))
     52  1.1  kiyohara 
     53  1.1  kiyohara static void mv78xx0_intr_init(void);
     54  1.1  kiyohara 
     55  1.1  kiyohara static void mv78xx0_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
     56  1.1  kiyohara static void mv78xx0_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
     57  1.1  kiyohara static void mv78xx0_pic_establish_irq(struct pic_softc *, struct intrsource *);
     58  1.1  kiyohara static void mv78xx0_pic_source_name(struct pic_softc *, int, char *, size_t);
     59  1.1  kiyohara 
     60  1.1  kiyohara static int mv78xx0_find_pending_irqs(void);
     61  1.1  kiyohara 
     62  1.2  kiyohara static void mv78xx0_getclks(vaddr_t);
     63  1.2  kiyohara 
     64  1.1  kiyohara static const char * const sources[64] = {
     65  1.1  kiyohara     "ErrSum(0)",       "SPI(1)",          "TWSI0(2)",        "TWSI1(3)",
     66  1.1  kiyohara     "IDMA0(4)",        "IDMA1(5)",        "IDMA2(6)",        "IDMA3(7)",
     67  1.1  kiyohara     "Timer0(8)",       "Timer1(9)",       "Timer2(10)",      "Timer3(11)",
     68  1.1  kiyohara     "UART0(12)",       "UART1(13)",       "UART2(14)",       "UART3(15)",
     69  1.1  kiyohara     "USB0(16)",        "USB1(17)",        "USB2(18)",        "Crypto(19)",
     70  1.1  kiyohara     "Reserved(20)",    "Reserved(21)",    "XOR0(22)",        "XOR1(23)",
     71  1.1  kiyohara     "Reserved(24)",    "Reserved(25)",    "SATA(26)",        "TDMI_INT(27)",
     72  1.1  kiyohara     "Reserved(28)",    "Reserved(29)",    "Reserved(30)",    "Reserved(31)"
     73  1.1  kiyohara 
     74  1.1  kiyohara     "PEX00INTA(32)",   "PEX01INTA(33)",   "PEX02INTA(34)",   "PEX03INTA(35)"
     75  1.1  kiyohara     "PEX10INTA(36)",   "PEX11INTA(37)",   "PEX12INTA(38)",   "PEX13INTA(39)"
     76  1.1  kiyohara     "GE00Sum(40)",     "GE00Rx(41)",      "GE00Tx(42)",      "GE00Misc(43)"
     77  1.1  kiyohara     "GE01Sum(44)",     "GE01Rx(45)",      "GE01Tx(46)",      "GE01Misc(47)"
     78  1.1  kiyohara     "GE10Sum(48)",     "GE10Rx(49)",      "GE10Tx(50)",      "GE10Misc(51)"
     79  1.1  kiyohara     "GE11Sum(52)",     "GE11Rx(53)",      "GE11Tx(54)",      "GE11Misc(55)"
     80  1.1  kiyohara     "GPIO0_7(56)",     "GPIO8_15(57)",    "GPIO16_23(58)",   "GPIO24_31(59)"
     81  1.1  kiyohara     "DB_INT(60)",      "DB_OUT(61)",      "Reserved(62)",    "Reserved(63)"
     82  1.1  kiyohara };
     83  1.1  kiyohara 
     84  1.1  kiyohara static struct pic_ops mv78xx0_picops = {
     85  1.1  kiyohara 	.pic_unblock_irqs = mv78xx0_pic_unblock_irqs,
     86  1.1  kiyohara 	.pic_block_irqs = mv78xx0_pic_block_irqs,
     87  1.1  kiyohara 	.pic_establish_irq = mv78xx0_pic_establish_irq,
     88  1.1  kiyohara 	.pic_source_name = mv78xx0_pic_source_name,
     89  1.1  kiyohara };
     90  1.1  kiyohara static struct pic_softc mv78xx0_pic = {
     91  1.1  kiyohara 	.pic_ops = &mv78xx0_picops,
     92  1.1  kiyohara 	.pic_maxsources = 64,
     93  1.1  kiyohara 	.pic_name = "mv78xx0_pic",
     94  1.1  kiyohara };
     95  1.1  kiyohara 
     96  1.1  kiyohara 
     97  1.1  kiyohara /*
     98  1.2  kiyohara  * mv78xx0_bootstrap:
     99  1.1  kiyohara  *
    100  1.2  kiyohara  *	Initialize the rest of the Discovery Innovation dependencies, making it
    101  1.1  kiyohara  *	ready to handle interrupts from devices.
    102  1.1  kiyohara  */
    103  1.1  kiyohara void
    104  1.2  kiyohara mv78xx0_bootstrap(vaddr_t iobase)
    105  1.1  kiyohara {
    106  1.1  kiyohara 
    107  1.1  kiyohara 	/* disable all interrupts */
    108  1.1  kiyohara 	write_mlmbreg(MV78XX0_ICI_IRQIMER, 0);
    109  1.1  kiyohara 	write_mlmbreg(MV78XX0_ICI_IRQIMLR, 0);
    110  1.1  kiyohara 	write_mlmbreg(MV78XX0_ICI_IRQIMHR, 0);
    111  1.1  kiyohara 
    112  1.1  kiyohara 	/* disable all bridge interrupts */
    113  1.1  kiyohara 	write_mlmbreg(MVSOC_MLMB_MLMBIMR, 0);
    114  1.1  kiyohara 
    115  1.1  kiyohara 	mvsoc_intr_init = mv78xx0_intr_init;
    116  1.1  kiyohara 
    117  1.2  kiyohara #if NMVSOCGPP > 0
    118  1.1  kiyohara 	gpp_npins = 32;
    119  1.1  kiyohara 	gpp_irqbase = 64;	/* Main Low(32) + High(32) */
    120  1.2  kiyohara #endif
    121  1.2  kiyohara 
    122  1.2  kiyohara 	mv78xx0_getclks(iobase);
    123  1.1  kiyohara }
    124  1.1  kiyohara 
    125  1.1  kiyohara static void
    126  1.1  kiyohara mv78xx0_intr_init(void)
    127  1.1  kiyohara {
    128  1.1  kiyohara 
    129  1.1  kiyohara 	pic_add(&mv78xx0_pic, 0);
    130  1.1  kiyohara 
    131  1.1  kiyohara 	find_pending_irqs = mv78xx0_find_pending_irqs;
    132  1.1  kiyohara }
    133  1.1  kiyohara 
    134  1.1  kiyohara /* ARGSUSED */
    135  1.1  kiyohara static void
    136  1.1  kiyohara mv78xx0_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
    137  1.1  kiyohara 			 uint32_t irq_mask)
    138  1.1  kiyohara {
    139  1.1  kiyohara 	const size_t group = irqbase / 32;
    140  1.1  kiyohara 
    141  1.1  kiyohara 	write_mlmbreg(MV78XX0_ICI_IRQIMR(group),
    142  1.1  kiyohara 	    read_mlmbreg(MV78XX0_ICI_IRQIMR(group)) | 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 mv78xx0_pic_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t irq_mask)
    148  1.1  kiyohara {
    149  1.1  kiyohara 	const size_t group = irqbase / 32;
    150  1.1  kiyohara 
    151  1.1  kiyohara 	write_mlmbreg(MV78XX0_ICI_IRQIMR(group),
    152  1.1  kiyohara 	    read_mlmbreg(MV78XX0_ICI_IRQIMR(group)) & ~irq_mask);
    153  1.1  kiyohara }
    154  1.1  kiyohara 
    155  1.1  kiyohara /* ARGSUSED */
    156  1.1  kiyohara static void
    157  1.1  kiyohara mv78xx0_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
    158  1.1  kiyohara {
    159  1.1  kiyohara 	uint32_t mlmbim;
    160  1.1  kiyohara 
    161  1.1  kiyohara 	/* Also enable MbusL-Mbus Bridge Interrupt Mask, if irq is TimerX. */
    162  1.1  kiyohara 	if (is->is_irq == MV78XX0_IRQ_TIMER0 ||
    163  1.1  kiyohara 	    is->is_irq == MV78XX0_IRQ_TIMER1 ||
    164  1.1  kiyohara 	    is->is_irq == MV78XX0_IRQ_TIMER2 ||
    165  1.1  kiyohara 	    is->is_irq == MV78XX0_IRQ_TIMER3) {
    166  1.1  kiyohara 		mlmbim = read_mlmbreg(MVSOC_MLMB_MLMBIMR);
    167  1.1  kiyohara 		mlmbim |= TIMER_IRQ2MLMBIMR(is->is_irq);
    168  1.1  kiyohara 		write_mlmbreg(MVSOC_MLMB_MLMBIMR, mlmbim);
    169  1.1  kiyohara 	}
    170  1.1  kiyohara }
    171  1.1  kiyohara 
    172  1.1  kiyohara static void
    173  1.1  kiyohara mv78xx0_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
    174  1.1  kiyohara {
    175  1.1  kiyohara 
    176  1.1  kiyohara 	strlcpy(buf, sources[pic->pic_irqbase + irq], len);
    177  1.1  kiyohara }
    178  1.1  kiyohara 
    179  1.1  kiyohara /*
    180  1.1  kiyohara  * Called with interrupts disabled
    181  1.1  kiyohara  */
    182  1.1  kiyohara static int
    183  1.1  kiyohara mv78xx0_find_pending_irqs(void)
    184  1.1  kiyohara {
    185  1.1  kiyohara 	uint32_t pending;
    186  1.1  kiyohara 	int ipl = 0;
    187  1.1  kiyohara 
    188  1.1  kiyohara 	pending = read_mlmbreg(MV78XX0_ICI_MICR(0)) &
    189  1.1  kiyohara 	    read_mlmbreg(MV78XX0_ICI_IRQIMR(0));
    190  1.1  kiyohara 	if (pending != 0)
    191  1.1  kiyohara 		ipl = pic_mark_pending_sources(&mv78xx0_pic, 0, pending);
    192  1.1  kiyohara 
    193  1.1  kiyohara 	pending = read_mlmbreg(MV78XX0_ICI_MICR(1)) &
    194  1.1  kiyohara 	    read_mlmbreg(MV78XX0_ICI_IRQIMR(1));
    195  1.1  kiyohara 	if (pending != 0)
    196  1.1  kiyohara 		ipl |= pic_mark_pending_sources(&mv78xx0_pic, 32, pending);
    197  1.1  kiyohara 
    198  1.1  kiyohara 	return ipl;
    199  1.1  kiyohara }
    200  1.1  kiyohara 
    201  1.1  kiyohara /*
    202  1.1  kiyohara  * Clock functions
    203  1.1  kiyohara  */
    204  1.1  kiyohara 
    205  1.2  kiyohara static void
    206  1.2  kiyohara mv78xx0_getclks(vaddr_t iobase)
    207  1.1  kiyohara {
    208  1.1  kiyohara 	const static int sys2cpu_clk_ratio_m[] =	/* Mul constant */
    209  1.1  kiyohara 	    { 1, 3, 2, 5, 3, 7, 4, 9, 5, 1, 6 };
    210  1.1  kiyohara 	const static int sys2cpu_clk_ratio_n[] =	/* Div constant */
    211  1.1  kiyohara 	    { 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 };
    212  1.1  kiyohara 	uint32_t reg;
    213  1.1  kiyohara 	int x;
    214  1.1  kiyohara 
    215  1.1  kiyohara #define MHz	* 1000 * 1000
    216  1.1  kiyohara 
    217  1.3       rin 	reg = le32toh(*(volatile uint32_t *)(iobase +
    218  1.3       rin 	    MV78XX0_SAMPLE_AT_RESET_HIGH));
    219  1.1  kiyohara 	switch (reg & 0x180) {
    220  1.1  kiyohara 	case 0x000: mvTclk = 166666667; break;
    221  1.1  kiyohara 	case 0x080: mvTclk =   200 MHz; break;
    222  1.1  kiyohara 	default:    mvTclk =   200 MHz; break;
    223  1.1  kiyohara 	}
    224  1.1  kiyohara 
    225  1.3       rin 	reg = le32toh(*(volatile uint32_t *)(iobase +
    226  1.3       rin 	    MV78XX0_SAMPLE_AT_RESET_LOW));
    227  1.1  kiyohara 
    228  1.1  kiyohara 	switch (reg & 0x0e0) {
    229  1.1  kiyohara 	case 0x020: mvSysclk =   200 MHz; break;
    230  1.1  kiyohara 	case 0x040: mvSysclk = 266666667; break;
    231  1.1  kiyohara 	case 0x060: mvSysclk = 333333334; break;
    232  1.1  kiyohara 	case 0x080: mvSysclk =   400 MHz; break;
    233  1.1  kiyohara 	case 0x0a0: mvSysclk =   250 MHz; break;
    234  1.1  kiyohara 	case 0x0c0: mvSysclk =   300 MHz; break;
    235  1.1  kiyohara 	default:    mvSysclk = 266666667; break;
    236  1.1  kiyohara 	}
    237  1.1  kiyohara 
    238  1.1  kiyohara 	x = (reg & 0xf00) >> 8;
    239  1.1  kiyohara 	mvPclk = sys2cpu_clk_ratio_m[x] * mvSysclk / sys2cpu_clk_ratio_n[x];
    240  1.1  kiyohara 
    241  1.1  kiyohara #undef MHz
    242  1.1  kiyohara 
    243  1.1  kiyohara }
    244