design_gsrd2.c revision 1.4.68.1 1 1.4.68.1 thorpej /* $NetBSD: design_gsrd2.c,v 1.4.68.1 2021/04/02 22:17:39 thorpej Exp $ */
2 1.1 freza
3 1.1 freza /*
4 1.1 freza * Copyright (c) 2006 Jachym Holecek
5 1.1 freza * All rights reserved.
6 1.1 freza *
7 1.1 freza * Written for DFC Design, s.r.o.
8 1.1 freza *
9 1.1 freza * Redistribution and use in source and binary forms, with or without
10 1.1 freza * modification, are permitted provided that the following conditions
11 1.1 freza * are met:
12 1.1 freza *
13 1.1 freza * 1. Redistributions of source code must retain the above copyright
14 1.1 freza * notice, this list of conditions and the following disclaimer.
15 1.1 freza *
16 1.1 freza * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 freza * notice, this list of conditions and the following disclaimer in the
18 1.1 freza * documentation and/or other materials provided with the distribution.
19 1.1 freza *
20 1.1 freza * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.1 freza * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.1 freza * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.1 freza * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.1 freza * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 1.1 freza * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 1.1 freza * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 1.1 freza * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 1.1 freza * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 1.1 freza * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 1.1 freza */
31 1.1 freza
32 1.1 freza #include "opt_virtex.h"
33 1.1 freza
34 1.1 freza #include <sys/cdefs.h>
35 1.4.68.1 thorpej __KERNEL_RCSID(0, "$NetBSD: design_gsrd2.c,v 1.4.68.1 2021/04/02 22:17:39 thorpej Exp $");
36 1.1 freza
37 1.1 freza #include <sys/param.h>
38 1.1 freza #include <sys/systm.h>
39 1.1 freza #include <sys/device.h>
40 1.1 freza #include <sys/kernel.h>
41 1.1 freza #include <sys/malloc.h>
42 1.1 freza #include <sys/extent.h>
43 1.4 matt #include <sys/cpu.h>
44 1.4 matt #include <sys/bus.h>
45 1.4 matt #include <sys/intr.h>
46 1.1 freza
47 1.1 freza #include <machine/powerpc.h>
48 1.1 freza #include <machine/tlb.h>
49 1.1 freza
50 1.4 matt #include <powerpc/ibm4xx/cpu.h>
51 1.1 freza #include <powerpc/ibm4xx/dev/plbvar.h>
52 1.1 freza
53 1.1 freza #include <evbppc/virtex/dev/xcvbusvar.h>
54 1.1 freza #include <evbppc/virtex/dev/cdmacreg.h>
55 1.1 freza #include <evbppc/virtex/dev/temacreg.h>
56 1.1 freza #include <evbppc/virtex/dev/tftreg.h>
57 1.1 freza
58 1.1 freza #include <evbppc/virtex/virtex.h>
59 1.1 freza #include <evbppc/virtex/dcr.h>
60 1.1 freza
61 1.1 freza
62 1.1 freza #define DCR_TEMAC_BASE 0x0030
63 1.1 freza #define DCR_TFT0_BASE 0x0082
64 1.1 freza #define DCR_TFT1_BASE 0x0086
65 1.1 freza #define DCR_CDMAC_BASE 0x0140
66 1.1 freza
67 1.1 freza #define OPB_BASE 0x80000000 /* below are offsets in opb */
68 1.1 freza #define OPB_XLCOM_BASE 0x010000
69 1.1 freza #define OPB_GPIO_BASE 0x020000
70 1.1 freza #define OPB_PSTWO0_BASE 0x040000
71 1.1 freza #define OPB_PSTWO1_BASE 0x041000
72 1.1 freza #define CDMAC_NCHAN 2 /* cdmac {Tx,Rx} */
73 1.1 freza #define CDMAC_INTR_LINE 0
74 1.1 freza
75 1.1 freza #define TFT_FB_BASE 0x3c00000
76 1.1 freza #define TFT_FB_SIZE (2*1024*1024)
77 1.1 freza
78 1.1 freza /*
79 1.1 freza * CDMAC per-channel interrupt handler. CDMAC has one interrupt signal
80 1.1 freza * per two channels on mpmc2, so we have to dispatch channels manually.
81 1.1 freza *
82 1.1 freza * Note: we hardwire priority to IPL_NET, temac(4) is the only device that
83 1.1 freza * needs to service DMA interrupts anyway.
84 1.1 freza */
85 1.1 freza typedef struct cdmac_intrhand {
86 1.1 freza void (*cih_func)(void *);
87 1.1 freza void *cih_arg;
88 1.1 freza } *cdmac_intrhand_t;
89 1.1 freza
90 1.1 freza /* Two instantiated channels, one logical interrupt per direction. */
91 1.1 freza static struct cdmac_intrhand cdmacintr[CDMAC_NCHAN];
92 1.1 freza static void *cdmac_ih;
93 1.1 freza
94 1.1 freza
95 1.1 freza /*
96 1.1 freza * DCR bus space leaf access routines.
97 1.1 freza */
98 1.1 freza
99 1.1 freza static void
100 1.1 freza tft0_write_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr,
101 1.1 freza uint32_t val)
102 1.1 freza {
103 1.1 freza addr += h;
104 1.1 freza
105 1.1 freza switch (addr) {
106 1.1 freza WCASE(DCR_TFT0_BASE, TFT_CTRL);
107 1.1 freza WCASE(DCR_TFT0_BASE, TFT_ADDR);
108 1.1 freza WDEAD(addr);
109 1.1 freza }
110 1.1 freza }
111 1.1 freza
112 1.1 freza static uint32_t
113 1.1 freza tft0_read_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr)
114 1.1 freza {
115 1.1 freza uint32_t val;
116 1.1 freza
117 1.1 freza addr += h;
118 1.1 freza
119 1.1 freza switch (addr) {
120 1.1 freza RCASE(DCR_TFT0_BASE, TFT_CTRL);
121 1.1 freza RCASE(DCR_TFT0_BASE, TFT_ADDR);
122 1.1 freza RDEAD(addr);
123 1.1 freza }
124 1.1 freza
125 1.1 freza return (val);
126 1.1 freza }
127 1.1 freza
128 1.1 freza static void
129 1.1 freza tft1_write_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr,
130 1.1 freza uint32_t val)
131 1.1 freza {
132 1.1 freza addr += h;
133 1.1 freza
134 1.1 freza switch (addr) {
135 1.1 freza WCASE(DCR_TFT1_BASE, TFT_CTRL);
136 1.1 freza WCASE(DCR_TFT0_BASE, TFT_ADDR);
137 1.1 freza WDEAD(addr);
138 1.1 freza }
139 1.1 freza }
140 1.1 freza
141 1.1 freza static uint32_t
142 1.1 freza tft1_read_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr)
143 1.1 freza {
144 1.1 freza uint32_t val;
145 1.1 freza
146 1.1 freza addr += h;
147 1.1 freza
148 1.1 freza switch (addr) {
149 1.1 freza RCASE(DCR_TFT1_BASE, TFT_CTRL);
150 1.1 freza RCASE(DCR_TFT0_BASE, TFT_ADDR);
151 1.1 freza RDEAD(addr);
152 1.1 freza }
153 1.1 freza
154 1.1 freza return (val);
155 1.1 freza }
156 1.1 freza
157 1.1 freza #define DOCHAN(op, base, channel) \
158 1.1 freza op(base, channel + CDMAC_NEXT); \
159 1.1 freza op(base, channel + CDMAC_CURADDR); \
160 1.1 freza op(base, channel + CDMAC_CURSIZE); \
161 1.1 freza op(base, channel + CDMAC_CURDESC)
162 1.1 freza
163 1.1 freza static void
164 1.1 freza cdmac_write_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr,
165 1.1 freza uint32_t val)
166 1.1 freza {
167 1.1 freza addr += h;
168 1.1 freza
169 1.1 freza switch (addr) {
170 1.1 freza WCASE(DCR_CDMAC_BASE, CDMAC_STAT_BASE(0)); /* Tx engine */
171 1.1 freza WCASE(DCR_CDMAC_BASE, CDMAC_STAT_BASE(1)); /* Rx engine */
172 1.1 freza WCASE(DCR_CDMAC_BASE, CDMAC_INTR);
173 1.1 freza DOCHAN(WCASE, DCR_CDMAC_BASE, CDMAC_CTRL_BASE(0));
174 1.1 freza DOCHAN(WCASE, DCR_CDMAC_BASE, CDMAC_CTRL_BASE(1));
175 1.1 freza WDEAD(addr);
176 1.1 freza }
177 1.1 freza }
178 1.1 freza
179 1.1 freza static uint32_t
180 1.1 freza cdmac_read_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr)
181 1.1 freza {
182 1.1 freza uint32_t val;
183 1.1 freza
184 1.1 freza addr += h;
185 1.1 freza
186 1.1 freza switch (addr) {
187 1.1 freza RCASE(DCR_CDMAC_BASE, CDMAC_STAT_BASE(0)); /* Tx engine */
188 1.1 freza RCASE(DCR_CDMAC_BASE, CDMAC_STAT_BASE(1)); /* Rx engine */
189 1.1 freza RCASE(DCR_CDMAC_BASE, CDMAC_INTR);
190 1.1 freza DOCHAN(RCASE, DCR_CDMAC_BASE, CDMAC_CTRL_BASE(0));
191 1.1 freza DOCHAN(RCASE, DCR_CDMAC_BASE, CDMAC_CTRL_BASE(1));
192 1.1 freza RDEAD(addr);
193 1.1 freza }
194 1.1 freza
195 1.1 freza return (val);
196 1.1 freza }
197 1.1 freza
198 1.1 freza #undef DOCHAN
199 1.1 freza
200 1.1 freza static void
201 1.1 freza temac_write_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr,
202 1.1 freza uint32_t val)
203 1.1 freza {
204 1.1 freza addr += h;
205 1.1 freza
206 1.1 freza switch (addr) {
207 1.1 freza WCASE(DCR_TEMAC_BASE, TEMAC_RESET);
208 1.1 freza WDEAD(addr);
209 1.1 freza }
210 1.1 freza }
211 1.1 freza
212 1.1 freza static uint32_t
213 1.1 freza temac_read_4(bus_space_tag_t t, bus_space_handle_t h, uint32_t addr)
214 1.1 freza {
215 1.1 freza uint32_t val;
216 1.1 freza
217 1.1 freza addr += h;
218 1.1 freza
219 1.1 freza switch (addr) {
220 1.1 freza RCASE(DCR_TEMAC_BASE, TEMAC_RESET);
221 1.1 freza RDEAD(addr);
222 1.1 freza }
223 1.1 freza
224 1.1 freza return (val);
225 1.1 freza }
226 1.1 freza
227 1.1 freza static const struct powerpc_bus_space cdmac_bst = {
228 1.1 freza DCR_BST_BODY(DCR_CDMAC_BASE, cdmac_read_4, cdmac_write_4)
229 1.1 freza };
230 1.1 freza
231 1.1 freza static const struct powerpc_bus_space temac_bst = {
232 1.1 freza DCR_BST_BODY(DCR_TEMAC_BASE, temac_read_4, temac_write_4)
233 1.1 freza };
234 1.1 freza
235 1.1 freza static const struct powerpc_bus_space tft0_bst = {
236 1.1 freza DCR_BST_BODY(DCR_TFT0_BASE, tft0_read_4, tft0_write_4)
237 1.1 freza };
238 1.1 freza
239 1.1 freza static const struct powerpc_bus_space tft1_bst = {
240 1.1 freza DCR_BST_BODY(DCR_TFT1_BASE, tft1_read_4, tft1_write_4)
241 1.1 freza };
242 1.1 freza
243 1.1 freza static struct powerpc_bus_space opb_bst = {
244 1.1 freza .pbs_flags = _BUS_SPACE_BIG_ENDIAN|_BUS_SPACE_MEM_TYPE,
245 1.1 freza .pbs_base = 0 /*OPB_BASE*/,
246 1.1 freza .pbs_offset = OPB_BASE,
247 1.1 freza };
248 1.1 freza
249 1.1 freza static char opb_extent_storage[EXTENT_FIXED_STORAGE_SIZE(8)] __aligned(8);
250 1.1 freza
251 1.1 freza /*
252 1.1 freza * Master device configuration table for GSRD2 design.
253 1.1 freza */
254 1.1 freza static const struct gsrddev {
255 1.1 freza const char *gdv_name;
256 1.1 freza const char *gdv_attr;
257 1.1 freza bus_space_tag_t gdv_bst;
258 1.1 freza bus_addr_t gdv_addr;
259 1.1 freza int gdv_intr;
260 1.1 freza int gdv_rx_dma;
261 1.1 freza int gdv_tx_dma;
262 1.1 freza int gdv_dcr; /* XXX bst flag */
263 1.1 freza } gsrd_devices[] = {
264 1.1 freza { /* gsrd_devices[0] */
265 1.1 freza .gdv_name = "xlcom",
266 1.1 freza .gdv_attr = "xcvbus",
267 1.1 freza .gdv_bst = &opb_bst,
268 1.1 freza .gdv_addr = OPB_XLCOM_BASE,
269 1.1 freza .gdv_intr = 2,
270 1.1 freza .gdv_rx_dma = -1,
271 1.1 freza .gdv_tx_dma = -1,
272 1.1 freza .gdv_dcr = 0,
273 1.1 freza },
274 1.1 freza { /* gsrd_devices[1] */
275 1.1 freza .gdv_name = "temac",
276 1.1 freza .gdv_attr = "xcvbus",
277 1.1 freza .gdv_bst = &temac_bst,
278 1.1 freza .gdv_addr = 0,
279 1.1 freza .gdv_intr = 1, /* unused MII intr */
280 1.1 freza .gdv_rx_dma = 1, /* cdmac Rx */
281 1.1 freza .gdv_tx_dma = 0, /* cdmac Tx */
282 1.1 freza .gdv_dcr = 1,
283 1.1 freza },
284 1.1 freza #ifndef DESIGN_DFC
285 1.1 freza { /* gsrd_devices[2] */
286 1.1 freza .gdv_name = "tft",
287 1.1 freza .gdv_attr = "plbus",
288 1.1 freza .gdv_bst = &tft0_bst,
289 1.1 freza .gdv_addr = 0,
290 1.1 freza .gdv_intr = -1,
291 1.1 freza .gdv_rx_dma = -1,
292 1.1 freza .gdv_tx_dma = -1,
293 1.1 freza .gdv_dcr = 1,
294 1.1 freza },
295 1.1 freza #endif
296 1.1 freza { /* gsrd_devices[2] */
297 1.1 freza .gdv_name = "tft",
298 1.1 freza .gdv_attr = "plbus",
299 1.1 freza .gdv_bst = &tft1_bst,
300 1.1 freza .gdv_addr = 0,
301 1.1 freza .gdv_intr = -1,
302 1.1 freza .gdv_rx_dma = -1,
303 1.1 freza .gdv_tx_dma = -1,
304 1.1 freza .gdv_dcr = 1,
305 1.1 freza },
306 1.1 freza #ifdef DESIGN_DFC
307 1.1 freza { /* gsrd_devices[3] */
308 1.1 freza .gdv_name = "pstwo",
309 1.1 freza .gdv_attr = "xcvbus",
310 1.1 freza .gdv_bst = &opb_bst,
311 1.1 freza .gdv_addr = OPB_PSTWO0_BASE,
312 1.1 freza .gdv_intr = 3,
313 1.1 freza .gdv_rx_dma = -1,
314 1.1 freza .gdv_tx_dma = -1,
315 1.1 freza .gdv_dcr = 0,
316 1.1 freza },
317 1.1 freza { /* gsrd_devices[4] */
318 1.1 freza .gdv_name = "pstwo",
319 1.1 freza .gdv_attr = "xcvbus",
320 1.1 freza .gdv_bst = &opb_bst,
321 1.1 freza .gdv_addr = OPB_PSTWO1_BASE,
322 1.1 freza .gdv_intr = 4,
323 1.1 freza .gdv_rx_dma = -1,
324 1.1 freza .gdv_tx_dma = -1,
325 1.1 freza .gdv_dcr = 0,
326 1.1 freza },
327 1.1 freza #endif
328 1.1 freza };
329 1.1 freza
330 1.1 freza static struct ll_dmac *
331 1.1 freza virtex_mpmc_mapdma(int idx, struct ll_dmac *chan)
332 1.1 freza {
333 1.1 freza if (idx == -1)
334 1.1 freza return (NULL);
335 1.1 freza
336 1.1 freza KASSERT(idx >= 0 && idx < CDMAC_NCHAN);
337 1.1 freza
338 1.1 freza chan->dmac_iot = &cdmac_bst;
339 1.1 freza chan->dmac_ctrl_addr = CDMAC_CTRL_BASE(idx);
340 1.1 freza chan->dmac_stat_addr = CDMAC_STAT_BASE(idx);
341 1.1 freza chan->dmac_chan = idx;
342 1.1 freza
343 1.1 freza return (chan);
344 1.1 freza }
345 1.1 freza
346 1.1 freza static int
347 1.1 freza cdmac_intr(void *arg)
348 1.1 freza {
349 1.1 freza uint32_t isr;
350 1.1 freza int did = 0;
351 1.1 freza
352 1.1 freza isr = bus_space_read_4(&cdmac_bst, 0, CDMAC_INTR);
353 1.1 freza
354 1.1 freza if (ISSET(isr, CDMAC_INTR_TX0) && cdmacintr[0].cih_func) {
355 1.1 freza (cdmacintr[0].cih_func)(cdmacintr[0].cih_arg);
356 1.1 freza did++;
357 1.1 freza }
358 1.1 freza if (ISSET(isr, CDMAC_INTR_RX0) && cdmacintr[1].cih_func) {
359 1.1 freza (cdmacintr[1].cih_func)(cdmacintr[1].cih_arg);
360 1.1 freza did++;
361 1.1 freza }
362 1.1 freza
363 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_INTR, isr); /* ack */
364 1.1 freza
365 1.1 freza /* XXX This still happens all the time under load. */
366 1.1 freza #if 0
367 1.1 freza if (did == 0)
368 1.1 freza aprint_normal("WARNING: stray cdmac isr 0x%x\n", isr);
369 1.1 freza #endif
370 1.1 freza return (0);
371 1.1 freza }
372 1.1 freza
373 1.1 freza /*
374 1.1 freza * Public interface.
375 1.1 freza */
376 1.1 freza
377 1.1 freza void
378 1.1 freza virtex_autoconf(device_t self, struct plb_attach_args *paa)
379 1.1 freza {
380 1.1 freza
381 1.1 freza struct xcvbus_attach_args vaa;
382 1.1 freza struct ll_dmac rx, tx;
383 1.1 freza int i;
384 1.1 freza
385 1.1 freza /* Reset DMA channels. */
386 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_STAT_BASE(0), CDMAC_STAT_RESET);
387 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_STAT_BASE(1), CDMAC_STAT_RESET);
388 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_INTR, 0);
389 1.1 freza
390 1.1 freza vaa.vaa_dmat = paa->plb_dmat;
391 1.1 freza
392 1.1 freza for (i = 0; i < __arraycount(gsrd_devices); i++) {
393 1.1 freza const struct gsrddev *g = &gsrd_devices[i];
394 1.1 freza
395 1.1 freza vaa._vaa_is_dcr = g->gdv_dcr; /* XXX bst flag */
396 1.1 freza vaa.vaa_name = g->gdv_name;
397 1.1 freza vaa.vaa_addr = g->gdv_addr;
398 1.1 freza vaa.vaa_intr = g->gdv_intr;
399 1.1 freza vaa.vaa_iot = g->gdv_bst;
400 1.1 freza
401 1.1 freza vaa.vaa_rx_dmac = virtex_mpmc_mapdma(g->gdv_rx_dma, &rx);
402 1.1 freza vaa.vaa_tx_dmac = virtex_mpmc_mapdma(g->gdv_tx_dma, &tx);
403 1.1 freza
404 1.4.68.1 thorpej config_found(self, &vaa, xcvbus_print,
405 1.4.68.1 thorpej CFARG_IATTR, g->gdv_attr,
406 1.4.68.1 thorpej CFARG_EOL);
407 1.1 freza }
408 1.1 freza
409 1.1 freza /* Setup the dispatch handler. */
410 1.1 freza cdmac_ih = intr_establish(CDMAC_INTR_LINE, IST_LEVEL, IPL_NET,
411 1.1 freza cdmac_intr, NULL);
412 1.1 freza if (cdmac_ih == NULL)
413 1.1 freza panic("virtex_mpmc_done: could not establish cdmac intr");
414 1.1 freza
415 1.1 freza /* Clear (XXX?) and enable interrupts. */
416 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_INTR, ~CDMAC_INTR_MIE);
417 1.1 freza bus_space_write_4(&cdmac_bst, 0, CDMAC_INTR, CDMAC_INTR_MIE);
418 1.1 freza }
419 1.1 freza
420 1.1 freza void *
421 1.1 freza ll_dmac_intr_establish(int chan, void (*handler)(void *), void *arg)
422 1.1 freza {
423 1.1 freza KASSERT(chan >= 0 && chan < CDMAC_NCHAN);
424 1.1 freza KASSERT(cdmacintr[chan].cih_func == NULL);
425 1.1 freza KASSERT(cdmacintr[chan].cih_arg == NULL);
426 1.1 freza
427 1.1 freza cdmacintr[chan].cih_func = handler;
428 1.1 freza cdmacintr[chan].cih_arg = arg;
429 1.1 freza
430 1.1 freza return (&cdmacintr[chan]);
431 1.1 freza }
432 1.1 freza
433 1.1 freza void
434 1.1 freza ll_dmac_intr_disestablish(int chan, void *handle)
435 1.1 freza {
436 1.1 freza int s;
437 1.1 freza
438 1.1 freza KASSERT(chan >= 0 && chan < CDMAC_NCHAN);
439 1.1 freza KASSERT(&cdmacintr[chan] == handle);
440 1.1 freza
441 1.1 freza s = splnet();
442 1.1 freza cdmacintr[chan].cih_func = NULL;
443 1.1 freza cdmacintr[chan].cih_arg = NULL;
444 1.1 freza splx(s);
445 1.1 freza }
446 1.1 freza
447 1.1 freza int
448 1.3 garbled virtex_bus_space_tag(const char *xname, bus_space_tag_t *bst)
449 1.1 freza {
450 1.1 freza if (strncmp(xname, "xlcom", 5) == 0) {
451 1.1 freza *bst = &opb_bst;
452 1.1 freza return (0);
453 1.1 freza }
454 1.1 freza
455 1.1 freza return (ENODEV);
456 1.1 freza }
457 1.1 freza
458 1.1 freza void
459 1.1 freza virtex_machdep_init(vaddr_t endva, vsize_t maxsz, struct mem_region *phys,
460 1.1 freza struct mem_region *avail)
461 1.1 freza {
462 1.1 freza ppc4xx_tlb_reserve(OPB_BASE, endva, maxsz, TLB_I | TLB_G);
463 1.1 freza endva += maxsz;
464 1.1 freza
465 1.1 freza opb_bst.pbs_limit = maxsz;
466 1.1 freza
467 1.1 freza if (bus_space_init(&opb_bst, "opbtag", opb_extent_storage,
468 1.1 freza sizeof(opb_extent_storage)))
469 1.1 freza panic("virtex_machdep_init: failed to initialize opb_bst");
470 1.1 freza
471 1.1 freza /*
472 1.1 freza * The TFT controller is broken, we can't change FB address.
473 1.1 freza * Hardwire it at predefined base address, create uncached
474 1.1 freza * mapping.
475 1.1 freza */
476 1.1 freza
477 1.1 freza avail[0].size = TFT_FB_BASE - avail[0].start;
478 1.1 freza ppc4xx_tlb_reserve(TFT_FB_BASE, endva, TFT_FB_SIZE, TLB_I | TLB_G);
479 1.1 freza }
480 1.1 freza
481 1.1 freza void
482 1.4 matt device_register(device_t dev, void *aux)
483 1.1 freza {
484 1.1 freza prop_number_t pn;
485 1.1 freza void *fb;
486 1.1 freza
487 1.1 freza if (strncmp(device_xname(dev), "tft0", 4) == 0) {
488 1.1 freza fb = ppc4xx_tlb_mapiodev(TFT_FB_BASE, TFT_FB_SIZE);
489 1.1 freza if (fb == NULL)
490 1.1 freza panic("device_register: framebuffer mapping gone!\n");
491 1.1 freza
492 1.1 freza pn = prop_number_create_unsigned_integer(TFT_FB_BASE);
493 1.1 freza if (pn == NULL) {
494 1.1 freza printf("WARNING: could not allocate virtex-tft-pa\n");
495 1.1 freza return ;
496 1.1 freza }
497 1.1 freza if (prop_dictionary_set(device_properties(dev),
498 1.2 thorpej "virtex-tft-pa", pn) != true)
499 1.1 freza printf("WARNING: could not set virtex-tft-pa\n");
500 1.1 freza prop_object_release(pn);
501 1.1 freza
502 1.1 freza pn = prop_number_create_unsigned_integer((uintptr_t)fb);
503 1.1 freza if (pn == NULL) {
504 1.1 freza printf("WARNING: could not allocate virtex-tft-va\n");
505 1.1 freza return ;
506 1.1 freza }
507 1.1 freza if (prop_dictionary_set(device_properties(dev),
508 1.2 thorpej "virtex-tft-va", pn) != true)
509 1.1 freza printf("WARNING: could not set virtex-tft-va\n");
510 1.1 freza prop_object_release(pn);
511 1.1 freza }
512 1.1 freza }
513