diff options
author | Noralf Trønnes <noralf@tronnes.org> | 2022-02-27 15:47:11 +0300 |
---|---|---|
committer | Maxime Ripard <maxime@cerno.tech> | 2022-02-28 12:29:33 +0300 |
commit | 95ae342dc939a220b7afbd3a65f7106258f67cad (patch) | |
tree | 30e8a916db63f16879b36ff014fd6240d53da369 | |
parent | 5558d6c23d18f2143f60d7bb387e43a5d8216fa5 (diff) | |
download | linux-95ae342dc939a220b7afbd3a65f7106258f67cad.tar.xz |
drm/modes: Add of_get_drm_panel_display_mode()
Add a function to get a drm_display_mode from a panel-timing
device tree subnode.
Suggested-by: Sam Ravnborg <sam@ravnborg.org>
Reviewed-by: Sam Ravnborg <sam@ravnborg.org>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20220227124713.39766-4-noralf@tronnes.org
-rw-r--r-- | drivers/gpu/drm/drm_modes.c | 49 | ||||
-rw-r--r-- | include/drm/drm_modes.h | 8 |
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 77a4c8dd0bb8..3f819c7a021b 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -35,6 +35,7 @@ #include <linux/list_sort.h> #include <linux/export.h> +#include <video/of_display_timing.h> #include <video/of_videomode.h> #include <video/videomode.h> @@ -727,6 +728,54 @@ int of_get_drm_display_mode(struct device_node *np, return 0; } EXPORT_SYMBOL_GPL(of_get_drm_display_mode); + +/** + * of_get_drm_panel_display_mode - get a panel-timing drm_display_mode from devicetree + * @np: device_node with the panel-timing specification + * @dmode: will be set to the return value + * @bus_flags: information about pixelclk, sync and DE polarity + * + * The Device Tree properties width-mm and height-mm will be read and set on + * the display mode if they are present. + * + * Returns: + * Zero on success, negative error code on failure. + */ +int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags) +{ + u32 width_mm = 0, height_mm = 0; + struct display_timing timing; + struct videomode vm; + int ret; + + ret = of_get_display_timing(np, "panel-timing", &timing); + if (ret) + return ret; + + videomode_from_timing(&timing, &vm); + + memset(dmode, 0, sizeof(*dmode)); + drm_display_mode_from_videomode(&vm, dmode); + if (bus_flags) + drm_bus_flags_from_videomode(&vm, bus_flags); + + ret = of_property_read_u32(np, "width-mm", &width_mm); + if (ret && ret != -EINVAL) + return ret; + + ret = of_property_read_u32(np, "height-mm", &height_mm); + if (ret && ret != -EINVAL) + return ret; + + dmode->width_mm = width_mm; + dmode->height_mm = height_mm; + + drm_mode_debug_printmodeline(dmode); + + return 0; +} +EXPORT_SYMBOL_GPL(of_get_drm_panel_display_mode); #endif /* CONFIG_OF */ #endif /* CONFIG_VIDEOMODE_HELPERS */ diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 29ba4adf0c53..2fa6b2c33b3f 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -466,6 +466,8 @@ void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, u32 *bus_flags, int index); +int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags); #else static inline int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, @@ -473,6 +475,12 @@ static inline int of_get_drm_display_mode(struct device_node *np, { return -EINVAL; } + +static inline int of_get_drm_panel_display_mode(struct device_node *np, + struct drm_display_mode *dmode, u32 *bus_flags) +{ + return -EINVAL; +} #endif void drm_mode_set_name(struct drm_display_mode *mode); |