Module Name: src Committed By: jmcneill Date: Wed Jul 24 19:37:52 UTC 2019
Modified Files: src/sys/arch/arm/acpi: acpi_platform.c Log Message: Add early fb console support To generate a diff of this commit: cvs rdiff -u -r1.14 -r1.15 src/sys/arch/arm/acpi/acpi_platform.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/acpi/acpi_platform.c diff -u src/sys/arch/arm/acpi/acpi_platform.c:1.14 src/sys/arch/arm/acpi/acpi_platform.c:1.15 --- src/sys/arch/arm/acpi/acpi_platform.c:1.14 Sat Jun 22 19:47:27 2019 +++ src/sys/arch/arm/acpi/acpi_platform.c Wed Jul 24 19:37:52 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_platform.c,v 1.14 2019/06/22 19:47:27 jmcneill Exp $ */ +/* $NetBSD: acpi_platform.c,v 1.15 2019/07/24 19:37:52 jmcneill Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -31,11 +31,13 @@ #include "com.h" #include "plcom.h" +#include "wsdisplay.h" +#include "genfb.h" #include "opt_efi.h" #include "opt_multiprocessor.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.14 2019/06/22 19:47:27 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_platform.c,v 1.15 2019/07/24 19:37:52 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -71,6 +73,14 @@ __KERNEL_RCSID(0, "$NetBSD: acpi_platfor #include <dev/pci/pucvar.h> #endif +#if NWSDISPLAY > 0 +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> +#include <dev/wsfont/wsfont.h> +#include <dev/wscons/wsdisplay_vconsvar.h> +#endif + #ifdef EFI_RUNTIME #include <arm/arm/efi_runtime.h> #endif @@ -124,6 +134,107 @@ acpi_platform_bootstrap(void) acpi_coherent_dma_tag._nranges = __arraycount(acpi_coherent_ranges); } +#if NWSDISPLAY > 0 && NGENFB > 0 +static struct wsscreen_descr acpi_platform_stdscreen = { + .name = "std", + .ncols = 0, + .nrows = 0, + .textops = NULL, + .fontwidth = 0, + .fontheight = 0, + .capabilities = 0, + .modecookie = NULL +}; + +static struct vcons_screen acpi_platform_screen; + +static int +acpi_platform_find_simplefb(void) +{ + static const char * simplefb_compatible[] = { "simple-framebuffer", NULL }; + int chosen_phandle, child; + + chosen_phandle = OF_finddevice("/chosen"); + if (chosen_phandle == -1) + return -1; + + for (child = OF_child(chosen_phandle); child; child = OF_peer(child)) { + if (!fdtbus_status_okay(child)) + continue; + if (!of_match_compatible(child, simplefb_compatible)) + continue; + + return child; + } + + return -1; +} + +static void +acpi_platform_wsdisplay_preattach(void) +{ + struct rasops_info *ri = &acpi_platform_screen.scr_ri; + bus_space_tag_t bst = &arm_generic_bs_tag; + bus_space_handle_t bsh; + uint32_t width, height, stride; + const char *format; + bus_addr_t addr; + bus_size_t size; + uint16_t depth; + long defattr; + + memset(&acpi_platform_screen, 0, sizeof(acpi_platform_screen)); + + const int phandle = acpi_platform_find_simplefb(); + if (phandle == -1) + return; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 || size == 0) + return; + + if (of_getprop_uint32(phandle, "width", &width) != 0 || + of_getprop_uint32(phandle, "height", &height) != 0 || + of_getprop_uint32(phandle, "stride", &stride) != 0 || + (format = fdtbus_get_string(phandle, "format")) == NULL) + return; + + if (strcmp(format, "a8b8g8r8") == 0 || + strcmp(format, "x8r8g8b8") == 0) { + depth = 32; + } else if (strcmp(format, "r5g6b5") == 0) { + depth = 16; + } else { + return; + } + + if (bus_space_map(bst, addr, size, + BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &bsh) != 0) + return; + + wsfont_init(); + + ri->ri_width = width; + ri->ri_height = height; + ri->ri_depth = depth; + ri->ri_stride = stride; + ri->ri_bits = bus_space_vaddr(bst, bsh); + ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_CLEAR; + rasops_init(ri, ri->ri_height / 8, ri->ri_width / 8); + ri->ri_caps = WSSCREEN_WSCOLORS; + rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight, + ri->ri_width / ri->ri_font->fontwidth); + + acpi_platform_stdscreen.nrows = ri->ri_rows; + acpi_platform_stdscreen.ncols = ri->ri_cols; + acpi_platform_stdscreen.textops = &ri->ri_ops; + acpi_platform_stdscreen.capabilities = ri->ri_caps; + + ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr); + + wsdisplay_preattach(&acpi_platform_stdscreen, ri, 0, 0, defattr); +} +#endif + static void acpi_platform_startup(void) { @@ -203,6 +314,13 @@ acpi_platform_startup(void) } /* + * Setup framebuffer console, if present. + */ +#if NWSDISPLAY > 0 && NGENFB > 0 + acpi_platform_wsdisplay_preattach(); +#endif + + /* * Initialize PSCI 0.2+ if implemented */ if (ACPI_SUCCESS(acpi_table_find(ACPI_SIG_FADT, (void **)&fadt))) {