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