fix a few 8bit tcx issues:

- set ROP when clearing the screen, tcx actually uses it
- deal with possible 2MB VRAM tcx
while there, consistently use aprint_* in tcxattach()
This commit is contained in:
macallan 2014-06-17 14:25:17 +00:00
parent 11b42c4183
commit 875518eacc

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcx.c,v 1.49 2014/06/17 10:47:27 macallan Exp $ */
/* $NetBSD: tcx.c,v 1.50 2014/06/17 14:25:17 macallan Exp $ */
/*
* Copyright (c) 1996, 1998, 2009 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.49 2014/06/17 10:47:27 macallan Exp $");
__KERNEL_RCSID(0, "$NetBSD: tcx.c,v 1.50 2014/06/17 14:25:17 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -86,18 +86,19 @@ struct tcx_softc {
bus_space_handle_t sc_bt; /* Brooktree registers */
bus_space_handle_t sc_thc; /* THC registers */
uint8_t *sc_fbaddr; /* framebuffer */
uint64_t *sc_rblit; /* blitspace */
uint64_t *sc_rstip; /* stipple space */
uint8_t *sc_fbaddr; /* framebuffer */
uint64_t *sc_rblit; /* blitspace */
uint64_t *sc_rstip; /* stipple space */
short sc_8bit; /* true if 8-bit hardware */
short sc_blanked; /* true if blanked */
u_char sc_cmap_red[256];
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
int sc_mode, sc_bg;
int sc_cursor_x, sc_cursor_y;
int sc_hotspot_x, sc_hotspot_y;
short sc_8bit; /* true if 8-bit hardware */
short sc_blanked; /* true if blanked */
uint32_t sc_fbsize; /* size of the 8bit fb */
u_char sc_cmap_red[256];
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
int sc_mode, sc_bg;
int sc_cursor_x, sc_cursor_y;
int sc_hotspot_x, sc_hotspot_y;
struct vcons_data vd;
};
@ -138,6 +139,15 @@ struct wsscreen_list tcx_screenlist = {
#define TCX_CTL_24_LEVEL 0x03000000 /* 24 bits, ignores color map */
#define TCX_CTL_PIXELMASK 0x00FFFFFF /* mask for index/level */
/*
* differences between S24 and tcx, as far as this driver is concerned:
* - S24 has 4MB VRAM, 24bit + 2bit control planes, no expansion possible
* - tcx has 1MB VRAM, 8bit, no control planes, may have a VSIMM toat bumps
* VRAM to 2MB
* - tcx can apply ROPs to STIP operations, unlike S24
* - tcx has a Bt458 DAC, just like CG6. S24 has an AT&T 20C567
*/
/* autoconfiguration driver */
static void tcxattach(device_t, device_t, void *);
static int tcxmatch(device_t, cfdata_t, void *);
@ -223,7 +233,7 @@ tcxattach(device_t parent, device_t self, void *args)
struct wsemuldisplaydev_attach_args aa;
struct rasops_info *ri;
unsigned long defattr;
int node, ramsize;
int node;
struct fbdevice *fb = &sc->sc_fb;
bus_space_handle_t bh;
int isconsole, i, j;
@ -251,17 +261,23 @@ tcxattach(device_t parent, device_t self, void *args)
fb->fb_type.fb_depth = 8;
fb_setsize_obp(fb, fb->fb_type.fb_depth, 1152, 900, node);
/*
* actual FB size ( of the 8bit region )
* no need to restrict userland mappings to the visible VRAM
*/
if (sc->sc_8bit) {
printf(" (8-bit only TCX)\n");
ramsize = 1024 * 1024;
aprint_normal(" (8-bit only TCX)\n");
/* at least the SS4 can have 2MB with a VSIMM */
sc->sc_fbsize = 0x100000 * prom_getpropint(node, "vram", 1);
} else {
printf(" (S24)\n");
ramsize = 4 * 1024 * 1024;
aprint_normal(" (S24)\n");
/* all S24 I know of have 4MB, non-expandable */
sc->sc_fbsize = 0x100000;
}
fb->fb_type.fb_cmsize = 256;
fb->fb_type.fb_size = ramsize;
printf("%s: %s, %d x %d", device_xname(self), OBPNAME,
fb->fb_type.fb_size = sc->sc_fbsize; /* later code assumes 8bit */
aprint_normal_dev(self, "%s, %d x %d\n", OBPNAME,
fb->fb_type.fb_width,
fb->fb_type.fb_height);
@ -289,7 +305,8 @@ tcxattach(device_t parent, device_t self, void *args)
sc->sc_physaddr[TCX_REG_THC].oa_base,
0x1000,
BUS_SPACE_MAP_LINEAR, &sc->sc_thc) != 0) {
printf("tcxattach: cannot map thc registers\n");
aprint_error_dev(self,
"tcxattach: cannot map thc registers\n");
return;
}
@ -298,7 +315,7 @@ tcxattach(device_t parent, device_t self, void *args)
sc->sc_physaddr[TCX_REG_CMAP].oa_base,
0x1000,
BUS_SPACE_MAP_LINEAR, &sc->sc_bt) != 0) {
printf("tcxattach: cannot map bt registers\n");
aprint_error_dev(self, "tcxattach: cannot map DAC registers\n");
return;
}
@ -306,10 +323,10 @@ tcxattach(device_t parent, device_t self, void *args)
if (sbus_bus_map(sa->sa_bustag,
sc->sc_physaddr[TCX_REG_DFB8].oa_space,
sc->sc_physaddr[TCX_REG_DFB8].oa_base,
1024 * 1024,
sc->sc_fbsize,
BUS_SPACE_MAP_LINEAR,
&bh) != 0) {
printf("tcxattach: cannot map framebuffer\n");
aprint_error_dev(self, "tcxattach: cannot map framebuffer\n");
return;
}
sc->sc_fbaddr = bus_space_vaddr(sa->sa_bustag, bh);
@ -318,10 +335,10 @@ tcxattach(device_t parent, device_t self, void *args)
if (sbus_bus_map(sa->sa_bustag,
sc->sc_physaddr[TCX_REG_RBLIT].oa_space,
sc->sc_physaddr[TCX_REG_RBLIT].oa_base,
8 * 1024 * 1024,
sc->sc_fbsize << 3,
BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
&bh) != 0) {
printf("tcxattach: cannot map RBLIT space\n");
aprint_error_dev(self, "tcxattach: cannot map RBLIT space\n");
return;
}
sc->sc_rblit = bus_space_vaddr(sa->sa_bustag, bh);
@ -330,10 +347,10 @@ tcxattach(device_t parent, device_t self, void *args)
if (sbus_bus_map(sa->sa_bustag,
sc->sc_physaddr[TCX_REG_RSTIP].oa_space,
sc->sc_physaddr[TCX_REG_RSTIP].oa_base,
8 * 1024 * 1024,
sc->sc_fbsize << 3,
BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_LARGE,
&bh) != 0) {
printf("tcxattach: cannot map RSTIP space\n");
aprint_error_dev(self, "tcxattach: cannot map RSTIP space\n");
return;
}
sc->sc_rstip = bus_space_vaddr(sa->sa_bustag, bh);
@ -341,7 +358,7 @@ tcxattach(device_t parent, device_t self, void *args)
isconsole = fb_is_console(node);
confreg = bus_space_read_4(sa->sa_bustag, sc->sc_thc, THC_CONFIG);
printf(", id %d, rev %d, sense %d",
aprint_normal_dev(self, "id %d, rev %d, sense %d\n",
(confreg & THC_CFG_FBID) >> THC_CFG_FBID_SHIFT,
(confreg & THC_CFG_REV) >> THC_CFG_REV_SHIFT,
(confreg & THC_CFG_SENSE) >> THC_CFG_SENSE_SHIFT
@ -368,9 +385,8 @@ tcxattach(device_t parent, device_t self, void *args)
bus_space_write_4(sa->sa_bustag, sc->sc_thc, THC_MISC, confreg);
if (isconsole) {
printf(" (console)\n");
} else
printf("\n");
aprint_error_dev(self, "(console)\n");
}
fb_attach(&sc->sc_fb, isconsole);
@ -383,11 +399,11 @@ tcxattach(device_t parent, device_t self, void *args)
vcons_init_screen(&sc->vd, &tcx_console_screen, 1, &defattr);
tcx_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
sc->sc_bg = (defattr >> 16) & 0xff;
tcx_clearscreen(sc, 0);
ri = &tcx_console_screen.scr_ri;
sc->sc_bg = ri->ri_devcmap[(defattr >> 16) & 0xff];
tcx_clearscreen(sc, 0);
tcx_defscreendesc.nrows = ri->ri_rows;
tcx_defscreendesc.ncols = ri->ri_cols;
tcx_defscreendesc.textops = &ri->ri_ops;
@ -786,14 +802,14 @@ tcx_mmap(void *v, void *vs, off_t offset, int prot)
/* 'regular' framebuffer mmap()ing */
if (sc->sc_8bit) {
/* on 8Bit boards hand over the 8 bit aperture */
if (offset > 1024 * 1024)
if (offset > sc->sc_fbsize)
return -1;
return bus_space_mmap(sc->sc_bustag,
sc->sc_physaddr[TCX_REG_DFB8].oa_base + offset, 0, prot,
BUS_SPACE_MAP_LINEAR);
} else {
/* ... but if we have a 24bit aperture we use it */
if (offset > 1024 * 1024 * 4)
if (offset > sc->sc_fbsize * 4)
return -1;
return bus_space_mmap(sc->sc_bustag,
sc->sc_physaddr[TCX_REG_DFB24].oa_base + offset, 0, prot,
@ -836,15 +852,18 @@ tcx_init_screen(void *cookie, struct vcons_screen *scr,
static void
tcx_clearscreen(struct tcx_softc *sc, int spc)
{
uint64_t bg = ((uint64_t)sc->sc_bg << 32) | 0xffffffffLL;
/* ROP in the upper 4bit is necessary, tcx actually uses it */
uint64_t bg = 0x30000000ffffffffLL;
uint64_t spc64;
int i;
int i, len;
spc64 = spc & 3;
spc64 = spc64 << 56;
bg |= ((uint64_t)sc->sc_bg << 32);
spc64 = (spc & 3) << 24;
bg |= spc64;
for (i = 0; i < 1024 * 1024; i += 32)
sc->sc_rstip[i] = bg | spc64;
len = sc->sc_fb.fb_type.fb_width * sc->sc_fb.fb_type.fb_height;
for (i = 0; i < len; i += 32)
sc->sc_rstip[i] = bg;
}
static void