mv78xx0.c revision 1.2 1 1.2 kiyohara /* $NetBSD: mv78xx0.c,v 1.2 2017/01/07 16:19:28 kiyohara 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.2 kiyohara __KERNEL_RCSID(0, "$NetBSD: mv78xx0.c,v 1.2 2017/01/07 16:19:28 kiyohara 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.1 kiyohara reg = *(volatile uint32_t *)(iobase + MV78XX0_SAMPLE_AT_RESET_HIGH);
218 1.1 kiyohara switch (reg & 0x180) {
219 1.1 kiyohara case 0x000: mvTclk = 166666667; break;
220 1.1 kiyohara case 0x080: mvTclk = 200 MHz; break;
221 1.1 kiyohara default: mvTclk = 200 MHz; break;
222 1.1 kiyohara }
223 1.1 kiyohara
224 1.1 kiyohara reg = *(volatile uint32_t *)(iobase + MV78XX0_SAMPLE_AT_RESET_LOW);
225 1.1 kiyohara
226 1.1 kiyohara switch (reg & 0x0e0) {
227 1.1 kiyohara case 0x020: mvSysclk = 200 MHz; break;
228 1.1 kiyohara case 0x040: mvSysclk = 266666667; break;
229 1.1 kiyohara case 0x060: mvSysclk = 333333334; break;
230 1.1 kiyohara case 0x080: mvSysclk = 400 MHz; break;
231 1.1 kiyohara case 0x0a0: mvSysclk = 250 MHz; break;
232 1.1 kiyohara case 0x0c0: mvSysclk = 300 MHz; break;
233 1.1 kiyohara default: mvSysclk = 266666667; break;
234 1.1 kiyohara }
235 1.1 kiyohara
236 1.1 kiyohara x = (reg & 0xf00) >> 8;
237 1.1 kiyohara mvPclk = sys2cpu_clk_ratio_m[x] * mvSysclk / sys2cpu_clk_ratio_n[x];
238 1.1 kiyohara
239 1.1 kiyohara #undef MHz
240 1.1 kiyohara
241 1.1 kiyohara }
242