Index | Thread | Search

From:
Paul Fertser <fercerpav@gmail.com>
Subject:
arm64 bootstrap: support BPP16 EFI framebuffer
To:
tech@openbsd.org
Date:
Sun, 3 Nov 2024 03:11:21 +0300

Download raw body.

Thread
Hi,

This change adds support for the only 16-bit colour framebuffer format
offered by U-Boot[0].

Tested on RK3399-based Pineboook Pro with RAMDISK config.

[0] https://source.denx.de/u-boot/u-boot/-/blob/master/lib/efi_loader/efi_gop.c?ref_type=heads#L544

diff --git sys/arch/arm64/stand/efiboot/efiboot.c sys/arch/arm64/stand/efiboot/efiboot.c
index 07e04c331..83be3f249 100644
--- sys/arch/arm64/stand/efiboot/efiboot.c
+++ sys/arch/arm64/stand/efiboot/efiboot.c
@@ -397,7 +397,7 @@ efi_framebuffer(void)
 	uint32_t acells, scells;
 	uint64_t base, size;
 	uint32_t reg[4];
-	uint32_t width, height, stride;
+	uint32_t width, height, stride, pxsize;
 	char *format;
 	char *prop;
 
@@ -443,15 +443,31 @@ efi_framebuffer(void)
 	if (gop == NULL || gop->Mode == NULL || gop->Mode->Info == NULL)
 		return;
 
-	/* We only support 32-bit pixel modes for now. */
 	switch (gop->Mode->Info->PixelFormat) {
 	case PixelRedGreenBlueReserved8BitPerColor:
 		format = "x8b8g8r8";
+		pxsize = 4;
 		break;
 	case PixelBlueGreenRedReserved8BitPerColor:
 		format = "x8r8g8b8";
+		pxsize = 4;
 		break;
+	case PixelBitMask: {
+		EFI_PIXEL_BITMASK *bm = &gop->Mode->Info->PixelInformation;
+		if (bm->RedMask == 0xf800 &&
+		    bm->GreenMask == 0x07e0 &&
+		    bm->BlueMask == 0x001f) {
+			format = "r5g6b5";
+			pxsize = 2;
+			break;
+		}
+		printf("Unsupported PixelInformation bitmasks\n");
+		/* FALLTHROUGH */
+	}
 	default:
+		printf("Unsupported PixelFormat %d, not adding "
+		    "\"simple-framebuffer\" DT node\n",
+		    gop->Mode->Info->PixelFormat);
 		return;
 	}
 
@@ -459,7 +475,7 @@ efi_framebuffer(void)
 	size = gop->Mode->FrameBufferSize;
 	width = htobe32(gop->Mode->Info->HorizontalResolution);
 	height = htobe32(gop->Mode->Info->VerticalResolution);
-	stride = htobe32(gop->Mode->Info->PixelsPerScanLine * 4);
+	stride = htobe32(gop->Mode->Info->PixelsPerScanLine * pxsize);
 
 	node = fdt_find_node("/");
 	if (fdt_node_property_int(node, "#address-cells", &acells) != 1)