Module Name:    src
Committed By:   rin
Date:           Mon Oct 19 01:12:14 UTC 2020

Modified Files:
        src/sys/arch/arm/fdt: arm_simplefb.c
        src/sys/arch/evbarm/fdt: fdt_machdep.c
        src/sys/dev/fdt: simplefb.c

Log Message:
Fix colors of 32-bpp raster console for evbarm/aarch64eb and armeb.

Most boards are configured to little-endian in initial, and switched
to big-endian after kernel is loaded. In this case, framebuffer seems
byte-swapped to CPU.

It is best to reconfigure framebuffer (as done recently for sunxi_mixer
by jmcneill), but in most cases, HW is incapable, or we just don't know
register bits to configure them.

Therefore, override "format" FDT property for "simple-framebuffer" to
let drivers know byte-order for 32-bpp framebuffer.

Then, make fdt/simplefb (genfb) and arm_simplefb (early console) detect
byte-swapped FB, and configure genfb(4) or rasops(4) layers accordingly.

Tested on Pine A64+ (arm_simplefb) and Cubietruck (both fdt/simplefb and
arm_simplefb).

Discussed with jmcneill. Thanks!!


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/fdt/arm_simplefb.c
cvs rdiff -u -r1.75 -r1.76 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r1.8 -r1.9 src/sys/dev/fdt/simplefb.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/fdt/arm_simplefb.c
diff -u src/sys/arch/arm/fdt/arm_simplefb.c:1.1 src/sys/arch/arm/fdt/arm_simplefb.c:1.2
--- src/sys/arch/arm/fdt/arm_simplefb.c:1.1	Sat Oct 10 15:25:31 2020
+++ src/sys/arch/arm/fdt/arm_simplefb.c	Mon Oct 19 01:12:14 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: arm_simplefb.c,v 1.1 2020/10/10 15:25:31 jmcneill Exp $ */
+/* $NetBSD: arm_simplefb.c,v 1.2 2020/10/19 01:12:14 rin Exp $ */
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #include "opt_pci.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm_simplefb.c,v 1.1 2020/10/10 15:25:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm_simplefb.c,v 1.2 2020/10/19 01:12:14 rin Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -66,6 +66,7 @@ static struct arm_simplefb_softc {
 	uint32_t	sc_height;
 	uint32_t	sc_stride;
 	uint16_t	sc_depth;
+	bool		sc_swapped;
 	void		*sc_bits;
 } arm_simplefb_softc;
 
