orion.c revision 1.7 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