For shadowfb, only allocate the memory we're going to use rather than the

entire possible framebuffer size allowed on this machine (4MB).

Fix a bug in av pack detection to make HDTV actually work now.
This commit is contained in:
jmcneill 2007-01-07 04:53:29 +00:00
parent bee2705c99
commit 20e62597f7
1 changed files with 77 additions and 67 deletions

View File

@ -1,6 +1,7 @@
/* $NetBSD: xboxfb.c,v 1.5 2007/01/07 01:12:42 jmcneill Exp $ */
/* $NetBSD: xboxfb.c,v 1.6 2007/01/07 04:53:29 jmcneill Exp $ */
/*
* Copyright (c) 2007 Jared D. McNeill <jmcneill@invisible.ca>
* Copyright (c) 2006 Andrew Gillham
* All rights reserved.
*
@ -70,7 +71,14 @@ MALLOC_DEFINE(M_XBOXFB, "xboxfb", "xboxfb shadow framebuffer");
#define SCREEN_WIDTH_VGA 800
#define SCREEN_HEIGHT_VGA 600
#define SCREEN_BPP 32
#define SCREEN_SIZE(sc) ((sc)->width * (sc)->height * SCREEN_BPP)
/*
* Define a safe area border for TV displays.
*/
#define XBOXFB_SAFE_AREA_SDTV_LEFT 40
#define XBOXFB_SAFE_AREA_SDTV_TOP 40
#define XBOXFB_SAFE_AREA_HDTV_LEFT 72
#define XBOXFB_SAFE_AREA_HDTV_TOP 16
#define FONT_HEIGHT 16
#define FONT_WIDTH 8
@ -85,7 +93,6 @@ MALLOC_DEFINE(M_XBOXFB, "xboxfb", "xboxfb shadow framebuffer");
#define XBOX_FB_START_PTR (0xFD600800)
*/
static char *xboxfb_console_shadowbits;
static bus_space_handle_t xboxfb_console_memh;
struct xboxfb_softc {
@ -95,20 +102,12 @@ struct xboxfb_softc {
bus_space_tag_t sc_memt;
bus_space_handle_t sc_memh;
vaddr_t fbva;
paddr_t fbpa;
void *sc_ih;
size_t memsize;
int bits_per_pixel;
int width, height, linebytes;
int sc_mode;
uint32_t sc_bg;
char *sc_shadowbits;
};
static struct vcons_screen xboxfb_console_screen;
@ -198,24 +197,9 @@ xboxfb_attach(struct device *parent, struct device *self, void *aux)
sc->sc_memt = X86_BUS_SPACE_MEM;
sc->sc_memh = xboxfb_console_memh;
sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
sc->width = ri->ri_width;
sc->height = ri->ri_height;
sc->bits_per_pixel = SCREEN_BPP;
sc->fbpa = XBOX_FB_START;
aprint_normal(": %dx%d, %d bit framebuffer console\n",
sc->width, sc->height, sc->bits_per_pixel);
sc->fbva = (vaddr_t)bus_space_vaddr(sc->sc_memt, sc->sc_memh);
if (sc->fbva == 0)
return;
sc->sc_shadowbits = xboxfb_console_shadowbits;
if (sc->sc_shadowbits == NULL) {
aprint_error(": unable to allocate %d bytes for shadowfb\n",
XBOX_FB_SIZE);
return;
}
ri->ri_width, ri->ri_height, ri->ri_depth);
vcons_init(&sc->vd, sc, &xboxfb_defaultscreen, &xboxfb_accessops);
sc->vd.init_screen = xboxfb_init_screen;
@ -273,7 +257,7 @@ xboxfb_ioctl(void *v, void*vs, u_long cmd, caddr_t data, int flag,
return EINVAL;
case WSDISPLAYIO_LINEBYTES:
*(u_int *)data = sc->width * 4;
*(u_int *)data = ms->scr_ri.ri_width * 4;
return 0;
case WSDISPLAYIO_SMODE:
@ -313,33 +297,31 @@ static void
xboxfb_init_screen(void *cookie, struct vcons_screen *scr,
int existing, long *defattr)
{
struct xboxfb_softc *sc = cookie;
/*struct xboxfb_softc *sc = cookie;*/
struct rasops_info *ri = &scr->scr_ri;
struct rasops_info *console_ri;
if (scr == &xboxfb_console_screen)
return;
console_ri = &xboxfb_console_screen.scr_ri;
ri->ri_depth = sc->bits_per_pixel;
ri->ri_width = sc->width;
ri->ri_height = sc->height;
ri->ri_stride = sc->width * (sc->bits_per_pixel / 8);
ri->ri_flg = RI_CENTER;
ri->ri_depth = console_ri->ri_depth;
ri->ri_width = console_ri->ri_width;
ri->ri_height = console_ri->ri_height;
ri->ri_stride = console_ri->ri_stride;
ri->ri_flg = console_ri->ri_flg;
if (xboxfb_console_shadowbits != NULL) {
ri->ri_hwbits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
ri->ri_bits = sc->sc_shadowbits;
} else
ri->ri_bits = bus_space_vaddr(sc->sc_memt, sc->sc_memh);
ri->ri_hwbits = console_ri->ri_hwbits;
ri->ri_bits = console_ri->ri_bits;
if (existing) {
if (existing)
ri->ri_flg |= RI_CLEAR;
}
rasops_init(ri, sc->height/8, sc->width/8);
rasops_init(ri, ri->ri_height / 8, ri->ri_width / 8);
ri->ri_caps = WSSCREEN_WSCOLORS;
rasops_reconfig(ri, sc->height / ri->ri_font->fontheight,
sc->width / ri->ri_font->fontwidth);
rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
ri->ri_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
}
@ -378,7 +360,7 @@ xboxfb_get_avpack(void)
if (rv)
return PIC16LC_REG_AVPACK_COMPOSITE; /* shouldn't happen */
xboxfb_smbus_pic_read(t, h, PIC16LC_REG_AVPACK);
rv = xboxfb_smbus_pic_read(t, h, PIC16LC_REG_AVPACK);
bus_space_unmap(t, h, 16);
@ -390,8 +372,11 @@ xboxfb_cnattach(void)
{
static int ncalls = 0;
struct rasops_info *ri = &xboxfb_console_screen.scr_ri;
uint8_t *xboxfb_console_shadowbits = NULL;
long defattr;
uint8_t avpack;
uint32_t fbsize;
uint32_t sa_top, sa_left;
/* We can't attach if we're not running on an Xbox... */
if (!arch_i386_is_xbox)
@ -406,17 +391,6 @@ xboxfb_cnattach(void)
if (ncalls < 3)
return -1;
xboxfb_console_shadowbits = malloc(XBOX_FB_SIZE, M_XBOXFB, M_NOWAIT);
if (xboxfb_console_shadowbits == NULL)
aprint_error("xboxfb_cnattach: failed to allocate shadowfb\n");
if (bus_space_map(X86_BUS_SPACE_MEM, XBOX_FB_START, XBOX_FB_SIZE,
BUS_SPACE_MAP_LINEAR, &xboxfb_console_memh)) {
aprint_error("xboxfb_cnattach: failed to map memory.\n");
return 1;
}
wsfont_init();
/*
@ -428,35 +402,71 @@ xboxfb_cnattach(void)
case PIC16LC_REG_AVPACK_HDTV:
ri->ri_width = SCREEN_WIDTH_HDTV;
ri->ri_height = SCREEN_HEIGHT_HDTV;
sa_top = XBOXFB_SAFE_AREA_HDTV_TOP;
sa_left = XBOXFB_SAFE_AREA_HDTV_LEFT;
break;
case PIC16LC_REG_AVPACK_VGA:
case PIC16LC_REG_AVPACK_VGA_SOG:
ri->ri_width = SCREEN_WIDTH_VGA;
ri->ri_height = SCREEN_HEIGHT_VGA;
sa_top = sa_left = 0;
break;
default:
ri->ri_width = SCREEN_WIDTH_SDTV;
ri->ri_height = SCREEN_HEIGHT_SDTV;
sa_top = XBOXFB_SAFE_AREA_SDTV_TOP;
sa_left = XBOXFB_SAFE_AREA_SDTV_LEFT;
break;
}
ri->ri_depth = SCREEN_BPP;
ri->ri_stride = ri->ri_width * ri->ri_depth / 8;
ri->ri_flg = RI_CENTER;
ri->ri_bits = xboxfb_console_shadowbits;
ri->ri_hwbits = bus_space_vaddr(X86_BUS_SPACE_MEM,
xboxfb_console_memh);
if (ri->ri_hwbits == NULL) {
aprint_error("xboxfb_cnattach: bus_space_vaddr failed\n");
fbsize = ri->ri_width * ri->ri_height * 4;
xboxfb_console_shadowbits = malloc(fbsize, M_XBOXFB, M_NOWAIT);
if (xboxfb_console_shadowbits == NULL)
aprint_error("xboxfb_cnattach: failed to allocate shadowfb\n");
if (bus_space_map(X86_BUS_SPACE_MEM, XBOX_FB_START, fbsize,
BUS_SPACE_MAP_LINEAR, &xboxfb_console_memh)) {
aprint_error("xboxfb_cnattach: failed to map memory.\n");
return 1;
}
ri->ri_depth = SCREEN_BPP;
ri->ri_stride = ri->ri_width * ri->ri_depth / 8;
ri->ri_flg = RI_CENTER;
if (xboxfb_console_shadowbits) {
ri->ri_bits = xboxfb_console_shadowbits;
ri->ri_hwbits = bus_space_vaddr(X86_BUS_SPACE_MEM,
xboxfb_console_memh);
} else {
ri->ri_bits = bus_space_vaddr(X86_BUS_SPACE_MEM,
xboxfb_console_memh);
ri->ri_hwbits = NULL;
}
/* clear screen */
memset(ri->ri_bits, 0, XBOX_FB_SIZE);
memset(ri->ri_hwbits, 0, XBOX_FB_SIZE);
if (ri->ri_bits != NULL)
memset(ri->ri_bits, 0, fbsize);
if (ri->ri_hwbits != NULL)
memset(ri->ri_hwbits, 0, fbsize);
#if notyet
/* Define a TV safe area where applicable */
if (sa_left > 0) {
ri->ri_hwbits += (sa_left * 4);
ri->ri_width -= (sa_left * 2);
}
if (sa_top > 0) {
ri->ri_hwbits += (ri->ri_stride * sa_top);
ri->ri_height -= (sa_top * 2);
}
#endif
rasops_init(ri, ri->ri_height / 8, ri->ri_width / 8);
ri->ri_caps = WSSCREEN_WSCOLORS;
rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
rasops_reconfig(ri,
ri->ri_height / ri->ri_font->fontheight,
ri->ri_width / ri->ri_font->fontwidth);
xboxfb_defaultscreen.nrows = ri->ri_rows;