Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/sunxi Allow the graphic driver to be the kernel...



details:   https://anonhg.NetBSD.org/src/rev/8ffa7fe3e270
branches:  trunk
changeset: 321832:8ffa7fe3e270
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Apr 07 18:09:33 2018 +0000

description:
Allow the graphic driver to be the kernel's console.
Match either from the allwinner,pipeline entry in the simple-framebuffer
fdt entry, or from console= from the command line.
console=fb0 and console=fb1 selects display backend unit 0 or 1 respectively;
console=fb selects the first activated display backend.

diffstat:

 sys/arch/arm/sunxi/sunxi_debe.c    |  101 +++++++++++++++++++++++++++++++-----
 sys/arch/arm/sunxi/sunxi_dep.c     |   21 +++++--
 sys/arch/arm/sunxi/sunxi_display.h |    3 +-
 sys/arch/arm/sunxi/sunxi_tcon.c    |   53 ++++++++++++++++++-
 4 files changed, 155 insertions(+), 23 deletions(-)

diffs (truncated from 331 to 300 lines):

diff -r d0ab9c114b61 -r 8ffa7fe3e270 sys/arch/arm/sunxi/sunxi_debe.c
--- a/sys/arch/arm/sunxi/sunxi_debe.c   Sat Apr 07 18:06:27 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_debe.c   Sat Apr 07 18:09:33 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_debe.c,v 1.7 2018/04/05 10:21:39 jmcneill Exp $ */
+/* $NetBSD: sunxi_debe.c,v 1.8 2018/04/07 18:09:33 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2018 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
@@ -38,7 +38,7 @@
 #define SUNXI_DEBE_CURMAX      64
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.7 2018/04/05 10:21:39 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c,v 1.8 2018/04/07 18:09:33 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -58,6 +58,8 @@
 
 #include <arm/sunxi/sunxi_debereg.h>
 #include <arm/sunxi/sunxi_display.h>
+#include <arm/sunxi/sunxi_platform.h>
+#include <machine/bootconfig.h>
 
 enum sunxi_debe_type {
        DEBE_A10 = 1,
@@ -128,6 +130,9 @@
 static void    sunxi_befb_set_videomode(device_t, u_int, u_int);
 void sunxi_debe_dump_regs(int);
 
+static struct sunxi_debe_softc *debe_console_sc;
+static int sunxi_simplefb_phandle = -1;
+
 CFATTACH_DECL_NEW(sunxi_debe, sizeof(struct sunxi_debe_softc),
        sunxi_debe_match, sunxi_debe_attach, NULL, NULL);
 
@@ -242,8 +247,6 @@
        }
 }
 
-
-
 static void
 sunxi_debe_ep_connect(device_t self, struct fdt_endpoint *ep, bool connect)
 {
@@ -337,6 +340,32 @@
        const u_int fb_height = (mode->vdisplay << interlace_p);
 
        if (mode && sc->sc_fbdev == NULL) {
+               /* see if we are the console */
+               if (sunxi_simplefb_phandle >= 0) {
+                       const char *cons_pipeline =
+                           fdtbus_get_string(sunxi_simplefb_phandle,
+                               "allwinner,pipeline");
+                       struct fdt_endpoint *ep = fdt_endpoint_get_from_index(
+                           &sc->sc_ports, SUNXI_PORT_OUTPUT, sc->sc_unit);
+                       struct fdt_endpoint *rep = fdt_endpoint_remote(ep);
+                       if (sunxi_tcon_is_console(
+                           fdt_endpoint_device(rep), cons_pipeline))
+                               debe_console_sc = sc;
+               } else if (debe_console_sc == NULL) {
+                       if (match_bootconf_option(boot_args,
+                           "console", "fb0")) {
+                               if (sc->sc_unit == 0)
+                                       debe_console_sc = sc;
+                       } else if (match_bootconf_option(boot_args,
+                           "console", "fb1")) {
+                               if (sc->sc_unit == 1)
+                                       debe_console_sc = sc;
+                       } else if (match_bootconf_option(boot_args,
+                           "console", "fb")) {
+                               /* match first activated */
+                               debe_console_sc = sc;
+                       }
+               }
                struct sunxifb_attach_args afb = {
                        .afb_fb = sc->sc_dmap,
                        .afb_width = fb_width,
@@ -684,9 +713,6 @@
        prop_dictionary_t cfg = device_properties(self);
        struct genfb_ops ops;
 
-       if (sunxi_befb_consoledev == NULL)
-               sunxi_befb_consoledev = self;
-
        sc->sc_gen.sc_dev = self;
        sc->sc_debedev = parent;
        sc->sc_dmat = afb->afb_dmat;
@@ -716,14 +742,27 @@
 
        aprint_naive("\n");
 
-       bool is_console = false;
-       prop_dictionary_set_bool(cfg, "is_console", is_console);
-
+       bool is_console = (debe_console_sc == device_private(parent));
        if (is_console)
                aprint_normal(": switching to framebuffer console\n");
        else
                aprint_normal("\n");
 
+#ifdef WSDISPLAY_MULTICONS
+       /*
+        * if we support multicons, only the first framebuffer is console,
+        * unless we already know which framebuffer will be the console
+        */
+       if (!is_console && debe_console_sc == NULL &&
+           sunxi_befb_consoledev == NULL)
+               is_console = true;
+#endif
+       prop_dictionary_set_bool(cfg, "is_console", is_console);
+       if (is_console) {
+               KASSERT(sunxi_befb_consoledev == NULL);
+               sunxi_befb_consoledev = self;
+       }
+
        genfb_attach(&sc->sc_gen, &ops);
 }
 
