tech-kern archive

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

graphic drivers and simplefb



Hello,
What's missing from the sunxi video drivers is console handling.
I got this working, but this needs some change to the simplefb driver.

the /chosen/framebuffer node is (if I understood is properly) set up by
the firmware/bootloader and will always exists if a framebuffer has been
set up. Or, we can't have a framebuffer in the firmware/bootloader without
a valid /chosen/framebuffer node (if I understood it properly).
Our simplefb driver will attach to it.
In addition, if this is going to be the OS's console, our simplefb
driver will match it very early.

Now if we attach and configure the display hardware in the OS, the
simplefb won't be functional as the display driver. Also, the
display drivers needs to know if they will be the console, and the simplefb
driver knows this.

So I propose to add 2 public functions to dev/fdt/simplefb.c, for use
by display drivers:
- int fdt_simplefb_get_console(void) which returns the phandle of
  the /chosen/framebuffer node, if it has been selected as console.
  The display driver may need more information from here
  (like the content of allwinner,pipeline in my case).
- void fdt_simplefb_disable(void) which, once called, will prevent the
  simplefb from matching.

The attached patch implements this, as well as console handling the
the sunxi drivers. In addition to 'console=fb', console=fb0 or fb1 is
supported to select a specific pipeline, which may not have been set up
by the bootloader.

For this to work, the display pipelines have to be fully configured before
simplefb could be matched. So I has to move
sunxidep*      at fdt?
to pass 5.

I believe that with this, the display drivers could be enabled by default
in the sunxi kernel.

-- 
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
     NetBSD: 26 ans d'experience feront toujours la difference
--
Index: dev/fdt/simplefb.c
===================================================================
RCS file: /cvsroot/src/sys/dev/fdt/simplefb.c,v
retrieving revision 1.4
diff -u -p -u -r1.4 simplefb.c
--- dev/fdt/simplefb.c	1 Apr 2018 04:35:05 -0000	1.4
+++ dev/fdt/simplefb.c	4 Apr 2018 16:03:38 -0000
@@ -37,6 +37,7 @@ __KERNEL_RCSID(0, "$NetBSD: simplefb.c,v
 #include <sys/systm.h>
 
 #include <dev/fdt/fdtvar.h>
+#include <dev/fdt/simplefb_fdt.h>
 
 #include <dev/wsfb/genfbvar.h>
 
@@ -55,6 +56,7 @@ struct simplefb_softc {
 };
 
 static int simplefb_console_phandle = -1;
+static bool simplefb_disabled = false;
 
 static bool
 simplefb_shutdown(device_t self, int flags)
@@ -200,6 +202,8 @@ static int
 simplefb_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct fdt_attach_args * const faa = aux;
+	if (simplefb_disabled)
+		return 0;
 
 	return of_match_compatible(faa->faa_phandle, compatible);
 }
@@ -241,3 +245,15 @@ static const struct fdt_console simplefb
 };
 
 FDT_CONSOLE(simplefb, &simplefb_fdt_console);
+
+int
+fdt_simplefb_get_console(void)
+{
+	return simplefb_console_phandle;
+}
+
+void
+fdt_simplefb_disable(void)
+{
+	simplefb_disabled = true;
+}
Index: dev/fdt/simplefb_fdt.h
===================================================================
RCS file: dev/fdt/simplefb_fdt.h
diff -N dev/fdt/simplefb_fdt.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ dev/fdt/simplefb_fdt.h	4 Apr 2018 16:03:38 -0000
@@ -0,0 +1,31 @@
+/* $NetBSD: simplefb.c,v 1.4 2018/04/01 04:35:05 ryo Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
+ * All rights reserved.
+ *
+ * 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 AUTHOR ``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 AUTHOR 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.
+ */
+
+/* return the console phandle if console is a simplefb, or -1 */
+int fdt_simplefb_get_console(void);
+void fdt_simplefb_disable(void);
Index: arch/evbarm/conf/SUNXI
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/conf/SUNXI,v
retrieving revision 1.61
diff -u -p -u -r1.61 SUNXI
--- arch/evbarm/conf/SUNXI	3 Apr 2018 12:56:21 -0000	1.61
+++ arch/evbarm/conf/SUNXI	4 Apr 2018 16:03:38 -0000
@@ -284,13 +284,14 @@ wd*		at atabus? drive ?
 genfb*		at fdt?
 wsdisplay*	at genfb?
 
-#sunxidebe*	at fdt? pass 4	# Display Backend
-#genfb*		at sunxidebe?
-#sunxitcon*	at fdt? pass 4	# LCD LVDS/RGB controller
-#sunxihdmi*	at fdt? pass 4	# HDMI controller
-#connector*	at fdt? pass 4
-#panel*		at fdt? pass 4
-#sunxidep*	at fdt?		# Display Engine Pipeline
+sunxidebe*	at fdt? pass 4	# Display Backend
+genfb*		at sunxidebe?
+sunxitcon*	at fdt? pass 4	# LCD LVDS/RGB controller
+sunxihdmi*	at fdt? pass 4	# HDMI controller
+connector*	at fdt? pass 4
+panel*		at fdt? pass 4
+#sunxidep must be after display pipeline elements but before genfb@fdt
+sunxidep*	at fdt?	pass 5	# Display Engine Pipeline
 options 	VCONS_DRAW_INTR
 options 	WSEMUL_VT100
 options 	WS_DEFAULT_FG=WSCOL_WHITE
