mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 07:22:33 +00:00
4a0839b44e
Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.1.76 All patches automatically rebased. Build system: x86/64 Build-tested: x86/64/AMD Cezanne Run-tested: x86/64/AMD Cezanne Signed-off-by: John Audia <therealgraysky@proton.me>
177 lines
5.4 KiB
Diff
177 lines
5.4 KiB
Diff
From 0a0084b8621682ad96d001e798aa239b11a3cf00 Mon Sep 17 00:00:00 2001
|
|
From: Timon Skerutsch <kernel@diodes-delight.com>
|
|
Date: Mon, 13 Nov 2023 22:53:12 +0100
|
|
Subject: [PATCH] drm/panel: add panel-dsi
|
|
|
|
Equivalent to panel-dpi for configuring a simple DSI panel with
|
|
device tree side timings and bus settings.
|
|
Motiviation is the same as for panel-dpi of wanting to support
|
|
new simple panels without needing to patch the kernel.
|
|
|
|
Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
|
|
---
|
|
drivers/gpu/drm/panel/panel-simple.c | 123 ++++++++++++++++++++++++++-
|
|
1 file changed, 122 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/gpu/drm/panel/panel-simple.c
|
|
+++ b/drivers/gpu/drm/panel/panel-simple.c
|
|
@@ -40,6 +40,7 @@
|
|
#include <drm/drm_edid.h>
|
|
#include <drm/drm_mipi_dsi.h>
|
|
#include <drm/drm_panel.h>
|
|
+#include <drm/drm_of.h>
|
|
|
|
/**
|
|
* struct panel_desc - Describes a simple panel.
|
|
@@ -4662,6 +4663,9 @@ static const struct panel_desc_dsi osd10
|
|
.lanes = 4,
|
|
};
|
|
|
|
+// for panels using generic panel-dsi binding
|
|
+static struct panel_desc_dsi panel_dsi;
|
|
+
|
|
static const struct of_device_id dsi_of_match[] = {
|
|
{
|
|
.compatible = "auo,b080uan01",
|
|
@@ -4685,14 +4689,118 @@ static const struct of_device_id dsi_of_
|
|
.compatible = "osddisplays,osd101t2045-53ts",
|
|
.data = &osd101t2045_53ts
|
|
}, {
|
|
+ /* Must be the last entry */
|
|
+ .compatible = "panel-dsi",
|
|
+ .data = &panel_dsi,
|
|
+ }, {
|
|
/* sentinel */
|
|
}
|
|
};
|
|
MODULE_DEVICE_TABLE(of, dsi_of_match);
|
|
|
|
+
|
|
+/* Checks for DSI panel definition in device-tree, analog to panel_dpi */
|
|
+static int panel_dsi_dt_probe(struct device *dev,
|
|
+ struct panel_desc_dsi *desc_dsi)
|
|
+{
|
|
+ struct panel_desc *desc;
|
|
+ struct display_timing *timing;
|
|
+ const struct device_node *np;
|
|
+ const char *dsi_color_format;
|
|
+ const char *dsi_mode_flags;
|
|
+ struct property *prop;
|
|
+ int dsi_lanes, ret;
|
|
+
|
|
+ np = dev->of_node;
|
|
+
|
|
+ desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
|
|
+ if (!desc)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);
|
|
+ if (!timing)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ret = of_get_display_timing(np, "panel-timing", timing);
|
|
+ if (ret < 0) {
|
|
+ dev_err(dev, "%pOF: no panel-timing node found for \"panel-dsi\" binding\n",
|
|
+ np);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ desc->timings = timing;
|
|
+ desc->num_timings = 1;
|
|
+
|
|
+ of_property_read_u32(np, "width-mm", &desc->size.width);
|
|
+ of_property_read_u32(np, "height-mm", &desc->size.height);
|
|
+
|
|
+ dsi_lanes = drm_of_get_data_lanes_count_ep(np, 0, 0, 1, 4);
|
|
+
|
|
+ if (dsi_lanes < 0) {
|
|
+ dev_err(dev, "%pOF: no or too many data-lanes defined", np);
|
|
+ return dsi_lanes;
|
|
+ }
|
|
+
|
|
+ desc_dsi->lanes = dsi_lanes;
|
|
+
|
|
+ of_property_read_string(np, "dsi-color-format", &dsi_color_format);
|
|
+ if (!strcmp(dsi_color_format, "RGB888")) {
|
|
+ desc_dsi->format = MIPI_DSI_FMT_RGB888;
|
|
+ desc->bpc = 8;
|
|
+ } else if (!strcmp(dsi_color_format, "RGB565")) {
|
|
+ desc_dsi->format = MIPI_DSI_FMT_RGB565;
|
|
+ desc->bpc = 6;
|
|
+ } else if (!strcmp(dsi_color_format, "RGB666")) {
|
|
+ desc_dsi->format = MIPI_DSI_FMT_RGB666;
|
|
+ desc->bpc = 6;
|
|
+ } else if (!strcmp(dsi_color_format, "RGB666_PACKED")) {
|
|
+ desc_dsi->format = MIPI_DSI_FMT_RGB666_PACKED;
|
|
+ desc->bpc = 6;
|
|
+ } else {
|
|
+ dev_err(dev, "%pOF: no valid dsi-color-format defined", np);
|
|
+ return -EINVAL;
|
|
+ }
|
|
+
|
|
+
|
|
+ of_property_for_each_string(np, "mode", prop, dsi_mode_flags) {
|
|
+ if (!strcmp(dsi_mode_flags, "MODE_VIDEO"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_BURST"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_BURST;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_SYNC_PULSE"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_AUTO_VERT"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_AUTO_VERT;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_HSE"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_HSE;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HFP"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HFP;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HBP"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HBP;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HSA"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HSA;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_VSYNC_FLUSH"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_VSYNC_FLUSH;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_NO_EOT_PACKET"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_NO_EOT_PACKET;
|
|
+ else if (!strcmp(dsi_mode_flags, "CLOCK_NON_CONTINUOUS"))
|
|
+ desc_dsi->flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS;
|
|
+ else if (!strcmp(dsi_mode_flags, "MODE_LPM"))
|
|
+ desc_dsi->flags |= MIPI_DSI_MODE_LPM;
|
|
+ else if (!strcmp(dsi_mode_flags, "HS_PKT_END_ALIGNED"))
|
|
+ desc_dsi->flags |= MIPI_DSI_HS_PKT_END_ALIGNED;
|
|
+ }
|
|
+
|
|
+ desc->connector_type = DRM_MODE_CONNECTOR_DSI;
|
|
+ desc_dsi->desc = *desc;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
|
|
{
|
|
const struct panel_desc_dsi *desc;
|
|
+ struct panel_desc_dsi *dt_desc;
|
|
const struct of_device_id *id;
|
|
int err;
|
|
|
|
@@ -4700,7 +4808,20 @@ static int panel_simple_dsi_probe(struct
|
|
if (!id)
|
|
return -ENODEV;
|
|
|
|
- desc = id->data;
|
|
+ if (id->data == &panel_dsi) {
|
|
+ /* Handle the generic panel-dsi binding */
|
|
+ dt_desc = devm_kzalloc(&dsi->dev, sizeof(*dt_desc), GFP_KERNEL);
|
|
+ if (!dt_desc)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ err = panel_dsi_dt_probe(&dsi->dev, dt_desc);
|
|
+ if (err < 0)
|
|
+ return err;
|
|
+
|
|
+ desc = dt_desc;
|
|
+ } else {
|
|
+ desc = id->data;
|
|
+ }
|
|
|
|
err = panel_simple_probe(&dsi->dev, &desc->desc);
|
|
if (err < 0)
|