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