GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / gpu / drm / panel / panel-novatek-nt35950.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Novatek NT35950 DriverIC panels driver
4  *
5  * Copyright (c) 2021 AngeloGioacchino Del Regno
6  *                    <angelogioacchino.delregno@somainline.org>
7  */
8 #include <linux/delay.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/module.h>
11 #include <linux/of_device.h>
12 #include <linux/of_graph.h>
13 #include <linux/regulator/consumer.h>
14
15 #include <drm/drm_connector.h>
16 #include <drm/drm_crtc.h>
17 #include <drm/drm_mipi_dsi.h>
18 #include <drm/drm_modes.h>
19 #include <drm/drm_panel.h>
20
21 #define MCS_CMD_MAUCCTR                 0xf0 /* Manufacturer command enable */
22 #define MCS_PARAM_SCALER_FUNCTION       0x58 /* Scale-up function */
23 #define MCS_PARAM_SCALEUP_MODE          0xc9
24  #define MCS_SCALEUP_SIMPLE             0x0
25  #define MCS_SCALEUP_BILINEAR           BIT(0)
26  #define MCS_SCALEUP_DUPLICATE          (BIT(0) | BIT(4))
27
28 /* VESA Display Stream Compression param */
29 #define MCS_PARAM_VESA_DSC_ON           0x03
30
31 /* Data Compression mode */
32 #define MCS_PARAM_DATA_COMPRESSION      0x90
33  #define MCS_DATA_COMPRESSION_NONE      0x00
34  #define MCS_DATA_COMPRESSION_FBC       0x02
35  #define MCS_DATA_COMPRESSION_DSC       0x03
36
37 /* Display Output control */
38 #define MCS_PARAM_DISP_OUTPUT_CTRL      0xb4
39  #define MCS_DISP_OUT_SRAM_EN           BIT(0)
40  #define MCS_DISP_OUT_VIDEO_MODE        BIT(4)
41
42 /* VESA Display Stream Compression setting */
43 #define MCS_PARAM_VESA_DSC_SETTING      0xc0
44
45 /* SubPixel Rendering (SPR) */
46 #define MCS_PARAM_SPR_EN                0xe3
47 #define MCS_PARAM_SPR_MODE              0xef
48  #define MCS_SPR_MODE_YYG_RAINBOW_RGB   0x01
49
50 #define NT35950_VREG_MAX                4
51
52 struct nt35950 {
53         struct drm_panel panel;
54         struct drm_connector *connector;
55         struct mipi_dsi_device *dsi[2];
56         struct regulator_bulk_data vregs[NT35950_VREG_MAX];
57         struct gpio_desc *reset_gpio;
58         const struct nt35950_panel_desc *desc;
59
60         int cur_mode;
61         u8 last_page;
62         bool prepared;
63 };
64
65 struct nt35950_panel_mode {
66         const struct drm_display_mode mode;
67
68         bool enable_sram;
69         bool is_video_mode;
70         u8 scaler_on;
71         u8 scaler_mode;
72         u8 compression;
73         u8 spr_en;
74         u8 spr_mode;
75 };
76
77 struct nt35950_panel_desc {
78         const char *model_name;
79         const struct mipi_dsi_device_info dsi_info;
80         const struct nt35950_panel_mode *mode_data;
81
82         bool is_dual_dsi;
83         u8 num_lanes;
84         u8 num_modes;
85 };
86
87 static inline struct nt35950 *to_nt35950(struct drm_panel *panel)
88 {
89         return container_of(panel, struct nt35950, panel);
90 }
91
92 #define dsi_dcs_write_seq(dsi, seq...) do {                             \
93                 static const u8 d[] = { seq };                          \
94                 int ret;                                                \
95                 ret = mipi_dsi_dcs_write_buffer(dsi, d, ARRAY_SIZE(d)); \
96                 if (ret < 0)                                            \
97                         return ret;                                     \
98         } while (0)
99
100 static void nt35950_reset(struct nt35950 *nt)
101 {
102         gpiod_set_value_cansleep(nt->reset_gpio, 1);
103         usleep_range(12000, 13000);
104         gpiod_set_value_cansleep(nt->reset_gpio, 0);
105         usleep_range(300, 400);
106         gpiod_set_value_cansleep(nt->reset_gpio, 1);
107         usleep_range(12000, 13000);
108 }
109
110 /*
111  * nt35950_set_cmd2_page - Select manufacturer control (CMD2) page
112  * @nt:   Main driver structure
113  * @page: Page number (0-7)
114  *
115  * Return: Number of transferred bytes or negative number on error
116  */
117 static int nt35950_set_cmd2_page(struct nt35950 *nt, u8 page)
118 {
119         const u8 mauc_cmd2_page[] = { MCS_CMD_MAUCCTR, 0x55, 0xaa, 0x52,
120                                       0x08, page };
121         int ret;
122
123         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], mauc_cmd2_page,
124                                         ARRAY_SIZE(mauc_cmd2_page));
125         if (ret < 0)
126                 return ret;
127
128         nt->last_page = page;
129         return 0;
130 }
131
132 /*
133  * nt35950_set_data_compression - Set data compression mode
134  * @nt:        Main driver structure
135  * @comp_mode: Compression mode
136  *
137  * Return: Number of transferred bytes or negative number on error
138  */
139 static int nt35950_set_data_compression(struct nt35950 *nt, u8 comp_mode)
140 {
141         u8 cmd_data_compression[] = { MCS_PARAM_DATA_COMPRESSION, comp_mode };
142         u8 cmd_vesa_dsc_on[] = { MCS_PARAM_VESA_DSC_ON, !!comp_mode };
143         u8 cmd_vesa_dsc_setting[] = { MCS_PARAM_VESA_DSC_SETTING, 0x03 };
144         u8 last_page = nt->last_page;
145         int ret;
146
147         /* Set CMD2 Page 0 if we're not there yet */
148         if (last_page != 0) {
149                 ret = nt35950_set_cmd2_page(nt, 0);
150                 if (ret < 0)
151                         return ret;
152         }
153
154         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_data_compression,
155                                         ARRAY_SIZE(cmd_data_compression));
156         if (ret < 0)
157                 return ret;
158
159         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_vesa_dsc_on,
160                                         ARRAY_SIZE(cmd_vesa_dsc_on));
161         if (ret < 0)
162                 return ret;
163
164         /* Set the vesa dsc setting on Page 4 */
165         ret = nt35950_set_cmd2_page(nt, 4);
166         if (ret < 0)
167                 return ret;
168
169         /* Display Stream Compression setting, always 0x03 */
170         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_vesa_dsc_setting,
171                                         ARRAY_SIZE(cmd_vesa_dsc_setting));
172         if (ret < 0)
173                 return ret;
174
175         /* Get back to the previously set page */
176         return nt35950_set_cmd2_page(nt, last_page);
177 }
178
179 /*
180  * nt35950_set_scaler - Enable/disable resolution upscaling
181  * @nt:        Main driver structure
182  * @scale_up:  Scale up function control
183  *
184  * Return: Number of transferred bytes or negative number on error
185  */
186 static int nt35950_set_scaler(struct nt35950 *nt, u8 scale_up)
187 {
188         u8 cmd_scaler[] = { MCS_PARAM_SCALER_FUNCTION, scale_up };
189
190         return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_scaler,
191                                          ARRAY_SIZE(cmd_scaler));
192 }
193
194 /*
195  * nt35950_set_scale_mode - Resolution upscaling mode
196  * @nt:   Main driver structure
197  * @mode: Scaler mode (MCS_DATA_COMPRESSION_*)
198  *
199  * Return: Number of transferred bytes or negative number on error
200  */
201 static int nt35950_set_scale_mode(struct nt35950 *nt, u8 mode)
202 {
203         u8 cmd_scaler[] = { MCS_PARAM_SCALEUP_MODE, mode };
204
205         return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_scaler,
206                                          ARRAY_SIZE(cmd_scaler));
207 }
208
209 /*
210  * nt35950_inject_black_image - Display a completely black image
211  * @nt:   Main driver structure
212  *
213  * After IC setup, the attached panel may show random data
214  * due to driveric behavior changes (resolution, compression,
215  * scaling, etc). This function, called after parameters setup,
216  * makes the driver ic to output a completely black image to
217  * the display.
218  * It makes sense to push a black image before sending the sleep-out
219  * and display-on commands.
220  *
221  * Return: Number of transferred bytes or negative number on error
222  */
223 static int nt35950_inject_black_image(struct nt35950 *nt)
224 {
225         const u8 cmd0_black_img[] = { 0x6f, 0x01 };
226         const u8 cmd1_black_img[] = { 0xf3, 0x10 };
227         u8 cmd_test[] = { 0xff, 0xaa, 0x55, 0xa5, 0x80 };
228         int ret;
229
230         /* Enable test command */
231         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_test, ARRAY_SIZE(cmd_test));
232         if (ret < 0)
233                 return ret;
234
235         /* Send a black image */
236         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd0_black_img,
237                                         ARRAY_SIZE(cmd0_black_img));
238         if (ret < 0)
239                 return ret;
240         ret = mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd1_black_img,
241                                         ARRAY_SIZE(cmd1_black_img));
242         if (ret < 0)
243                 return ret;
244
245         /* Disable test command */
246         cmd_test[ARRAY_SIZE(cmd_test) - 1] = 0x00;
247         return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_test, ARRAY_SIZE(cmd_test));
248 }
249
250 /*
251  * nt35950_set_dispout - Set Display Output register parameters
252  * @nt:    Main driver structure
253  *
254  * Return: Number of transferred bytes or negative number on error
255  */
256 static int nt35950_set_dispout(struct nt35950 *nt)
257 {
258         u8 cmd_dispout[] = { MCS_PARAM_DISP_OUTPUT_CTRL, 0x00 };
259         const struct nt35950_panel_mode *mode_data = nt->desc->mode_data;
260
261         if (mode_data[nt->cur_mode].is_video_mode)
262                 cmd_dispout[1] |= MCS_DISP_OUT_VIDEO_MODE;
263         if (mode_data[nt->cur_mode].enable_sram)
264                 cmd_dispout[1] |= MCS_DISP_OUT_SRAM_EN;
265
266         return mipi_dsi_dcs_write_buffer(nt->dsi[0], cmd_dispout,
267                                          ARRAY_SIZE(cmd_dispout));
268 }
269
270 static int nt35950_get_current_mode(struct nt35950 *nt)
271 {
272         struct drm_connector *connector = nt->connector;
273         struct drm_crtc_state *crtc_state;
274         int i;
275
276         /* Return the default (first) mode if no info available yet */
277         if (!connector->state || !connector->state->crtc)
278                 return 0;
279
280         crtc_state = connector->state->crtc->state;
281
282         for (i = 0; i < nt->desc->num_modes; i++) {
283                 if (drm_mode_match(&crtc_state->mode,
284                                    &nt->desc->mode_data[i].mode,
285                                    DRM_MODE_MATCH_TIMINGS | DRM_MODE_MATCH_CLOCK))
286                         return i;
287         }
288
289         return 0;
290 }
291
292 static int nt35950_on(struct nt35950 *nt)
293 {
294         const struct nt35950_panel_mode *mode_data = nt->desc->mode_data;
295         struct mipi_dsi_device *dsi = nt->dsi[0];
296         struct device *dev = &dsi->dev;
297         int ret;
298
299         nt->cur_mode = nt35950_get_current_mode(nt);
300         nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
301         nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
302
303         ret = nt35950_set_cmd2_page(nt, 0);
304         if (ret < 0)
305                 return ret;
306
307         ret = nt35950_set_data_compression(nt, mode_data[nt->cur_mode].compression);
308         if (ret < 0)
309                 return ret;
310
311         ret = nt35950_set_scale_mode(nt, mode_data[nt->cur_mode].scaler_mode);
312         if (ret < 0)
313                 return ret;
314
315         ret = nt35950_set_scaler(nt, mode_data[nt->cur_mode].scaler_on);
316         if (ret < 0)
317                 return ret;
318
319         ret = nt35950_set_dispout(nt);
320         if (ret < 0)
321                 return ret;
322
323         ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
324         if (ret < 0) {
325                 dev_err(dev, "Failed to set tear on: %d\n", ret);
326                 return ret;
327         }
328
329         ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0);
330         if (ret < 0) {
331                 dev_err(dev, "Failed to set tear scanline: %d\n", ret);
332                 return ret;
333         }
334
335         /* CMD2 Page 1 */
336         ret = nt35950_set_cmd2_page(nt, 1);
337         if (ret < 0)
338                 return ret;
339
340         /* Unknown command */
341         dsi_dcs_write_seq(dsi, 0xd4, 0x88, 0x88);
342
343         /* CMD2 Page 7 */
344         ret = nt35950_set_cmd2_page(nt, 7);
345         if (ret < 0)
346                 return ret;
347
348         /* Enable SubPixel Rendering */
349         dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_EN, 0x01);
350
351         /* SPR Mode: YYG Rainbow-RGB */
352         dsi_dcs_write_seq(dsi, MCS_PARAM_SPR_MODE, MCS_SPR_MODE_YYG_RAINBOW_RGB);
353
354         /* CMD3 */
355         ret = nt35950_inject_black_image(nt);
356         if (ret < 0)
357                 return ret;
358
359         ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
360         if (ret < 0)
361                 return ret;
362         msleep(120);
363
364         ret = mipi_dsi_dcs_set_display_on(dsi);
365         if (ret < 0)
366                 return ret;
367         msleep(120);
368
369         nt->dsi[0]->mode_flags &= ~MIPI_DSI_MODE_LPM;
370         nt->dsi[1]->mode_flags &= ~MIPI_DSI_MODE_LPM;
371
372         return 0;
373 }
374
375 static int nt35950_off(struct nt35950 *nt)
376 {
377         struct device *dev = &nt->dsi[0]->dev;
378         int ret;
379
380         ret = mipi_dsi_dcs_set_display_off(nt->dsi[0]);
381         if (ret < 0) {
382                 dev_err(dev, "Failed to set display off: %d\n", ret);
383                 goto set_lpm;
384         }
385         usleep_range(10000, 11000);
386
387         ret = mipi_dsi_dcs_enter_sleep_mode(nt->dsi[0]);
388         if (ret < 0) {
389                 dev_err(dev, "Failed to enter sleep mode: %d\n", ret);
390                 goto set_lpm;
391         }
392         msleep(150);
393
394 set_lpm:
395         nt->dsi[0]->mode_flags |= MIPI_DSI_MODE_LPM;
396         nt->dsi[1]->mode_flags |= MIPI_DSI_MODE_LPM;
397
398         return 0;
399 }
400
401 static int nt35950_sharp_init_vregs(struct nt35950 *nt, struct device *dev)
402 {
403         int ret;
404
405         nt->vregs[0].supply = "vddio";
406         nt->vregs[1].supply = "avdd";
407         nt->vregs[2].supply = "avee";
408         nt->vregs[3].supply = "dvdd";
409         ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(nt->vregs),
410                                       nt->vregs);
411         if (ret < 0)
412                 return ret;
413
414         ret = regulator_is_supported_voltage(nt->vregs[0].consumer,
415                                              1750000, 1950000);
416         if (!ret)
417                 return -EINVAL;
418         ret = regulator_is_supported_voltage(nt->vregs[1].consumer,
419                                              5200000, 5900000);
420         if (!ret)
421                 return -EINVAL;
422         /* AVEE is negative: -5.90V to -5.20V */
423         ret = regulator_is_supported_voltage(nt->vregs[2].consumer,
424                                              5200000, 5900000);
425         if (!ret)
426                 return -EINVAL;
427
428         ret = regulator_is_supported_voltage(nt->vregs[3].consumer,
429                                              1300000, 1400000);
430         if (!ret)
431                 return -EINVAL;
432
433         return 0;
434 }
435
436 static int nt35950_prepare(struct drm_panel *panel)
437 {
438         struct nt35950 *nt = to_nt35950(panel);
439         struct device *dev = &nt->dsi[0]->dev;
440         int ret;
441
442         if (nt->prepared)
443                 return 0;
444
445         ret = regulator_enable(nt->vregs[0].consumer);
446         if (ret)
447                 return ret;
448         usleep_range(2000, 5000);
449
450         ret = regulator_enable(nt->vregs[3].consumer);
451         if (ret)
452                 goto end;
453         usleep_range(15000, 18000);
454
455         ret = regulator_enable(nt->vregs[1].consumer);
456         if (ret)
457                 goto end;
458
459         ret = regulator_enable(nt->vregs[2].consumer);
460         if (ret)
461                 goto end;
462         usleep_range(12000, 13000);
463
464         nt35950_reset(nt);
465
466         ret = nt35950_on(nt);
467         if (ret < 0) {
468                 dev_err(dev, "Failed to initialize panel: %d\n", ret);
469                 goto end;
470         }
471         nt->prepared = true;
472
473 end:
474         if (ret < 0) {
475                 regulator_bulk_disable(ARRAY_SIZE(nt->vregs), nt->vregs);
476                 return ret;
477         }
478
479         return 0;
480 }
481
482 static int nt35950_unprepare(struct drm_panel *panel)
483 {
484         struct nt35950 *nt = to_nt35950(panel);
485         struct device *dev = &nt->dsi[0]->dev;
486         int ret;
487
488         if (!nt->prepared)
489                 return 0;
490
491         ret = nt35950_off(nt);
492         if (ret < 0)
493                 dev_err(dev, "Failed to deinitialize panel: %d\n", ret);
494
495         gpiod_set_value_cansleep(nt->reset_gpio, 0);
496         regulator_bulk_disable(ARRAY_SIZE(nt->vregs), nt->vregs);
497
498         nt->prepared = false;
499         return 0;
500 }
501
502 static int nt35950_get_modes(struct drm_panel *panel,
503                              struct drm_connector *connector)
504 {
505         struct nt35950 *nt = to_nt35950(panel);
506         int i;
507
508         for (i = 0; i < nt->desc->num_modes; i++) {
509                 struct drm_display_mode *mode;
510
511                 mode = drm_mode_duplicate(connector->dev,
512                                           &nt->desc->mode_data[i].mode);
513                 if (!mode)
514                         return -ENOMEM;
515
516                 drm_mode_set_name(mode);
517
518                 mode->type |= DRM_MODE_TYPE_DRIVER;
519                 if (nt->desc->num_modes == 1)
520                         mode->type |= DRM_MODE_TYPE_PREFERRED;
521
522                 drm_mode_probed_add(connector, mode);
523         }
524
525         connector->display_info.bpc = 8;
526         connector->display_info.height_mm = nt->desc->mode_data[0].mode.height_mm;
527         connector->display_info.width_mm = nt->desc->mode_data[0].mode.width_mm;
528         nt->connector = connector;
529
530         return nt->desc->num_modes;
531 }
532
533 static const struct drm_panel_funcs nt35950_panel_funcs = {
534         .prepare = nt35950_prepare,
535         .unprepare = nt35950_unprepare,
536         .get_modes = nt35950_get_modes,
537 };
538
539 static int nt35950_probe(struct mipi_dsi_device *dsi)
540 {
541         struct device *dev = &dsi->dev;
542         struct device_node *dsi_r;
543         struct mipi_dsi_host *dsi_r_host;
544         struct nt35950 *nt;
545         const struct mipi_dsi_device_info *info;
546         int i, num_dsis = 1, ret;
547
548         nt = devm_kzalloc(dev, sizeof(*nt), GFP_KERNEL);
549         if (!nt)
550                 return -ENOMEM;
551
552         ret = nt35950_sharp_init_vregs(nt, dev);
553         if (ret)
554                 return dev_err_probe(dev, ret, "Regulator init failure.\n");
555
556         nt->desc = of_device_get_match_data(dev);
557         if (!nt->desc)
558                 return -ENODEV;
559
560         nt->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
561         if (IS_ERR(nt->reset_gpio)) {
562                 return dev_err_probe(dev, PTR_ERR(nt->reset_gpio),
563                                      "Failed to get reset gpio\n");
564         }
565
566         /* If the panel is connected on two DSIs then DSI0 left, DSI1 right */
567         if (nt->desc->is_dual_dsi) {
568                 info = &nt->desc->dsi_info;
569                 dsi_r = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
570                 if (!dsi_r) {
571                         dev_err(dev, "Cannot get secondary DSI node.\n");
572                         return -ENODEV;
573                 }
574                 dsi_r_host = of_find_mipi_dsi_host_by_node(dsi_r);
575                 of_node_put(dsi_r);
576                 if (!dsi_r_host) {
577                         dev_err(dev, "Cannot get secondary DSI host\n");
578                         return -EPROBE_DEFER;
579                 }
580
581                 nt->dsi[1] = mipi_dsi_device_register_full(dsi_r_host, info);
582                 if (!nt->dsi[1]) {
583                         dev_err(dev, "Cannot get secondary DSI node\n");
584                         return -ENODEV;
585                 }
586                 num_dsis++;
587         }
588
589         nt->dsi[0] = dsi;
590         mipi_dsi_set_drvdata(dsi, nt);
591
592         drm_panel_init(&nt->panel, dev, &nt35950_panel_funcs,
593                        DRM_MODE_CONNECTOR_DSI);
594
595         ret = drm_panel_of_backlight(&nt->panel);
596         if (ret)
597                 return dev_err_probe(dev, ret, "Failed to get backlight\n");
598
599         drm_panel_add(&nt->panel);
600
601         for (i = 0; i < num_dsis; i++) {
602                 nt->dsi[i]->lanes = nt->desc->num_lanes;
603                 nt->dsi[i]->format = MIPI_DSI_FMT_RGB888;
604
605                 nt->dsi[i]->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS |
606                                          MIPI_DSI_MODE_LPM;
607
608                 if (nt->desc->mode_data[0].is_video_mode)
609                         nt->dsi[i]->mode_flags |= MIPI_DSI_MODE_VIDEO;
610
611                 ret = mipi_dsi_attach(nt->dsi[i]);
612                 if (ret < 0) {
613                         return dev_err_probe(dev, ret,
614                                              "Cannot attach to DSI%d host.\n", i);
615                 }
616         }
617
618         /* Make sure to set RESX LOW before starting the power-on sequence */
619         gpiod_set_value_cansleep(nt->reset_gpio, 0);
620         return 0;
621 }
622
623 static int nt35950_remove(struct mipi_dsi_device *dsi)
624 {
625         struct nt35950 *nt = mipi_dsi_get_drvdata(dsi);
626         int ret;
627
628         ret = mipi_dsi_detach(nt->dsi[0]);
629         if (ret < 0)
630                 dev_err(&dsi->dev,
631                         "Failed to detach from DSI0 host: %d\n", ret);
632
633         if (nt->dsi[1]) {
634                 ret = mipi_dsi_detach(nt->dsi[1]);
635                 if (ret < 0)
636                         dev_err(&dsi->dev,
637                                 "Failed to detach from DSI1 host: %d\n", ret);
638                 mipi_dsi_device_unregister(nt->dsi[1]);
639         }
640
641         drm_panel_remove(&nt->panel);
642
643         return 0;
644 }
645
646 static const struct nt35950_panel_mode sharp_ls055d1sx04_modes[] = {
647         {
648                 /* 1920x1080 60Hz no compression */
649                 .mode = {
650                         .clock = 214537,
651                         .hdisplay = 1080,
652                         .hsync_start = 1080 + 400,
653                         .hsync_end = 1080 + 400 + 40,
654                         .htotal = 1080 + 400 + 40 + 300,
655                         .vdisplay = 1920,
656                         .vsync_start = 1920 + 12,
657                         .vsync_end = 1920 + 12 + 2,
658                         .vtotal = 1920 + 12 + 2 + 10,
659                         .width_mm = 68,
660                         .height_mm = 121,
661                 },
662                 .compression = MCS_DATA_COMPRESSION_NONE,
663                 .enable_sram = true,
664                 .is_video_mode = false,
665                 .scaler_on = 1,
666                 .scaler_mode = MCS_SCALEUP_DUPLICATE,
667         },
668         /* TODO: Add 2160x3840 60Hz when DSC is supported */
669 };
670
671 static const struct nt35950_panel_desc sharp_ls055d1sx04 = {
672         .model_name = "Sharp LS055D1SX04",
673         .dsi_info = {
674                 .type = "LS055D1SX04",
675                 .channel = 0,
676                 .node = NULL,
677         },
678         .mode_data = sharp_ls055d1sx04_modes,
679         .num_modes = ARRAY_SIZE(sharp_ls055d1sx04_modes),
680         .is_dual_dsi = true,
681         .num_lanes = 4,
682 };
683
684 static const struct of_device_id nt35950_of_match[] = {
685         { .compatible = "sharp,ls055d1sx04", .data = &sharp_ls055d1sx04 },
686         {  }
687 };
688 MODULE_DEVICE_TABLE(of, nt35950_of_match);
689
690 static struct mipi_dsi_driver nt35950_driver = {
691         .probe = nt35950_probe,
692         .remove = nt35950_remove,
693         .driver = {
694                 .name = "panel-novatek-nt35950",
695                 .of_match_table = nt35950_of_match,
696         },
697 };
698 module_mipi_dsi_driver(nt35950_driver);
699
700 MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>");
701 MODULE_DESCRIPTION("Novatek NT35950 DriverIC panels driver");
702 MODULE_LICENSE("GPL v2");