From 073ea490348952e1152028e8d95966914d863f41 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Sat, 27 Dec 2008 17:23:04 +0000 Subject: Sync the sparc64 fb* api with the recent changes done on sparc. --- sys/arch/sparc64/dev/creator.c | 63 ++----------- sys/arch/sparc64/dev/fb.c | 195 +++++++++++++++++++++++++++++++++++---- sys/arch/sparc64/dev/ifb.c | 58 ++---------- sys/arch/sparc64/dev/vgafb.c | 64 ++----------- sys/arch/sparc64/include/fbvar.h | 5 +- 5 files changed, 205 insertions(+), 180 deletions(-) (limited to 'sys/arch') diff --git a/sys/arch/sparc64/dev/creator.c b/sys/arch/sparc64/dev/creator.c index c9de9719a8a..be6ea44fba4 100644 --- a/sys/arch/sparc64/dev/creator.c +++ b/sys/arch/sparc64/dev/creator.c @@ -1,4 +1,4 @@ -/* $OpenBSD: creator.c,v 1.39 2007/03/06 23:10:26 kettenis Exp $ */ +/* $OpenBSD: creator.c,v 1.40 2008/12/27 17:23:01 miod Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -49,11 +49,6 @@ int creator_match(struct device *, void *, void *); void creator_attach(struct device *, struct device *, void *); int creator_ioctl(void *, u_long, caddr_t, int, struct proc *); -int creator_alloc_screen(void *, const struct wsscreen_descr *, void **, - int *, int *, long *); -void creator_free_screen(void *, void *); -int creator_show_screen(void *, void *, int, void (*cb)(void *, int, int), - void *); paddr_t creator_mmap(void *, off_t, int); void creator_ras_fifo_wait(struct creator_softc *, int); void creator_ras_wait(struct creator_softc *); @@ -70,10 +65,10 @@ void creator_curs_enable(struct creator_softc *, u_int); struct wsdisplay_accessops creator_accessops = { creator_ioctl, creator_mmap, - creator_alloc_screen, - creator_free_screen, - creator_show_screen, - NULL, /* load font */ + NULL, /* alloc_screen */ + NULL, /* free_screen */ + NULL, /* show_screen */ + NULL, /* load_font */ NULL, /* scrollback */ NULL, /* getchar */ NULL, /* burner */ @@ -187,7 +182,7 @@ creator_attach(parent, self, aux) sc->sc_sunfb.sf_ro.ri_bits = (void *)bus_space_vaddr(sc->sc_bt, sc->sc_pixel_h); sc->sc_sunfb.sf_ro.ri_hw = sc; - fbwscons_init(&sc->sc_sunfb, sc->sc_console ? 0 : RI_CLEAR); + fbwscons_init(&sc->sc_sunfb, 0, sc->sc_console); if ((sc->sc_sunfb.sf_dev.dv_cfdata->cf_flags & CREATOR_CFFLAG_NOACCEL) == 0) { @@ -197,9 +192,8 @@ creator_attach(parent, self, aux) creator_ras_init(sc); } - if (sc->sc_console) { + if (sc->sc_console) fbwscons_console_init(&sc->sc_sunfb, -1); - } fbwscons_attach(&sc->sc_sunfb, &creator_accessops, sc->sc_console); return; @@ -432,49 +426,6 @@ creator_updatecursor(struct creator_softc *sc, u_int which) return (0); } -int -creator_alloc_screen(v, type, cookiep, curxp, curyp, attrp) - void *v; - const struct wsscreen_descr *type; - void **cookiep; - int *curxp, *curyp; - long *attrp; -{ - struct creator_softc *sc = v; - - if (sc->sc_nscreens > 0) - return (ENOMEM); - - *cookiep = &sc->sc_sunfb.sf_ro; - *curyp = 0; - *curxp = 0; - sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro, - WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); - sc->sc_nscreens++; - return (0); -} - -void -creator_free_screen(v, cookie) - void *v; - void *cookie; -{ - struct creator_softc *sc = v; - - sc->sc_nscreens--; -} - -int -creator_show_screen(v, cookie, waitok, cb, cbarg) - void *v; - void *cookie; - int waitok; - void (*cb)(void *, int, int); - void *cbarg; -{ - return (0); -} - const struct creator_mappings { bus_addr_t uoff; bus_addr_t poff; diff --git a/sys/arch/sparc64/dev/fb.c b/sys/arch/sparc64/dev/fb.c index bb2db23a871..11fd1bd2b2b 100644 --- a/sys/arch/sparc64/dev/fb.c +++ b/sys/arch/sparc64/dev/fb.c @@ -1,8 +1,8 @@ -/* $OpenBSD: fb.c,v 1.17 2007/11/10 15:17:16 jsing Exp $ */ +/* $OpenBSD: fb.c,v 1.18 2008/12/27 17:23:01 miod Exp $ */ /* $NetBSD: fb.c,v 1.23 1997/07/07 23:30:22 pk Exp $ */ /* - * Copyright (c) 2002, 2004 Miodrag Vallat. + * Copyright (c) 2002, 2004, 2008 Miodrag Vallat. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -78,6 +78,7 @@ #include #include +#include #include #include @@ -112,8 +113,15 @@ fb_unblank() #if NWSDISPLAY > 0 static int a2int(char *, int); -static void fb_initwsd(struct sunfb *); -static void fb_updatecursor(struct rasops_info *); +int fb_get_console_metrics(int *, int *, int *, int *); +void fb_initwsd(struct sunfb *); +void fb_updatecursor(struct rasops_info *); + +int fb_alloc_screen(void *, const struct wsscreen_descr *, void **, + int *, int *, long *); +void fb_free_screen(void *, void *); +int fb_show_screen(void *, void *, int, void (*)(void *, int, int), + void *); void fb_setsize(struct sunfb *sf, int def_depth, int def_width, int def_height, @@ -128,15 +136,15 @@ fb_setsize(struct sunfb *sf, int def_depth, int def_width, int def_height, def_linebytes = roundup(sf->sf_width, sf->sf_depth) * sf->sf_depth / 8; sf->sf_linebytes = getpropint(node, "linebytes", def_linebytes); + /* * XXX If we are configuring a board in a wider depth level * than the mode it is currently operating in, the PROM will * return a linebytes property tied to the current depth value, * which is NOT what we are relying upon! */ - if (sf->sf_linebytes < (sf->sf_width * sf->sf_depth) / 8) { + if (sf->sf_linebytes < (sf->sf_width * sf->sf_depth) / 8) sf->sf_linebytes = def_linebytes; - } sf->sf_fbsize = sf->sf_height * sf->sf_linebytes; } @@ -154,7 +162,7 @@ a2int(char *cp, int deflt) } /* setup the embedded wsscreen_descr structure from rasops settings */ -static void +void fb_initwsd(struct sunfb *sf) { strlcpy(sf->sf_wsd.name, "std", sizeof(sf->sf_wsd.name)); @@ -164,7 +172,7 @@ fb_initwsd(struct sunfb *sf) sf->sf_wsd.textops = &sf->sf_ro.ri_ops; } -static void +void fb_updatecursor(struct rasops_info *ri) { struct sunfb *sf = (struct sunfb *)ri->ri_hw; @@ -176,13 +184,13 @@ fb_updatecursor(struct rasops_info *ri) } void -fbwscons_init(struct sunfb *sf, int flags) +fbwscons_init(struct sunfb *sf, int flags, int isconsole) { struct rasops_info *ri = &sf->sf_ro; - int cols, rows; + int cols, rows, fw, fh, wt, wl; /* ri_hw and ri_bits must have already been setup by caller */ - ri->ri_flg = RI_CENTER | RI_FULLCLEAR | flags; + ri->ri_flg = RI_FULLCLEAR | flags; ri->ri_depth = sf->sf_depth; ri->ri_stride = sf->sf_linebytes; ri->ri_width = sf->sf_width; @@ -191,8 +199,78 @@ fbwscons_init(struct sunfb *sf, int flags) rows = a2int(getpropstring(optionsnode, "screen-#rows"), 34); cols = a2int(getpropstring(optionsnode, "screen-#columns"), 80); + /* + * If the framebuffer width is under 960 pixels, rasops will + * switch from the 12x22 font to the more adequate 8x16 font + * here. + * If we are the console device, we need to adjust two things: + * - the display row should be overrided from the current PROM + * metrics, since it will not match the PROM reality anymore. + * - the screen needs to be cleared. + * + * However, to accomodate laptops with specific small fonts, + * it is necessary to compare the resolution with the actual + * font metrics. + */ + + if (isconsole) { + if (fb_get_console_metrics(&fw, &fh, &wt, &wl) != 0) { + /* + * Assume a 12x22 prom font and a centered + * 80x34 console window. + */ + fw = 12; fh = 22; + ri->ri_flg |= RI_CENTER; + + /* + * Since the console window might not be + * centered (e.g. on a 1280x1024 vigra + * VS-12 frame buffer), have rasops + * clear the margins even if the screen is + * not cleared. + */ + ri->ri_flg |= RI_CLEARMARGINS; + } + + if (ri->ri_wsfcookie != 0) { + /* driver handles font issues. do nothing. */ + } else { + /* + * If the PROM uses a different font than the + * one we are expecting it to use, or if the + * display is shorter than 960 pixels wide, + * we'll force a screen clear. + */ + if (fw != 12 || sf->sf_width < 12 * 80) + ri->ri_flg |= RI_CLEAR | RI_CENTER; + } + } else { + ri->ri_flg |= RI_CLEAR | RI_CENTER; + } + + /* ifb(4) doesn't set ri_bits at the moment */ + if (ri->ri_bits == NULL) + ri->ri_flg &= ~RI_CLEAR; + rasops_init(ri, rows, cols); + /* + * If this is the console display and there is no font change, + * adjust our terminal window to the position of the PROM + * window - in case it is not exactly centered. + */ + if ((ri->ri_flg & RI_CENTER) == 0) { + /* code above made sure wt and wl are initialized */ + ri->ri_bits += wt * ri->ri_stride; + if (ri->ri_depth >= 8) /* for 15bpp to compute ok */ + ri->ri_bits += wl * ri->ri_pelbytes; + else + ri->ri_bits += (wl * ri->ri_depth) >> 3; + + ri->ri_xorigin = wl; + ri->ri_yorigin = wt; + } + if (sf->sf_depth == 8) { /* * If we are running with an indexed palette, compensate @@ -221,21 +299,26 @@ fbwscons_console_init(struct sunfb *sf, int row) if (sf->sf_ccolp != NULL) ri->ri_ccol = *sf->sf_ccolp; - if (row < 0) { - if (sf->sf_crowp != NULL) - ri->ri_crow = *sf->sf_crowp; - else - /* assume last row */ - ri->ri_crow = ri->ri_rows - 1; - } else { + if (ri->ri_flg & RI_CLEAR) { /* - * If we force the display row, this is because the screen - * has been cleared or the font has been changed. + * If we have cleared the screen, this is because either + * we are not the console display, or the font has been + * changed. * In this case, choose not to keep pointers to the PROM * cursor position, as the values are likely to be inaccurate * upon shutdown... */ sf->sf_crowp = sf->sf_ccolp = NULL; + row = 0; + } + + if (row < 0) /* no override */ { + if (sf->sf_crowp != NULL) + ri->ri_crow = *sf->sf_crowp; + else + /* assume last row */ + ri->ri_crow = ri->ri_rows - 1; + } else { ri->ri_crow = row; } @@ -308,6 +391,13 @@ fbwscons_attach(struct sunfb *sf, struct wsdisplay_accessops *op, int isconsole) fb_cookie = sf; } + /* plug common wsdisplay_accessops if necessary */ + if (op->alloc_screen == NULL) { + op->alloc_screen = fb_alloc_screen; + op->free_screen = fb_free_screen; + op->show_screen = fb_show_screen; + } + sf->sf_scrlist[0] = &sf->sf_wsd; sf->sf_wsl.nscreens = 1; sf->sf_wsl.screens = (const struct wsscreen_descr **)sf->sf_scrlist; @@ -320,4 +410,69 @@ fbwscons_attach(struct sunfb *sf, struct wsdisplay_accessops *op, int isconsole) config_found(&sf->sf_dev, &waa, wsemuldisplaydevprint); } +/* + * Common wsdisplay_accessops routines. + */ +int +fb_alloc_screen(void *v, const struct wsscreen_descr *type, + void **cookiep, int *curxp, int *curyp, long *attrp) +{ + struct sunfb *sf = v; + struct rasops_info *ri = &sf->sf_ro; + + if (sf->sf_nscreens > 0) + return (ENOMEM); + + *cookiep = ri; + *curyp = 0; + *curxp = 0; + if (ISSET(ri->ri_caps, WSSCREEN_WSCOLORS)) + ri->ri_ops.alloc_attr(ri, + WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); + else + ri->ri_ops.alloc_attr(ri, 0, 0, 0, attrp); + sf->sf_nscreens++; + return (0); +} + +void +fb_free_screen(void *v, void *cookie) +{ + struct sunfb *sf = v; + + sf->sf_nscreens--; +} + +int +fb_show_screen(void *v, void *cookie, int waitok, void (*cb)(void *, int, int), + void *cbarg) +{ + return (0); +} + +int +fb_get_console_metrics(int *fontwidth, int *fontheight, int *wtop, int *wleft) +{ + cell_t romheight, romwidth, windowtop, windowleft; + + /* + * Get the PROM font metrics and address + */ + OF_interpret("stdout @ is my-self " + "addr char-height addr char-width " + "addr window-top addr window-left", + 4, &windowleft, &windowtop, &romwidth, &romheight); + + if (romheight == NULL || romwidth == NULL || + windowtop == NULL || windowleft == NULL) + return (1); + + *fontwidth = (int)*(uint64_t *)romwidth; + *fontheight = (int)*(uint64_t *)romheight; + *wtop = (int)*(uint64_t *)windowtop; + *wleft = (int)*(uint64_t *)windowleft; + + return (0); +} + #endif /* NWSDISPLAY */ diff --git a/sys/arch/sparc64/dev/ifb.c b/sys/arch/sparc64/dev/ifb.c index 9cc81b0ff53..bdd42275a80 100644 --- a/sys/arch/sparc64/dev/ifb.c +++ b/sys/arch/sparc64/dev/ifb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifb.c,v 1.3 2008/12/27 14:33:55 kettenis Exp $ */ +/* $OpenBSD: ifb.c,v 1.4 2008/12/27 17:23:01 miod Exp $ */ /* * Copyright (c) 2007, 2008 Miodrag Vallat. @@ -210,23 +210,19 @@ struct ifb_softc { int ifb_ioctl(void *, u_long, caddr_t, int, struct proc *); paddr_t ifb_mmap(void *, off_t, int); -int ifb_alloc_screen(void *, const struct wsscreen_descr *, void **, - int *, int *, long *); -void ifb_free_screen(void *, void *); -int ifb_show_screen(void *, void *, int, - void (*cb)(void *, int, int), void *); void ifb_burner(void *, u_int, u_int); struct wsdisplay_accessops ifb_accessops = { ifb_ioctl, ifb_mmap, - ifb_alloc_screen, - ifb_free_screen, - ifb_show_screen, - NULL, - NULL, - NULL, - ifb_burner + NULL, /* alloc_screen */ + NULL, /* free_screen */ + NULL, /* show_screen */ + NULL, /* load_font */ + NULL, /* scrollback */ + NULL, /* getchar */ + ifb_burner, + NULL /* pollc */ }; int ifbmatch(struct device *, void *, void *); @@ -328,8 +324,7 @@ ifbattach(struct device *parent, struct device *self, void *aux) ri->ri_bits = NULL; ri->ri_hw = sc; - /* do NOT pass RI_CLEAR yet */ - fbwscons_init(&sc->sc_sunfb, RI_BSWAP); + fbwscons_init(&sc->sc_sunfb, RI_BSWAP, sc->sc_console); ri->ri_flg &= ~RI_FULLCLEAR; /* due to the way we handle updates */ if (!sc->sc_console) { @@ -483,39 +478,6 @@ ifb_setcolor(void *v, u_int index, u_int8_t r, u_int8_t g, u_int8_t b) (((u_int)b) << 22) | (((u_int)g) << 12) | (((u_int)r) << 2)); } -int -ifb_alloc_screen(void *v, const struct wsscreen_descr *type, void **cookiep, - int *curxp, int *curyp, long *attrp) -{ - struct ifb_softc *sc = v; - - if (sc->sc_nscreens > 0) - return ENOMEM; - - *cookiep = &sc->sc_sunfb.sf_ro; - *curyp = 0; - *curxp = 0; - sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro, - WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); - sc->sc_nscreens++; - return 0; -} - -void -ifb_free_screen(void *v, void *cookie) -{ - struct ifb_softc *sc = v; - - sc->sc_nscreens--; -} - -int -ifb_show_screen(void *v, void *cookie, int waitok, - void (*cb)(void *, int, int), void *cbarg) -{ - return 0; -} - paddr_t ifb_mmap(void *v, off_t off, int prot) { diff --git a/sys/arch/sparc64/dev/vgafb.c b/sys/arch/sparc64/dev/vgafb.c index d0fd962141b..c6943f76d04 100644 --- a/sys/arch/sparc64/dev/vgafb.c +++ b/sys/arch/sparc64/dev/vgafb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vgafb.c,v 1.54 2008/10/01 21:06:42 kettenis Exp $ */ +/* $OpenBSD: vgafb.c,v 1.55 2008/12/27 17:23:01 miod Exp $ */ /* * Copyright (c) 2001 Jason L. Wright (jason@thought.net) @@ -76,11 +76,6 @@ struct vgafb_softc { int vgafb_mapregs(struct vgafb_softc *, struct pci_attach_args *); int vgafb_rommap(struct vgafb_softc *, struct pci_attach_args *); int vgafb_ioctl(void *, u_long, caddr_t, int, struct proc *); -int vgafb_alloc_screen(void *, const struct wsscreen_descr *, void **, - int *, int *, long *); -void vgafb_free_screen(void *, void *); -int vgafb_show_screen(void *, void *, int, - void (*cb)(void *, int, int), void *); paddr_t vgafb_mmap(void *, off_t, int); int vgafb_is_console(int); int vgafb_getcmap(struct vgafb_softc *, struct wsdisplay_cmap *); @@ -90,10 +85,14 @@ void vgafb_setcolor(void *, u_int, u_int8_t, u_int8_t, u_int8_t); struct wsdisplay_accessops vgafb_accessops = { vgafb_ioctl, vgafb_mmap, - vgafb_alloc_screen, - vgafb_free_screen, - vgafb_show_screen, - 0 /* load_font */ + NULL, /* alloc_screen */ + NULL, /* free_screen */ + NULL, /* show_screen */ + NULL, /* load_font */ + NULL, /* scrollback */ + NULL, /* getchar */ + NULL, /* burner */ + NULL /* pollc */ }; int vgafbmatch(struct device *, void *, void *); @@ -197,7 +196,7 @@ vgafbattach(parent, self, aux) sc->sc_sunfb.sf_ro.ri_hw = sc; fbwscons_init(&sc->sc_sunfb, - RI_BSWAP | (sc->sc_console ? 0 : RI_FORCEMONO | RI_CLEAR)); + RI_BSWAP | (sc->sc_console ? 0 : RI_FORCEMONO), sc->sc_console); if (sc->sc_console) { sc->sc_ofhandle = OF_stdout(); @@ -348,49 +347,6 @@ vgafb_setcolor(v, index, r, g, b) OF_call_method("color!", sc->sc_ofhandle, 4, 0, r, g, b, index); } -int -vgafb_alloc_screen(v, type, cookiep, curxp, curyp, attrp) - void *v; - const struct wsscreen_descr *type; - void **cookiep; - int *curxp, *curyp; - long *attrp; -{ - struct vgafb_softc *sc = v; - - if (sc->sc_nscreens > 0) - return (ENOMEM); - - *cookiep = &sc->sc_sunfb.sf_ro; - *curyp = 0; - *curxp = 0; - sc->sc_sunfb.sf_ro.ri_ops.alloc_attr(&sc->sc_sunfb.sf_ro, - WSCOL_BLACK, WSCOL_WHITE, WSATTR_WSCOLORS, attrp); - sc->sc_nscreens++; - return (0); -} - -void -vgafb_free_screen(v, cookie) - void *v; - void *cookie; -{ - struct vgafb_softc *sc = v; - - sc->sc_nscreens--; -} - -int -vgafb_show_screen(v, cookie, waitok, cb, cbarg) - void *v; - void *cookie; - int waitok; - void (*cb)(void *, int, int); - void *cbarg; -{ - return (0); -} - paddr_t vgafb_mmap(v, off, prot) void *v; diff --git a/sys/arch/sparc64/include/fbvar.h b/sys/arch/sparc64/include/fbvar.h index 59a1aeb38bd..aadb7339ac3 100644 --- a/sys/arch/sparc64/include/fbvar.h +++ b/sys/arch/sparc64/include/fbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fbvar.h,v 1.6 2006/03/12 22:53:02 miod Exp $ */ +/* $OpenBSD: fbvar.h,v 1.7 2008/12/27 17:23:03 miod Exp $ */ /* $NetBSD: fbvar.h,v 1.9 1997/07/07 23:31:30 pk Exp $ */ /* @@ -62,6 +62,7 @@ struct sunfb { struct wsscreen_descr sf_wsd; struct wsscreen_list sf_wsl; struct wsscreen_descr *sf_scrlist[1]; + int sf_nscreens; }; /* @@ -70,7 +71,7 @@ struct sunfb { extern int fbnode; void fb_setsize(struct sunfb*, int, int, int, int, int); -void fbwscons_init(struct sunfb *, int); +void fbwscons_init(struct sunfb *, int, int); void fbwscons_console_init(struct sunfb *, int); void fbwscons_setcolormap(struct sunfb *, void (*)(void *, u_int, u_int8_t, u_int8_t, u_int8_t)); -- cgit v1.2.3