diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index d2d04615be0e..3b1d9252d4de 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -613,6 +613,10 @@ void drm_display_mode_from_videomode(const struct videomode *vm, dmode->flags |= DRM_MODE_FLAG_DBLCLK; if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) dmode->flags |= DRM_MODE_FLAG_PPIXDATA; + if (vm->flags & DISPLAY_FLAGS_MIRROR_Y) + dmode->flags |= DRM_MODE_FLAG_YMIRROR; + if (vm->flags & DISPLAY_FLAGS_MIRROR_X) + dmode->flags |= DRM_MODE_FLAG_XMIRROR; drm_mode_set_name(dmode); } diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index b253875e99c7..69ee95366a72 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -91,6 +91,16 @@ static int of_parse_display_timing(const struct device_node *np, if (!of_property_read_u32(np, "pixelclk-active", &val)) dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : DISPLAY_FLAGS_PIXDATA_NEGEDGE; + if (!of_property_read_u32(np, "screen-rotate", &val)) { + if (val == DRM_MODE_FLAG_XMIRROR) { + dt->flags |= DISPLAY_FLAGS_MIRROR_X; + } else if (val == DRM_MODE_FLAG_YMIRROR) { + dt->flags |= DISPLAY_FLAGS_MIRROR_Y; + } else if (val == DRM_MODE_FLAG_XYMIRROR) { + dt->flags |= DISPLAY_FLAGS_MIRROR_X; + dt->flags |= DISPLAY_FLAGS_MIRROR_Y; + } + } if (of_property_read_bool(np, "interlaced")) dt->flags |= DISPLAY_FLAGS_INTERLACED; diff --git a/include/dt-bindings/display/media-bus-format.h b/include/dt-bindings/display/media-bus-format.h index 3ae48c8514d8..2d4b66675948 100644 --- a/include/dt-bindings/display/media-bus-format.h +++ b/include/dt-bindings/display/media-bus-format.h @@ -150,4 +150,9 @@ /* HSV - next is 0x6002 */ #define MEDIA_BUS_FMT_AHSV8888_1X32 0x6001 +/* Panel Mirror control */ +#define DRM_MODE_FLAG_XMIRROR (1 << 28) +#define DRM_MODE_FLAG_YMIRROR (1 << 29) +#define DRM_MODE_FLAG_XYMIRROR (DRM_MODE_FLAG_XMIRROR | DRM_MODE_FLAG_YMIRROR) + #endif /* __LINUX_MEDIA_BUS_FORMAT_H */ diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index fd3126a04b57..0117bab84044 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -87,6 +87,11 @@ #define DRM_MODE_FLAG_PIC_AR_16_9 \ (DRM_MODE_PICTURE_ASPECT_16_9<<19) +/* Panel Mirror control */ +#define DRM_MODE_FLAG_XMIRROR (1 << 28) +#define DRM_MODE_FLAG_YMIRROR (1 << 29) +#define DRM_MODE_FLAG_XYMIRROR (DRM_MODE_FLAG_XMIRROR | DRM_MODE_FLAG_YMIRROR) + #define DRM_MODE_FLAG_PPIXDATA (1<<31) /* DPMS flags */ /* bit compatible with the xorg definitions. */ diff --git a/include/video/display_timing.h b/include/video/display_timing.h index e9e168a56c5c..662826c03b1c 100644 --- a/include/video/display_timing.h +++ b/include/video/display_timing.h @@ -28,13 +28,18 @@ enum display_flags { DISPLAY_FLAGS_INTERLACED = BIT(8), DISPLAY_FLAGS_DOUBLESCAN = BIT(9), DISPLAY_FLAGS_DOUBLECLK = BIT(10), -#if defined(CONFIG_FB_ROCKCHIP) DISPLAY_FLAGS_SWAP_GB = BIT(16), DISPLAY_FLAGS_SWAP_RG = BIT(17), DISPLAY_FLAGS_SWAP_RB = BIT(18), -#endif + DISPLAY_FLAGS_MIRROR_X = BIT(19), + DISPLAY_FLAGS_MIRROR_Y = BIT(20), }; +/* Panel Mirror control */ +#define DRM_MODE_FLAG_XMIRROR (1 << 28) +#define DRM_MODE_FLAG_YMIRROR (1 << 29) +#define DRM_MODE_FLAG_XYMIRROR (DRM_MODE_FLAG_XMIRROR | DRM_MODE_FLAG_YMIRROR) + /* * A single signal can be specified via a range of minimal and maximal values * with a typical value, that lies somewhere inbetween.