Martin Roth has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/34732 )
Change subject: libpayload: cbgfx: Allow rotation of the display ......................................................................
libpayload: cbgfx: Allow rotation of the display
Sometimes the display native orientation does not match the device default orientation, so allow rotation of the framebuffer before it is displayed on screen.
set_pixel now take coordinates in the rotated coordinate system, and converts the coordinates before writing to the framebuffer.
Also, screen.size now matches the rotated system (_not_ the framebuffer size).
BUG=b:132049716 TEST=Boot krane, see that FW screen is orientation properly.
Change-Id: If9316c0ce33c17057372ef5995a2c68de4f11f02 Signed-off-by: Nicolas Boichat drinkcat@chromium.org Reviewed-on: https://review.coreboot.org/c/coreboot/+/34732 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Julius Werner jwerner@chromium.org Reviewed-by: Christian Walter christian.walter@9elements.com --- M payloads/libpayload/drivers/video/graphics.c M payloads/libpayload/include/coreboot_tables.h 2 files changed, 44 insertions(+), 4 deletions(-)
Approvals: build bot (Jenkins): Verified Julius Werner: Looks good to me, approved Christian Walter: Looks good to me, but someone else must approve
diff --git a/payloads/libpayload/drivers/video/graphics.c b/payloads/libpayload/drivers/video/graphics.c index 85a8642..6b5664b 100644 --- a/payloads/libpayload/drivers/video/graphics.c +++ b/payloads/libpayload/drivers/video/graphics.c @@ -129,8 +129,30 @@ { const int bpp = fbinfo->bits_per_pixel; const int bpl = fbinfo->bytes_per_line; + struct vector rcoord; int i; - uint8_t * const pixel = fbaddr + coord->y * bpl + coord->x * bpp / 8; + + switch (fbinfo->orientation) { + case CB_FB_ORIENTATION_NORMAL: + default: + rcoord.x = coord->x; + rcoord.y = coord->y; + break; + case CB_FB_ORIENTATION_BOTTOM_UP: + rcoord.x = screen.size.width - 1 - coord->x; + rcoord.y = screen.size.height - 1 - coord->y; + break; + case CB_FB_ORIENTATION_LEFT_UP: + rcoord.x = coord->y; + rcoord.y = screen.size.width - 1 - coord->x; + break; + case CB_FB_ORIENTATION_RIGHT_UP: + rcoord.x = screen.size.height - 1 - coord->y; + rcoord.y = coord->x; + break; + } + + uint8_t * const pixel = fbaddr + rcoord.y * bpl + rcoord.x * bpp / 8; for (i = 0; i < bpp / 8; i++) pixel[i] = (color >> (i * 8)); } @@ -152,8 +174,17 @@ if (!fbaddr) return CBGFX_ERROR_FRAMEBUFFER_ADDR;
- screen.size.width = fbinfo->x_resolution; - screen.size.height = fbinfo->y_resolution; + switch (fbinfo->orientation) { + default: /* Normal or rotated 180 degrees. */ + screen.size.width = fbinfo->x_resolution; + screen.size.height = fbinfo->y_resolution; + break; + case CB_FB_ORIENTATION_LEFT_UP: /* 90 degree rotation. */ + case CB_FB_ORIENTATION_RIGHT_UP: + screen.size.width = fbinfo->y_resolution; + screen.size.height = fbinfo->x_resolution; + break; + } screen.offset.x = 0; screen.offset.y = 0;
@@ -242,7 +273,7 @@ * We assume that for 32bpp the high byte gets ignored anyway. */ if ((((color >> 8) & 0xff) == (color & 0xff)) && (bpp == 16 || (((color >> 16) & 0xff) == (color & 0xff)))) { - memset(fbaddr, color & 0xff, screen.size.height * bpl); + memset(fbaddr, color & 0xff, fbinfo->y_resolution * bpl); } else { for (p.y = 0; p.y < screen.size.height; p.y++) for (p.x = 0; p.x < screen.size.width; p.x++) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 9b69a6d..bf2cf02 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -189,6 +189,14 @@ u64 forward; };
+/* Panel orientation, matches drm_connector.h in the Linux kernel. */ +enum cb_fb_orientation { + CB_FB_ORIENTATION_NORMAL = 0, + CB_FB_ORIENTATION_BOTTOM_UP = 1, + CB_FB_ORIENTATION_LEFT_UP = 2, + CB_FB_ORIENTATION_RIGHT_UP = 3, +}; + struct cb_framebuffer { u32 tag; u32 size; @@ -206,6 +214,7 @@ u8 blue_mask_size; u8 reserved_mask_pos; u8 reserved_mask_size; + u8 orientation; };
#define CB_GPIO_ACTIVE_LOW 0