@@ -120,6 +121,14 @@ arm_simplefb_init_screen(void *cookie, s
 	ri->ri_bits = sc->sc_bits;
 	ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_CLEAR;
 
+	if (sc->sc_swapped) {
+		KASSERT(ri->ri_depth == 32);
+		ri->ri_rnum = ri->ri_gnum = ri->ri_bnum = 8;
+		ri->ri_rpos =  8;
+		ri->ri_gpos = 16;
+		ri->ri_bpos = 24;
+	}
+
 	scr->scr_flags |= VCONS_LOADFONT;
 	scr->scr_flags |= VCONS_DONT_READ;
 
@@ -161,6 +170,7 @@ arm_simplefb_preattach(void)
 	bus_size_t size;
 	uint16_t depth;
 	long defattr;
+	bool swapped = false;
 
 	const int phandle = arm_simplefb_find_node();
 	if (phandle == -1)
@@ -181,6 +191,10 @@ arm_simplefb_preattach(void)
 	if (strcmp(format, "a8b8g8r8") == 0 ||
 	    strcmp(format, "x8r8g8b8") == 0) {
 		depth = 32;
+	} else if (strcmp(format, "r8g8b8a8") == 0 ||
+		   strcmp(format, "b8g8r8x8") == 0) {
+		depth = 32;
+		swapped = true;
 	} else if (strcmp(format, "r5g6b5") == 0) {
 		depth = 16;
 	} else {
@@ -196,6 +210,7 @@ arm_simplefb_preattach(void)
 	sc->sc_depth = depth;
 	sc->sc_stride = stride;
 	sc->sc_bits = bus_space_vaddr(bst, bsh);
+	sc->sc_swapped = swapped;
 
 	wsfont_init();
 

Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.75 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.76
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.75	Sat Oct 10 15:25:30 2020
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c	Mon Oct 19 01:12:14 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.75 2020/10/10 15:25:30 jmcneill Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.76 2020/10/19 01:12:14 rin Exp $ */
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.75 2020/10/10 15:25:30 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.76 2020/10/19 01:12:14 rin Exp $");
 
 #include "opt_machdep.h"
 #include "opt_bootconfig.h"
@@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep.
 #include <sys/atomic.h>
 #include <sys/cpu.h>
 #include <sys/device.h>
+#include <sys/endian.h>
 #include <sys/exec.h>
 #include <sys/kernel.h>
 #include <sys/kmem.h>
@@ -143,6 +144,10 @@ static void fdt_cpu_rootconf(void);
 static void fdt_reset(void);
 static void fdt_powerdown(void);
 
+#if BYTE_ORDER == BIG_ENDIAN
+static void fdt_update_fb_format(void);
+#endif
+
 static void
 earlyconsputc(dev_t dev, int c)
 {
@@ -578,6 +583,17 @@ initarm(void *arg)
 	VPRINTF("stdout\n");
 	fdt_update_stdout_path();
 
+#if BYTE_ORDER == BIG_ENDIAN
+	/*
+	 * Most boards are configured to little-endian mode in initial, and
+	 * switched to big-endian mode after kernel is loaded. In this case,
+	 * framebuffer seems byte-swapped to CPU. Override FDT to let
+	 * drivers know.
+	 */
+	VPRINTF("fb_format\n");
+	fdt_update_fb_format();
+#endif
+
 	/*
 	 * Done making changes to the FDT.
 	 */
@@ -916,3 +932,36 @@ fdt_powerdown(void)
 {
 	fdtbus_power_poweroff();
 }
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void
+fdt_update_fb_format(void)
+{
+	int off, len;
+	const char *format, *replace;
+
+	off = fdt_path_offset(fdt_data, "/chosen");
+	if (off < 0)
+		return;
+
+	for (;;) {
+		off = fdt_node_offset_by_compatible(fdt_data, off,
+		    "simple-framebuffer");
+		if (off < 0)
+			return;
+
+		format = fdt_getprop(fdt_data, off, "format", &len);
+		if (format == NULL)
+			continue;
+
+		replace = NULL;
+		if (strcmp(format, "a8b8g8r8") == 0)
+			replace = "r8g8b8a8";
+		else if (strcmp(format, "x8r8g8b8") == 0)
+			replace = "b8g8r8x8";
+		if (replace != NULL)
+			fdt_setprop(fdt_data, off, "format", replace,
+			    strlen(replace) + 1);
+	}
+}
+#endif

Index: src/sys/dev/fdt/simplefb.c
diff -u src/sys/dev/fdt/simplefb.c:1.8 src/sys/dev/fdt/simplefb.c:1.9
--- src/sys/dev/fdt/simplefb.c:1.8	Tue Jul 23 14:34:12 2019
+++ src/sys/dev/fdt/simplefb.c	Mon Oct 19 01:12:14 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: simplefb.c,v 1.8 2019/07/23 14:34:12 rin Exp $ */
+/* $NetBSD: simplefb.c,v 1.9 2020/10/19 01:12:14 rin Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
@@ -29,7 +29,7 @@
 #include "opt_wsdisplay_compat.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: simplefb.c,v 1.8 2019/07/23 14:34:12 rin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: simplefb.c,v 1.9 2020/10/19 01:12:14 rin Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -157,6 +157,10 @@ simplefb_attach_genfb(struct simplefb_so
 	if (strcmp(format, "a8b8g8r8") == 0 ||
 	    strcmp(format, "x8r8g8b8") == 0) {
 		depth = 32;
+	} else if (strcmp(format, "r8g8b8a8") == 0 ||
+		   strcmp(format, "b8g8r8x8") == 0) {
+		depth = 32;
+		prop_dictionary_set_bool(dict, "is_swapped", true);
 	} else if (strcmp(format, "r5g6b5") == 0) {
 		depth = 16;
 	} else {

Reply via email to