[RFC PATCH 1/2] drm/panel: add support for simple-panel description definition using DT

From: Boris BREZILLON
Date: Fri May 09 2014 - 10:16:52 EST


Currently, the only way to add new panel descriptions to the simple panel
driver is to add new entries in the platform_of_match table.

Add support for panel description retrieval from the DT.

Signed-off-by: Boris BREZILLON <boris.brezillon@xxxxxxxxxxxxxxxxxx>
---
drivers/gpu/drm/panel/Kconfig | 1 +
drivers/gpu/drm/panel/panel-simple.c | 70 ++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4ec874d..4fe3d48 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -1,6 +1,7 @@
config DRM_PANEL
bool
depends on DRM
+ select VIDEOMODE_HELPERS
help
Panel registration and lookup framework.

diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index 309f29e..fcf648d 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -33,6 +33,10 @@
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>

+#include <video/display_timing.h>
+#include <video/of_display_timing.h>
+#include <video/videomode.h>
+
struct panel_desc {
const struct drm_display_mode *modes;
unsigned int num_modes;
@@ -168,6 +172,61 @@ static const struct drm_panel_funcs panel_simple_funcs = {
.get_modes = panel_simple_get_modes,
};

+static struct panel_desc *of_panel_desc_init(struct device *dev)
+{
+ struct display_timings *timings;
+ struct panel_desc *desc;
+ u32 width, height;
+ int err;
+ int i;
+
+ err = of_property_read_u32(dev->of_node, "width", &width);
+ if (err)
+ return ERR_PTR(err);
+
+ err = of_property_read_u32(dev->of_node, "height", &height);
+ if (err)
+ return ERR_PTR(err);
+
+ desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return ERR_PTR(-ENOMEM);
+
+ timings = of_get_display_timings(dev->of_node);
+ if (timings) {
+ struct drm_display_mode *modes =
+ devm_kzalloc(dev,
+ timings->num_timings *
+ sizeof(*desc->modes),
+ GFP_KERNEL);
+
+ if (!modes)
+ return ERR_PTR(-ENOMEM);
+
+ for (i = 0; i < timings->num_timings; i++) {
+ struct videomode vm;
+
+ if (videomode_from_timings(timings, &vm, i))
+ break;
+
+ drm_display_mode_from_videomode(&vm, modes + i);
+
+ modes[i].type = DRM_MODE_TYPE_DRIVER;
+
+ if (timings->native_mode == i)
+ modes[i].type |= DRM_MODE_TYPE_PREFERRED;
+ desc->num_modes++;
+ }
+
+ kfree(timings);
+ }
+
+ desc->size.width = width;
+ desc->size.height = height;
+
+ return desc;
+}
+
static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
{
struct device_node *backlight, *ddc;
@@ -178,6 +237,17 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
if (!panel)
return -ENOMEM;

+ if (!desc) {
+ desc = of_panel_desc_init(dev);
+ /*
+ * Do not fail on DT panel desc retrieval error because
+ * some systems do not need a panel description to work
+ * properly.
+ */
+ if (IS_ERR(desc))
+ desc = NULL;
+ }
+
panel->enabled = false;
panel->desc = desc;

--
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/