Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Factor generic parts of intelfb out into a drmfb.



details:   https://anonhg.NetBSD.org/src/rev/a3ec286fb2ee
branches:  trunk
changeset: 336550:a3ec286fb2ee
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Thu Mar 05 17:50:41 2015 +0000

description:
Factor generic parts of intelfb out into a drmfb.

Adapting radeondrmkmsfb should not be hard.

This will make nouveaufb easier too.

diffstat:

 sys/external/bsd/drm2/drm/drmfb.c              |  293 +++++++++++++++++++++
 sys/external/bsd/drm2/drm/files.drmkms         |    6 +-
 sys/external/bsd/drm2/i915drm/files.i915drmkms |    4 +-
 sys/external/bsd/drm2/i915drm/intelfb.c        |  343 +++++-------------------
 sys/external/bsd/drm2/include/drm/drmfb.h      |   92 ++++++
 sys/external/bsd/drm2/include/drm/drmfb_pci.h  |   44 +++
 sys/external/bsd/drm2/pci/drmfb_pci.c          |  134 +++++++++
 sys/external/bsd/drm2/pci/files.drmkms_pci     |    5 +-
 sys/modules/drmkms/Makefile                    |    3 +-
 sys/modules/drmkms_pci/Makefile                |    4 +-
 10 files changed, 651 insertions(+), 277 deletions(-)

diffs (truncated from 1108 to 300 lines):

