Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/wsfb genfb(4): Make internal parts of struct genfb_s...
details: https://anonhg.NetBSD.org/src/rev/0bda026e8b90
branches: trunk
changeset: 368528:0bda026e8b90
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Jul 17 13:10:54 2022 +0000
description:
genfb(4): Make internal parts of struct genfb_softc private.
This way the ABI has no ifdefs, so it has a chance to be usable in
modules. This also makes genfb much easier to maintain without
worrying about ABI breakage.
diffstat:
sys/dev/wsfb/genfb.c | 458 ++++++++++++++++++++++++++++-------------------
sys/dev/wsfb/genfbvar.h | 59 +-----
2 files changed, 273 insertions(+), 244 deletions(-)
diffs (truncated from 1086 to 300 lines):
diff -r 2763b2fd5a68 -r 0bda026e8b90 sys/dev/wsfb/genfb.c
--- a/sys/dev/wsfb/genfb.c Sun Jul 17 13:10:04 2022 +0000
+++ b/sys/dev/wsfb/genfb.c Sun Jul 17 13:10:54 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $ */
+/* $NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $ */
/*-
* Copyright (c) 2007 Michael Lorenz
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.88 2022/07/17 13:10:04 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: genfb.c,v 1.89 2022/07/17 13:10:54 riastradh Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -75,6 +75,64 @@
#define GENFB_BRIGHTNESS_STEP 15
#define GENFB_CHAR_WIDTH_MM 3
+struct genfb_private {
+ struct genfb_ops sc_ops;
+ struct vcons_screen sc_console_screen;
+ struct wsscreen_descr sc_defaultscreen_descr;
+ const struct wsscreen_descr *sc_screens[1];
+ struct wsscreen_list sc_screenlist;
+ struct genfb_colormap_callback *sc_cmcb;
+ struct genfb_parameter_callback *sc_backlight;
+ struct genfb_parameter_callback *sc_brightness;
+ struct genfb_mode_callback *sc_modecb;
+ int sc_backlight_level, sc_backlight_on;
+ void *sc_shadowfb;
+ bool sc_enable_shadowfb;
+ int sc_mode;
+ u_char sc_cmap_red[256];
+ u_char sc_cmap_green[256];
+ u_char sc_cmap_blue[256];
+ bool sc_want_clear;
+#ifdef SPLASHSCREEN
+ struct splash_info sc_splash;
+#endif
+ struct wsdisplay_accessops sc_accessops;
+#if GENFB_GLYPHCACHE > 0
+ /*
+ * The generic glyphcache code makes a bunch of assumptions that are
+ * true for most graphics hardware with a directly supported blitter.
+ * For example it assume that
+ * - VRAM access from the host is expensive
+ * - copying data around in VRAM is cheap and can happen in parallel
+ * to the host CPU
+ * -> therefore we draw glyphs normally if we have to, so the ( assumed
+ * to be hardware assisted ) driver supplied putchar() method doesn't
+ * need to be glyphcache aware, then copy them away for later use
+ * for genfb things are a bit different. On most hardware:
+ * - VRAM access from the host is still expensive
+ * - copying data around in VRAM is also expensive since we don't have
+ * a blitter and VRAM is mapped uncached
+ * - VRAM reads are usually slower than writes ( write combining and
+ * such help writes but not reads, and VRAM might be behind an
+ * asymmetric bus like AGP ) and must be avoided, both are much
+ * slower than main memory
+ * -> therefore we cache glyphs in main memory, no reason to map it
+ * uncached, we draw into the cache first and then copy the glyph
+ * into video memory to avoid framebuffer reads and to allow more
+ * efficient write accesses than putchar() would offer
+ * Because of this we can't use the generic code but we can recycle a
+ * few data structures.
+ */
+ uint8_t *sc_cache;
+ struct rasops_info sc_cache_ri;
+ void (*sc_putchar)(void *, int, int, u_int, long);
+ int sc_cache_cells;
+ int sc_nbuckets; /* buckets allocated */
+ gc_bucket *sc_buckets; /* we allocate as many as we can get into ram */
+ int sc_attrmap[256]; /* mapping a colour attribute to a bucket */
+#endif
+};
+
static int genfb_ioctl(void *, void *, u_long, void *, int, struct lwp *);
static paddr_t genfb_mmap(void *, void *, off_t, int);
static void genfb_pollc(void *, int);
@@ -107,11 +165,14 @@
void
genfb_init(struct genfb_softc *sc)
{
+ struct genfb_private *scp;
prop_dictionary_t dict;
uint64_t cmap_cb, pmf_cb, mode_cb, bl_cb, br_cb, fbaddr;
uint64_t fboffset;
bool console;
+ scp = sc->sc_private = kmem_zalloc(sizeof(*sc->sc_private), KM_SLEEP);
+
dict = device_properties(sc->sc_dev);
#ifdef GENFB_DEBUG
printf("%s", prop_dictionary_externalize(dict));
@@ -120,20 +181,20 @@
if (!prop_dictionary_get_uint32(dict, "width", &sc->sc_width)) {
GPRINTF("no width property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint32(dict, "height", &sc->sc_height)) {
GPRINTF("no height property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
GPRINTF("no depth property\n");
- return;
+ goto bad;
}
if (!prop_dictionary_get_uint64(dict, "address", &fboffset)) {
GPRINTF("no address property\n");
- return;
+ goto bad;
}
sc->sc_fboffset = (bus_addr_t)fboffset;
@@ -143,13 +204,13 @@
sc->sc_fbaddr = (void *)(uintptr_t)fbaddr;
}
- sc->sc_shadowfb = NULL;
+ scp->sc_shadowfb = NULL;
if (!prop_dictionary_get_bool(dict, "enable_shadowfb",
- &sc->sc_enable_shadowfb))
+ &scp->sc_enable_shadowfb))
#ifdef GENFB_SHADOWFB
- sc->sc_enable_shadowfb = true;
+ scp->sc_enable_shadowfb = true;
#else
- sc->sc_enable_shadowfb = false;
+ scp->sc_enable_shadowfb = false;
#endif
if (!prop_dictionary_get_uint32(dict, "linebytes", &sc->sc_stride))
@@ -165,10 +226,10 @@
sc->sc_fbsize = sc->sc_height * sc->sc_stride;
/* optional colour map callback */
- sc->sc_cmcb = NULL;
+ scp->sc_cmcb = NULL;
if (prop_dictionary_get_uint64(dict, "cmap_callback", &cmap_cb)) {
if (cmap_cb != 0)
- sc->sc_cmcb = (void *)(vaddr_t)cmap_cb;
+ scp->sc_cmcb = (void *)(vaddr_t)cmap_cb;
}
/* optional pmf callback */
@@ -179,31 +240,31 @@
}
/* optional mode callback */
- sc->sc_modecb = NULL;
+ scp->sc_modecb = NULL;
if (prop_dictionary_get_uint64(dict, "mode_callback", &mode_cb)) {
if (mode_cb != 0)
- sc->sc_modecb = (void *)(vaddr_t)mode_cb;
+ scp->sc_modecb = (void *)(vaddr_t)mode_cb;
}
/* optional backlight control callback */
- sc->sc_backlight = NULL;
+ scp->sc_backlight = NULL;
if (prop_dictionary_get_uint64(dict, "backlight_callback", &bl_cb)) {
if (bl_cb != 0) {
- sc->sc_backlight = (void *)(vaddr_t)bl_cb;
+ scp->sc_backlight = (void *)(vaddr_t)bl_cb;
aprint_naive_dev(sc->sc_dev,
"enabling backlight control\n");
}
}
/* optional brightness control callback */
- sc->sc_brightness = NULL;
+ scp->sc_brightness = NULL;
if (prop_dictionary_get_uint64(dict, "brightness_callback", &br_cb)) {
if (br_cb != 0) {
- sc->sc_brightness = (void *)(vaddr_t)br_cb;
+ scp->sc_brightness = (void *)(vaddr_t)br_cb;
aprint_naive_dev(sc->sc_dev,
"enabling brightness control\n");
if (console &&
- sc->sc_brightness->gpc_upd_parameter != NULL) {
+ scp->sc_brightness->gpc_upd_parameter != NULL) {
pmf_event_register(sc->sc_dev,
PMFE_DISPLAY_BRIGHTNESS_UP,
genfb_brightness_up, TRUE);
@@ -213,11 +274,17 @@
}
}
}
+
+ return;
+
+bad: kmem_free(sc->sc_private, sizeof(*sc->sc_private));
+ sc->sc_private = NULL;
}
int
genfb_attach(struct genfb_softc *sc, struct genfb_ops *ops)
{
+ struct genfb_private *scp = sc->sc_private;
struct wsemuldisplaydev_attach_args aa;
prop_dictionary_t dict;
struct rasops_info *ri;
@@ -230,14 +297,16 @@
int error = ENXIO;
#endif
+ KASSERTMSG(scp != NULL, "missing genfb_init");
+
dict = device_properties(sc->sc_dev);
prop_dictionary_get_bool(dict, "is_console", &console);
if (prop_dictionary_get_uint16(dict, "cursor-row", &crow) == false)
crow = 0;
- if (prop_dictionary_get_bool(dict, "clear-screen", &sc->sc_want_clear)
+ if (prop_dictionary_get_bool(dict, "clear-screen", &scp->sc_want_clear)
== false)
- sc->sc_want_clear = true;
+ scp->sc_want_clear = true;
fb_phys = (paddr_t)sc->sc_fboffset;
if (fb_phys == 0) {
@@ -251,7 +320,7 @@
fb_phys ? (void *)(intptr_t)fb_phys : sc->sc_fbaddr,
sc->sc_width, sc->sc_height, sc->sc_depth, sc->sc_stride);
- sc->sc_defaultscreen_descr = (struct wsscreen_descr){
+ scp->sc_defaultscreen_descr = (struct wsscreen_descr){
"default",
0, 0,
NULL,
@@ -260,38 +329,39 @@
WSSCREEN_RESIZE,
NULL
};
- sc->sc_screens[0] = &sc->sc_defaultscreen_descr;
- sc->sc_screenlist = (struct wsscreen_list){1, sc->sc_screens};
- memcpy(&sc->sc_ops, ops, sizeof(struct genfb_ops));
- sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
- if (sc->sc_modecb != NULL)
- sc->sc_modecb->gmc_setmode(sc, sc->sc_mode);
+ scp->sc_screens[0] = &scp->sc_defaultscreen_descr;
+ scp->sc_screenlist = (struct wsscreen_list){1, scp->sc_screens};
+ memcpy(&scp->sc_ops, ops, sizeof(struct genfb_ops));
+ scp->sc_mode = WSDISPLAYIO_MODE_EMUL;
+ if (scp->sc_modecb != NULL)
+ scp->sc_modecb->gmc_setmode(sc, scp->sc_mode);
- sc->sc_accessops.ioctl = genfb_ioctl;
- sc->sc_accessops.mmap = genfb_mmap;
- sc->sc_accessops.pollc = genfb_pollc;
+ scp->sc_accessops.ioctl = genfb_ioctl;
+ scp->sc_accessops.mmap = genfb_mmap;
+ scp->sc_accessops.pollc = genfb_pollc;
- if (sc->sc_enable_shadowfb) {
- sc->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
- if (sc->sc_want_clear == false)
- memcpy(sc->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+ if (scp->sc_enable_shadowfb) {
+ scp->sc_shadowfb = kmem_alloc(sc->sc_fbsize, KM_SLEEP);
+ if (scp->sc_want_clear == false) {
+ memcpy(scp->sc_shadowfb, sc->sc_fbaddr, sc->sc_fbsize);
+ }
aprint_verbose_dev(sc->sc_dev,
"shadow framebuffer enabled, size %zu KB\n",
sc->sc_fbsize >> 10);
}
- vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
- &sc->sc_accessops);
+ vcons_init(&sc->vd, sc, &scp->sc_defaultscreen_descr,
+ &scp->sc_accessops);
sc->vd.init_screen = genfb_init_screen;
/* Do not print anything between this point and the screen
* clear operation below. Otherwise it will be lost. */
- ri = &sc->sc_console_screen.scr_ri;
+ ri = &scp->sc_console_screen.scr_ri;
- vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+ vcons_init_screen(&sc->vd, &scp->sc_console_screen, 1,
&defattr);
- sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
+ scp->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
#if GENFB_GLYPHCACHE > 0
genfb_setup_glyphcache(sc, defattr);
@@ -304,24 +374,24 @@
*/
if (DISABLESPLASH)
Home |
Main Index |
Thread Index |
Old Index