bcm27xx: update 6.1 patches to latest version
[openwrt/staging/svanheule.git] / target / linux / bcm27xx / patches-6.1 / 950-1182-drm-panel-add-panel-dsi.patch
1 From 0a0084b8621682ad96d001e798aa239b11a3cf00 Mon Sep 17 00:00:00 2001
2 From: Timon Skerutsch <kernel@diodes-delight.com>
3 Date: Mon, 13 Nov 2023 22:53:12 +0100
4 Subject: [PATCH] drm/panel: add panel-dsi
5
6 Equivalent to panel-dpi for configuring a simple DSI panel with
7 device tree side timings and bus settings.
8 Motiviation is the same as for panel-dpi of wanting to support
9 new simple panels without needing to patch the kernel.
10
11 Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
12 ---
13 drivers/gpu/drm/panel/panel-simple.c | 123 ++++++++++++++++++++++++++-
14 1 file changed, 122 insertions(+), 1 deletion(-)
15
16 --- a/drivers/gpu/drm/panel/panel-simple.c
17 +++ b/drivers/gpu/drm/panel/panel-simple.c
18 @@ -40,6 +40,7 @@
19 #include <drm/drm_edid.h>
20 #include <drm/drm_mipi_dsi.h>
21 #include <drm/drm_panel.h>
22 +#include <drm/drm_of.h>
23
24 /**
25 * struct panel_desc - Describes a simple panel.
26 @@ -4660,6 +4661,9 @@ static const struct panel_desc_dsi osd10
27 .lanes = 4,
28 };
29
30 +// for panels using generic panel-dsi binding
31 +static struct panel_desc_dsi panel_dsi;
32 +
33 static const struct of_device_id dsi_of_match[] = {
34 {
35 .compatible = "auo,b080uan01",
36 @@ -4683,14 +4687,118 @@ static const struct of_device_id dsi_of_
37 .compatible = "osddisplays,osd101t2045-53ts",
38 .data = &osd101t2045_53ts
39 }, {
40 + /* Must be the last entry */
41 + .compatible = "panel-dsi",
42 + .data = &panel_dsi,
43 + }, {
44 /* sentinel */
45 }
46 };
47 MODULE_DEVICE_TABLE(of, dsi_of_match);
48
49 +
50 +/* Checks for DSI panel definition in device-tree, analog to panel_dpi */
51 +static int panel_dsi_dt_probe(struct device *dev,
52 + struct panel_desc_dsi *desc_dsi)
53 +{
54 + struct panel_desc *desc;
55 + struct display_timing *timing;
56 + const struct device_node *np;
57 + const char *dsi_color_format;
58 + const char *dsi_mode_flags;
59 + struct property *prop;
60 + int dsi_lanes, ret;
61 +
62 + np = dev->of_node;
63 +
64 + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL);
65 + if (!desc)
66 + return -ENOMEM;
67 +
68 + timing = devm_kzalloc(dev, sizeof(*timing), GFP_KERNEL);
69 + if (!timing)
70 + return -ENOMEM;
71 +
72 + ret = of_get_display_timing(np, "panel-timing", timing);
73 + if (ret < 0) {
74 + dev_err(dev, "%pOF: no panel-timing node found for \"panel-dsi\" binding\n",
75 + np);
76 + return ret;
77 + }
78 +
79 + desc->timings = timing;
80 + desc->num_timings = 1;
81 +
82 + of_property_read_u32(np, "width-mm", &desc->size.width);
83 + of_property_read_u32(np, "height-mm", &desc->size.height);
84 +
85 + dsi_lanes = drm_of_get_data_lanes_count_ep(np, 0, 0, 1, 4);
86 +
87 + if (dsi_lanes < 0) {
88 + dev_err(dev, "%pOF: no or too many data-lanes defined", np);
89 + return dsi_lanes;
90 + }
91 +
92 + desc_dsi->lanes = dsi_lanes;
93 +
94 + of_property_read_string(np, "dsi-color-format", &dsi_color_format);
95 + if (!strcmp(dsi_color_format, "RGB888")) {
96 + desc_dsi->format = MIPI_DSI_FMT_RGB888;
97 + desc->bpc = 8;
98 + } else if (!strcmp(dsi_color_format, "RGB565")) {
99 + desc_dsi->format = MIPI_DSI_FMT_RGB565;
100 + desc->bpc = 6;
101 + } else if (!strcmp(dsi_color_format, "RGB666")) {
102 + desc_dsi->format = MIPI_DSI_FMT_RGB666;
103 + desc->bpc = 6;
104 + } else if (!strcmp(dsi_color_format, "RGB666_PACKED")) {
105 + desc_dsi->format = MIPI_DSI_FMT_RGB666_PACKED;
106 + desc->bpc = 6;
107 + } else {
108 + dev_err(dev, "%pOF: no valid dsi-color-format defined", np);
109 + return -EINVAL;
110 + }
111 +
112 +
113 + of_property_for_each_string(np, "mode", prop, dsi_mode_flags) {
114 + if (!strcmp(dsi_mode_flags, "MODE_VIDEO"))
115 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO;
116 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_BURST"))
117 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_BURST;
118 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_SYNC_PULSE"))
119 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
120 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_AUTO_VERT"))
121 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_AUTO_VERT;
122 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_HSE"))
123 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_HSE;
124 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HFP"))
125 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HFP;
126 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HBP"))
127 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HBP;
128 + else if (!strcmp(dsi_mode_flags, "MODE_VIDEO_NO_HSA"))
129 + desc_dsi->flags |= MIPI_DSI_MODE_VIDEO_NO_HSA;
130 + else if (!strcmp(dsi_mode_flags, "MODE_VSYNC_FLUSH"))
131 + desc_dsi->flags |= MIPI_DSI_MODE_VSYNC_FLUSH;
132 + else if (!strcmp(dsi_mode_flags, "MODE_NO_EOT_PACKET"))
133 + desc_dsi->flags |= MIPI_DSI_MODE_NO_EOT_PACKET;
134 + else if (!strcmp(dsi_mode_flags, "CLOCK_NON_CONTINUOUS"))
135 + desc_dsi->flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS;
136 + else if (!strcmp(dsi_mode_flags, "MODE_LPM"))
137 + desc_dsi->flags |= MIPI_DSI_MODE_LPM;
138 + else if (!strcmp(dsi_mode_flags, "HS_PKT_END_ALIGNED"))
139 + desc_dsi->flags |= MIPI_DSI_HS_PKT_END_ALIGNED;
140 + }
141 +
142 + desc->connector_type = DRM_MODE_CONNECTOR_DSI;
143 + desc_dsi->desc = *desc;
144 +
145 + return 0;
146 +}
147 +
148 static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
149 {
150 const struct panel_desc_dsi *desc;
151 + struct panel_desc_dsi *dt_desc;
152 const struct of_device_id *id;
153 int err;
154
155 @@ -4698,7 +4806,20 @@ static int panel_simple_dsi_probe(struct
156 if (!id)
157 return -ENODEV;
158
159 - desc = id->data;
160 + if (id->data == &panel_dsi) {
161 + /* Handle the generic panel-dsi binding */
162 + dt_desc = devm_kzalloc(&dsi->dev, sizeof(*dt_desc), GFP_KERNEL);
163 + if (!dt_desc)
164 + return -ENOMEM;
165 +
166 + err = panel_dsi_dt_probe(&dsi->dev, dt_desc);
167 + if (err < 0)
168 + return err;
169 +
170 + desc = dt_desc;
171 + } else {
172 + desc = id->data;
173 + }
174
175 err = panel_simple_probe(&dsi->dev, &desc->desc);
176 if (err < 0)