Index: arch/arm/sunxi/sunxi_debe.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sunxi/sunxi_debe.c,v
retrieving revision 1.5
diff -u -p -u -r1.5 sunxi_debe.c
--- arch/arm/sunxi/sunxi_debe.c	3 Apr 2018 16:17:59 -0000	1.5
+++ arch/arm/sunxi/sunxi_debe.c	4 Apr 2018 16:03:38 -0000
@@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c
 
 #include <dev/fdt/fdtvar.h>
 #include <dev/fdt/fdt_port.h>
+#include <dev/fdt/simplefb_fdt.h>
 
 #include <dev/videomode/videomode.h>
 #include <dev/wscons/wsconsio.h>
@@ -58,6 +59,8 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_debe.c
 
 #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 +131,8 @@ static int	sunxi_debe_ioctl(device_t, u_
 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;
+
 CFATTACH_DECL_NEW(sunxi_debe, sizeof(struct sunxi_debe_softc),
 	sunxi_debe_match, sunxi_debe_attach, NULL, NULL);
 
@@ -289,8 +294,6 @@ sunxi_debe_attach(device_t parent, devic
 #endif
 }
 
-
-
 static void
 sunxi_debe_ep_connect(device_t self, struct fdt_endpoint *ep, bool connect)
 {
@@ -732,9 +735,6 @@ sunxi_befb_attach(device_t parent, devic
 	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;
@@ -765,14 +765,27 @@ sunxi_befb_attach(device_t parent, devic
 
 	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);
 }
 
@@ -861,8 +874,9 @@ sunxi_debe_pipeline(int phandle, bool ac
 {
 	device_t dev;
 	struct sunxi_debe_softc *sc;
-	struct fdt_endpoint *ep;
+	struct fdt_endpoint *ep, *rep;
 	int i, error;
+	int console_phandle;
 
 	if (!active)
 		return EOPNOTSUPP;
@@ -890,10 +904,31 @@ sunxi_debe_pipeline(int phandle, bool ac
 		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;
+	/* see if we are the console */
+	console_phandle = fdt_simplefb_get_console();
+	if (console_phandle >= 0) {
+		const char *cons_pipeline = fdtbus_get_string(console_phandle,
+		    "allwinner,pipeline");
+		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 (sc->sc_unit == 0) {
+			if (match_bootconf_option(boot_args, "console", "fb") ||
+			    match_bootconf_option(boot_args, "console", "fb0"))
+				debe_console_sc = sc;
+		} else if (sc->sc_unit == 1) {
+			if (match_bootconf_option(boot_args, "console", "fb1"))
+				debe_console_sc = sc;
+		}
 	}
+	fdt_simplefb_disable();
+	error = fdt_endpoint_enable(ep, true);
 	return error;
 }
 
Index: arch/arm/sunxi/sunxi_display.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sunxi/sunxi_display.h,v
retrieving revision 1.1
diff -u -p -u -r1.1 sunxi_display.h
--- arch/arm/sunxi/sunxi_display.h	3 Apr 2018 12:52:16 -0000	1.1
+++ arch/arm/sunxi/sunxi_display.h	4 Apr 2018 16:03:38 -0000
@@ -37,3 +37,4 @@ struct videomode;
 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 *);
Index: arch/arm/sunxi/sunxi_tcon.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/sunxi/sunxi_tcon.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 sunxi_tcon.c
--- arch/arm/sunxi/sunxi_tcon.c	3 Apr 2018 16:17:59 -0000	1.3
+++ arch/arm/sunxi/sunxi_tcon.c	4 Apr 2018 16:03:38 -0000
@@ -798,6 +812,55 @@ sunxi_tcon1_set_videomode(device_t dev, 
 	}
 }
 
+/* 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, "-");
+	 if (e == NULL || memcmp(e, "de_be", 5) != 0)
+		goto bad;
+	 e = strsep(&n, "-");
+	 if (e == NULL)
+		goto bad;
+	 if (n == NULL) {
+		/* second case */
+		if (strcmp(e, "lcd0") == 0) {
+			if (sc->sc_unit == 0)
+				is_console = true;
+		 } else if (strcmp(e, "lcd1") == 0) {
+			if (sc->sc_unit == 1)
+				is_console = true;
+		} else
+			goto bad;
+		return is_console;
+	}
+	/* first case */
+	if (strcmp(n, "hdmi") == 0) {
+		if (sc->sc_output_type == OUTPUT_HDMI)
+			is_console = true;
+		return is_console;
+	}
+bad:
+	aprint_error("warning: can't parse pipeline %s\n", pipeline);
+	return is_console;
+}
+
 #if defined(DDB) || defined(SUNXI_TCON_DEBUG)
 void
 sunxi_tcon_dump_regs(int u)


Home | Main Index | Thread Index | Old Index