summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2005-01-21 16:22:35 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2005-01-21 16:22:35 +0000
commit6405d08b800a0b4df1a326899f3fac2c24649acb (patch)
tree0e82d443e5f01328416142c48bc5172dd92d4cc4
parenta682022fdcaf037e0749c3d29b5b238237ef6ea9 (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.c7
-rw-r--r--sys/arch/arm/include/cpu.h5
-rw-r--r--sys/arch/arm/xscale/pxa2x0_gpio.c8
-rw-r--r--sys/arch/arm/xscale/pxa2x0_lcd.c486
-rw-r--r--sys/arch/arm/xscale/pxa2x0_lcd.h21
-rw-r--r--sys/arch/cats/cats/cats_machdep.c7
-rw-r--r--sys/arch/hp300/dev/dvbox.c4
-rw-r--r--sys/arch/hp300/dev/gbox.c4
-rw-r--r--sys/arch/hp300/dev/hyper.c4
-rw-r--r--sys/arch/hp300/dev/rbox.c4
-rw-r--r--sys/arch/hp300/dev/topcat.c4
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_lcd.c107
-rw-r--r--sys/arch/zaurus/zaurus/zaurus_machdep.c158
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 )