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