- Declare lookup tables etc. const.
- Let creator_bitblt() return ENODEV as it's not implemented (missed in sys/dev/fb/creator.c rev. 1.6). - As a speed optimization inline the creator_ras_wait() etc. helper functions and also cache setting the font increment, font width and plane mask. [1] - I got the meaning of V_DISPLAY_BLANK wrong, it's blank like turn off and not blank like turn on and clear the screen. So move clearing the screen to creator_clear() were it hopefully belongs. - Properly implement V_DISPLAY_BLANK, V_DISPLAY_STAND_BY and V_DISPLAY_SUSPEND. This makes blank_saver.ko and green_saver.ko work. [1] - Change the order of operations in creator_fill_rect(), i.e. write y before x and cy before cx. This fixes drawing the top part of the border with Elite3D cards when switching from Xorg to a VTY. - Move setting the chip configuration we use and invalidating the cache variables to creator_set_mode() and set the V_ADP_MODECHANGE flag. This causes creator_set_mode() to be called when the X server shuts down which fixes the screen corruption caused most of the time by Xorg not restoring the original configuration present at startup. Inspired by/based on: Xorg [1] Approved by: re (scottl)
This commit is contained in:
parent
c48c19592a
commit
caf07ad5af
@ -83,10 +83,6 @@ static vi_putm_t creator_putm;
|
||||
|
||||
static void creator_cursor_enable(struct creator_softc *sc, int onoff);
|
||||
static void creator_cursor_install(struct creator_softc *sc);
|
||||
static void creator_ras_fifo_wait(struct creator_softc *sc, int n);
|
||||
static void creator_ras_setbg(struct creator_softc *sc, int bg);
|
||||
static void creator_ras_setfg(struct creator_softc *sc, int fg);
|
||||
static void creator_ras_wait(struct creator_softc *sc);
|
||||
|
||||
static video_switch_t creatorvidsw = {
|
||||
.probe = creator_probe,
|
||||
@ -134,7 +130,7 @@ RENDERER_MODULE(creator, gfb_set);
|
||||
extern struct bus_space_tag nexus_bustag;
|
||||
|
||||
#define C(r, g, b) ((b << 16) | (g << 8) | (r))
|
||||
static int cmap[] = {
|
||||
static const int cmap[] = {
|
||||
C(0x00, 0x00, 0x00), /* black */
|
||||
C(0x00, 0x00, 0xff), /* blue */
|
||||
C(0x00, 0xff, 0x00), /* green */
|
||||
@ -153,7 +149,7 @@ static int cmap[] = {
|
||||
C(0xff, 0xff, 0xff), /* white */
|
||||
};
|
||||
|
||||
static u_char creator_mouse_pointer[64][8] __aligned(8) = {
|
||||
static const u_char creator_mouse_pointer[64][8] __aligned(8) = {
|
||||
{ 0x00, 0x00, }, /* ............ */
|
||||
{ 0x80, 0x00, }, /* *........... */
|
||||
{ 0xc0, 0x00, }, /* **.......... */
|
||||
@ -180,6 +176,102 @@ static u_char creator_mouse_pointer[64][8] __aligned(8) = {
|
||||
|
||||
static struct creator_softc creator_softc;
|
||||
|
||||
static inline void creator_ras_fifo_wait(struct creator_softc *sc, int n);
|
||||
static inline void creator_ras_setfontinc(struct creator_softc *sc, int fontinc);
|
||||
static inline void creator_ras_setfontw(struct creator_softc *sc, int fontw);
|
||||
static inline void creator_ras_setbg(struct creator_softc *sc, int bg);
|
||||
static inline void creator_ras_setfg(struct creator_softc *sc, int fg);
|
||||
static inline void creator_ras_setpmask(struct creator_softc *sc, int pmask);
|
||||
static inline void creator_ras_wait(struct creator_softc *sc);
|
||||
|
||||
static inline void
|
||||
creator_ras_wait(struct creator_softc *sc)
|
||||
{
|
||||
int ucsr;
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
ucsr = FFB_READ(sc, FFB_FBC, FFB_FBC_UCSR);
|
||||
if ((ucsr & (FBC_UCSR_FB_BUSY | FBC_UCSR_RP_BUSY)) == 0)
|
||||
break;
|
||||
r = ucsr & (FBC_UCSR_READ_ERR | FBC_UCSR_FIFO_OVFL);
|
||||
if (r != 0)
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_UCSR, r);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_fifo_wait(struct creator_softc *sc, int n)
|
||||
{
|
||||
int cache;
|
||||
|
||||
cache = sc->sc_fifo_cache;
|
||||
while (cache < n)
|
||||
cache = (FFB_READ(sc, FFB_FBC, FFB_FBC_UCSR) &
|
||||
FBC_UCSR_FIFO_MASK) - 8;
|
||||
sc->sc_fifo_cache = cache - n;
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_setfontinc(struct creator_softc *sc, int fontinc)
|
||||
{
|
||||
|
||||
if (fontinc == sc->sc_fontinc_cache)
|
||||
return;
|
||||
sc->sc_fontinc_cache = fontinc;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONTINC, fontinc);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_setfontw(struct creator_softc *sc, int fontw)
|
||||
{
|
||||
|
||||
if (fontw == sc->sc_fontw_cache)
|
||||
return;
|
||||
sc->sc_fontw_cache = fontw;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONTW, fontw);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_setbg(struct creator_softc *sc, int bg)
|
||||
{
|
||||
|
||||
if (bg == sc->sc_bg_cache)
|
||||
return;
|
||||
sc->sc_bg_cache = bg;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BG, bg);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_setfg(struct creator_softc *sc, int fg)
|
||||
{
|
||||
|
||||
if (fg == sc->sc_fg_cache)
|
||||
return;
|
||||
sc->sc_fg_cache = fg;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FG, fg);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
creator_ras_setpmask(struct creator_softc *sc, int pmask)
|
||||
{
|
||||
|
||||
if (pmask == sc->sc_pmask_cache)
|
||||
return;
|
||||
sc->sc_pmask_cache = pmask;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_PMASK, pmask);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
creator_configure(int flags)
|
||||
{
|
||||
@ -281,17 +373,7 @@ creator_init(int unit, video_adapter_t *adp, int flags)
|
||||
sc->sc_xmargin = (sc->sc_width - (vi->vi_width * vi->vi_cwidth)) / 2;
|
||||
sc->sc_ymargin = (sc->sc_height - (vi->vi_height * vi->vi_cheight)) / 2;
|
||||
|
||||
sc->sc_bg_cache = -1;
|
||||
sc->sc_fg_cache = -1;
|
||||
|
||||
creator_ras_wait(sc);
|
||||
sc->sc_fifo_cache = 0;
|
||||
creator_ras_fifo_wait(sc, 2);
|
||||
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_PPC, FBC_PPC_VCE_DIS |
|
||||
FBC_PPC_TBE_OPAQUE | FBC_PPC_APE_DIS | FBC_PPC_CS_CONST);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FBC, FFB_FBC_WB_A | FFB_FBC_RB_A |
|
||||
FFB_FBC_SB_BOTH | FFB_FBC_XE_OFF | FFB_FBC_RGBE_MASK);
|
||||
creator_set_mode(adp, 0);
|
||||
|
||||
if (!(sc->sc_flags & CREATOR_AFB)) {
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE, FFB_DAC_CFG_DID);
|
||||
@ -305,9 +387,17 @@ creator_init(int unit, video_adapter_t *adp, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
creator_blank_display(adp, V_DISPLAY_BLANK);
|
||||
creator_blank_display(adp, V_DISPLAY_ON);
|
||||
creator_clear(adp);
|
||||
|
||||
adp->va_flags |= V_ADP_COLOR | V_ADP_BORDER | V_ADP_INITIALIZED;
|
||||
/*
|
||||
* Setting V_ADP_MODECHANGE serves as hack so creator_set_mode()
|
||||
* (which will invalidate our caches and restore our settings) is
|
||||
* called when the X server shuts down. Otherwise screen corruption
|
||||
* happens most of the time.
|
||||
*/
|
||||
adp->va_flags |= V_ADP_COLOR | V_ADP_MODECHANGE | V_ADP_BORDER |
|
||||
V_ADP_INITIALIZED;
|
||||
if (vid_register(adp) < 0)
|
||||
return (ENXIO);
|
||||
adp->va_flags |= V_ADP_REGISTERED;
|
||||
@ -333,8 +423,23 @@ creator_query_mode(video_adapter_t *adp, video_info_t *info)
|
||||
static int
|
||||
creator_set_mode(video_adapter_t *adp, int mode)
|
||||
{
|
||||
struct creator_softc *sc;
|
||||
|
||||
return (ENODEV);
|
||||
sc = (struct creator_softc *)adp;
|
||||
sc->sc_bg_cache = -1;
|
||||
sc->sc_fg_cache = -1;
|
||||
sc->sc_fontinc_cache = -1;
|
||||
sc->sc_fontw_cache = -1;
|
||||
sc->sc_pmask_cache = -1;
|
||||
|
||||
creator_ras_wait(sc);
|
||||
sc->sc_fifo_cache = 0;
|
||||
creator_ras_fifo_wait(sc, 2);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_PPC, FBC_PPC_VCE_DIS |
|
||||
FBC_PPC_TBE_OPAQUE | FBC_PPC_APE_DIS | FBC_PPC_CS_CONST);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FBC, FFB_FBC_WB_A | FFB_FBC_RB_A |
|
||||
FFB_FBC_SB_BOTH | FFB_FBC_XE_OFF | FFB_FBC_RGBE_MASK);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -438,20 +543,37 @@ static int
|
||||
creator_blank_display(video_adapter_t *adp, int mode)
|
||||
{
|
||||
struct creator_softc *sc;
|
||||
int v;
|
||||
uint32_t v;
|
||||
int i;
|
||||
|
||||
sc = (struct creator_softc *)adp;
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE, FFB_DAC_CFG_TGEN);
|
||||
v = FFB_READ(sc, FFB_DAC, FFB_DAC_VALUE);
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE, FFB_DAC_CFG_TGEN);
|
||||
if (mode == V_DISPLAY_ON || mode == V_DISPLAY_BLANK)
|
||||
switch (mode) {
|
||||
case V_DISPLAY_ON:
|
||||
v &= ~(FFB_DAC_CFG_TGEN_VSD | FFB_DAC_CFG_TGEN_HSD);
|
||||
v |= FFB_DAC_CFG_TGEN_VIDE;
|
||||
else
|
||||
break;
|
||||
case V_DISPLAY_BLANK:
|
||||
v |= (FFB_DAC_CFG_TGEN_VSD | FFB_DAC_CFG_TGEN_HSD);
|
||||
v &= ~FFB_DAC_CFG_TGEN_VIDE;
|
||||
break;
|
||||
case V_DISPLAY_STAND_BY:
|
||||
v &= ~FFB_DAC_CFG_TGEN_VSD;
|
||||
v &= ~FFB_DAC_CFG_TGEN_VIDE;
|
||||
break;
|
||||
case V_DISPLAY_SUSPEND:
|
||||
v |= FFB_DAC_CFG_TGEN_VSD;
|
||||
v &= ~FFB_DAC_CFG_TGEN_HSD;
|
||||
v &= ~FFB_DAC_CFG_TGEN_VIDE;
|
||||
break;
|
||||
}
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE, FFB_DAC_CFG_TGEN);
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_VALUE, v);
|
||||
if (mode == V_DISPLAY_BLANK)
|
||||
creator_fill_rect(adp, (SC_NORM_ATTR >> 4) & 0xf, 0, 0,
|
||||
sc->sc_width, sc->sc_height);
|
||||
for (i = 0; i < 10; i++) {
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_TYPE, FFB_DAC_CFG_TGEN);
|
||||
(void)FFB_READ(sc, FFB_DAC, FFB_DAC_VALUE);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -497,7 +619,11 @@ creator_ioctl(video_adapter_t *adp, u_long cmd, caddr_t data)
|
||||
static int
|
||||
creator_clear(video_adapter_t *adp)
|
||||
{
|
||||
struct creator_softc *sc;
|
||||
|
||||
sc = (struct creator_softc *)adp;
|
||||
creator_fill_rect(adp, (SC_NORM_ATTR >> 4) & 0xf, 0, 0, sc->sc_width,
|
||||
sc->sc_height);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -507,16 +633,20 @@ creator_fill_rect(video_adapter_t *adp, int val, int x, int y, int cx, int cy)
|
||||
struct creator_softc *sc;
|
||||
|
||||
sc = (struct creator_softc *)adp;
|
||||
creator_ras_fifo_wait(sc, 3);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_PMASK, 0xffffffff);
|
||||
creator_ras_setpmask(sc, 0xffffffff);
|
||||
creator_ras_fifo_wait(sc, 2);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_ROP, FBC_ROP_NEW);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_DRAWOP, FBC_DRAWOP_RECTANGLE);
|
||||
creator_ras_setfg(sc, cmap[val & 0xf]);
|
||||
/*
|
||||
* Note that at least the Elite3D cards are sensitive to the order
|
||||
* of operations here.
|
||||
*/
|
||||
creator_ras_fifo_wait(sc, 4);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BX, x);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BY, y);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BW, cx);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BX, x);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BH, cy);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BW, cx);
|
||||
creator_ras_wait(sc);
|
||||
return (0);
|
||||
}
|
||||
@ -525,7 +655,7 @@ static int
|
||||
creator_bitblt(video_adapter_t *adp, ...)
|
||||
{
|
||||
|
||||
return (0);
|
||||
return (ENODEV);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -583,11 +713,11 @@ creator_putc(video_adapter_t *adp, vm_offset_t off, u_int8_t c, u_int8_t a)
|
||||
p = (uint16_t *)sc->sc_font + (c * adp->va_info.vi_cheight);
|
||||
creator_ras_setfg(sc, cmap[a & 0xf]);
|
||||
creator_ras_setbg(sc, cmap[(a >> 4) & 0xf]);
|
||||
creator_ras_fifo_wait(sc, 3 + adp->va_info.vi_cheight);
|
||||
creator_ras_fifo_wait(sc, 1 + adp->va_info.vi_cheight);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONTXY,
|
||||
((row + sc->sc_ymargin) << 16) | (col + sc->sc_xmargin));
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONTW, adp->va_info.vi_cwidth);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONTINC, 0x10000);
|
||||
creator_ras_setfontw(sc, adp->va_info.vi_cwidth);
|
||||
creator_ras_setfontinc(sc, 0x10000);
|
||||
for (i = 0; i < adp->va_info.vi_cheight; i++) {
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FONT, *p++ << 16);
|
||||
}
|
||||
@ -624,60 +754,6 @@ creator_putm(video_adapter_t *adp, int x, int y, u_int8_t *pixel_image,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
creator_ras_fifo_wait(struct creator_softc *sc, int n)
|
||||
{
|
||||
int cache;
|
||||
|
||||
cache = sc->sc_fifo_cache;
|
||||
while (cache < n) {
|
||||
cache = (FFB_READ(sc, FFB_FBC, FFB_FBC_UCSR) &
|
||||
FBC_UCSR_FIFO_MASK) - 8;
|
||||
}
|
||||
sc->sc_fifo_cache = cache - n;
|
||||
}
|
||||
|
||||
static void
|
||||
creator_ras_setbg(struct creator_softc *sc, int bg)
|
||||
{
|
||||
|
||||
if (bg == sc->sc_bg_cache)
|
||||
return;
|
||||
sc->sc_bg_cache = bg;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_BG, bg);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
creator_ras_setfg(struct creator_softc *sc, int fg)
|
||||
{
|
||||
|
||||
if (fg == sc->sc_fg_cache)
|
||||
return;
|
||||
sc->sc_fg_cache = fg;
|
||||
creator_ras_fifo_wait(sc, 1);
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_FG, fg);
|
||||
creator_ras_wait(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
creator_ras_wait(struct creator_softc *sc)
|
||||
{
|
||||
int ucsr;
|
||||
int r;
|
||||
|
||||
for (;;) {
|
||||
ucsr = FFB_READ(sc, FFB_FBC, FFB_FBC_UCSR);
|
||||
if ((ucsr & (FBC_UCSR_FB_BUSY | FBC_UCSR_RP_BUSY)) == 0)
|
||||
break;
|
||||
r = ucsr & (FBC_UCSR_READ_ERR | FBC_UCSR_FIFO_OVFL);
|
||||
if (r != 0) {
|
||||
FFB_WRITE(sc, FFB_FBC, FFB_FBC_UCSR, r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
creator_cursor_enable(struct creator_softc *sc, int onoff)
|
||||
{
|
||||
@ -705,9 +781,9 @@ creator_cursor_install(struct creator_softc *sc)
|
||||
i ? FFB_DAC_CUR_BITMAP_P0 : FFB_DAC_CUR_BITMAP_P1);
|
||||
for (j = 0; j < 64; j++) {
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_VALUE2,
|
||||
*(uint32_t *)(&creator_mouse_pointer[j][0]));
|
||||
*(const uint32_t *)(&creator_mouse_pointer[j][0]));
|
||||
FFB_WRITE(sc, FFB_DAC, FFB_DAC_VALUE2,
|
||||
*(uint32_t *)(&creator_mouse_pointer[j][4]));
|
||||
*(const uint32_t *)(&creator_mouse_pointer[j][4]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -231,6 +231,9 @@ struct creator_softc {
|
||||
int sc_bg_cache;
|
||||
int sc_fg_cache;
|
||||
int sc_fifo_cache;
|
||||
int sc_fontinc_cache;
|
||||
int sc_fontw_cache;
|
||||
int sc_pmask_cache;
|
||||
|
||||
int sc_flags;
|
||||
#define CREATOR_AFB (1 << 0)
|
||||
|
@ -231,6 +231,9 @@ struct creator_softc {
|
||||
int sc_bg_cache;
|
||||
int sc_fg_cache;
|
||||
int sc_fifo_cache;
|
||||
int sc_fontinc_cache;
|
||||
int sc_fontw_cache;
|
||||
int sc_pmask_cache;
|
||||
|
||||
int sc_flags;
|
||||
#define CREATOR_AFB (1 << 0)
|
||||
|
@ -93,7 +93,7 @@ struct ffb_map {
|
||||
uint64_t fm_size;
|
||||
};
|
||||
|
||||
static struct ffb_map ffb_map[] = {
|
||||
static const struct ffb_map ffb_map[] = {
|
||||
{ FFB_VIRT_SFB8R, FFB_PHYS_SFB8R, 0x00400000 },
|
||||
{ FFB_VIRT_SFB8G, FFB_PHYS_SFB8G, 0x00400000 },
|
||||
{ FFB_VIRT_SFB8B, FFB_PHYS_SFB8B, 0x00400000 },
|
||||
@ -278,7 +278,7 @@ static int
|
||||
creator_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int prot)
|
||||
{
|
||||
struct creator_softc *sc;
|
||||
struct ffb_map *fm;
|
||||
const struct ffb_map *fm;
|
||||
|
||||
sc = dev->si_drv1;
|
||||
for (fm = ffb_map; fm->fm_size != 0; fm++) {
|
||||
|
Loading…
Reference in New Issue
Block a user