@@ -829,13 +868,47 @@
                return ENODEV;
        }
        error = fdt_endpoint_activate(ep, true);
-       if (error == 0) {
-               sc->sc_out_ep = ep;
-               fdt_endpoint_enable(ep, true);
-       }
+       if (error)
+               return error;
+
+       sc->sc_out_ep = ep;
+       error = fdt_endpoint_enable(ep, true);
        return error;
 }
 
+/*
+ * we don't want to take over console at this time - simplefb will
+ * do a better job than us. We will take over later.
+ * But we want to record the /chose/framebuffer phandle if there is one
+ */
+
+static const char * const simplefb_compatible[] = {
+       "allwinner,simple-framebuffer",
+       NULL
+};
+
+static int
+sunxidebe_console_match(int phandle)
+{
+       if (of_match_compatible(phandle, simplefb_compatible)) {
+               sunxi_simplefb_phandle = phandle;
+       }
+       return 0;
+}
+
+static void
+sunxidebe_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
+{
+       panic("sunxidebe_console_consinit");
+}
+
+static const struct fdt_console sunxidebe_fdt_console = {
+       .match = sunxidebe_console_match,
+       .consinit = sunxidebe_console_consinit
+};
+
+FDT_CONSOLE(sunxidebe, &sunxidebe_fdt_console);
+
 #if defined(SUNXI_DEBE_DEBUG)
 void
 sunxi_debe_dump_regs(int u)
diff -r d0ab9c114b61 -r 8ffa7fe3e270 sys/arch/arm/sunxi/sunxi_dep.c
--- a/sys/arch/arm/sunxi/sunxi_dep.c    Sat Apr 07 18:06:27 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_dep.c    Sat Apr 07 18:09:33 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sunxi_dep.c,v 1.2 2018/04/03 13:38:13 bouyer Exp $     */
+/*     $NetBSD: sunxi_dep.c,v 1.3 2018/04/07 18:09:33 bouyer Exp $     */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: sunxi_dep.c,v 1.2 2018/04/03 13:38:13 bouyer Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sunxi_dep.c,v 1.3 2018/04/07 18:09:33 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -57,6 +57,11 @@
        {NULL}
 };
 