diff -r 80a7dc22b6f2 -r a3ec286fb2ee sys/external/bsd/drm2/drm/drmfb.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/external/bsd/drm2/drm/drmfb.c Thu Mar 05 17:50:41 2015 +0000
@@ -0,0 +1,293 @@
+/*     $NetBSD: drmfb.c,v 1.1 2015/03/05 17:50:41 riastradh Exp $      */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Taylor R. Campbell.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * drmfb: wsdisplay support, via genfb, for any drm device.  Use this
+ * if you're too lazy to write a hardware-accelerated framebuffer using
+ * wsdisplay directly.
+ *
+ * This doesn't actually do anything interesting -- just hooks up
+ * drmkms crap and genfb crap.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: drmfb.c,v 1.1 2015/03/05 17:50:41 riastradh Exp $");
+
+#ifdef _KERNEL_OPT
+#include "vga.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/kauth.h>
+
+#if NVGA > 0
+/*
+ * XXX All we really need is vga_is_console from vgavar.h, but the
+ * header files are missing their own dependencies, so we need to
+ * explicitly drag in the other crap.
+ */
+#include <dev/ic/mc6845reg.h>
+#include <dev/ic/pcdisplayvar.h>
+#include <dev/ic/vgareg.h>
+#include <dev/ic/vgavar.h>
+#endif
+
+#include <dev/wsfb/genfbvar.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drmfb.h>
+
+static int     drmfb_genfb_ioctl(void *, void *, unsigned long, void *, int,
+                   struct lwp *);
+static paddr_t drmfb_genfb_mmap(void *, void *, off_t, int);
+static int     drmfb_genfb_enable_polling(void *);
+static int     drmfb_genfb_disable_polling(void *);
+static bool    drmfb_genfb_setmode(struct genfb_softc *, int);
+
+static const struct genfb_mode_callback drmfb_genfb_mode_callback = {
+       .gmc_setmode = drmfb_genfb_setmode,
+};
+
+int
+drmfb_attach(struct drmfb_softc *sc, const struct drmfb_attach_args *da)
+{
+       const struct drm_fb_helper_surface_size *const sizes = da->da_fb_sizes;
+       const prop_dictionary_t dict = device_properties(da->da_dev);
+#if NVGA > 0
+       struct drm_device *const dev = da->da_fb_helper->dev;
+#endif
+       static const struct genfb_ops zero_genfb_ops;
+       struct genfb_ops genfb_ops = zero_genfb_ops;
+       enum { CONS_VGA, CONS_GENFB, CONS_NONE } what_was_cons;
+       int error;
+
+       /* genfb requires this.  */
+       KASSERTMSG((void *)&sc->sc_genfb == device_private(da->da_dev),
+           "drmfb_softc must be first member of device softc");
+
+       sc->sc_da = *da;
+
+       prop_dictionary_set_uint32(dict, "width", sizes->surface_width);
+       prop_dictionary_set_uint32(dict, "height", sizes->surface_height);
+       prop_dictionary_set_uint8(dict, "depth", sizes->surface_bpp);
+       prop_dictionary_set_uint16(dict, "linebytes",
+           roundup2((sizes->surface_width * howmany(sizes->surface_bpp, 8)),
+               64));
+       prop_dictionary_set_uint32(dict, "address", 0); /* XXX >32-bit */
+       CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
+       prop_dictionary_set_uint64(dict, "virtual_address",
+           (uint64_t)(uintptr_t)da->da_fb_vaddr);
+
+       prop_dictionary_set_uint64(dict, "mode_callback",
+           (uint64_t)(uintptr_t)&drmfb_genfb_mode_callback);
+
+       /* XXX Whattakludge!  */
+#if NVGA > 0
+       if ((da->da_params->dp_is_vga_console != NULL) &&
+           (*da->da_params->dp_is_vga_console)(dev)) {
+               what_was_cons = CONS_VGA;
+               prop_dictionary_set_bool(dict, "is_console", true);
+               vga_cndetach();
+               if (da->da_params->dp_disable_vga)
+                       (*da->da_params->dp_disable_vga)(dev);
+       } else
+#endif
+       if (genfb_is_console() && genfb_is_enabled()) {
+               what_was_cons = CONS_GENFB;
+               prop_dictionary_set_bool(dict, "is_console", true);
+       } else {
+               what_was_cons = CONS_NONE;
+               prop_dictionary_set_bool(dict, "is_console", false);
+       }
+
+       sc->sc_genfb.sc_dev = sc->sc_da.da_dev;
+       genfb_init(&sc->sc_genfb);
+       genfb_ops.genfb_ioctl = drmfb_genfb_ioctl;
+       genfb_ops.genfb_mmap = drmfb_genfb_mmap;
+       genfb_ops.genfb_enable_polling = drmfb_genfb_enable_polling;
+       genfb_ops.genfb_disable_polling = drmfb_genfb_disable_polling;
+
+       error = genfb_attach(&sc->sc_genfb, &genfb_ops);
+       if (error) {
+               aprint_error_dev(sc->sc_da.da_dev,
+                   "failed to attach genfb: %d\n", error);
+               goto fail0;
+       }
+
+       /* Success!  */
+       return 0;
+
+fail0: KASSERT(error);
+       /* XXX Restore console...  */
+       switch (what_was_cons) {
+       case CONS_VGA:
+               break;
+       case CONS_GENFB:
+               break;
+       case CONS_NONE:
+               break;
+       default:
+               break;
+       }
+       return error;
+}
+
+int
+drmfb_detach(struct drmfb_softc *sc, int flags)
+{
+
+       /* XXX genfb detach?  */
+       return 0;
+}
+
+static int
+drmfb_genfb_ioctl(void *v, void *vs, unsigned long cmd, void *data, int flag,
+    struct lwp *l)
+{
+       struct genfb_softc *const genfb = v;
+       struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc,
+           sc_genfb);
+       int error;
+
+       if (sc->sc_da.da_params->dp_ioctl) {
+               error = (*sc->sc_da.da_params->dp_ioctl)(sc, cmd, data, flag,
+                   l);
+               if (error != EPASSTHROUGH)
+                       return error;
+       }
+
+       switch (cmd) {
+       /*
+        * Screen blanking ioctls.  Not to be confused with backlight
+        * (can be disabled while stuff is still drawn on the screen),
+        * brightness, or contrast (which we don't support).  Backlight
+        * and brightness are done through WSDISPLAYIO_{GET,SET}PARAM.
+        * This toggles between DPMS ON and DPMS OFF; backlight toggles
+        * between DPMS ON and DPMS SUSPEND.
+        */
+       case WSDISPLAYIO_GVIDEO: {
+               int *onp = (int *)data;
+
+               /* XXX Can't really determine a single answer here.  */
+               *onp = 1;
+               return 0;
+       }
+       case WSDISPLAYIO_SVIDEO: {
+               const int on = *(const int *)data;
+               const int dpms_mode = on? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF;
+               struct drm_fb_helper *const fb_helper = sc->sc_da.da_fb_helper;
+               struct drm_device *const dev = fb_helper->dev;
+               unsigned i;
+
+               drm_modeset_lock_all(dev);
+               for (i = 0; i < fb_helper->connector_count; i++) {
+                       struct drm_connector *const connector =
+                           fb_helper->connector_info[i]->connector;
+                       (*connector->funcs->dpms)(connector, dpms_mode);
+                       drm_object_property_set_value(&connector->base,
+                           dev->mode_config.dpms_property, dpms_mode);
+               }
+               drm_modeset_unlock_all(dev);
+
+               return 0;
+       }
+       default:
+               return EPASSTHROUGH;
+       }
+}
+
+static paddr_t
+drmfb_genfb_mmap(void *v, void *vs, off_t offset, int prot)
+{
+       struct genfb_softc *const genfb = v;
+       struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc,
+           sc_genfb);
+
+       KASSERT(0 <= offset);
+
+       if (offset < genfb->sc_fbsize) {
+               if (sc->sc_da.da_params->dp_mmapfb == NULL)
+                       return -1;
+               return (*sc->sc_da.da_params->dp_mmapfb)(sc, offset, prot);
+       } else {
+               if (kauth_authorize_machdep(kauth_cred_get(),
+                       KAUTH_MACHDEP_UNMANAGEDMEM, NULL, NULL, NULL, NULL)
+                   != 0)
+                       return -1;
+               if (sc->sc_da.da_params->dp_mmap == NULL)
+                       return -1;
+               return (*sc->sc_da.da_params->dp_mmap)(sc, offset, prot);
+       }
+}
+
+static int
+drmfb_genfb_enable_polling(void *cookie)
+{
+       struct genfb_softc *const genfb = cookie;
+       struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc,
+           sc_genfb);
+
+       return drm_fb_helper_debug_enter_fb(sc->sc_da.da_fb_helper);
+}
+
+static int
+drmfb_genfb_disable_polling(void *cookie)
+{
+       struct genfb_softc *const genfb = cookie;
+       struct drmfb_softc *const sc = container_of(genfb, struct drmfb_softc,
+           sc_genfb);
+
+       return drm_fb_helper_debug_leave_fb(sc->sc_da.da_fb_helper);
+}
+
+static bool
+drmfb_genfb_setmode(struct genfb_softc *genfb, int mode)
+{
+       struct drmfb_softc *sc = container_of(genfb, struct drmfb_softc,
+           sc_genfb);
+
+       if (mode == WSDISPLAYIO_MODE_EMUL)
+               drm_fb_helper_set_config(sc->sc_da.da_fb_helper);
+
+       return true;
+}
+
+bool
+drmfb_shutdown(struct drmfb_softc *sc, int flags __unused)
+{
+
+       genfb_enable_polling(sc->sc_da.da_dev);
+       return true;
+}
diff -r 80a7dc22b6f2 -r a3ec286fb2ee sys/external/bsd/drm2/drm/files.drmkms
--- a/sys/external/bsd/drm2/drm/files.drmkms    Thu Mar 05 17:42:48 2015 +0000
+++ b/sys/external/bsd/drm2/drm/files.drmkms    Thu Mar 05 17:50:41 2015 +0000



Home | Main Index | Thread Index | Old Index