diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2005-01-21 16:22:35 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2005-01-21 16:22:35 +0000 |
commit | 6405d08b800a0b4df1a326899f3fac2c24649acb (patch) | |
tree | 0e82d443e5f01328416142c48bc5172dd92d4cc4 | |
parent | a682022fdcaf037e0749c3d29b5b238237ef6ea9 (diff) |
Overhaul of the pxa2x0_lcd code, to allow early (before autoconf) attachment,
and collateral changes.
Because this driver requires us_dma (and as such, vm services) to work, it
can not be selected in consinit(). Instead, add a hook to the arm
cpu_startup() which will, on zaurus, switch console from serial (selected
in consinit()) to lcd.
This also makes the zaurus-specific early pxa2x0_clkman() substitute code
cleaner.
While there, move boot -c handling later, after the glass console is set up.
Tested by drahn@ and uwe@
-rw-r--r-- | sys/arch/arm/arm/arm32_machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/arm/include/cpu.h | 5 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_gpio.c | 8 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_lcd.c | 486 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_lcd.h | 21 | ||||
-rw-r--r-- | sys/arch/cats/cats/cats_machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/hp300/dev/dvbox.c | 4 | ||||
-rw-r--r-- | sys/arch/hp300/dev/gbox.c | 4 | ||||
-rw-r--r-- | sys/arch/hp300/dev/hyper.c | 4 | ||||
-rw-r--r-- | sys/arch/hp300/dev/rbox.c | 4 | ||||
-rw-r--r-- | sys/arch/hp300/dev/topcat.c | 4 | ||||
-rw-r--r-- | sys/arch/zaurus/zaurus/zaurus_lcd.c | 107 | ||||
-rw-r--r-- | sys/arch/zaurus/zaurus/zaurus_machdep.c | 158 |
13 files changed, 472 insertions, 347 deletions
diff --git a/sys/arch/arm/arm/arm32_machdep.c b/sys/arch/arm/arm/arm32_machdep.c index 49ffa909a62..1a80689b9b5 100644 --- a/sys/arch/arm/arm/arm32_machdep.c +++ b/sys/arch/arm/arm/arm32_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arm32_machdep.c,v 1.5 2004/05/19 03:17:06 drahn Exp $ */ +/* $OpenBSD: arm32_machdep.c,v 1.6 2005/01/21 16:22:32 miod Exp $ */ /* $NetBSD: arm32_machdep.c,v 1.42 2003/12/30 12:33:15 pk Exp $ */ /* @@ -254,6 +254,11 @@ cpu_startup() pmap_postinit(); /* + * Allow per-board specific initialization + */ + board_startup(); + + /* * Initialize error message buffer (at end of core). */ diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 9d5bb9d675b..e5e6ffb9667 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.4 2004/05/19 03:17:07 drahn Exp $ */ +/* $OpenBSD: cpu.h,v 1.5 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -295,6 +295,9 @@ int badaddr_read (void *, size_t, void *); /* syscall.c */ void swi_handler (trapframe_t *); +/* machine_machdep.c */ +void board_startup(void); + #endif /* !_LOCORE */ #endif /* _KERNEL */ diff --git a/sys/arch/arm/xscale/pxa2x0_gpio.c b/sys/arch/arm/xscale/pxa2x0_gpio.c index dc41d76d7d2..44ccbd15144 100644 --- a/sys/arch/arm/xscale/pxa2x0_gpio.c +++ b/sys/arch/arm/xscale/pxa2x0_gpio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pxa2x0_gpio.c,v 1.11 2005/01/17 04:27:20 drahn Exp $ */ +/* $OpenBSD: pxa2x0_gpio.c,v 1.12 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: pxa2x0_gpio.c,v 1.2 2003/07/15 00:24:55 lukem Exp $ */ /* @@ -467,7 +467,8 @@ pxa2x0_gpio_get_function(u_int gpio) struct pxagpio_softc *sc = pxagpio_softc; u_int32_t rv, io; - KDASSERT(gpio < sc->npins); + if (__predict_true(sc != NULL)) + KDASSERT(gpio < sc->npins); rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio); rv = GPIO_FN(rv); @@ -490,7 +491,8 @@ pxa2x0_gpio_set_function(u_int gpio, u_int fn) u_int32_t rv, bit; u_int oldfn; - KDASSERT(gpio < sc->npins); + if (__predict_true(sc != NULL)) + KDASSERT(gpio < sc->npins); oldfn = pxa2x0_gpio_get_function(gpio); diff --git a/sys/arch/arm/xscale/pxa2x0_lcd.c b/sys/arch/arm/xscale/pxa2x0_lcd.c index d902daf6d4e..d01502ec642 100644 --- a/sys/arch/arm/xscale/pxa2x0_lcd.c +++ b/sys/arch/arm/xscale/pxa2x0_lcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pxa2x0_lcd.c,v 1.10 2005/01/17 04:22:34 drahn Exp $ */ +/* $OpenBSD: pxa2x0_lcd.c,v 1.11 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: pxa2x0_lcd.c,v 1.8 2003/10/03 07:24:05 bsh Exp $ */ /* @@ -48,11 +48,10 @@ #include <uvm/uvm_extern.h> #include <dev/cons.h> + #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsdisplayvar.h> -#include <dev/wscons/wscons_callbacks.h> #include <dev/rasops/rasops.h> -#include <dev/wsfont/wsfont.h> #include <machine/bus.h> #include <machine/cpu.h> @@ -63,23 +62,48 @@ #include <arm/xscale/pxa2x0_lcd.h> #include <arm/xscale/pxa2x0_gpio.h> -int lcdintr(void *); +/* + * Console variables. These are necessary since console is setup very early, + * before devices get attached. + */ +struct { + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_dma_tag_t dma_tag; + const struct lcd_panel_geometry *geometry; + struct pxa2x0_lcd_screen scr; +} pxa2x0_lcd_console; + +int lcdintr(void *); +void pxa2x0_lcd_geometry(bus_space_tag_t, bus_space_handle_t, + const struct lcd_panel_geometry *); +void pxa2x0_lcd_initialize(bus_space_tag_t, bus_space_handle_t, + const struct lcd_panel_geometry *, void (*)(u_int, int)); +int pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *, + struct pxa2x0_lcd_screen *, int); +void pxa2x0_lcd_setup_console(struct pxa2x0_lcd_softc *, + const struct pxa2x0_wsscreen_descr *); +void pxa2x0_lcd_setup_rasops(struct rasops_info *, + struct pxa2x0_wsscreen_descr *, + const struct lcd_panel_geometry *); +void pxa2x0_lcd_start_dma(bus_space_tag_t, bus_space_handle_t, + struct pxa2x0_lcd_screen *); +void pxa2x0_lcd_stop_dma(bus_space_tag_t, bus_space_handle_t); +/* + * Setup display geometry parameters. + */ void -pxa2x0_lcd_geometry(struct pxa2x0_lcd_softc *sc, +pxa2x0_lcd_geometry(bus_space_tag_t iot, bus_space_handle_t ioh, const struct lcd_panel_geometry *info) { int lines; - bus_space_tag_t iot = sc->iot; - bus_space_handle_t ioh = sc->ioh; uint32_t ccr0; - sc->geometry = info; - ccr0 = LCCR0_IMASK; if (info->panel_info & LCDPANEL_ACTIVE) ccr0 |= LCCR0_PAS; /* active mode */ - if ((info->panel_info & (LCDPANEL_DUAL|LCDPANEL_ACTIVE)) + if ((info->panel_info & (LCDPANEL_DUAL | LCDPANEL_ACTIVE)) == LCDPANEL_DUAL) ccr0 |= LCCR0_SDS; /* dual panel */ if (info->panel_info & LCDPANEL_MONOCHROME) @@ -93,64 +117,43 @@ pxa2x0_lcd_geometry(struct pxa2x0_lcd_softc *sc, bus_space_write_4(iot, ioh, LCDC_LCCR0, ccr0); bus_space_write_4(iot, ioh, LCDC_LCCR1, - (info->panel_width-1) - | ((info->hsync_pulse_width-1)<<10) - | ((info->end_line_wait-1)<<16) - | ((info->beg_line_wait-1)<<24)); + (info->panel_width - 1) + | ((info->hsync_pulse_width - 1) << 10) + | ((info->end_line_wait - 1) << 16) + | ((info->beg_line_wait - 1) << 24)); if (info->panel_info & LCDPANEL_DUAL) - lines = info->panel_height/2 + info->extra_lines; + lines = info->panel_height / 2 + info->extra_lines; else lines = info->panel_height + info->extra_lines; bus_space_write_4(iot, ioh, LCDC_LCCR2, - (lines-1) - | (info->vsync_pulse_width<<10) - | (info->end_frame_wait<<16) - | (info->beg_frame_wait<<24)); + (lines - 1) + | (info->vsync_pulse_width << 10) + | (info->end_frame_wait << 16) + | (info->beg_frame_wait << 24)); bus_space_write_4(iot, ioh, LCDC_LCCR3, - (info->pixel_clock_div<<0) + (info->pixel_clock_div << 0) | (info->ac_bias << 8) | ((info->panel_info & - (LCDPANEL_VSP|LCDPANEL_HSP|LCDPANEL_PCP|LCDPANEL_OEP)) - <<20) + (LCDPANEL_VSP | LCDPANEL_HSP | LCDPANEL_PCP | LCDPANEL_OEP)) + << 20) | (4 << 24) /* 16bpp */ - | ((info->panel_info & LCDPANEL_DPC) ? (1<<27) : 0) + | ((info->panel_info & LCDPANEL_DPC) ? (1 << 27) : 0) ); } +/* + * Initialize the LCD controller. + */ void -pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *sc, - struct pxaip_attach_args *pxa, const struct lcd_panel_geometry *geom) +pxa2x0_lcd_initialize(bus_space_tag_t iot, bus_space_handle_t ioh, + const struct lcd_panel_geometry *geom, void (*clkman)(u_int, int)) { - bus_space_tag_t iot = pxa->pxa_iot; - bus_space_handle_t ioh; - int error, nldd; + int nldd; u_int32_t lccr0, lscr; - sc->n_screens = 0; - LIST_INIT(&sc->screens); - - /* map controller registers */ - error = bus_space_map(iot, PXA2X0_LCDC_BASE, PXA2X0_LCDC_SIZE, 0, &ioh); - if (error) { - printf(": failed to map registers %d", error); - return; - } - - sc->iot = iot; - sc->ioh = ioh; - sc->dma_tag = &pxa2x0_bus_dma_tag; - - sc->ih = pxa2x0_intr_establish(17, IPL_BIO, lcdintr, sc, - sc->dev.dv_xname); - if (sc->ih == NULL) - printf("%s: unable to establish interrupt at irq %d", - sc->dev.dv_xname, 17); - - /* Initialize LCD controller */ - /* Check if LCD is enabled before programming, it should not * be enabled while it is being reprogrammed, therefore disable * it first. @@ -168,7 +171,7 @@ pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *sc, } /* enable clock */ - pxa2x0_clkman_config(CKEN_LCD, 1); + (*clkman)(CKEN_LCD, 1); bus_space_write_4(iot, ioh, LCDC_LCCR0, LCCR0_IMASK); @@ -199,9 +202,69 @@ pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *sc, while (nldd--) pxa2x0_gpio_set_function(58 + nldd, GPIO_ALT_FN_2_OUT); - pxa2x0_lcd_geometry(sc, geom); + pxa2x0_lcd_geometry(iot, ioh, geom); +} + +/* + * Common driver attachment code. + */ +void +pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *sc, + struct pxaip_attach_args *pxa, struct pxa2x0_wsscreen_descr *descr, + const struct lcd_panel_geometry *geom, int console) +{ + bus_space_tag_t iot; + bus_space_handle_t ioh; + int error; + + sc->n_screens = 0; + LIST_INIT(&sc->screens); + + /* map controller registers if not console */ + if (console != 0) { + iot = pxa2x0_lcd_console.iot; + ioh = pxa2x0_lcd_console.ioh; + } else { + iot = pxa->pxa_iot; + error = bus_space_map(iot, PXA2X0_LCDC_BASE, PXA2X0_LCDC_SIZE, + 0, &ioh); + if (error) { + printf(": failed to map registers %d", error); + return; + } + } + + sc->iot = iot; + sc->ioh = ioh; + sc->dma_tag = &pxa2x0_bus_dma_tag; + + sc->ih = pxa2x0_intr_establish(17, IPL_BIO, lcdintr, sc, + sc->dev.dv_xname); + if (sc->ih == NULL) + printf("%s: unable to establish interrupt at irq %d", + sc->dev.dv_xname, 17); + + sc->geometry = geom; + + if (console != 0) { + /* complete console attachment */ + pxa2x0_lcd_setup_console(sc, descr); + } else { + struct rasops_info dummy; + + pxa2x0_lcd_initialize(iot, ioh, geom, pxa2x0_clkman_config); + + /* + * Initialize a dummy rasops_info to compute fontsize and + * the screen size in chars. + */ + pxa2x0_lcd_setup_rasops(&dummy, descr, geom); + } } +/* + * Interrupt handler. + */ int lcdintr(void *arg) { @@ -218,13 +281,15 @@ lcdintr(void *arg) return 1; } +/* + * Enable DMA to cause the display to be refreshed periodically. + * This brings the screen to life... + */ void -pxa2x0_lcd_start_dma(struct pxa2x0_lcd_softc *sc, +pxa2x0_lcd_start_dma(bus_space_tag_t iot, bus_space_handle_t ioh, struct pxa2x0_lcd_screen *scr) { uint32_t tmp; - bus_space_tag_t iot = sc->iot; - bus_space_handle_t ioh = sc->ioh; int val, save; save = disable_interrupts(I32_bit); @@ -261,26 +326,29 @@ pxa2x0_lcd_start_dma(struct pxa2x0_lcd_softc *sc, bus_space_write_4(iot, ioh, LCDC_LCCR0, tmp | LCCR0_ENB); restore_interrupts(save); - } -static void -pxa2x0_lcd_stop_dma(struct pxa2x0_lcd_softc *sc) +/* + * Disable screen refresh. + */ +void +pxa2x0_lcd_stop_dma(bus_space_tag_t iot, bus_space_handle_t ioh) { + /* Stop LCD DMA after current frame */ - bus_space_write_4(sc->iot, sc->ioh, LCDC_LCCR0, + bus_space_write_4(iot, ioh, LCDC_LCCR0, LCCR0_DIS | - bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0)); + bus_space_read_4(iot, ioh, LCDC_LCCR0)); /* wait for disabling done. XXX: use interrupt. */ while (LCCR0_ENB & - bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0)) + bus_space_read_4(iot, ioh, LCDC_LCCR0)) ; - bus_space_write_4(sc->iot, sc->ioh, LCDC_LCCR0, + bus_space_write_4(iot, ioh, LCDC_LCCR0, ~LCCR0_DIS & - bus_space_read_4(sc->iot, sc->ioh, LCDC_LCCR0)); + bus_space_read_4(iot, ioh, LCDC_LCCR0)); } #define _rgb(r,g,b) (((r)<<11) | ((g)<<5) | b) @@ -322,14 +390,14 @@ init_palette(uint16_t *buf, int depth) case 8: case 4: #if 0 - for (i=0; i <= 255; ++i) { - buf[i] = ((9 * ((i>>5) & 0x07)) <<11) | - ((9 * ((i>>2) & 0x07)) << 5) | - ((21 * (i & 0x03))/2); + for (i = 0; i <= 255; ++i) { + buf[i] = ((9 * ((i >> 5) & 0x07)) << 11) | + ((9 * ((i >> 2) & 0x07)) << 5) | + ((21 * (i & 0x03)) / 2); } #else memcpy(buf, basic_color_map, sizeof basic_color_map); - for (i=16; i < (1<<depth); ++i) + for (i = 16; i < (1 << depth); ++i) buf[i] = 0xffff; #endif break; @@ -342,11 +410,17 @@ init_palette(uint16_t *buf, int depth) } } -struct pxa2x0_lcd_screen * +/* + * Create and initialize a new screen buffer. + */ +int pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc, - int depth) + struct pxa2x0_lcd_screen *scr, int depth) { - struct pxa2x0_lcd_screen *scr = NULL; + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_dma_tag_t dma_tag; + const struct lcd_panel_geometry *geometry; int width, height; bus_size_t size; int error, palette_size; @@ -354,8 +428,21 @@ pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc, struct lcd_dma_descriptor *desc; paddr_t buf_pa, desc_pa; - width = sc->geometry->panel_width; - height = sc->geometry->panel_height; + if (sc != NULL) { + iot = sc->iot; + ioh = sc->ioh; + dma_tag = sc->dma_tag; + geometry = sc->geometry; + } else { + /* We are creating the console screen. */ + iot = pxa2x0_lcd_console.iot; + ioh = pxa2x0_lcd_console.ioh; + dma_tag = pxa2x0_lcd_console.dma_tag; + geometry = pxa2x0_lcd_console.geometry; + } + + width = geometry->panel_width; + height = geometry->panel_height; palette_size = 0; switch (depth) { @@ -363,64 +450,61 @@ pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc, case 2: case 4: case 8: - palette_size = (1<<depth) * sizeof (uint16_t); + palette_size = (1 << depth) * sizeof (uint16_t); /* FALLTHROUGH */ case 16: - size = roundup(width,4)*depth/8 * height; + size = roundup(width, 4) * depth / 8 * height; break; default: - printf("%s: Unknown depth (%d)\n", sc->dev.dv_xname, depth); - return NULL; + printf("%s: Unknown depth (%d)\n", + sc != NULL ? sc->dev.dv_xname : "console", depth); + return (EINVAL); } - scr = malloc(sizeof *scr, M_DEVBUF, (cold ? M_NOWAIT : M_WAITOK)); - - if (scr == NULL) - return NULL; - - bzero (scr, sizeof *scr); + bzero(scr, sizeof *scr); scr->nsegs = 0; scr->depth = depth; scr->buf_size = size; scr->buf_va = NULL; - size = roundup(size,16) + 3 * sizeof (struct lcd_dma_descriptor) + size = roundup(size, 16) + 3 * sizeof (struct lcd_dma_descriptor) + palette_size; - error = bus_dmamem_alloc(sc->dma_tag, size, 16, 0, + error = bus_dmamem_alloc(dma_tag, size, 16, 0, scr->segs, 1, &(scr->nsegs), busdma_flag); - - if (error || scr->nsegs != 1) { + if (error != 0 || scr->nsegs != 1) { /* XXX: Actually we can handle nsegs > 1 case by means of multiple DMA descriptors for a panel. It would make code here a bit hairy */ + if (error == 0) + error = E2BIG; goto bad; } - error = bus_dmamem_map(sc->dma_tag, scr->segs, scr->nsegs, + error = bus_dmamem_map(dma_tag, scr->segs, scr->nsegs, size, (caddr_t *)&(scr->buf_va), busdma_flag | BUS_DMA_COHERENT); - if (error) + if (error != 0) goto bad; - memset (scr->buf_va, 0, scr->buf_size); + memset(scr->buf_va, 0, scr->buf_size); /* map memory for DMA */ - if (bus_dmamap_create(sc->dma_tag, 1024*1024*2, 1, - 1024*1024*2, 0, busdma_flag, &scr->dma)) + if (bus_dmamap_create(dma_tag, 1024 * 1024 * 2, 1, + 1024 * 1024 * 2, 0, busdma_flag, &scr->dma)) goto bad; - error = bus_dmamap_load(sc->dma_tag, scr->dma, + error = bus_dmamap_load(dma_tag, scr->dma, scr->buf_va, size, NULL, busdma_flag); - if (error) { + if (error != 0) { goto bad; } buf_pa = scr->segs[0].ds_addr; - desc_pa = buf_pa + roundup(size, PAGE_SIZE) - 3*sizeof *desc; + desc_pa = buf_pa + roundup(size, PAGE_SIZE) - 3 * sizeof *desc; /* make descriptors at the top of mapped memory */ - desc = (struct lcd_dma_descriptor *)( - (caddr_t)(scr->buf_va) + roundup(size, PAGE_SIZE) - - 3*sizeof *desc); + desc = (struct lcd_dma_descriptor *) + ((caddr_t)(scr->buf_va) + roundup(size, PAGE_SIZE) - + 3 * sizeof *desc); desc[0].fdadr = desc_pa; desc[0].fsadr = buf_pa; @@ -434,11 +518,11 @@ pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc, desc[2].ldcmd = palette_size | LDCMD_PAL; } - if (sc->geometry->panel_info & LCDPANEL_DUAL) { + if (geometry->panel_info & LCDPANEL_DUAL) { /* Dual panel */ desc[1].fdadr = desc_pa + sizeof *desc; - desc[1].fsadr = buf_pa + scr->buf_size/2; - desc[0].ldcmd = desc[1].ldcmd = scr->buf_size/2; + desc[1].fsadr = buf_pa + scr->buf_size / 2; + desc[0].ldcmd = desc[1].ldcmd = scr->buf_size / 2; } @@ -451,62 +535,42 @@ pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *sc, scr->dma_desc_pa = desc_pa; scr->map_size = size; /* used when unmap this. */ - LIST_INSERT_HEAD(&(sc->screens), scr, link); - sc->n_screens++; + if (sc != NULL) { + LIST_INSERT_HEAD(&(sc->screens), scr, link); + sc->n_screens++; + } - return scr; + return (0); bad: - if (scr) { - if (scr->buf_va) - bus_dmamem_unmap(sc->dma_tag, scr->buf_va, size); - if (scr->nsegs) - bus_dmamem_free(sc->dma_tag, scr->segs, scr->nsegs); - free(scr, M_DEVBUF); - } - return NULL; + if (scr->buf_va) + bus_dmamem_unmap(dma_tag, scr->buf_va, size); + if (scr->nsegs) + bus_dmamem_free(dma_tag, scr->segs, scr->nsegs); + return (error); } /* - * Initialize struct wsscreen_descr based on values calculated by - * raster operation subsystem. + * Initialize rasops for a screen, as well as struct wsscreen_descr if this + * is the first screen creation. */ -int -pxa2x0_lcd_setup_wsscreen(struct pxa2x0_lcd_softc *sc, +void +pxa2x0_lcd_setup_rasops(struct rasops_info *rinfo, struct pxa2x0_wsscreen_descr *descr, - const struct lcd_panel_geometry *geom, - const char *fontname) + const struct lcd_panel_geometry *geom) { - int width = geom->panel_width; - int height = geom->panel_height; - int cookie = -1; - struct rasops_info *rinfo; - - rinfo = &sc->sc_ro; - memset(rinfo, 0, sizeof(struct rasops_info)); -#ifdef notyet - if (fontname) { - wsfont_init(); - cookie = wsfont_find((char *)fontname, 0, 0, 0, - WSDISPLAY_FONTORDER_L2R, WSDISPLAY_FONTORDER_L2R); - if (cookie < 0 || - wsfont_lock(cookie, &rinfo.ri_font)) - return -1; - } else { - /* let rasops_init() choose any font */ - } -#endif - - /* let rasops_init calculate # of cols and rows in character */ + bzero(rinfo, sizeof(struct rasops_info)); rinfo->ri_flg = 0; rinfo->ri_depth = descr->depth; - rinfo->ri_bits = NULL; - rinfo->ri_width = width; - rinfo->ri_height = height; - rinfo->ri_stride = width * rinfo->ri_depth / 8; - rinfo->ri_wsfcookie = cookie; + rinfo->ri_width = geom->panel_width; + rinfo->ri_height = geom->panel_height; + rinfo->ri_stride = rinfo->ri_width * rinfo->ri_depth / 8; +#ifdef notyet + rinfo->ri_wsfcookie = -1; /* XXX */ +#endif + /* swap B and R */ if (descr->depth == 16) { rinfo->ri_rnum = 5; rinfo->ri_rpos = 11; @@ -516,34 +580,91 @@ pxa2x0_lcd_setup_wsscreen(struct pxa2x0_lcd_softc *sc, rinfo->ri_bpos = 0; } - rasops_init(rinfo, 100, 100); - - descr->c.nrows = rinfo->ri_rows; - descr->c.ncols = rinfo->ri_cols; - descr->c.capabilities = rinfo->ri_caps; - descr->c.textops = &rinfo->ri_ops; + if (descr->c.nrows == 0) { + /* get rasops to compute screen size the first time */ + rasops_init(rinfo, 100, 100); - return cookie; + descr->c.nrows = rinfo->ri_rows; + descr->c.ncols = rinfo->ri_cols; + descr->c.capabilities = rinfo->ri_caps; + descr->c.textops = &rinfo->ri_ops; + } else + rasops_init(rinfo, descr->c.nrows, descr->c.ncols); } +/* + * Early console attachment. + * This initializes the LCD, then creates and displays a screen buffer. + * This screen will be accounted for in the softc when the lcd device attaches. + */ int -pxa2x0_lcd_setup_console(struct pxa2x0_lcd_softc *sc, - const struct pxa2x0_wsscreen_descr *descr) +pxa2x0_lcd_cnattach(struct pxa2x0_wsscreen_descr *descr, + const struct lcd_panel_geometry *geom, void (*clkman)(u_int, int)) { - struct pxa2x0_lcd_screen *scr; + struct rasops_info *ri; + long defattr; + int error; - scr = pxa2x0_lcd_new_screen(sc, descr->depth); - if (scr == NULL) - return (ENOMEM); + /* map controller registers */ + pxa2x0_lcd_console.iot = &pxa2x0_bs_tag; + error = bus_space_map(pxa2x0_lcd_console.iot, + PXA2X0_LCDC_BASE, PXA2X0_LCDC_SIZE, 0, &pxa2x0_lcd_console.ioh); + if (error != 0) + return (error); - sc->sc_ro.ri_hw = (void *)scr; - sc->sc_ro.ri_bits = scr->buf_va; - bcopy(&sc->sc_ro, &scr->rinfo, sizeof(struct rasops_info)); + pxa2x0_lcd_console.dma_tag = &pxa2x0_bus_dma_tag; + pxa2x0_lcd_console.geometry = geom; + + pxa2x0_lcd_initialize(pxa2x0_lcd_console.iot, pxa2x0_lcd_console.ioh, + pxa2x0_lcd_console.geometry, clkman); + + error = pxa2x0_lcd_new_screen(NULL, &pxa2x0_lcd_console.scr, + descr->depth); + if (error != 0) + return (error); + + ri = &pxa2x0_lcd_console.scr.rinfo; + pxa2x0_lcd_setup_rasops(ri, descr, pxa2x0_lcd_console.geometry); + ri->ri_hw = (void *)&pxa2x0_lcd_console.scr; + ri->ri_bits = pxa2x0_lcd_console.scr.buf_va; + + /* assumes 16 bpp */ + ri->ri_ops.alloc_attr(ri, 0, 0, 0, &defattr); + + pxa2x0_lcd_start_dma(pxa2x0_lcd_console.iot, pxa2x0_lcd_console.ioh, + &pxa2x0_lcd_console.scr); + + descr->c.nrows = ri->ri_rows; + descr->c.ncols = ri->ri_cols; + descr->c.capabilities = ri->ri_caps; + descr->c.textops = &ri->ri_ops; + wsdisplay_cnattach(&descr->c, ri, ri->ri_ccol, ri->ri_crow, defattr); - pxa2x0_lcd_show_screen(sc, &sc->sc_ro, 0, NULL, NULL); return (0); } +/* + * Do the necessary accounting to bring the console variables in the softc. + */ +void +pxa2x0_lcd_setup_console(struct pxa2x0_lcd_softc *sc, + const struct pxa2x0_wsscreen_descr *descr) +{ + struct pxa2x0_lcd_screen *scr = &pxa2x0_lcd_console.scr; + + /* + * Register the console screen as if it had been created + * when the lcd device attached. + */ + LIST_INSERT_HEAD(&(sc->screens), &pxa2x0_lcd_console.scr, link); + sc->n_screens++; + sc->active = scr; +} + +/* + * wsdisplay accessops + */ + int pxa2x0_lcd_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), void *cbarg) @@ -557,9 +678,9 @@ pxa2x0_lcd_show_screen(void *v, void *cookie, int waitok, return 0; if (old) - pxa2x0_lcd_stop_dma(sc); + pxa2x0_lcd_stop_dma(sc->iot, sc->ioh); - pxa2x0_lcd_start_dma(sc, scr); + pxa2x0_lcd_start_dma(sc->iot, sc->ioh, scr); sc->active = scr; return 0; @@ -572,38 +693,29 @@ pxa2x0_lcd_alloc_screen(void *v, const struct wsscreen_descr *_type, struct pxa2x0_lcd_softc *sc = v; struct pxa2x0_lcd_screen *scr; struct rasops_info *ri; - struct pxa2x0_wsscreen_descr *type = (struct pxa2x0_wsscreen_descr *)_type; + struct pxa2x0_wsscreen_descr *type = + (struct pxa2x0_wsscreen_descr *)_type; + int error; - scr = pxa2x0_lcd_new_screen(sc, type->depth); + scr = malloc(sizeof *scr, M_DEVBUF, (cold ? M_NOWAIT : M_WAITOK)); if (scr == NULL) return (ENOMEM); + error = pxa2x0_lcd_new_screen(sc, scr, type->depth); + if (error != 0) { + free(scr, M_DEVBUF); + return (error); + } + /* * initialize raster operation for this screen. */ ri = &scr->rinfo; + pxa2x0_lcd_setup_rasops(ri, type, sc->geometry); ri->ri_hw = (void *)scr; - ri->ri_flg = 0; - ri->ri_depth = type->depth; ri->ri_bits = scr->buf_va; - ri->ri_width = sc->geometry->panel_width; - ri->ri_height = sc->geometry->panel_height; - ri->ri_stride = ri->ri_width * ri->ri_depth / 8; -#ifdef notyet - ri->ri_wsfcookie = -1; /* XXX */ -#endif - - if (type->depth == 16) { - ri->ri_rnum = 5; - ri->ri_rpos = 11; - ri->ri_gnum = 6; - ri->ri_gpos = 5; - ri->ri_bnum = 5; - ri->ri_bpos = 0; - } - - rasops_init(ri, type->c.nrows, type->c.ncols); + /* assumes 16 bpp */ ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp); *cookiep = ri; @@ -626,9 +738,11 @@ pxa2x0_lcd_free_screen(void *v, void *cookie) /* at first, we need to stop LCD DMA */ sc->active = NULL; +#ifdef DEBUG printf("lcd_free on active screen\n"); +#endif - pxa2x0_lcd_stop_dma(sc); + pxa2x0_lcd_stop_dma(sc->iot, sc->ioh); } if (scr->buf_va) @@ -696,7 +810,7 @@ pxa2x0_lcd_mmap(void *v, off_t offset, int prot) return (-1); if (offset < 0 || - offset > screen->rinfo.ri_stride * screen->rinfo.ri_height) + offset >= screen->rinfo.ri_stride * screen->rinfo.ri_height) return (-1); return (bus_dmamem_mmap(sc->dma_tag, screen->segs, screen->nsegs, diff --git a/sys/arch/arm/xscale/pxa2x0_lcd.h b/sys/arch/arm/xscale/pxa2x0_lcd.h index 5695e295ffd..6ad1c2b92c5 100644 --- a/sys/arch/arm/xscale/pxa2x0_lcd.h +++ b/sys/arch/arm/xscale/pxa2x0_lcd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pxa2x0_lcd.h,v 1.6 2005/01/06 23:47:20 miod Exp $ */ +/* $OpenBSD: pxa2x0_lcd.h,v 1.7 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: pxa2x0_lcd.h,v 1.2 2003/06/17 09:43:14 bsh Exp $ */ /* * Copyright (c) 2002 Genetec Corporation. All rights reserved. @@ -85,15 +85,10 @@ struct pxa2x0_lcd_softc { int n_screens; LIST_HEAD(, pxa2x0_lcd_screen) screens; struct pxa2x0_lcd_screen *active; - struct rasops_info sc_ro; /* main (console) rasops */ void *ih; /* interrupt handler */ }; -void pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *, struct pxaip_attach_args *, - const struct lcd_panel_geometry *); -void pxa2x0_lcd_start_dma(struct pxa2x0_lcd_softc *, struct pxa2x0_lcd_screen *); - struct lcd_panel_geometry { short panel_width; short panel_height; @@ -124,10 +119,6 @@ struct lcd_panel_geometry { short end_frame_wait; /* end of frame wait (EFW) */ }; -void pxa2x0_lcd_geometry(struct pxa2x0_lcd_softc *, - const struct lcd_panel_geometry *); -struct pxa2x0_lcd_screen *pxa2x0_lcd_new_screen(struct pxa2x0_lcd_softc *, int); - /* * we need bits-per-pixel value to configure wsdisplay screen */ @@ -136,11 +127,11 @@ struct pxa2x0_wsscreen_descr { int depth; /* bits per pixel */ }; -int pxa2x0_lcd_setup_console(struct pxa2x0_lcd_softc *, - const struct pxa2x0_wsscreen_descr *); -int pxa2x0_lcd_setup_wsscreen(struct pxa2x0_lcd_softc *, - struct pxa2x0_wsscreen_descr *, const struct lcd_panel_geometry *, - const char * ); +void pxa2x0_lcd_attach_sub(struct pxa2x0_lcd_softc *, + struct pxaip_attach_args *, struct pxa2x0_wsscreen_descr *, + const struct lcd_panel_geometry *, int); +int pxa2x0_lcd_cnattach(struct pxa2x0_wsscreen_descr *, + const struct lcd_panel_geometry *, void (*)(u_int, int)); int pxa2x0_lcd_alloc_screen(void *, const struct wsscreen_descr *, void **, int *, int *, long *); diff --git a/sys/arch/cats/cats/cats_machdep.c b/sys/arch/cats/cats/cats_machdep.c index 79555b3c2b6..06e89c7290c 100644 --- a/sys/arch/cats/cats/cats_machdep.c +++ b/sys/arch/cats/cats/cats_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cats_machdep.c,v 1.9 2004/09/16 21:52:50 miod Exp $ */ +/* $OpenBSD: cats_machdep.c,v 1.10 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: cats_machdep.c,v 1.50 2003/10/04 14:28:28 chris Exp $ */ /* @@ -907,6 +907,11 @@ initarm(bootargs) return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); } +void +board_startup(void) +{ +} + char *console = CONSDEVNAME; static void diff --git a/sys/arch/hp300/dev/dvbox.c b/sys/arch/hp300/dev/dvbox.c index fd81b222804..a9a7888820b 100644 --- a/sys/arch/hp300/dev/dvbox.c +++ b/sys/arch/hp300/dev/dvbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dvbox.c,v 1.4 2005/01/19 10:51:23 miod Exp $ */ +/* $OpenBSD: dvbox.c,v 1.5 2005/01/21 16:22:34 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -356,7 +356,7 @@ dvbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) wdf->cmsize = 8; /* XXX 16 because of overlay? */ break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->fbwidth; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: diff --git a/sys/arch/hp300/dev/gbox.c b/sys/arch/hp300/dev/gbox.c index 801a995a0f8..061b60eb627 100644 --- a/sys/arch/hp300/dev/gbox.c +++ b/sys/arch/hp300/dev/gbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gbox.c,v 1.5 2005/01/19 10:51:23 miod Exp $ */ +/* $OpenBSD: gbox.c,v 1.6 2005/01/21 16:22:34 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -337,7 +337,7 @@ gbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) wdf->cmsize = 1 << fb->planes; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->fbwidth; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: diff --git a/sys/arch/hp300/dev/hyper.c b/sys/arch/hp300/dev/hyper.c index c7589bd2243..5f5f1de6264 100644 --- a/sys/arch/hp300/dev/hyper.c +++ b/sys/arch/hp300/dev/hyper.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hyper.c,v 1.5 2005/01/19 10:51:23 miod Exp $ */ +/* $OpenBSD: hyper.c,v 1.6 2005/01/21 16:22:34 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -220,7 +220,7 @@ hyper_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) wdf->cmsize = 0; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->fbwidth; break; case WSDISPLAYIO_GVIDEO: case WSDISPLAYIO_SVIDEO: diff --git a/sys/arch/hp300/dev/rbox.c b/sys/arch/hp300/dev/rbox.c index 60f20abe6fb..6945b853777 100644 --- a/sys/arch/hp300/dev/rbox.c +++ b/sys/arch/hp300/dev/rbox.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rbox.c,v 1.4 2005/01/19 10:51:24 miod Exp $ */ +/* $OpenBSD: rbox.c,v 1.5 2005/01/21 16:22:34 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat @@ -317,7 +317,7 @@ rbox_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) wdf->cmsize = 1 << fb->planes; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->fbwidth; break; case WSDISPLAYIO_GETCMAP: case WSDISPLAYIO_PUTCMAP: diff --git a/sys/arch/hp300/dev/topcat.c b/sys/arch/hp300/dev/topcat.c index 0f3639bf576..d9b918fde31 100644 --- a/sys/arch/hp300/dev/topcat.c +++ b/sys/arch/hp300/dev/topcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: topcat.c,v 1.6 2005/01/19 10:51:24 miod Exp $ */ +/* $OpenBSD: topcat.c,v 1.7 2005/01/21 16:22:34 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -387,7 +387,7 @@ topcat_ioctl(void *v, u_long cmd, caddr_t data, int flags, struct proc *p) wdf->cmsize = 1 << fb->planes; break; case WSDISPLAYIO_LINEBYTES: - *(u_int *)data = (fb->fbwidth * fb->planes) >> 3; + *(u_int *)data = fb->fbwidth; break; case WSDISPLAYIO_GETCMAP: return (topcat_getcmap(fb, (struct wsdisplay_cmap *)data)); diff --git a/sys/arch/zaurus/zaurus/zaurus_lcd.c b/sys/arch/zaurus/zaurus/zaurus_lcd.c index b42fed15bf9..1a41096caef 100644 --- a/sys/arch/zaurus/zaurus/zaurus_lcd.c +++ b/sys/arch/zaurus/zaurus/zaurus_lcd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: zaurus_lcd.c,v 1.10 2005/01/13 17:44:43 drahn Exp $ */ +/* $OpenBSD: zaurus_lcd.c,v 1.11 2005/01/21 16:22:34 miod Exp $ */ /* $NetBSD: lubbock_lcd.c,v 1.1 2003/08/09 19:38:53 bsh Exp $ */ /* @@ -60,9 +60,9 @@ #include <machine/zaurus_reg.h> #include <machine/zaurus_var.h> -int lcd_match(struct device *, void *, void *); void lcd_attach(struct device *, struct device *, void *); -int lcdintr(void *); +int lcd_match(struct device *, void *, void *); +int lcd_cnattach(void (*)(u_int, int)); /* * wsdisplay glue @@ -70,31 +70,13 @@ int lcdintr(void *); struct pxa2x0_wsscreen_descr lcd_bpp16_screen = { { - "std" /* "bpp16" */ + "std" }, 16 /* bits per pixel */ -#ifdef notyet -}, lcd_bpp8_screen = { - { - "bpp8" - }, - 8 /* bits per pixel */ -}, lcd_bpp4_screen = { - { - "bpp4" - }, - 4 /* bits per pixel */ -#endif }; - static const struct wsscreen_descr *lcd_scr_descr[] = { -#ifdef notyet - /* bpp4 needs a patch to rasops4 */ - &lcd_bpp4_screen.c, - &lcd_bpp8_screen.c, -#endif - &lcd_bpp16_screen.c, + &lcd_bpp16_screen.c }; const struct wsscreen_list lcd_screen_list = { @@ -125,68 +107,48 @@ struct cfdriver lcd_cd = { NULL, "lcd_pxaip", DV_DULL }; -int -lcd_match(struct device *parent, void *cf, void *aux) -{ - return 1; -} - #define CURRENT_DISPLAY &sharp_zaurus_C3000 -static const struct lcd_panel_geometry sharp_zaurus_C3000 = +const struct lcd_panel_geometry sharp_zaurus_C3000 = { - 480, /* Width */ - 640, /* Height */ - 0, /* No extra lines */ + 480, /* Width */ + 640, /* Height */ + 0, /* No extra lines */ - LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP, - 1, /* clock divider */ - 0, /* AC bias pin freq */ + LCDPANEL_ACTIVE | LCDPANEL_VSP | LCDPANEL_HSP, + 1, /* clock divider */ + 0, /* AC bias pin freq */ - 0x28, /* horizontal sync pulse width */ - 0x2e, /* BLW */ - 0x7d, /* ELW */ + 0x28, /* horizontal sync pulse width */ + 0x2e, /* BLW */ + 0x7d, /* ELW */ - 2, /* vertical sync pulse width */ - 1, /* BFW */ - 0, /* EFW */ + 2, /* vertical sync pulse width */ + 1, /* BFW */ + 0, /* EFW */ }; +int +lcd_match(struct device *parent, void *cf, void *aux) +{ + return 1; +} + void lcd_attach(struct device *parent, struct device *self, void *aux) { struct pxa2x0_lcd_softc *sc = (struct pxa2x0_lcd_softc *)self; struct wsemuldisplaydev_attach_args aa; - long defattr; - - pxa2x0_lcd_attach_sub(sc, aux, CURRENT_DISPLAY); + int console; - /* make wsdisplay screen list */ - pxa2x0_lcd_setup_wsscreen(sc, &lcd_bpp16_screen, CURRENT_DISPLAY, NULL); -#ifdef notyet - pxa2x0_lcd_setup_wsscreen(sc, &lcd_bpp8_screen, CURRENT_DISPLAY, NULL); - pxa2x0_lcd_setup_wsscreen(sc, &lcd_bpp4_screen, CURRENT_DISPLAY, NULL); -#endif + console = 1; /* XXX allow user configuration? */ printf("\n"); - aa.console = 1; /* XXX allow user configuration? */ - - if (aa.console != 0) { - if (pxa2x0_lcd_setup_console(sc, &lcd_bpp16_screen) == 0) { - /* assumes 16bpp */ - sc->sc_ro.ri_ops.alloc_attr(&sc->sc_ro, 0, 0, 0, - &defattr); - - wsdisplay_cnattach(&lcd_bpp16_screen.c, &sc->sc_ro, - sc->sc_ro.ri_ccol, sc->sc_ro.ri_crow, defattr); - } else { - printf("%s: failed to initialize console!\n", - sc->dev.dv_xname); - aa.console = 0; /* better than panicing... */ - } - } + pxa2x0_lcd_attach_sub(sc, aux, &lcd_bpp16_screen, CURRENT_DISPLAY, + console); + aa.console = console; aa.scrdata = &lcd_screen_list; aa.accessops = &lcd_accessops; aa.accesscookie = sc; @@ -194,6 +156,17 @@ lcd_attach(struct device *parent, struct device *self, void *aux) (void)config_found(self, &aa, wsemuldisplaydevprint); } +int +lcd_cnattach(void (*clkman)(u_int, int)) +{ + return + (pxa2x0_lcd_cnattach(&lcd_bpp16_screen, CURRENT_DISPLAY, clkman)); +} + +/* + * wsdisplay accessops overrides + */ + void lcd_burner(void *v, u_int on, u_int flags) { diff --git a/sys/arch/zaurus/zaurus/zaurus_machdep.c b/sys/arch/zaurus/zaurus/zaurus_machdep.c index d05b1e2ed6e..ea5f3e67c96 100644 --- a/sys/arch/zaurus/zaurus/zaurus_machdep.c +++ b/sys/arch/zaurus/zaurus/zaurus_machdep.c @@ -112,10 +112,6 @@ * S20: no-dot: set RB_SINGLE. don't go multi user mode. */ -#include <sys/cdefs.h> -#include "rd.h" -#include "lcd.h" - #include <sys/param.h> #include <sys/device.h> #include <sys/systm.h> @@ -155,6 +151,8 @@ #include <machine/zaurus_reg.h> #include <machine/zaurus_var.h> +#include "wsdisplay.h" + /* Kernel text starts 2MB in from the bottom of the kernel address space. */ #define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00200000) #define KERNEL_VM_BASE (KERNEL_BASE + 0x04000000) @@ -244,6 +242,7 @@ void parse_mi_bootargs(char *args); #endif void consinit(void); +void early_clkman(u_int, int); void kgdb_port_init(void); void change_clock(uint32_t v); @@ -499,7 +498,7 @@ bootstrap_bs_map(void *t, bus_addr_t bpa, bus_size_t size, startpa = trunc_page(bpa); pmap_map_section((vaddr_t)pagedir, va, startpa, - VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE); + VM_PROT_READ | VM_PROT_WRITE, PTE_NOCACHE); cpu_tlb_flushD(); *bshp = (bus_space_handle_t)(va + (bpa - startpa)); @@ -595,12 +594,12 @@ initarm(void *arg) #ifdef DIAGNOSTIC extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */ #endif + /* early bus_space_map support */ struct bus_space tmp_bs_tag; int (*map_func_save)(void *, bus_addr_t, bus_size_t, int, bus_space_handle_t *); - #if 0 /* XXX */ /* start 32.768KHz OSC */ @@ -689,18 +688,25 @@ initarm(void *arg) #if 1 /* turn on clock to UART block. - XXX: this should not be done here. */ - ioreg_write(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN, CKEN_FFUART|CKEN_BTUART | - ioreg_read(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN)); + XXX this should not be necessary, consinit() will do it */ + early_clkman(CKEN_FFUART | CKEN_BTUART, 1); #endif green_on(0); + /* + * Temporarily replace bus_space_map() functions so that + * console devices can get mapped. + * + * Note that this relies upon the fact that both regular + * and a4x bus_space tags use the same map function. + */ tmp_bs_tag = pxa2x0_bs_tag; tmp_bs_tag.bs_map = bootstrap_bs_map; - map_func_save = pxa2x0_a4x_bs_tag.bs_map; - pxa2x0_a4x_bs_tag.bs_map = bootstrap_bs_map; + map_func_save = pxa2x0_bs_tag.bs_map; + pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = bootstrap_bs_map; + /* setup a serial console for very early boot */ consinit(); #ifdef KGDB kgdb_port_init(); @@ -1076,15 +1082,6 @@ initarm(void *arg) printf("bootstrap done.\n"); #endif - if (boothowto & RB_CONFIG) { -#ifdef BOOT_CONFIG - user_config(); -#else - printf("kernel does not support -c; continuing..\n"); -#endif - } - - arm32_vector_init(ARM_VECTORS_LOW, ARM_VEC_ALL); /* @@ -1162,6 +1159,11 @@ initarm(void *arg) } #endif + /* + * Restore proper bus_space operation, now that pmap is initialized. + */ + pxa2x0_a4x_bs_tag.bs_map = pxa2x0_bs_tag.bs_map = map_func_save; + #ifdef DDB db_machine_init(); @@ -1172,8 +1174,6 @@ initarm(void *arg) Debugger(); #endif - pxa2x0_a4x_bs_tag.bs_map = map_func_save ; - /* We return the new stack pointer address */ return(kernelstack.pv_va + USPACE_SVC_STACK_TOP); } @@ -1225,12 +1225,10 @@ int comkgdbmode = KGDB_DEVMODE; #endif /* KGDB */ - void consinit(void) { static int consinit_called = 0; - uint32_t ckenreg = ioreg_read(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN); #if 0 char *console = CONSDEVNAME; #endif @@ -1243,45 +1241,32 @@ consinit(void) #if NCOM > 0 #ifdef FFUARTCONSOLE - if (0) { - /* We don't use FF serial when S17=no-dot position */ - } #ifdef KGDB - else if (0 == strcmp(kgdb_devname, "ffuart")) { + if (strcmp(kgdb_devname, "ffuart") == 0) { /* port is reserved for kgdb */ - } -#endif - else if (0 == comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, - comcnspeed, PXA2X0_COM_FREQ, comcnmode)) { -#if 0 - /* XXX: can't call pxa2x0_clkman_config yet */ - pxa2x0_clkman_config(CKEN_FFUART, 1); -#else - ioreg_write(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN, - ckenreg|CKEN_FFUART); + } else #endif - + if (comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, comcnspeed, + PXA2X0_COM_FREQ, comcnmode) == 0) { + early_clkman(CKEN_FFUART, 1); return; } #endif /* FFUARTCONSOLE */ #ifdef BTUARTCONSOLE #ifdef KGDB - if (0 == strcmp(kgdb_devname, "btuart")) { + if (strcmp(kgdb_devname, "btuart") == 0) { /* port is reserved for kgdb */ } else #endif - if (0 == comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE, - comcnspeed, PXA2X0_COM_FREQ, comcnmode)) { - ioreg_write(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN, - ckenreg|CKEN_BTUART); + if (comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE, comcnspeed, + PXA2X0_COM_FREQ, comcnmode) == 0) { + early_clkman(CKEN_BTUART, 1); return; } #endif /* BTUARTCONSOLE */ - #endif /* NCOM */ - } #ifdef KGDB @@ -1289,28 +1274,75 @@ void kgdb_port_init(void) { #if (NCOM > 0) && defined(COM_PXA2X0) - paddr_t paddr = 0; - enum pxa2x0_uart_id uart_id; - uint32_t ckenreg = ioreg_read(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN); + paddr_t paddr; + u_int cken; - if (0 == strcmp(kgdb_devname, "ffuart")) { + if (strcmp(kgdb_devname, "ffuart") == 0) { paddr = PXA2X0_FFUART_BASE; - clenreg |= CKEN_FFUART; - } - else if (0 == strcmp(kgdb_devname, "btuart")) { + cken = CKEN_FFUART; + } else if (strcmp(kgdb_devname, "btuart") == 0) { paddr = PXA2X0_BTUART_BASE; - clenreg |= CKEN_BTUART; + cken = CKEN_BTUART; + } else + return; + + if (com_kgdb_attach_pxa2x0(&pxa2x0_a4x_bs_tag, paddr, + kgdb_rate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode) == 0) { + early_clkman(cken, 1); } +#endif +} +#endif + +/* same as pxa2x0_clkman, but before autoconf */ +void +early_clkman(u_int clk, int enable) +{ + u_int32_t rv; - if (paddr && - 0 == com_kgdb_attach_pxa2x0(&pxa2x0_a4x_bs_tag, paddr, - kgdb_rate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode)) { + rv = ioreg_read(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN); + if (enable) + rv |= clk; + else + rv &= ~clk; + ioreg_write(ZAURUS_CLKMAN_VBASE + CLKMAN_CKEN, rv); +} + +void +board_startup(void) +{ + extern int lcd_cnattach(void (*)(u_int, int)); + extern bus_addr_t comconsaddr; + +#if NWSDISPLAY > 0 + /* + * Try to attach the display console now that VM services + * are available. + */ - ioreg_write(ZAURUS_CLKMAN_VBASE+CLKMAN_CKEN, ckenreg); + printf("attempting to switch console to lcd screen\n"); + if (lcd_cnattach(early_clkman) == 0) { + /* + * Kill the existing serial console. + * XXX need to bus_space_unmap resources and disable + * clocks... + */ + comconsaddr = 0; + + /* Display the copyright notice again on the new console */ + extern const char copyright[]; + printf("%s\n", copyright); } #endif -} + + if (boothowto & RB_CONFIG) { +#ifdef BOOT_CONFIG + user_config(); +#else + printf("kernel does not support -c; continuing..\n"); #endif + } +} /* * Cotulla's integrated ICU doesn't have IRQ0..7, so @@ -1370,11 +1402,11 @@ pxa2x0_spllower(int ipl) void pxa2x0_setsoftintr(int si) { - #if 0 +#if 0 atomic_set_bit( (u_int *)&softint_pending, SI_TO_IRQBIT(si) ); - #else - softint_pending |= SI_TO_IRQBIT(si); - #endif +#else + softint_pending |= SI_TO_IRQBIT(si); +#endif /* Process unmasked pending soft interrupts. */ if ( softint_pending & intr_mask ) |