Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/fdt Fix colors of 32-bpp raster console for evbarm/a...
details: https://anonhg.NetBSD.org/src/rev/79000f975998
branches: trunk
changeset: 945033:79000f975998
user: rin <rin%NetBSD.org@localhost>
date: Mon Oct 19 01:12:14 2020 +0000
description:
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!!
diffstat:
sys/arch/arm/fdt/arm_simplefb.c | 19 ++++++++++++-
sys/arch/evbarm/fdt/fdt_machdep.c | 53 +++++++++++++++++++++++++++++++++++++-
sys/dev/fdt/simplefb.c | 8 ++++-
3 files changed, 74 insertions(+), 6 deletions(-)
diffs (189 lines):
diff -r 88d0c320a3bf -r 79000f975998 sys/arch/arm/fdt/arm_simplefb.c
--- a/sys/arch/arm/fdt/arm_simplefb.c Mon Oct 19 01:08:06 2020 +0000
+++ b/sys/arch/arm/fdt/arm_simplefb.c Mon Oct 19 01:12:14 2020 +0000
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
sc->sc_depth = depth;
sc->sc_stride = stride;
sc->sc_bits = bus_space_vaddr(bst, bsh);
+ sc->sc_swapped = swapped;
wsfont_init();
diff -r 88d0c320a3bf -r 79000f975998 sys/arch/evbarm/fdt/fdt_machdep.c
--- a/sys/arch/evbarm/fdt/fdt_machdep.c Mon Oct 19 01:08:06 2020 +0000
+++ b/sys/arch/evbarm/fdt/fdt_machdep.c Mon Oct 19 01:12:14 2020 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
#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_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 @@
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 @@
{
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
diff -r 88d0c320a3bf -r 79000f975998 sys/dev/fdt/simplefb.c
--- a/sys/dev/fdt/simplefb.c Mon Oct 19 01:08:06 2020 +0000
+++ b/sys/dev/fdt/simplefb.c Mon Oct 19 01:12:14 2020 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
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 {
Home |
Main Index |
Thread Index |
Old Index