Index: arch/evbarm/fdt/fdt_machdep.c =================================================================== RCS file: /home/netbsd/src/sys/arch/evbarm/fdt/fdt_machdep.c,v retrieving revision 1.75 diff -p -u -r1.75 fdt_machdep.c --- arch/evbarm/fdt/fdt_machdep.c 10 Oct 2020 15:25:30 -0000 1.75 +++ arch/evbarm/fdt/fdt_machdep.c 18 Oct 2020 16:11:53 -0000 @@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: fdt_machdep. #include #include #include +#include #include #include #include @@ -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 after kernel is load. In this case, + * frame buffer 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: dev/fdt/simplefb.c =================================================================== RCS file: /home/netbsd/src/sys/dev/fdt/simplefb.c,v retrieving revision 1.8 diff -p -u -r1.8 simplefb.c --- dev/fdt/simplefb.c 23 Jul 2019 14:34:12 -0000 1.8 +++ dev/fdt/simplefb.c 18 Oct 2020 15:12:34 -0000 @@ -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 { Index: arch/arm/fdt/arm_simplefb.c =================================================================== RCS file: /home/netbsd/src/sys/arch/arm/fdt/arm_simplefb.c,v retrieving revision 1.1 diff -p -u -r1.1 arm_simplefb.c --- arch/arm/fdt/arm_simplefb.c 10 Oct 2020 15:25:31 -0000 1.1 +++ arch/arm/fdt/arm_simplefb.c 18 Oct 2020 15:16:49 -0000 @@ -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: dev/wsfb/genfb.c =================================================================== RCS file: /home/netbsd/src/sys/dev/wsfb/genfb.c,v retrieving revision 1.77 diff -p -u -r1.77 genfb.c --- dev/wsfb/genfb.c 18 Oct 2020 12:47:37 -0000 1.77 +++ dev/wsfb/genfb.c 18 Oct 2020 16:05:29 -0000 @@ -539,7 +539,7 @@ genfb_init_screen(void *cookie, struct v struct genfb_softc *sc = cookie; struct rasops_info *ri = &scr->scr_ri; int wantcols; - bool is_bgr; + bool is_bgr, is_swapped; ri->ri_depth = sc->sc_depth; ri->ri_width = sc->sc_width; @@ -566,23 +566,29 @@ genfb_init_screen(void *cookie, struct v case 32: case 24: ri->ri_flg |= RI_ENABLE_ALPHA; + ri->ri_rnum = 8; + ri->ri_gnum = 8; + ri->ri_bnum = 8; is_bgr = false; prop_dictionary_get_bool(device_properties(sc->sc_dev), "is_bgr", &is_bgr); + is_swapped = false; + prop_dictionary_get_bool(device_properties(sc->sc_dev), + "is_swapped", &is_swapped); if (is_bgr) { /* someone requested BGR */ - ri->ri_rnum = 8; - ri->ri_gnum = 8; - ri->ri_bnum = 8; ri->ri_rpos = 0; ri->ri_gpos = 8; ri->ri_bpos = 16; + } else if (is_swapped) { + /* byte-swapped, must be 32bpp */ + KASSERT(ri->ri_depth == 32); + ri->ri_rpos = 8; + ri->ri_gpos = 16; + ri->ri_bpos = 24; } else { /* assume RGB */ - ri->ri_rnum = 8; - ri->ri_gnum = 8; - ri->ri_bnum = 8; ri->ri_rpos = 16; ri->ri_gpos = 8; ri->ri_bpos = 0; Index: arch/arm/sunxi/sunxi_debe.c =================================================================== RCS file: /home/netbsd/src/sys/arch/arm/sunxi/sunxi_debe.c,v retrieving revision 1.9 diff -p -u -r1.9 sunxi_debe.c --- arch/arm/sunxi/sunxi_debe.c 1 Jun 2018 17:18:44 -0000 1.9 +++ arch/arm/sunxi/sunxi_debe.c 18 Oct 2020 16:09:46 -0000 @@ -560,6 +560,10 @@ sunxi_debe_ep_enable(device_t dev, struc return 0; } +/* + * FIXME 2020/10/19 + * This function is not called actually. + */ void sunxi_debe_set_videomode(device_t dev, const struct videomode *mode) { @@ -613,7 +617,11 @@ sunxi_debe_set_videomode(device_t dev, c SUNXI_DEBE_ATTCTL1_LAY_FBFMT); val &= ~SUNXI_DEBE_ATTCTL1_LAY_BRSWAPEN; val &= ~SUNXI_DEBE_ATTCTL1_LAY_FBPS; -#if __ARMEB__ +#if 0 /* __ARMEB__ */ + /* + * For big endian, we dynamically override FDT to let + * genfb(4) know that framebuffer is byte-swapped. + */ val |= __SHIFTIN(SUNXI_DEBE_ATTCTL1_LAY_FBPS_32BPP_BGRA, SUNXI_DEBE_ATTCTL1_LAY_FBPS); #else