Add fields and constants for coreboot framebuffer orientation. Set corebootdrm's DRM connector state from the values. Not all firmware provides orientation, so make it optional. Systems without continue to use unknown orientation.
Signed-off-by: Thomas Zimmermann <[email protected]> --- drivers/gpu/drm/sysfb/corebootdrm.c | 30 +++++++++++++++++++++++++---- include/linux/coreboot.h | 9 +++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/sysfb/corebootdrm.c b/drivers/gpu/drm/sysfb/corebootdrm.c index 745318580a5d..5dc6f3c76f7b 100644 --- a/drivers/gpu/drm/sysfb/corebootdrm.c +++ b/drivers/gpu/drm/sysfb/corebootdrm.c @@ -110,6 +110,26 @@ static phys_addr_t corebootdrm_get_address_fb(struct drm_device *dev, resource_s return fb->physical_address; } +static enum drm_panel_orientation corebootdrm_get_orientation_fb(struct drm_device *dev, + const struct lb_framebuffer *fb) +{ + if (!LB_FRAMEBUFFER_HAS_ORIENTATION(fb)) + return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; + + switch (fb->orientation) { + case LB_FRAMEBUFFER_ORIENTATION_NORMAL: + return DRM_MODE_PANEL_ORIENTATION_NORMAL; + case LB_FRAMEBUFFER_ORIENTATION_BOTTOM_UP: + return DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; + case LB_FRAMEBUFFER_ORIENTATION_LEFT_UP: + return DRM_MODE_PANEL_ORIENTATION_LEFT_UP; + case LB_FRAMEBUFFER_ORIENTATION_RIGHT_UP: + return DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; + } + + return DRM_MODE_PANEL_ORIENTATION_UNKNOWN; +} + /* * Simple Framebuffer device */ @@ -168,7 +188,8 @@ static const struct drm_mode_config_funcs corebootdrm_mode_config_funcs = { DRM_SYSFB_MODE_CONFIG_FUNCS, }; -static int corebootdrm_mode_config_init(struct corebootdrm_device *cdev) +static int corebootdrm_mode_config_init(struct corebootdrm_device *cdev, + enum drm_panel_orientation orientation) { struct drm_sysfb_device *sysfb = &cdev->sysfb; struct drm_device *dev = &sysfb->dev; @@ -234,8 +255,7 @@ static int corebootdrm_mode_config_init(struct corebootdrm_device *cdev) if (ret) return ret; drm_connector_helper_add(connector, &corebootdrm_connector_helper_funcs); - drm_connector_set_panel_orientation_with_quirk(connector, - DRM_MODE_PANEL_ORIENTATION_UNKNOWN, + drm_connector_set_panel_orientation_with_quirk(connector, orientation, width, height); ret = drm_connector_attach_encoder(connector, encoder); @@ -276,6 +296,7 @@ static int corebootdrm_probe(struct platform_device *pdev) int width, height, pitch; resource_size_t size; phys_addr_t address; + enum drm_panel_orientation orientation; struct resource *res, *mem = NULL; struct resource aperture; void __iomem *screen_base; @@ -320,6 +341,7 @@ static int corebootdrm_probe(struct platform_device *pdev) address = corebootdrm_get_address_fb(dev, size, fb); if (!address) return -EINVAL; + orientation = corebootdrm_get_orientation_fb(dev, fb); sysfb->fb_mode = drm_sysfb_mode(width, height, 0, 0); sysfb->fb_format = format; @@ -375,7 +397,7 @@ static int corebootdrm_probe(struct platform_device *pdev) * DRM mode setting and registration */ - ret = corebootdrm_mode_config_init(cdev); + ret = corebootdrm_mode_config_init(cdev, orientation); if (ret) return ret; diff --git a/include/linux/coreboot.h b/include/linux/coreboot.h index e81ee5746e2b..d1de94f49cd3 100644 --- a/include/linux/coreboot.h +++ b/include/linux/coreboot.h @@ -45,6 +45,11 @@ struct lb_cbmem_entry { u32 id; } __packed; +#define LB_FRAMEBUFFER_ORIENTATION_NORMAL 0 +#define LB_FRAMEBUFFER_ORIENTATION_BOTTOM_UP 1 +#define LB_FRAMEBUFFER_ORIENTATION_LEFT_UP 2 +#define LB_FRAMEBUFFER_ORIENTATION_RIGHT_UP 3 + /* Describes framebuffer setup by coreboot */ struct lb_framebuffer { u32 tag; @@ -63,9 +68,13 @@ struct lb_framebuffer { u8 blue_mask_size; u8 reserved_mask_pos; u8 reserved_mask_size; + u8 orientation; } __packed; #define LB_FRAMEBUFFER_HAS_LFB(__fb) \ ((__fb)->size >= offsetofend(struct lb_framebuffer, reserved_mask_size)) +#define LB_FRAMEBUFFER_HAS_ORIENTATION(__fb) \ + ((__fb)->size >= offsetofend(struct lb_framebuffer, orientation)) + #endif /* _LINUX_COREBOOT_H */ -- 2.52.0