+static const char *fb_compat[] = {
+       "allwinner,simple-framebuffer",
+       NULL
+};
+
 static int sunxi_dep_match(device_t, cfdata_t, void *);
 static void sunxi_dep_attach(device_t, device_t, void *);
 
@@ -68,9 +73,8 @@
 {
 #if NSUNXI_DEBE > 0
        struct fdt_attach_args * const faa = aux;
-       if (!of_match_compat_data(faa->faa_phandle, compat_data))
-               return 0;
-       return 1;
+
+       return  of_match_compat_data(faa->faa_phandle, compat_data);
 #else
        return 0;
 #endif
@@ -82,6 +86,7 @@
        struct sunxi_dep_softc * const sc = device_private(self);
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;
+       int sunxi_dep_npipelines = 0;
        int len;
        const u_int *buf;
        u_int ref;
@@ -95,7 +100,6 @@
                aprint_error("bad/missing allwinner,pipelines property\n");
                return;
        }
-       aprint_naive("\n");
        aprint_normal(": ");
 #if NSUNXI_DEBE > 0
        for (int i = 0; i < (len / sizeof(ref)); i++) {
@@ -106,7 +110,12 @@
                    fdtbus_get_phandle_from_native(ref), true);
                if (error)
                        aprint_error("can't activate pipeline %d\n", i);
+               else
+                       sunxi_dep_npipelines++;
        }
+       aprint_naive("\n");
+       if (sunxi_dep_npipelines > 0)
+               fdt_remove_bycompat(fb_compat);
 #else
        aprint_error("debe not configured\n");
        return;
diff -r d0ab9c114b61 -r 8ffa7fe3e270 sys/arch/arm/sunxi/sunxi_display.h
--- a/sys/arch/arm/sunxi/sunxi_display.h        Sat Apr 07 18:06:27 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_display.h        Sat Apr 07 18:09:33 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sunxi_display.h,v 1.1 2018/04/03 12:52:16 bouyer Exp $ */
+/*     $NetBSD: sunxi_display.h,v 1.2 2018/04/07 18:09:33 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -37,3 +37,4 @@
 int sunxi_debe_pipeline(int, bool);
 void sunxi_tcon1_set_videomode(device_t, const struct videomode *);
 void sunxi_debe_set_videomode(device_t, const struct videomode *);
+bool sunxi_tcon_is_console(device_t, const char *);
diff -r d0ab9c114b61 -r 8ffa7fe3e270 sys/arch/arm/sunxi/sunxi_tcon.c
--- a/sys/arch/arm/sunxi/sunxi_tcon.c   Sat Apr 07 18:06:27 2018 +0000
+++ b/sys/arch/arm/sunxi/sunxi_tcon.c   Sat Apr 07 18:09:33 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_tcon.c,v 1.5 2018/04/06 08:23:40 bouyer Exp $ */
+/* $NetBSD: sunxi_tcon.c,v 1.6 2018/04/07 18:09:33 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2018 Manuel Bouyer <bouyer%antioche.eu.org@localhost>
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_tcon.c,v 1.5 2018/04/06 08:23:40 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_tcon.c,v 1.6 2018/04/07 18:09:33 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -812,6 +812,55 @@
        }
 }
 
+/* check if this tcon is the console chosen by firmare */
+bool
+sunxi_tcon_is_console(device_t dev, const char *pipeline)
+{
+       struct sunxi_tcon_softc *sc = device_private(dev);
+       char p[64];
+       char *e, *n = p;
+       bool is_console = false;
+
+       KASSERT(device_is_a(dev, "sunxitcon"));
+       strncpy(p, pipeline, sizeof(p) - 1);
+       p[sizeof(p) - 1] = '\0';
+
+       /*
+        * pipeline is like "de_be0-lcd0-hdmi"
+        * of "de_be0-lcd1".
+        * In the first case check output type
+        * In the second check tcon unit number
+        */
+        n = p;
+        e = strsep(&n, "-");



Home | Main Index | Thread Index | Old Index