--- drivers/gpu/drm/linux_fb.c.orig 2022-05-31 08:17:34 UTC +++ drivers/gpu/drm/linux_fb.c @@ -222,6 +222,33 @@ __register_framebuffer(struct linux_fb_info *fb_info) fb_info->fbio.fb_fbd_dev = device_add_child(fb_info->fb_bsddev, "fbd", device_get_unit(fb_info->fb_bsddev)); +/* This block should be removed after /sys/sys/fbio.h has been updated. */ +#ifndef FB_FLAG_ROTATE_MASK /* Transitional, from /sys/sys/fbio.h */ +#define FB_FLAG_ROTATE_0 0x00 /* rotate fb 0 degrees clockwise */ +#define FB_FLAG_ROTATE_90 0x08 /* rotate fb 90 degrees clockwise */ +#define FB_FLAG_ROTATE_180 0x10 /* rotate fb 180 degrees clockwise */ +#define FB_FLAG_ROTATE_270 (FB_FLAG_ROTATE_90 | FB_FLAG_ROTATE_180) +#define FB_FLAG_ROTATE_MASK 0x18 +#define FB_FLAG_ROTATE_NODEFAULT 0x20 /* do not load console defaults */ +#endif + + /* Pass the FB_ROTATE hints to FreeBSD's vt(4) fb_flags. */ + fb_info->fbio.fb_flags &= ~FB_FLAG_ROTATE_MASK; + switch (fb_info->fbcon_rotate_hint) { + case FB_ROTATE_UR: + fb_info->fbio.fb_flags |= FB_FLAG_ROTATE_0 | FB_FLAG_ROTATE_NODEFAULT; + break; + case FB_ROTATE_CW: + fb_info->fbio.fb_flags |= FB_FLAG_ROTATE_90 | FB_FLAG_ROTATE_NODEFAULT; + break; + case FB_ROTATE_UD: + fb_info->fbio.fb_flags |= FB_FLAG_ROTATE_180 | FB_FLAG_ROTATE_NODEFAULT; + break; + case FB_ROTATE_CCW: + fb_info->fbio.fb_flags |= FB_FLAG_ROTATE_270 | FB_FLAG_ROTATE_NODEFAULT; + break; + } + /* tell vt_fb to initialize color map */ fb_info->fbio.fb_cmsize = 0; if (fb_info->fbio.fb_bpp == 0) { @@ -281,7 +308,9 @@ linux_unregister_framebuffer(struct linux_fb_info *fb_ int linux_fb_get_options(const char *connector_name, char **option) { + int rotation; char tunable[64]; + char (*optbuf)[sizeof(",rotate=360")]; /* * A user may use loader tunables to set a specific mode for the @@ -295,6 +324,11 @@ linux_fb_get_options(const char *connector_name, char * Example of a mode applied to all connectors not having a * connector-specific mode: * kern.vt.fb.default_mode="640x480" + * + * Example of a mode option applied to all connectors not having a + * connector-specific mode, where the angle is the number of degrees + * counter-clockwise to rotate the display: + * kern.vt.fb.default_mode=",rotate=270" */ snprintf(tunable, sizeof(tunable), "kern.vt.fb.modes.%s", connector_name); @@ -302,10 +336,26 @@ linux_fb_get_options(const char *connector_name, char printf("[drm] Connector %s: get mode from tunables:\n", connector_name); printf("[drm] - %s\n", tunable); printf("[drm] - kern.vt.fb.default_mode\n"); + printf("[drm] - screen.rotate\n"); } *option = kern_getenv(tunable); if (*option == NULL) *option = kern_getenv("kern.vt.fb.default_mode"); + if (*option == NULL) { + if (getenv_int("screen.rotate", &rotation) != 0) { + switch (rotation) { + case 90: + case 270: + rotation = (rotation + 180) % 360; + case 180: + optbuf = malloc(sizeof(*optbuf), DRM_MEM_DRIVER, + M_WAITOK | M_ZERO); + snprintf(*optbuf, sizeof(*optbuf), ",rotate=%d", + rotation); + *option = *optbuf; + } + } + } return (*option != NULL ? 0 : -ENOENT); }