Merge tag 'sound-5.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-microblaze.git] / drivers / gpu / drm / panel / panel-mantix-mlaf057we51.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Mantix MLAF057WE51 5.7" MIPI-DSI panel driver
4  *
5  * Copyright (C) Purism SPC 2020
6  */
7
8 #include <linux/backlight.h>
9 #include <linux/delay.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.h>
12 #include <linux/of_device.h>
13 #include <linux/regulator/consumer.h>
14
15 #include <video/mipi_display.h>
16
17 #include <drm/drm_mipi_dsi.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_panel.h>
20
21 #define DRV_NAME "panel-mantix-mlaf057we51"
22
23 /* Manufacturer specific Commands send via DSI */
24 #define MANTIX_CMD_OTP_STOP_RELOAD_MIPI 0x41
25 #define MANTIX_CMD_INT_CANCEL           0x4C
26 #define MANTIX_CMD_SPI_FINISH           0x90
27
28 struct mantix {
29         struct device *dev;
30         struct drm_panel panel;
31
32         struct gpio_desc *reset_gpio;
33         struct gpio_desc *tp_rstn_gpio;
34
35         struct regulator *avdd;
36         struct regulator *avee;
37         struct regulator *vddi;
38
39         const struct drm_display_mode *default_mode;
40 };
41
42 static inline struct mantix *panel_to_mantix(struct drm_panel *panel)
43 {
44         return container_of(panel, struct mantix, panel);
45 }
46
47 #define dsi_generic_write_seq(dsi, seq...) do {                         \
48                 static const u8 d[] = { seq };                          \
49                 int ret;                                                \
50                 ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d));    \
51                 if (ret < 0)                                            \
52                         return ret;                                     \
53         } while (0)
54
55 static int mantix_init_sequence(struct mantix *ctx)
56 {
57         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
58         struct device *dev = ctx->dev;
59
60         /*
61          * Init sequence was supplied by the panel vendor.
62          */
63         dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A);
64
65         dsi_generic_write_seq(dsi, MANTIX_CMD_INT_CANCEL, 0x03);
66         dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x03);
67         dsi_generic_write_seq(dsi, 0x80, 0xA9, 0x00);
68
69         dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x09);
70         dsi_generic_write_seq(dsi, 0x80, 0x64, 0x00, 0x64, 0x00, 0x00);
71         msleep(20);
72
73         dsi_generic_write_seq(dsi, MANTIX_CMD_SPI_FINISH, 0xA5);
74         dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x00, 0x2F);
75         msleep(20);
76
77         dev_dbg(dev, "Panel init sequence done\n");
78         return 0;
79 }
80
81 static int mantix_enable(struct drm_panel *panel)
82 {
83         struct mantix *ctx = panel_to_mantix(panel);
84         struct device *dev = ctx->dev;
85         struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
86         int ret;
87
88         ret = mantix_init_sequence(ctx);
89         if (ret < 0) {
90                 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
91                 return ret;
92         }
93
94         ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
95         if (ret < 0) {
96                 dev_err(dev, "Failed to exit sleep mode\n");
97                 return ret;
98         }
99         msleep(20);
100
101         ret = mipi_dsi_dcs_set_display_on(dsi);
102         if (ret)
103                 return ret;
104         usleep_range(10000, 12000);
105
106         ret = mipi_dsi_turn_on_peripheral(dsi);
107         if (ret < 0) {
108                 dev_err(dev, "Failed to turn on peripheral\n");
109                 return ret;
110         }
111
112         return 0;
113 }
114
115 static int mantix_disable(struct drm_panel *panel)
116 {
117         struct mantix *ctx = panel_to_mantix(panel);
118         struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
119         int ret;
120
121         ret = mipi_dsi_dcs_set_display_off(dsi);
122         if (ret < 0)
123                 dev_err(ctx->dev, "Failed to turn off the display: %d\n", ret);
124
125         ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
126         if (ret < 0)
127                 dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret);
128
129
130         return 0;
131 }
132
133 static int mantix_unprepare(struct drm_panel *panel)
134 {
135         struct mantix *ctx = panel_to_mantix(panel);
136
137         gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 1);
138         usleep_range(5000, 6000);
139         gpiod_set_value_cansleep(ctx->reset_gpio, 1);
140
141         regulator_disable(ctx->avee);
142         regulator_disable(ctx->avdd);
143         /* T11 */
144         usleep_range(5000, 6000);
145         regulator_disable(ctx->vddi);
146         /* T14 */
147         msleep(50);
148
149         return 0;
150 }
151
152 static int mantix_prepare(struct drm_panel *panel)
153 {
154         struct mantix *ctx = panel_to_mantix(panel);
155         int ret;
156
157         /* Focaltech FT8006P, section 7.3.1 and 7.3.4 */
158         dev_dbg(ctx->dev, "Resetting the panel\n");
159         ret = regulator_enable(ctx->vddi);
160         if (ret < 0) {
161                 dev_err(ctx->dev, "Failed to enable vddi supply: %d\n", ret);
162                 return ret;
163         }
164
165         /* T1 + T2 */
166         usleep_range(8000, 10000);
167
168         ret = regulator_enable(ctx->avdd);
169         if (ret < 0) {
170                 dev_err(ctx->dev, "Failed to enable avdd supply: %d\n", ret);
171                 return ret;
172         }
173
174         /* T2d */
175         usleep_range(3500, 4000);
176         ret = regulator_enable(ctx->avee);
177         if (ret < 0) {
178                 dev_err(ctx->dev, "Failed to enable avee supply: %d\n", ret);
179                 return ret;
180         }
181
182         /* T3 + T4 + time for voltage to become stable: */
183         usleep_range(6000, 7000);
184         gpiod_set_value_cansleep(ctx->reset_gpio, 0);
185         gpiod_set_value_cansleep(ctx->tp_rstn_gpio, 0);
186
187         /* T6 */
188         msleep(50);
189
190         return 0;
191 }
192
193 static const struct drm_display_mode default_mode_mantix = {
194         .hdisplay    = 720,
195         .hsync_start = 720 + 45,
196         .hsync_end   = 720 + 45 + 14,
197         .htotal      = 720 + 45 + 14 + 25,
198         .vdisplay    = 1440,
199         .vsync_start = 1440 + 130,
200         .vsync_end   = 1440 + 130 + 8,
201         .vtotal      = 1440 + 130 + 8 + 106,
202         .clock       = 85298,
203         .flags       = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
204         .width_mm    = 65,
205         .height_mm   = 130,
206 };
207
208 static const struct drm_display_mode default_mode_ys = {
209         .hdisplay    = 720,
210         .hsync_start = 720 + 45,
211         .hsync_end   = 720 + 45 + 14,
212         .htotal      = 720 + 45 + 14 + 25,
213         .vdisplay    = 1440,
214         .vsync_start = 1440 + 175,
215         .vsync_end   = 1440 + 175 + 8,
216         .vtotal      = 1440 + 175 + 8 + 50,
217         .clock       = 85298,
218         .flags       = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
219         .width_mm    = 65,
220         .height_mm   = 130,
221 };
222
223 static int mantix_get_modes(struct drm_panel *panel,
224                             struct drm_connector *connector)
225 {
226         struct mantix *ctx = panel_to_mantix(panel);
227         struct drm_display_mode *mode;
228
229         mode = drm_mode_duplicate(connector->dev, ctx->default_mode);
230         if (!mode) {
231                 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
232                         ctx->default_mode->hdisplay, ctx->default_mode->vdisplay,
233                         drm_mode_vrefresh(ctx->default_mode));
234                 return -ENOMEM;
235         }
236
237         drm_mode_set_name(mode);
238
239         mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
240         connector->display_info.width_mm = mode->width_mm;
241         connector->display_info.height_mm = mode->height_mm;
242         drm_mode_probed_add(connector, mode);
243
244         return 1;
245 }
246
247 static const struct drm_panel_funcs mantix_drm_funcs = {
248         .disable   = mantix_disable,
249         .unprepare = mantix_unprepare,
250         .prepare   = mantix_prepare,
251         .enable    = mantix_enable,
252         .get_modes = mantix_get_modes,
253 };
254
255 static int mantix_probe(struct mipi_dsi_device *dsi)
256 {
257         struct device *dev = &dsi->dev;
258         struct mantix *ctx;
259         int ret;
260
261         ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
262         if (!ctx)
263                 return -ENOMEM;
264         ctx->default_mode = of_device_get_match_data(dev);
265
266         ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
267         if (IS_ERR(ctx->reset_gpio)) {
268                 dev_err(dev, "cannot get reset gpio\n");
269                 return PTR_ERR(ctx->reset_gpio);
270         }
271
272         ctx->tp_rstn_gpio = devm_gpiod_get(dev, "mantix,tp-rstn", GPIOD_OUT_HIGH);
273         if (IS_ERR(ctx->tp_rstn_gpio)) {
274                 dev_err(dev, "cannot get tp-rstn gpio\n");
275                 return PTR_ERR(ctx->tp_rstn_gpio);
276         }
277
278         mipi_dsi_set_drvdata(dsi, ctx);
279         ctx->dev = dev;
280
281         dsi->lanes = 4;
282         dsi->format = MIPI_DSI_FMT_RGB888;
283         dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
284                 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
285
286         ctx->avdd = devm_regulator_get(dev, "avdd");
287         if (IS_ERR(ctx->avdd))
288                 return dev_err_probe(dev, PTR_ERR(ctx->avdd), "Failed to request avdd regulator\n");
289
290         ctx->avee = devm_regulator_get(dev, "avee");
291         if (IS_ERR(ctx->avee))
292                 return dev_err_probe(dev, PTR_ERR(ctx->avee), "Failed to request avee regulator\n");
293
294         ctx->vddi = devm_regulator_get(dev, "vddi");
295         if (IS_ERR(ctx->vddi))
296                 return dev_err_probe(dev, PTR_ERR(ctx->vddi), "Failed to request vddi regulator\n");
297
298         drm_panel_init(&ctx->panel, dev, &mantix_drm_funcs,
299                        DRM_MODE_CONNECTOR_DSI);
300
301         ret = drm_panel_of_backlight(&ctx->panel);
302         if (ret)
303                 return ret;
304
305         drm_panel_add(&ctx->panel);
306
307         ret = mipi_dsi_attach(dsi);
308         if (ret < 0) {
309                 dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret);
310                 drm_panel_remove(&ctx->panel);
311                 return ret;
312         }
313
314         dev_info(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
315                  ctx->default_mode->hdisplay, ctx->default_mode->vdisplay,
316                  drm_mode_vrefresh(ctx->default_mode),
317                  mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
318
319         return 0;
320 }
321
322 static void mantix_shutdown(struct mipi_dsi_device *dsi)
323 {
324         struct mantix *ctx = mipi_dsi_get_drvdata(dsi);
325
326         drm_panel_unprepare(&ctx->panel);
327         drm_panel_disable(&ctx->panel);
328 }
329
330 static int mantix_remove(struct mipi_dsi_device *dsi)
331 {
332         struct mantix *ctx = mipi_dsi_get_drvdata(dsi);
333
334         mantix_shutdown(dsi);
335
336         mipi_dsi_detach(dsi);
337         drm_panel_remove(&ctx->panel);
338
339         return 0;
340 }
341
342 static const struct of_device_id mantix_of_match[] = {
343         { .compatible = "mantix,mlaf057we51-x", .data = &default_mode_mantix },
344         { .compatible = "ys,ys57pss36bh5gq", .data = &default_mode_ys },
345         { /* sentinel */ }
346 };
347 MODULE_DEVICE_TABLE(of, mantix_of_match);
348
349 static struct mipi_dsi_driver mantix_driver = {
350         .probe  = mantix_probe,
351         .remove = mantix_remove,
352         .shutdown = mantix_shutdown,
353         .driver = {
354                 .name = DRV_NAME,
355                 .of_match_table = mantix_of_match,
356         },
357 };
358 module_mipi_dsi_driver(mantix_driver);
359
360 MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>");
361 MODULE_DESCRIPTION("DRM driver for Mantix MLAF057WE51-X MIPI DSI panel");
362 MODULE_LICENSE("GPL v2");