blob: 44756853aa0eb0ad28301ff56c1dabf39ed31d82 [file] [log] [blame]
Thierry Reding280921d2013-08-30 15:10:14 +02001/*
2 * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/backlight.h>
Alexandre Courbotcfdf0542014-03-01 14:00:58 +090025#include <linux/gpio/consumer.h>
Thierry Reding280921d2013-08-30 15:10:14 +020026#include <linux/module.h>
Thierry Reding280921d2013-08-30 15:10:14 +020027#include <linux/of_platform.h>
28#include <linux/platform_device.h>
29#include <linux/regulator/consumer.h>
30
31#include <drm/drmP.h>
32#include <drm/drm_crtc.h>
Thierry Reding210fcd92013-11-22 19:27:11 +010033#include <drm/drm_mipi_dsi.h>
Thierry Reding280921d2013-08-30 15:10:14 +020034#include <drm/drm_panel.h>
35
Philipp Zabela5d3e622014-12-11 18:32:45 +010036#include <video/display_timing.h>
37#include <video/videomode.h>
38
Thierry Reding280921d2013-08-30 15:10:14 +020039struct panel_desc {
40 const struct drm_display_mode *modes;
41 unsigned int num_modes;
Philipp Zabela5d3e622014-12-11 18:32:45 +010042 const struct display_timing *timings;
43 unsigned int num_timings;
Thierry Reding280921d2013-08-30 15:10:14 +020044
Stéphane Marchesin0208d512014-06-19 18:18:28 -070045 unsigned int bpc;
46
Ulrich Ölmann85533e32015-12-04 12:31:28 +010047 /**
48 * @width: width (in millimeters) of the panel's active display area
49 * @height: height (in millimeters) of the panel's active display area
50 */
Thierry Reding280921d2013-08-30 15:10:14 +020051 struct {
52 unsigned int width;
53 unsigned int height;
54 } size;
Ajay Kumarf673c372014-07-31 23:12:11 +053055
56 /**
57 * @prepare: the time (in milliseconds) that it takes for the panel to
58 * become ready and start receiving video data
59 * @enable: the time (in milliseconds) that it takes for the panel to
60 * display the first valid frame after starting to receive
61 * video data
62 * @disable: the time (in milliseconds) that it takes for the panel to
63 * turn the display off (no content is visible)
64 * @unprepare: the time (in milliseconds) that it takes for the panel
65 * to power itself down completely
66 */
67 struct {
68 unsigned int prepare;
69 unsigned int enable;
70 unsigned int disable;
71 unsigned int unprepare;
72 } delay;
Boris Brezillon795f7ab2014-07-22 13:33:59 +020073
74 u32 bus_format;
Stefan Agnerf0aa0832016-02-08 11:38:14 -080075 u32 bus_flags;
Thierry Reding280921d2013-08-30 15:10:14 +020076};
77
Thierry Reding280921d2013-08-30 15:10:14 +020078struct panel_simple {
79 struct drm_panel base;
Ajay Kumar613a6332014-07-31 23:12:10 +053080 bool prepared;
Thierry Reding280921d2013-08-30 15:10:14 +020081 bool enabled;
82
83 const struct panel_desc *desc;
84
85 struct backlight_device *backlight;
86 struct regulator *supply;
87 struct i2c_adapter *ddc;
88
Alexandre Courbotcfdf0542014-03-01 14:00:58 +090089 struct gpio_desc *enable_gpio;
Thierry Reding280921d2013-08-30 15:10:14 +020090};
91
92static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
93{
94 return container_of(panel, struct panel_simple, base);
95}
96
97static int panel_simple_get_fixed_modes(struct panel_simple *panel)
98{
99 struct drm_connector *connector = panel->base.connector;
100 struct drm_device *drm = panel->base.drm;
101 struct drm_display_mode *mode;
102 unsigned int i, num = 0;
103
104 if (!panel->desc)
105 return 0;
106
Philipp Zabela5d3e622014-12-11 18:32:45 +0100107 for (i = 0; i < panel->desc->num_timings; i++) {
108 const struct display_timing *dt = &panel->desc->timings[i];
109 struct videomode vm;
110
111 videomode_from_timing(dt, &vm);
112 mode = drm_mode_create(drm);
113 if (!mode) {
114 dev_err(drm->dev, "failed to add mode %ux%u\n",
115 dt->hactive.typ, dt->vactive.typ);
116 continue;
117 }
118
119 drm_display_mode_from_videomode(&vm, mode);
Boris Brezilloncda55372016-04-15 18:23:33 +0200120
121 mode->type |= DRM_MODE_TYPE_DRIVER;
122
Chen-Yu Tsai230c5b42016-10-24 21:21:15 +0800123 if (panel->desc->num_timings == 1)
Boris Brezilloncda55372016-04-15 18:23:33 +0200124 mode->type |= DRM_MODE_TYPE_PREFERRED;
125
Philipp Zabela5d3e622014-12-11 18:32:45 +0100126 drm_mode_probed_add(connector, mode);
127 num++;
128 }
129
Thierry Reding280921d2013-08-30 15:10:14 +0200130 for (i = 0; i < panel->desc->num_modes; i++) {
131 const struct drm_display_mode *m = &panel->desc->modes[i];
132
133 mode = drm_mode_duplicate(drm, m);
134 if (!mode) {
135 dev_err(drm->dev, "failed to add mode %ux%u@%u\n",
136 m->hdisplay, m->vdisplay, m->vrefresh);
137 continue;
138 }
139
Boris Brezilloncda55372016-04-15 18:23:33 +0200140 mode->type |= DRM_MODE_TYPE_DRIVER;
141
142 if (panel->desc->num_modes == 1)
143 mode->type |= DRM_MODE_TYPE_PREFERRED;
144
Thierry Reding280921d2013-08-30 15:10:14 +0200145 drm_mode_set_name(mode);
146
147 drm_mode_probed_add(connector, mode);
148 num++;
149 }
150
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700151 connector->display_info.bpc = panel->desc->bpc;
Thierry Reding280921d2013-08-30 15:10:14 +0200152 connector->display_info.width_mm = panel->desc->size.width;
153 connector->display_info.height_mm = panel->desc->size.height;
Boris Brezillon795f7ab2014-07-22 13:33:59 +0200154 if (panel->desc->bus_format)
155 drm_display_info_set_bus_formats(&connector->display_info,
156 &panel->desc->bus_format, 1);
Stefan Agnerf0aa0832016-02-08 11:38:14 -0800157 connector->display_info.bus_flags = panel->desc->bus_flags;
Thierry Reding280921d2013-08-30 15:10:14 +0200158
159 return num;
160}
161
162static int panel_simple_disable(struct drm_panel *panel)
163{
164 struct panel_simple *p = to_panel_simple(panel);
165
166 if (!p->enabled)
167 return 0;
168
169 if (p->backlight) {
170 p->backlight->props.power = FB_BLANK_POWERDOWN;
Thierry Redinge4aa3422016-06-17 19:11:53 +0200171 p->backlight->props.state |= BL_CORE_FBBLANK;
Thierry Reding280921d2013-08-30 15:10:14 +0200172 backlight_update_status(p->backlight);
173 }
174
Ajay Kumarf673c372014-07-31 23:12:11 +0530175 if (p->desc->delay.disable)
176 msleep(p->desc->delay.disable);
177
Thierry Reding280921d2013-08-30 15:10:14 +0200178 p->enabled = false;
179
180 return 0;
181}
182
Ajay Kumarc0e1d172014-07-31 23:12:04 +0530183static int panel_simple_unprepare(struct drm_panel *panel)
184{
Ajay Kumar613a6332014-07-31 23:12:10 +0530185 struct panel_simple *p = to_panel_simple(panel);
186
187 if (!p->prepared)
188 return 0;
189
190 if (p->enable_gpio)
191 gpiod_set_value_cansleep(p->enable_gpio, 0);
192
193 regulator_disable(p->supply);
194
Ajay Kumarf673c372014-07-31 23:12:11 +0530195 if (p->desc->delay.unprepare)
196 msleep(p->desc->delay.unprepare);
197
Ajay Kumar613a6332014-07-31 23:12:10 +0530198 p->prepared = false;
199
Ajay Kumarc0e1d172014-07-31 23:12:04 +0530200 return 0;
201}
202
203static int panel_simple_prepare(struct drm_panel *panel)
204{
Thierry Reding280921d2013-08-30 15:10:14 +0200205 struct panel_simple *p = to_panel_simple(panel);
206 int err;
207
Ajay Kumar613a6332014-07-31 23:12:10 +0530208 if (p->prepared)
Thierry Reding280921d2013-08-30 15:10:14 +0200209 return 0;
210
211 err = regulator_enable(p->supply);
212 if (err < 0) {
213 dev_err(panel->dev, "failed to enable supply: %d\n", err);
214 return err;
215 }
216
Alexandre Courbotcfdf0542014-03-01 14:00:58 +0900217 if (p->enable_gpio)
Thierry Reding15c1a912014-03-14 12:03:47 +0100218 gpiod_set_value_cansleep(p->enable_gpio, 1);
Thierry Reding280921d2013-08-30 15:10:14 +0200219
Ajay Kumarf673c372014-07-31 23:12:11 +0530220 if (p->desc->delay.prepare)
221 msleep(p->desc->delay.prepare);
222
Ajay Kumar613a6332014-07-31 23:12:10 +0530223 p->prepared = true;
224
225 return 0;
226}
227
228static int panel_simple_enable(struct drm_panel *panel)
229{
230 struct panel_simple *p = to_panel_simple(panel);
231
232 if (p->enabled)
233 return 0;
234
Ajay Kumarf673c372014-07-31 23:12:11 +0530235 if (p->desc->delay.enable)
236 msleep(p->desc->delay.enable);
237
Thierry Reding280921d2013-08-30 15:10:14 +0200238 if (p->backlight) {
Thierry Redinge4aa3422016-06-17 19:11:53 +0200239 p->backlight->props.state &= ~BL_CORE_FBBLANK;
Thierry Reding280921d2013-08-30 15:10:14 +0200240 p->backlight->props.power = FB_BLANK_UNBLANK;
241 backlight_update_status(p->backlight);
242 }
243
244 p->enabled = true;
245
246 return 0;
247}
248
249static int panel_simple_get_modes(struct drm_panel *panel)
250{
251 struct panel_simple *p = to_panel_simple(panel);
252 int num = 0;
253
254 /* probe EDID if a DDC bus is available */
255 if (p->ddc) {
256 struct edid *edid = drm_get_edid(panel->connector, p->ddc);
Stephen Warren70bf6872014-01-09 11:37:34 -0700257 drm_mode_connector_update_edid_property(panel->connector, edid);
Thierry Reding280921d2013-08-30 15:10:14 +0200258 if (edid) {
259 num += drm_add_edid_modes(panel->connector, edid);
260 kfree(edid);
261 }
262 }
263
264 /* add hard-coded panel modes */
265 num += panel_simple_get_fixed_modes(p);
266
267 return num;
268}
269
Philipp Zabela5d3e622014-12-11 18:32:45 +0100270static int panel_simple_get_timings(struct drm_panel *panel,
271 unsigned int num_timings,
272 struct display_timing *timings)
273{
274 struct panel_simple *p = to_panel_simple(panel);
275 unsigned int i;
276
277 if (p->desc->num_timings < num_timings)
278 num_timings = p->desc->num_timings;
279
280 if (timings)
281 for (i = 0; i < num_timings; i++)
282 timings[i] = p->desc->timings[i];
283
284 return p->desc->num_timings;
285}
286
Thierry Reding280921d2013-08-30 15:10:14 +0200287static const struct drm_panel_funcs panel_simple_funcs = {
288 .disable = panel_simple_disable,
Ajay Kumarc0e1d172014-07-31 23:12:04 +0530289 .unprepare = panel_simple_unprepare,
290 .prepare = panel_simple_prepare,
Thierry Reding280921d2013-08-30 15:10:14 +0200291 .enable = panel_simple_enable,
292 .get_modes = panel_simple_get_modes,
Philipp Zabela5d3e622014-12-11 18:32:45 +0100293 .get_timings = panel_simple_get_timings,
Thierry Reding280921d2013-08-30 15:10:14 +0200294};
295
296static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
297{
298 struct device_node *backlight, *ddc;
299 struct panel_simple *panel;
Thierry Reding280921d2013-08-30 15:10:14 +0200300 int err;
301
302 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
303 if (!panel)
304 return -ENOMEM;
305
306 panel->enabled = false;
Ajay Kumar613a6332014-07-31 23:12:10 +0530307 panel->prepared = false;
Thierry Reding280921d2013-08-30 15:10:14 +0200308 panel->desc = desc;
309
310 panel->supply = devm_regulator_get(dev, "power");
311 if (IS_ERR(panel->supply))
312 return PTR_ERR(panel->supply);
313
Alexandre Courbota61400d2014-10-23 17:16:58 +0900314 panel->enable_gpio = devm_gpiod_get_optional(dev, "enable",
315 GPIOD_OUT_LOW);
Alexandre Courbotcfdf0542014-03-01 14:00:58 +0900316 if (IS_ERR(panel->enable_gpio)) {
317 err = PTR_ERR(panel->enable_gpio);
Fabio Estevamb8e93802017-06-30 18:14:46 -0300318 if (err != -EPROBE_DEFER)
319 dev_err(dev, "failed to request GPIO: %d\n", err);
Alexandre Courbot9746c612014-07-25 23:47:25 +0900320 return err;
321 }
Thierry Reding280921d2013-08-30 15:10:14 +0200322
Thierry Reding280921d2013-08-30 15:10:14 +0200323 backlight = of_parse_phandle(dev->of_node, "backlight", 0);
324 if (backlight) {
325 panel->backlight = of_find_backlight_by_node(backlight);
326 of_node_put(backlight);
327
Alexandre Courbotcfdf0542014-03-01 14:00:58 +0900328 if (!panel->backlight)
329 return -EPROBE_DEFER;
Thierry Reding280921d2013-08-30 15:10:14 +0200330 }
331
332 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
333 if (ddc) {
334 panel->ddc = of_find_i2c_adapter_by_node(ddc);
335 of_node_put(ddc);
336
337 if (!panel->ddc) {
338 err = -EPROBE_DEFER;
339 goto free_backlight;
340 }
341 }
342
343 drm_panel_init(&panel->base);
344 panel->base.dev = dev;
345 panel->base.funcs = &panel_simple_funcs;
346
347 err = drm_panel_add(&panel->base);
348 if (err < 0)
349 goto free_ddc;
350
351 dev_set_drvdata(dev, panel);
352
353 return 0;
354
355free_ddc:
356 if (panel->ddc)
357 put_device(&panel->ddc->dev);
358free_backlight:
359 if (panel->backlight)
360 put_device(&panel->backlight->dev);
Thierry Reding280921d2013-08-30 15:10:14 +0200361
362 return err;
363}
364
365static int panel_simple_remove(struct device *dev)
366{
367 struct panel_simple *panel = dev_get_drvdata(dev);
368
369 drm_panel_detach(&panel->base);
370 drm_panel_remove(&panel->base);
371
372 panel_simple_disable(&panel->base);
Jonathan Liuf3621a82017-08-07 21:55:45 +1000373 panel_simple_unprepare(&panel->base);
Thierry Reding280921d2013-08-30 15:10:14 +0200374
375 if (panel->ddc)
376 put_device(&panel->ddc->dev);
377
378 if (panel->backlight)
379 put_device(&panel->backlight->dev);
380
Thierry Reding280921d2013-08-30 15:10:14 +0200381 return 0;
382}
383
Thierry Redingd02fd932014-04-29 17:21:21 +0200384static void panel_simple_shutdown(struct device *dev)
385{
386 struct panel_simple *panel = dev_get_drvdata(dev);
387
388 panel_simple_disable(&panel->base);
Jonathan Liuf3621a82017-08-07 21:55:45 +1000389 panel_simple_unprepare(&panel->base);
Thierry Redingd02fd932014-04-29 17:21:21 +0200390}
391
Yannick Fertre966fea72017-03-28 11:44:49 +0200392static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = {
393 .clock = 9000,
394 .hdisplay = 480,
395 .hsync_start = 480 + 2,
396 .hsync_end = 480 + 2 + 41,
397 .htotal = 480 + 2 + 41 + 2,
398 .vdisplay = 272,
399 .vsync_start = 272 + 2,
400 .vsync_end = 272 + 2 + 10,
401 .vtotal = 272 + 2 + 10 + 2,
402 .vrefresh = 60,
403 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
404};
405
406static const struct panel_desc ampire_am_480272h3tmqw_t01h = {
407 .modes = &ampire_am_480272h3tmqw_t01h_mode,
408 .num_modes = 1,
409 .bpc = 8,
410 .size = {
411 .width = 105,
412 .height = 67,
413 },
414 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
415};
416
Philipp Zabel1c550fa12015-02-11 18:50:09 +0100417static const struct drm_display_mode ampire_am800480r3tmqwa1h_mode = {
418 .clock = 33333,
419 .hdisplay = 800,
420 .hsync_start = 800 + 0,
421 .hsync_end = 800 + 0 + 255,
422 .htotal = 800 + 0 + 255 + 0,
423 .vdisplay = 480,
424 .vsync_start = 480 + 2,
425 .vsync_end = 480 + 2 + 45,
426 .vtotal = 480 + 2 + 45 + 0,
427 .vrefresh = 60,
428 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
429};
430
431static const struct panel_desc ampire_am800480r3tmqwa1h = {
432 .modes = &ampire_am800480r3tmqwa1h_mode,
433 .num_modes = 1,
434 .bpc = 6,
435 .size = {
436 .width = 152,
437 .height = 91,
438 },
439 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
440};
441
Thierry Reding280921d2013-08-30 15:10:14 +0200442static const struct drm_display_mode auo_b101aw03_mode = {
443 .clock = 51450,
444 .hdisplay = 1024,
445 .hsync_start = 1024 + 156,
446 .hsync_end = 1024 + 156 + 8,
447 .htotal = 1024 + 156 + 8 + 156,
448 .vdisplay = 600,
449 .vsync_start = 600 + 16,
450 .vsync_end = 600 + 16 + 6,
451 .vtotal = 600 + 16 + 6 + 16,
452 .vrefresh = 60,
453};
454
455static const struct panel_desc auo_b101aw03 = {
456 .modes = &auo_b101aw03_mode,
457 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700458 .bpc = 6,
Thierry Reding280921d2013-08-30 15:10:14 +0200459 .size = {
460 .width = 223,
461 .height = 125,
462 },
463};
464
Huang Lina531bc32015-02-28 10:18:58 +0800465static const struct drm_display_mode auo_b101ean01_mode = {
466 .clock = 72500,
467 .hdisplay = 1280,
468 .hsync_start = 1280 + 119,
469 .hsync_end = 1280 + 119 + 32,
470 .htotal = 1280 + 119 + 32 + 21,
471 .vdisplay = 800,
472 .vsync_start = 800 + 4,
473 .vsync_end = 800 + 4 + 20,
474 .vtotal = 800 + 4 + 20 + 8,
475 .vrefresh = 60,
476};
477
478static const struct panel_desc auo_b101ean01 = {
479 .modes = &auo_b101ean01_mode,
480 .num_modes = 1,
481 .bpc = 6,
482 .size = {
483 .width = 217,
484 .height = 136,
485 },
486};
487
Rob Clarkdac746e2014-08-01 17:01:06 -0400488static const struct drm_display_mode auo_b101xtn01_mode = {
489 .clock = 72000,
490 .hdisplay = 1366,
491 .hsync_start = 1366 + 20,
492 .hsync_end = 1366 + 20 + 70,
493 .htotal = 1366 + 20 + 70,
494 .vdisplay = 768,
495 .vsync_start = 768 + 14,
496 .vsync_end = 768 + 14 + 42,
497 .vtotal = 768 + 14 + 42,
498 .vrefresh = 60,
499 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
500};
501
502static const struct panel_desc auo_b101xtn01 = {
503 .modes = &auo_b101xtn01_mode,
504 .num_modes = 1,
505 .bpc = 6,
506 .size = {
507 .width = 223,
508 .height = 125,
509 },
510};
511
Ajay Kumare35e3052014-09-01 15:40:02 +0530512static const struct drm_display_mode auo_b116xw03_mode = {
513 .clock = 70589,
514 .hdisplay = 1366,
515 .hsync_start = 1366 + 40,
516 .hsync_end = 1366 + 40 + 40,
517 .htotal = 1366 + 40 + 40 + 32,
518 .vdisplay = 768,
519 .vsync_start = 768 + 10,
520 .vsync_end = 768 + 10 + 12,
521 .vtotal = 768 + 10 + 12 + 6,
522 .vrefresh = 60,
523};
524
525static const struct panel_desc auo_b116xw03 = {
526 .modes = &auo_b116xw03_mode,
527 .num_modes = 1,
528 .bpc = 6,
529 .size = {
530 .width = 256,
531 .height = 144,
532 },
533};
534
Stéphane Marchesina333f7a2014-05-23 19:27:59 -0700535static const struct drm_display_mode auo_b133xtn01_mode = {
536 .clock = 69500,
537 .hdisplay = 1366,
538 .hsync_start = 1366 + 48,
539 .hsync_end = 1366 + 48 + 32,
540 .htotal = 1366 + 48 + 32 + 20,
541 .vdisplay = 768,
542 .vsync_start = 768 + 3,
543 .vsync_end = 768 + 3 + 6,
544 .vtotal = 768 + 3 + 6 + 13,
545 .vrefresh = 60,
546};
547
548static const struct panel_desc auo_b133xtn01 = {
549 .modes = &auo_b133xtn01_mode,
550 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700551 .bpc = 6,
Stéphane Marchesina333f7a2014-05-23 19:27:59 -0700552 .size = {
553 .width = 293,
554 .height = 165,
555 },
556};
557
Ajay Kumar3e51d602014-07-31 23:12:12 +0530558static const struct drm_display_mode auo_b133htn01_mode = {
559 .clock = 150660,
560 .hdisplay = 1920,
561 .hsync_start = 1920 + 172,
562 .hsync_end = 1920 + 172 + 80,
563 .htotal = 1920 + 172 + 80 + 60,
564 .vdisplay = 1080,
565 .vsync_start = 1080 + 25,
566 .vsync_end = 1080 + 25 + 10,
567 .vtotal = 1080 + 25 + 10 + 10,
568 .vrefresh = 60,
569};
570
571static const struct panel_desc auo_b133htn01 = {
572 .modes = &auo_b133htn01_mode,
573 .num_modes = 1,
Thierry Redingd7a839c2014-11-06 10:11:01 +0100574 .bpc = 6,
Ajay Kumar3e51d602014-07-31 23:12:12 +0530575 .size = {
576 .width = 293,
577 .height = 165,
578 },
579 .delay = {
580 .prepare = 105,
581 .enable = 20,
582 .unprepare = 50,
583 },
584};
585
Lucas Stach697035c2016-11-30 14:09:55 +0100586static const struct display_timing auo_g133han01_timings = {
587 .pixelclock = { 134000000, 141200000, 149000000 },
588 .hactive = { 1920, 1920, 1920 },
589 .hfront_porch = { 39, 58, 77 },
590 .hback_porch = { 59, 88, 117 },
591 .hsync_len = { 28, 42, 56 },
592 .vactive = { 1080, 1080, 1080 },
593 .vfront_porch = { 3, 8, 11 },
594 .vback_porch = { 5, 14, 19 },
595 .vsync_len = { 4, 14, 19 },
596};
597
598static const struct panel_desc auo_g133han01 = {
599 .timings = &auo_g133han01_timings,
600 .num_timings = 1,
601 .bpc = 8,
602 .size = {
603 .width = 293,
604 .height = 165,
605 },
606 .delay = {
607 .prepare = 200,
608 .enable = 50,
609 .disable = 50,
610 .unprepare = 1000,
611 },
612 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
613};
614
Lucas Stach8c31f602016-11-30 14:09:56 +0100615static const struct display_timing auo_g185han01_timings = {
616 .pixelclock = { 120000000, 144000000, 175000000 },
617 .hactive = { 1920, 1920, 1920 },
618 .hfront_porch = { 18, 60, 74 },
619 .hback_porch = { 12, 44, 54 },
620 .hsync_len = { 10, 24, 32 },
621 .vactive = { 1080, 1080, 1080 },
622 .vfront_porch = { 6, 10, 40 },
623 .vback_porch = { 2, 5, 20 },
624 .vsync_len = { 2, 5, 20 },
625};
626
627static const struct panel_desc auo_g185han01 = {
628 .timings = &auo_g185han01_timings,
629 .num_timings = 1,
630 .bpc = 8,
631 .size = {
632 .width = 409,
633 .height = 230,
634 },
635 .delay = {
636 .prepare = 50,
637 .enable = 200,
638 .disable = 110,
639 .unprepare = 1000,
640 },
641 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
642};
643
Lucas Stach70c0d5b2017-06-08 20:07:58 +0200644static const struct display_timing auo_p320hvn03_timings = {
645 .pixelclock = { 106000000, 148500000, 164000000 },
646 .hactive = { 1920, 1920, 1920 },
647 .hfront_porch = { 25, 50, 130 },
648 .hback_porch = { 25, 50, 130 },
649 .hsync_len = { 20, 40, 105 },
650 .vactive = { 1080, 1080, 1080 },
651 .vfront_porch = { 8, 17, 150 },
652 .vback_porch = { 8, 17, 150 },
653 .vsync_len = { 4, 11, 100 },
654};
655
656static const struct panel_desc auo_p320hvn03 = {
657 .timings = &auo_p320hvn03_timings,
658 .num_timings = 1,
659 .bpc = 8,
660 .size = {
661 .width = 698,
662 .height = 393,
663 },
664 .delay = {
665 .prepare = 1,
666 .enable = 450,
667 .unprepare = 500,
668 },
669 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
670};
671
Haixia Shi7ee933a2016-10-11 14:59:16 -0700672static const struct drm_display_mode auo_t215hvn01_mode = {
673 .clock = 148800,
674 .hdisplay = 1920,
675 .hsync_start = 1920 + 88,
676 .hsync_end = 1920 + 88 + 44,
677 .htotal = 1920 + 88 + 44 + 148,
678 .vdisplay = 1080,
679 .vsync_start = 1080 + 4,
680 .vsync_end = 1080 + 4 + 5,
681 .vtotal = 1080 + 4 + 5 + 36,
682 .vrefresh = 60,
683};
684
685static const struct panel_desc auo_t215hvn01 = {
686 .modes = &auo_t215hvn01_mode,
687 .num_modes = 1,
688 .bpc = 8,
689 .size = {
690 .width = 430,
691 .height = 270,
692 },
693 .delay = {
694 .disable = 5,
695 .unprepare = 1000,
696 }
697};
698
Philipp Zabeld47df632014-12-18 16:43:43 +0100699static const struct drm_display_mode avic_tm070ddh03_mode = {
700 .clock = 51200,
701 .hdisplay = 1024,
702 .hsync_start = 1024 + 160,
703 .hsync_end = 1024 + 160 + 4,
704 .htotal = 1024 + 160 + 4 + 156,
705 .vdisplay = 600,
706 .vsync_start = 600 + 17,
707 .vsync_end = 600 + 17 + 1,
708 .vtotal = 600 + 17 + 1 + 17,
709 .vrefresh = 60,
710};
711
712static const struct panel_desc avic_tm070ddh03 = {
713 .modes = &avic_tm070ddh03_mode,
714 .num_modes = 1,
715 .bpc = 8,
716 .size = {
717 .width = 154,
718 .height = 90,
719 },
720 .delay = {
721 .prepare = 20,
722 .enable = 200,
723 .disable = 200,
724 },
725};
726
Caesar Wangcac1a412016-12-14 11:19:56 +0800727static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
728 {
729 .clock = 71900,
730 .hdisplay = 1280,
731 .hsync_start = 1280 + 48,
732 .hsync_end = 1280 + 48 + 32,
733 .htotal = 1280 + 48 + 32 + 80,
734 .vdisplay = 800,
735 .vsync_start = 800 + 3,
736 .vsync_end = 800 + 3 + 5,
737 .vtotal = 800 + 3 + 5 + 24,
738 .vrefresh = 60,
739 },
740 {
741 .clock = 57500,
742 .hdisplay = 1280,
743 .hsync_start = 1280 + 48,
744 .hsync_end = 1280 + 48 + 32,
745 .htotal = 1280 + 48 + 32 + 80,
746 .vdisplay = 800,
747 .vsync_start = 800 + 3,
748 .vsync_end = 800 + 3 + 5,
749 .vtotal = 800 + 3 + 5 + 24,
750 .vrefresh = 48,
751 },
752};
753
754static const struct panel_desc boe_nv101wxmn51 = {
755 .modes = boe_nv101wxmn51_modes,
756 .num_modes = ARRAY_SIZE(boe_nv101wxmn51_modes),
757 .bpc = 8,
758 .size = {
759 .width = 217,
760 .height = 136,
761 },
762 .delay = {
763 .prepare = 210,
764 .enable = 50,
765 .unprepare = 160,
766 },
767};
768
Randy Li2cb35c82016-09-20 03:02:51 +0800769static const struct drm_display_mode chunghwa_claa070wp03xg_mode = {
770 .clock = 66770,
771 .hdisplay = 800,
772 .hsync_start = 800 + 49,
773 .hsync_end = 800 + 49 + 33,
774 .htotal = 800 + 49 + 33 + 17,
775 .vdisplay = 1280,
776 .vsync_start = 1280 + 1,
777 .vsync_end = 1280 + 1 + 7,
778 .vtotal = 1280 + 1 + 7 + 15,
779 .vrefresh = 60,
780 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
781};
782
783static const struct panel_desc chunghwa_claa070wp03xg = {
784 .modes = &chunghwa_claa070wp03xg_mode,
785 .num_modes = 1,
786 .bpc = 6,
787 .size = {
788 .width = 94,
789 .height = 150,
790 },
791};
792
Stephen Warren4c930752014-01-07 16:46:26 -0700793static const struct drm_display_mode chunghwa_claa101wa01a_mode = {
794 .clock = 72070,
795 .hdisplay = 1366,
796 .hsync_start = 1366 + 58,
797 .hsync_end = 1366 + 58 + 58,
798 .htotal = 1366 + 58 + 58 + 58,
799 .vdisplay = 768,
800 .vsync_start = 768 + 4,
801 .vsync_end = 768 + 4 + 4,
802 .vtotal = 768 + 4 + 4 + 4,
803 .vrefresh = 60,
804};
805
806static const struct panel_desc chunghwa_claa101wa01a = {
807 .modes = &chunghwa_claa101wa01a_mode,
808 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700809 .bpc = 6,
Stephen Warren4c930752014-01-07 16:46:26 -0700810 .size = {
811 .width = 220,
812 .height = 120,
813 },
814};
815
Thierry Reding280921d2013-08-30 15:10:14 +0200816static const struct drm_display_mode chunghwa_claa101wb01_mode = {
817 .clock = 69300,
818 .hdisplay = 1366,
819 .hsync_start = 1366 + 48,
820 .hsync_end = 1366 + 48 + 32,
821 .htotal = 1366 + 48 + 32 + 20,
822 .vdisplay = 768,
823 .vsync_start = 768 + 16,
824 .vsync_end = 768 + 16 + 8,
825 .vtotal = 768 + 16 + 8 + 16,
826 .vrefresh = 60,
827};
828
829static const struct panel_desc chunghwa_claa101wb01 = {
830 .modes = &chunghwa_claa101wb01_mode,
831 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700832 .bpc = 6,
Thierry Reding280921d2013-08-30 15:10:14 +0200833 .size = {
834 .width = 223,
835 .height = 125,
836 },
837};
838
Stefan Agner26ab0062014-05-15 11:38:45 +0200839static const struct drm_display_mode edt_et057090dhu_mode = {
840 .clock = 25175,
841 .hdisplay = 640,
842 .hsync_start = 640 + 16,
843 .hsync_end = 640 + 16 + 30,
844 .htotal = 640 + 16 + 30 + 114,
845 .vdisplay = 480,
846 .vsync_start = 480 + 10,
847 .vsync_end = 480 + 10 + 3,
848 .vtotal = 480 + 10 + 3 + 32,
849 .vrefresh = 60,
850 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
851};
852
853static const struct panel_desc edt_et057090dhu = {
854 .modes = &edt_et057090dhu_mode,
855 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700856 .bpc = 6,
Stefan Agner26ab0062014-05-15 11:38:45 +0200857 .size = {
858 .width = 115,
859 .height = 86,
860 },
Stefan Agnereaeebff2016-12-08 14:54:31 -0800861 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
862 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
Stefan Agner26ab0062014-05-15 11:38:45 +0200863};
864
Philipp Zabelfff5de42014-05-15 12:25:47 +0200865static const struct drm_display_mode edt_etm0700g0dh6_mode = {
866 .clock = 33260,
867 .hdisplay = 800,
868 .hsync_start = 800 + 40,
869 .hsync_end = 800 + 40 + 128,
870 .htotal = 800 + 40 + 128 + 88,
871 .vdisplay = 480,
872 .vsync_start = 480 + 10,
873 .vsync_end = 480 + 10 + 2,
874 .vtotal = 480 + 10 + 2 + 33,
875 .vrefresh = 60,
876 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
877};
878
879static const struct panel_desc edt_etm0700g0dh6 = {
880 .modes = &edt_etm0700g0dh6_mode,
881 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -0700882 .bpc = 6,
Philipp Zabelfff5de42014-05-15 12:25:47 +0200883 .size = {
884 .width = 152,
885 .height = 91,
886 },
Stefan Agnereaeebff2016-12-08 14:54:31 -0800887 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
888 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
Philipp Zabelfff5de42014-05-15 12:25:47 +0200889};
890
Boris BREZILLON102932b2014-06-05 15:53:32 +0200891static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
892 .clock = 32260,
893 .hdisplay = 800,
894 .hsync_start = 800 + 168,
895 .hsync_end = 800 + 168 + 64,
896 .htotal = 800 + 168 + 64 + 88,
897 .vdisplay = 480,
898 .vsync_start = 480 + 37,
899 .vsync_end = 480 + 37 + 2,
900 .vtotal = 480 + 37 + 2 + 8,
901 .vrefresh = 60,
902};
903
904static const struct panel_desc foxlink_fl500wvr00_a0t = {
905 .modes = &foxlink_fl500wvr00_a0t_mode,
906 .num_modes = 1,
Thierry Redingd7a839c2014-11-06 10:11:01 +0100907 .bpc = 8,
Boris BREZILLON102932b2014-06-05 15:53:32 +0200908 .size = {
909 .width = 108,
910 .height = 65,
911 },
Boris Brezillonbb276cb2014-07-22 13:35:47 +0200912 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
Boris BREZILLON102932b2014-06-05 15:53:32 +0200913};
914
Philipp Zabeld435a2a2014-11-19 10:29:55 +0100915static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
916 .clock = 9000,
917 .hdisplay = 480,
918 .hsync_start = 480 + 5,
919 .hsync_end = 480 + 5 + 1,
920 .htotal = 480 + 5 + 1 + 40,
921 .vdisplay = 272,
922 .vsync_start = 272 + 8,
923 .vsync_end = 272 + 8 + 1,
924 .vtotal = 272 + 8 + 1 + 8,
925 .vrefresh = 60,
926};
927
928static const struct panel_desc giantplus_gpg482739qs5 = {
929 .modes = &giantplus_gpg482739qs5_mode,
930 .num_modes = 1,
931 .bpc = 8,
932 .size = {
933 .width = 95,
934 .height = 54,
935 },
Philipp Zabel33536a02015-02-11 18:50:07 +0100936 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
Philipp Zabeld435a2a2014-11-19 10:29:55 +0100937};
938
Philipp Zabelab077252014-12-11 18:32:46 +0100939static const struct display_timing hannstar_hsd070pww1_timing = {
940 .pixelclock = { 64300000, 71100000, 82000000 },
941 .hactive = { 1280, 1280, 1280 },
942 .hfront_porch = { 1, 1, 10 },
943 .hback_porch = { 1, 1, 10 },
Philipp Zabeld901d2b2015-08-12 12:32:13 +0200944 /*
945 * According to the data sheet, the minimum horizontal blanking interval
946 * is 54 clocks (1 + 52 + 1), but tests with a Nitrogen6X have shown the
947 * minimum working horizontal blanking interval to be 60 clocks.
948 */
949 .hsync_len = { 58, 158, 661 },
Philipp Zabelab077252014-12-11 18:32:46 +0100950 .vactive = { 800, 800, 800 },
951 .vfront_porch = { 1, 1, 10 },
952 .vback_porch = { 1, 1, 10 },
953 .vsync_len = { 1, 21, 203 },
954 .flags = DISPLAY_FLAGS_DE_HIGH,
Philipp Zabela8532052014-10-23 16:31:06 +0200955};
956
957static const struct panel_desc hannstar_hsd070pww1 = {
Philipp Zabelab077252014-12-11 18:32:46 +0100958 .timings = &hannstar_hsd070pww1_timing,
959 .num_timings = 1,
Philipp Zabela8532052014-10-23 16:31:06 +0200960 .bpc = 6,
961 .size = {
962 .width = 151,
963 .height = 94,
964 },
Philipp Zabel58d6a7b2015-08-12 12:32:12 +0200965 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
Philipp Zabela8532052014-10-23 16:31:06 +0200966};
967
Eric Nelsonc0d607e2015-04-13 15:09:26 -0700968static const struct display_timing hannstar_hsd100pxn1_timing = {
969 .pixelclock = { 55000000, 65000000, 75000000 },
970 .hactive = { 1024, 1024, 1024 },
971 .hfront_porch = { 40, 40, 40 },
972 .hback_porch = { 220, 220, 220 },
973 .hsync_len = { 20, 60, 100 },
974 .vactive = { 768, 768, 768 },
975 .vfront_porch = { 7, 7, 7 },
976 .vback_porch = { 21, 21, 21 },
977 .vsync_len = { 10, 10, 10 },
978 .flags = DISPLAY_FLAGS_DE_HIGH,
979};
980
981static const struct panel_desc hannstar_hsd100pxn1 = {
982 .timings = &hannstar_hsd100pxn1_timing,
983 .num_timings = 1,
984 .bpc = 6,
985 .size = {
986 .width = 203,
987 .height = 152,
988 },
Philipp Zabel4946b042015-05-20 11:34:08 +0200989 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
Eric Nelsonc0d607e2015-04-13 15:09:26 -0700990};
991
Lucas Stach61ac0bf2014-11-06 17:44:35 +0100992static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = {
993 .clock = 33333,
994 .hdisplay = 800,
995 .hsync_start = 800 + 85,
996 .hsync_end = 800 + 85 + 86,
997 .htotal = 800 + 85 + 86 + 85,
998 .vdisplay = 480,
999 .vsync_start = 480 + 16,
1000 .vsync_end = 480 + 16 + 13,
1001 .vtotal = 480 + 16 + 13 + 16,
1002 .vrefresh = 60,
1003};
1004
1005static const struct panel_desc hitachi_tx23d38vm0caa = {
1006 .modes = &hitachi_tx23d38vm0caa_mode,
1007 .num_modes = 1,
1008 .bpc = 6,
1009 .size = {
1010 .width = 195,
1011 .height = 117,
1012 },
1013};
1014
Nicolas Ferre41bcceb2015-03-19 14:43:01 +01001015static const struct drm_display_mode innolux_at043tn24_mode = {
1016 .clock = 9000,
1017 .hdisplay = 480,
1018 .hsync_start = 480 + 2,
1019 .hsync_end = 480 + 2 + 41,
1020 .htotal = 480 + 2 + 41 + 2,
1021 .vdisplay = 272,
1022 .vsync_start = 272 + 2,
1023 .vsync_end = 272 + 2 + 11,
1024 .vtotal = 272 + 2 + 11 + 2,
1025 .vrefresh = 60,
1026 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1027};
1028
1029static const struct panel_desc innolux_at043tn24 = {
1030 .modes = &innolux_at043tn24_mode,
1031 .num_modes = 1,
1032 .bpc = 8,
1033 .size = {
1034 .width = 95,
1035 .height = 54,
1036 },
1037 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1038};
1039
Riccardo Bortolato4fc24ab2016-04-20 15:37:15 +02001040static const struct drm_display_mode innolux_at070tn92_mode = {
1041 .clock = 33333,
1042 .hdisplay = 800,
1043 .hsync_start = 800 + 210,
1044 .hsync_end = 800 + 210 + 20,
1045 .htotal = 800 + 210 + 20 + 46,
1046 .vdisplay = 480,
1047 .vsync_start = 480 + 22,
1048 .vsync_end = 480 + 22 + 10,
1049 .vtotal = 480 + 22 + 23 + 10,
1050 .vrefresh = 60,
1051};
1052
1053static const struct panel_desc innolux_at070tn92 = {
1054 .modes = &innolux_at070tn92_mode,
1055 .num_modes = 1,
1056 .size = {
1057 .width = 154,
1058 .height = 86,
1059 },
1060 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1061};
1062
Michael Olbrich1e29b842016-08-15 14:32:02 +02001063static const struct display_timing innolux_g101ice_l01_timing = {
1064 .pixelclock = { 60400000, 71100000, 74700000 },
1065 .hactive = { 1280, 1280, 1280 },
1066 .hfront_porch = { 41, 80, 100 },
1067 .hback_porch = { 40, 79, 99 },
1068 .hsync_len = { 1, 1, 1 },
1069 .vactive = { 800, 800, 800 },
1070 .vfront_porch = { 5, 11, 14 },
1071 .vback_porch = { 4, 11, 14 },
1072 .vsync_len = { 1, 1, 1 },
1073 .flags = DISPLAY_FLAGS_DE_HIGH,
1074};
1075
1076static const struct panel_desc innolux_g101ice_l01 = {
1077 .timings = &innolux_g101ice_l01_timing,
1078 .num_timings = 1,
1079 .bpc = 8,
1080 .size = {
1081 .width = 217,
1082 .height = 135,
1083 },
1084 .delay = {
1085 .enable = 200,
1086 .disable = 200,
1087 },
1088 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1089};
1090
Lucas Stach4ae13e42016-11-30 14:09:54 +01001091static const struct display_timing innolux_g121i1_l01_timing = {
1092 .pixelclock = { 67450000, 71000000, 74550000 },
1093 .hactive = { 1280, 1280, 1280 },
1094 .hfront_porch = { 40, 80, 160 },
1095 .hback_porch = { 39, 79, 159 },
1096 .hsync_len = { 1, 1, 1 },
1097 .vactive = { 800, 800, 800 },
1098 .vfront_porch = { 5, 11, 100 },
1099 .vback_porch = { 4, 11, 99 },
1100 .vsync_len = { 1, 1, 1 },
Lucas Stachd731f662014-11-06 17:44:33 +01001101};
1102
1103static const struct panel_desc innolux_g121i1_l01 = {
Lucas Stach4ae13e42016-11-30 14:09:54 +01001104 .timings = &innolux_g121i1_l01_timing,
1105 .num_timings = 1,
Lucas Stachd731f662014-11-06 17:44:33 +01001106 .bpc = 6,
1107 .size = {
1108 .width = 261,
1109 .height = 163,
1110 },
Lucas Stach4ae13e42016-11-30 14:09:54 +01001111 .delay = {
1112 .enable = 200,
1113 .disable = 20,
1114 },
1115 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
Lucas Stachd731f662014-11-06 17:44:33 +01001116};
1117
Akshay Bhatf8fa17b2015-11-18 15:57:47 -05001118static const struct drm_display_mode innolux_g121x1_l03_mode = {
1119 .clock = 65000,
1120 .hdisplay = 1024,
1121 .hsync_start = 1024 + 0,
1122 .hsync_end = 1024 + 1,
1123 .htotal = 1024 + 0 + 1 + 320,
1124 .vdisplay = 768,
1125 .vsync_start = 768 + 38,
1126 .vsync_end = 768 + 38 + 1,
1127 .vtotal = 768 + 38 + 1 + 0,
1128 .vrefresh = 60,
Akshay Bhat2e8c5eb2016-03-01 18:06:54 -05001129 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
Akshay Bhatf8fa17b2015-11-18 15:57:47 -05001130};
1131
1132static const struct panel_desc innolux_g121x1_l03 = {
1133 .modes = &innolux_g121x1_l03_mode,
1134 .num_modes = 1,
1135 .bpc = 6,
1136 .size = {
1137 .width = 246,
1138 .height = 185,
1139 },
1140 .delay = {
1141 .enable = 200,
1142 .unprepare = 200,
1143 .disable = 400,
1144 },
1145};
1146
Thierry Reding0a2288c2014-07-03 14:02:59 +02001147static const struct drm_display_mode innolux_n116bge_mode = {
Daniel Kurtz7fe8c772014-09-02 10:56:46 +08001148 .clock = 76420,
Thierry Reding0a2288c2014-07-03 14:02:59 +02001149 .hdisplay = 1366,
Daniel Kurtz7fe8c772014-09-02 10:56:46 +08001150 .hsync_start = 1366 + 136,
1151 .hsync_end = 1366 + 136 + 30,
1152 .htotal = 1366 + 136 + 30 + 60,
Thierry Reding0a2288c2014-07-03 14:02:59 +02001153 .vdisplay = 768,
1154 .vsync_start = 768 + 8,
Daniel Kurtz7fe8c772014-09-02 10:56:46 +08001155 .vsync_end = 768 + 8 + 12,
1156 .vtotal = 768 + 8 + 12 + 12,
Thierry Reding0a2288c2014-07-03 14:02:59 +02001157 .vrefresh = 60,
1158 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1159};
1160
1161static const struct panel_desc innolux_n116bge = {
1162 .modes = &innolux_n116bge_mode,
1163 .num_modes = 1,
1164 .bpc = 6,
1165 .size = {
1166 .width = 256,
1167 .height = 144,
1168 },
1169};
1170
Alban Bedelea447392014-07-22 08:38:55 +02001171static const struct drm_display_mode innolux_n156bge_l21_mode = {
1172 .clock = 69300,
1173 .hdisplay = 1366,
1174 .hsync_start = 1366 + 16,
1175 .hsync_end = 1366 + 16 + 34,
1176 .htotal = 1366 + 16 + 34 + 50,
1177 .vdisplay = 768,
1178 .vsync_start = 768 + 2,
1179 .vsync_end = 768 + 2 + 6,
1180 .vtotal = 768 + 2 + 6 + 12,
1181 .vrefresh = 60,
1182};
1183
1184static const struct panel_desc innolux_n156bge_l21 = {
1185 .modes = &innolux_n156bge_l21_mode,
1186 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -07001187 .bpc = 6,
Alban Bedelea447392014-07-22 08:38:55 +02001188 .size = {
1189 .width = 344,
1190 .height = 193,
1191 },
1192};
1193
Michael Grzeschikbccac3f2015-03-19 12:22:44 +01001194static const struct drm_display_mode innolux_zj070na_01p_mode = {
1195 .clock = 51501,
1196 .hdisplay = 1024,
1197 .hsync_start = 1024 + 128,
1198 .hsync_end = 1024 + 128 + 64,
1199 .htotal = 1024 + 128 + 64 + 128,
1200 .vdisplay = 600,
1201 .vsync_start = 600 + 16,
1202 .vsync_end = 600 + 16 + 4,
1203 .vtotal = 600 + 16 + 4 + 16,
1204 .vrefresh = 60,
1205};
1206
1207static const struct panel_desc innolux_zj070na_01p = {
1208 .modes = &innolux_zj070na_01p_mode,
1209 .num_modes = 1,
1210 .bpc = 6,
1211 .size = {
Thierry Reding81598842016-06-10 15:33:13 +02001212 .width = 154,
1213 .height = 90,
Michael Grzeschikbccac3f2015-03-19 12:22:44 +01001214 },
1215};
1216
Lucas Stach8def22e2015-12-02 19:41:11 +01001217static const struct display_timing kyo_tcg121xglp_timing = {
1218 .pixelclock = { 52000000, 65000000, 71000000 },
1219 .hactive = { 1024, 1024, 1024 },
1220 .hfront_porch = { 2, 2, 2 },
1221 .hback_porch = { 2, 2, 2 },
1222 .hsync_len = { 86, 124, 244 },
1223 .vactive = { 768, 768, 768 },
1224 .vfront_porch = { 2, 2, 2 },
1225 .vback_porch = { 2, 2, 2 },
1226 .vsync_len = { 6, 34, 73 },
1227 .flags = DISPLAY_FLAGS_DE_HIGH,
1228};
1229
1230static const struct panel_desc kyo_tcg121xglp = {
1231 .timings = &kyo_tcg121xglp_timing,
1232 .num_timings = 1,
1233 .bpc = 8,
1234 .size = {
1235 .width = 246,
1236 .height = 184,
1237 },
1238 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1239};
1240
Heiko Schocherdd015002015-05-22 10:25:57 +02001241static const struct drm_display_mode lg_lb070wv8_mode = {
1242 .clock = 33246,
1243 .hdisplay = 800,
1244 .hsync_start = 800 + 88,
1245 .hsync_end = 800 + 88 + 80,
1246 .htotal = 800 + 88 + 80 + 88,
1247 .vdisplay = 480,
1248 .vsync_start = 480 + 10,
1249 .vsync_end = 480 + 10 + 25,
1250 .vtotal = 480 + 10 + 25 + 10,
1251 .vrefresh = 60,
1252};
1253
1254static const struct panel_desc lg_lb070wv8 = {
1255 .modes = &lg_lb070wv8_mode,
1256 .num_modes = 1,
1257 .bpc = 16,
1258 .size = {
1259 .width = 151,
1260 .height = 91,
1261 },
1262 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1263};
1264
Yakir Yangc5ece402016-06-28 12:51:15 +08001265static const struct drm_display_mode lg_lp079qx1_sp0v_mode = {
1266 .clock = 200000,
1267 .hdisplay = 1536,
1268 .hsync_start = 1536 + 12,
1269 .hsync_end = 1536 + 12 + 16,
1270 .htotal = 1536 + 12 + 16 + 48,
1271 .vdisplay = 2048,
1272 .vsync_start = 2048 + 8,
1273 .vsync_end = 2048 + 8 + 4,
1274 .vtotal = 2048 + 8 + 4 + 8,
1275 .vrefresh = 60,
1276 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1277};
1278
1279static const struct panel_desc lg_lp079qx1_sp0v = {
1280 .modes = &lg_lp079qx1_sp0v_mode,
1281 .num_modes = 1,
1282 .size = {
1283 .width = 129,
1284 .height = 171,
1285 },
1286};
1287
Yakir Yang0355dde2016-06-12 10:56:02 +08001288static const struct drm_display_mode lg_lp097qx1_spa1_mode = {
1289 .clock = 205210,
1290 .hdisplay = 2048,
1291 .hsync_start = 2048 + 150,
1292 .hsync_end = 2048 + 150 + 5,
1293 .htotal = 2048 + 150 + 5 + 5,
1294 .vdisplay = 1536,
1295 .vsync_start = 1536 + 3,
1296 .vsync_end = 1536 + 3 + 1,
1297 .vtotal = 1536 + 3 + 1 + 9,
1298 .vrefresh = 60,
1299};
1300
1301static const struct panel_desc lg_lp097qx1_spa1 = {
1302 .modes = &lg_lp097qx1_spa1_mode,
1303 .num_modes = 1,
1304 .size = {
1305 .width = 208,
1306 .height = 147,
1307 },
1308};
1309
Jitao Shi690d8fa2016-02-22 19:01:44 +08001310static const struct drm_display_mode lg_lp120up1_mode = {
1311 .clock = 162300,
1312 .hdisplay = 1920,
1313 .hsync_start = 1920 + 40,
1314 .hsync_end = 1920 + 40 + 40,
1315 .htotal = 1920 + 40 + 40+ 80,
1316 .vdisplay = 1280,
1317 .vsync_start = 1280 + 4,
1318 .vsync_end = 1280 + 4 + 4,
1319 .vtotal = 1280 + 4 + 4 + 12,
1320 .vrefresh = 60,
1321};
1322
1323static const struct panel_desc lg_lp120up1 = {
1324 .modes = &lg_lp120up1_mode,
1325 .num_modes = 1,
1326 .bpc = 8,
1327 .size = {
1328 .width = 267,
1329 .height = 183,
1330 },
1331};
1332
Thierry Redingec7c5652013-11-15 15:59:32 +01001333static const struct drm_display_mode lg_lp129qe_mode = {
1334 .clock = 285250,
1335 .hdisplay = 2560,
1336 .hsync_start = 2560 + 48,
1337 .hsync_end = 2560 + 48 + 32,
1338 .htotal = 2560 + 48 + 32 + 80,
1339 .vdisplay = 1700,
1340 .vsync_start = 1700 + 3,
1341 .vsync_end = 1700 + 3 + 10,
1342 .vtotal = 1700 + 3 + 10 + 36,
1343 .vrefresh = 60,
1344};
1345
1346static const struct panel_desc lg_lp129qe = {
1347 .modes = &lg_lp129qe_mode,
1348 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -07001349 .bpc = 8,
Thierry Redingec7c5652013-11-15 15:59:32 +01001350 .size = {
1351 .width = 272,
1352 .height = 181,
1353 },
1354};
1355
Lucas Stach01bacc132017-06-08 20:07:55 +02001356static const struct display_timing nec_nl12880bc20_05_timing = {
1357 .pixelclock = { 67000000, 71000000, 75000000 },
1358 .hactive = { 1280, 1280, 1280 },
1359 .hfront_porch = { 2, 30, 30 },
1360 .hback_porch = { 6, 100, 100 },
1361 .hsync_len = { 2, 30, 30 },
1362 .vactive = { 800, 800, 800 },
1363 .vfront_porch = { 5, 5, 5 },
1364 .vback_porch = { 11, 11, 11 },
1365 .vsync_len = { 7, 7, 7 },
1366};
1367
1368static const struct panel_desc nec_nl12880bc20_05 = {
1369 .timings = &nec_nl12880bc20_05_timing,
1370 .num_timings = 1,
1371 .bpc = 8,
1372 .size = {
1373 .width = 261,
1374 .height = 163,
1375 },
1376 .delay = {
1377 .enable = 50,
1378 .disable = 50,
1379 },
1380 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1381};
1382
jianwei wangc6e87f92015-07-29 16:30:02 +08001383static const struct drm_display_mode nec_nl4827hc19_05b_mode = {
1384 .clock = 10870,
1385 .hdisplay = 480,
1386 .hsync_start = 480 + 2,
1387 .hsync_end = 480 + 2 + 41,
1388 .htotal = 480 + 2 + 41 + 2,
1389 .vdisplay = 272,
1390 .vsync_start = 272 + 2,
1391 .vsync_end = 272 + 2 + 4,
1392 .vtotal = 272 + 2 + 4 + 2,
1393 .vrefresh = 74,
Stefan Agner4bc390c2015-11-17 19:10:29 -08001394 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
jianwei wangc6e87f92015-07-29 16:30:02 +08001395};
1396
1397static const struct panel_desc nec_nl4827hc19_05b = {
1398 .modes = &nec_nl4827hc19_05b_mode,
1399 .num_modes = 1,
1400 .bpc = 8,
1401 .size = {
1402 .width = 95,
1403 .height = 54,
1404 },
Stefan Agner2c806612016-02-08 12:50:13 -08001405 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1406 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
jianwei wangc6e87f92015-07-29 16:30:02 +08001407};
1408
Maxime Riparde6c2f062016-09-06 16:46:17 +02001409static const struct drm_display_mode netron_dy_e231732_mode = {
1410 .clock = 66000,
1411 .hdisplay = 1024,
1412 .hsync_start = 1024 + 160,
1413 .hsync_end = 1024 + 160 + 70,
1414 .htotal = 1024 + 160 + 70 + 90,
1415 .vdisplay = 600,
1416 .vsync_start = 600 + 127,
1417 .vsync_end = 600 + 127 + 20,
1418 .vtotal = 600 + 127 + 20 + 3,
1419 .vrefresh = 60,
1420};
1421
1422static const struct panel_desc netron_dy_e231732 = {
1423 .modes = &netron_dy_e231732_mode,
1424 .num_modes = 1,
1425 .size = {
1426 .width = 154,
1427 .height = 87,
1428 },
1429 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1430};
1431
Lucas Stach4177fa62017-06-08 20:07:57 +02001432static const struct display_timing nlt_nl192108ac18_02d_timing = {
1433 .pixelclock = { 130000000, 148350000, 163000000 },
1434 .hactive = { 1920, 1920, 1920 },
1435 .hfront_porch = { 80, 100, 100 },
1436 .hback_porch = { 100, 120, 120 },
1437 .hsync_len = { 50, 60, 60 },
1438 .vactive = { 1080, 1080, 1080 },
1439 .vfront_porch = { 12, 30, 30 },
1440 .vback_porch = { 4, 10, 10 },
1441 .vsync_len = { 4, 5, 5 },
1442};
1443
1444static const struct panel_desc nlt_nl192108ac18_02d = {
1445 .timings = &nlt_nl192108ac18_02d_timing,
1446 .num_timings = 1,
1447 .bpc = 8,
1448 .size = {
1449 .width = 344,
1450 .height = 194,
1451 },
1452 .delay = {
1453 .unprepare = 500,
1454 },
1455 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1456};
1457
Fabien Lahoudere05ec0e42016-10-17 11:38:01 +02001458static const struct drm_display_mode nvd_9128_mode = {
1459 .clock = 29500,
1460 .hdisplay = 800,
1461 .hsync_start = 800 + 130,
1462 .hsync_end = 800 + 130 + 98,
1463 .htotal = 800 + 0 + 130 + 98,
1464 .vdisplay = 480,
1465 .vsync_start = 480 + 10,
1466 .vsync_end = 480 + 10 + 50,
1467 .vtotal = 480 + 0 + 10 + 50,
1468};
1469
1470static const struct panel_desc nvd_9128 = {
1471 .modes = &nvd_9128_mode,
1472 .num_modes = 1,
1473 .bpc = 8,
1474 .size = {
1475 .width = 156,
1476 .height = 88,
1477 },
1478 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1479};
1480
Gary Bissona99fb622015-06-10 18:44:23 +02001481static const struct display_timing okaya_rs800480t_7x0gp_timing = {
1482 .pixelclock = { 30000000, 30000000, 40000000 },
1483 .hactive = { 800, 800, 800 },
1484 .hfront_porch = { 40, 40, 40 },
1485 .hback_porch = { 40, 40, 40 },
1486 .hsync_len = { 1, 48, 48 },
1487 .vactive = { 480, 480, 480 },
1488 .vfront_porch = { 13, 13, 13 },
1489 .vback_porch = { 29, 29, 29 },
1490 .vsync_len = { 3, 3, 3 },
1491 .flags = DISPLAY_FLAGS_DE_HIGH,
1492};
1493
1494static const struct panel_desc okaya_rs800480t_7x0gp = {
1495 .timings = &okaya_rs800480t_7x0gp_timing,
1496 .num_timings = 1,
1497 .bpc = 6,
1498 .size = {
1499 .width = 154,
1500 .height = 87,
1501 },
1502 .delay = {
1503 .prepare = 41,
1504 .enable = 50,
1505 .unprepare = 41,
1506 .disable = 50,
1507 },
1508 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1509};
1510
Maxime Ripardcf5c9e62016-03-23 17:38:34 +01001511static const struct drm_display_mode olimex_lcd_olinuxino_43ts_mode = {
1512 .clock = 9000,
1513 .hdisplay = 480,
1514 .hsync_start = 480 + 5,
1515 .hsync_end = 480 + 5 + 30,
1516 .htotal = 480 + 5 + 30 + 10,
1517 .vdisplay = 272,
1518 .vsync_start = 272 + 8,
1519 .vsync_end = 272 + 8 + 5,
1520 .vtotal = 272 + 8 + 5 + 3,
1521 .vrefresh = 60,
1522};
1523
1524static const struct panel_desc olimex_lcd_olinuxino_43ts = {
1525 .modes = &olimex_lcd_olinuxino_43ts_mode,
1526 .num_modes = 1,
1527 .size = {
Jonathan Liu30c6d7ab92017-07-20 20:29:43 +10001528 .width = 95,
1529 .height = 54,
Maxime Ripardcf5c9e62016-03-23 17:38:34 +01001530 },
Jonathan Liu5c2a7c62016-09-11 20:46:55 +10001531 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
Maxime Ripardcf5c9e62016-03-23 17:38:34 +01001532};
1533
Eric Anholte8b6f562016-03-24 17:23:48 -07001534/*
1535 * 800x480 CVT. The panel appears to be quite accepting, at least as far as
1536 * pixel clocks, but this is the timing that was being used in the Adafruit
1537 * installation instructions.
1538 */
1539static const struct drm_display_mode ontat_yx700wv03_mode = {
1540 .clock = 29500,
1541 .hdisplay = 800,
1542 .hsync_start = 824,
1543 .hsync_end = 896,
1544 .htotal = 992,
1545 .vdisplay = 480,
1546 .vsync_start = 483,
1547 .vsync_end = 493,
1548 .vtotal = 500,
1549 .vrefresh = 60,
1550 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1551};
1552
1553/*
1554 * Specification at:
1555 * https://www.adafruit.com/images/product-files/2406/c3163.pdf
1556 */
1557static const struct panel_desc ontat_yx700wv03 = {
1558 .modes = &ontat_yx700wv03_mode,
1559 .num_modes = 1,
1560 .bpc = 8,
1561 .size = {
1562 .width = 154,
1563 .height = 83,
1564 },
1565 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1566};
1567
Philipp Zabel725c9d42015-02-11 18:50:11 +01001568static const struct drm_display_mode ortustech_com43h4m85ulc_mode = {
1569 .clock = 25000,
1570 .hdisplay = 480,
1571 .hsync_start = 480 + 10,
1572 .hsync_end = 480 + 10 + 10,
1573 .htotal = 480 + 10 + 10 + 15,
1574 .vdisplay = 800,
1575 .vsync_start = 800 + 3,
1576 .vsync_end = 800 + 3 + 3,
1577 .vtotal = 800 + 3 + 3 + 3,
1578 .vrefresh = 60,
1579};
1580
1581static const struct panel_desc ortustech_com43h4m85ulc = {
1582 .modes = &ortustech_com43h4m85ulc_mode,
1583 .num_modes = 1,
1584 .bpc = 8,
1585 .size = {
1586 .width = 56,
1587 .height = 93,
1588 },
1589 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
Marek Vasute0932f92016-08-26 18:26:00 +02001590 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
Philipp Zabel725c9d42015-02-11 18:50:11 +01001591};
1592
Josh Wud2a6f0f2015-10-08 17:42:41 +02001593static const struct drm_display_mode qd43003c0_40_mode = {
1594 .clock = 9000,
1595 .hdisplay = 480,
1596 .hsync_start = 480 + 8,
1597 .hsync_end = 480 + 8 + 4,
1598 .htotal = 480 + 8 + 4 + 39,
1599 .vdisplay = 272,
1600 .vsync_start = 272 + 4,
1601 .vsync_end = 272 + 4 + 10,
1602 .vtotal = 272 + 4 + 10 + 2,
1603 .vrefresh = 60,
1604};
1605
1606static const struct panel_desc qd43003c0_40 = {
1607 .modes = &qd43003c0_40_mode,
1608 .num_modes = 1,
1609 .bpc = 8,
1610 .size = {
1611 .width = 95,
1612 .height = 53,
1613 },
1614 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1615};
1616
Yakir Yang0330eaf2016-06-12 10:56:13 +08001617static const struct drm_display_mode samsung_lsn122dl01_c01_mode = {
1618 .clock = 271560,
1619 .hdisplay = 2560,
1620 .hsync_start = 2560 + 48,
1621 .hsync_end = 2560 + 48 + 32,
1622 .htotal = 2560 + 48 + 32 + 80,
1623 .vdisplay = 1600,
1624 .vsync_start = 1600 + 2,
1625 .vsync_end = 1600 + 2 + 5,
1626 .vtotal = 1600 + 2 + 5 + 57,
1627 .vrefresh = 60,
1628};
1629
1630static const struct panel_desc samsung_lsn122dl01_c01 = {
1631 .modes = &samsung_lsn122dl01_c01_mode,
1632 .num_modes = 1,
1633 .size = {
1634 .width = 263,
1635 .height = 164,
1636 },
1637};
1638
Marc Dietrich6d54e3d2013-12-21 21:38:12 +01001639static const struct drm_display_mode samsung_ltn101nt05_mode = {
1640 .clock = 54030,
1641 .hdisplay = 1024,
1642 .hsync_start = 1024 + 24,
1643 .hsync_end = 1024 + 24 + 136,
1644 .htotal = 1024 + 24 + 136 + 160,
1645 .vdisplay = 600,
1646 .vsync_start = 600 + 3,
1647 .vsync_end = 600 + 3 + 6,
1648 .vtotal = 600 + 3 + 6 + 61,
1649 .vrefresh = 60,
1650};
1651
1652static const struct panel_desc samsung_ltn101nt05 = {
1653 .modes = &samsung_ltn101nt05_mode,
1654 .num_modes = 1,
Stéphane Marchesin0208d512014-06-19 18:18:28 -07001655 .bpc = 6,
Marc Dietrich6d54e3d2013-12-21 21:38:12 +01001656 .size = {
Thierry Reding81598842016-06-10 15:33:13 +02001657 .width = 223,
1658 .height = 125,
Marc Dietrich6d54e3d2013-12-21 21:38:12 +01001659 },
1660};
1661
Stéphane Marchesin0c934302015-03-18 10:52:18 +01001662static const struct drm_display_mode samsung_ltn140at29_301_mode = {
1663 .clock = 76300,
1664 .hdisplay = 1366,
1665 .hsync_start = 1366 + 64,
1666 .hsync_end = 1366 + 64 + 48,
1667 .htotal = 1366 + 64 + 48 + 128,
1668 .vdisplay = 768,
1669 .vsync_start = 768 + 2,
1670 .vsync_end = 768 + 2 + 5,
1671 .vtotal = 768 + 2 + 5 + 17,
1672 .vrefresh = 60,
1673};
1674
1675static const struct panel_desc samsung_ltn140at29_301 = {
1676 .modes = &samsung_ltn140at29_301_mode,
1677 .num_modes = 1,
1678 .bpc = 6,
1679 .size = {
1680 .width = 320,
1681 .height = 187,
1682 },
1683};
1684
Joshua Clayton592aa022016-07-06 15:59:16 -07001685static const struct display_timing sharp_lq101k1ly04_timing = {
1686 .pixelclock = { 60000000, 65000000, 80000000 },
1687 .hactive = { 1280, 1280, 1280 },
1688 .hfront_porch = { 20, 20, 20 },
1689 .hback_porch = { 20, 20, 20 },
1690 .hsync_len = { 10, 10, 10 },
1691 .vactive = { 800, 800, 800 },
1692 .vfront_porch = { 4, 4, 4 },
1693 .vback_porch = { 4, 4, 4 },
1694 .vsync_len = { 4, 4, 4 },
1695 .flags = DISPLAY_FLAGS_PIXDATA_POSEDGE,
1696};
1697
1698static const struct panel_desc sharp_lq101k1ly04 = {
1699 .timings = &sharp_lq101k1ly04_timing,
1700 .num_timings = 1,
1701 .bpc = 8,
1702 .size = {
1703 .width = 217,
1704 .height = 136,
1705 },
1706 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
1707};
1708
Yakir Yang739c7de2016-06-12 10:56:35 +08001709static const struct drm_display_mode sharp_lq123p1jx31_mode = {
1710 .clock = 252750,
1711 .hdisplay = 2400,
1712 .hsync_start = 2400 + 48,
1713 .hsync_end = 2400 + 48 + 32,
1714 .htotal = 2400 + 48 + 32 + 80,
1715 .vdisplay = 1600,
1716 .vsync_start = 1600 + 3,
1717 .vsync_end = 1600 + 3 + 10,
1718 .vtotal = 1600 + 3 + 10 + 33,
1719 .vrefresh = 60,
1720 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1721};
1722
1723static const struct panel_desc sharp_lq123p1jx31 = {
1724 .modes = &sharp_lq123p1jx31_mode,
1725 .num_modes = 1,
zain wang5466a632016-11-19 10:27:16 +08001726 .bpc = 8,
Yakir Yang739c7de2016-06-12 10:56:35 +08001727 .size = {
1728 .width = 259,
1729 .height = 173,
1730 },
Yakir Yanga42f6e32016-07-21 21:14:34 +08001731 .delay = {
1732 .prepare = 110,
1733 .enable = 50,
1734 .unprepare = 550,
1735 },
Yakir Yang739c7de2016-06-12 10:56:35 +08001736};
1737
Gustaf Lindström0f9cdd72016-10-04 17:29:21 +02001738static const struct drm_display_mode sharp_lq150x1lg11_mode = {
1739 .clock = 71100,
1740 .hdisplay = 1024,
1741 .hsync_start = 1024 + 168,
1742 .hsync_end = 1024 + 168 + 64,
1743 .htotal = 1024 + 168 + 64 + 88,
1744 .vdisplay = 768,
1745 .vsync_start = 768 + 37,
1746 .vsync_end = 768 + 37 + 2,
1747 .vtotal = 768 + 37 + 2 + 8,
1748 .vrefresh = 60,
1749};
1750
1751static const struct panel_desc sharp_lq150x1lg11 = {
1752 .modes = &sharp_lq150x1lg11_mode,
1753 .num_modes = 1,
1754 .bpc = 6,
1755 .size = {
1756 .width = 304,
1757 .height = 228,
1758 },
1759 .bus_format = MEDIA_BUS_FMT_RGB565_1X16,
1760};
1761
Boris BREZILLON9c6615b2015-03-19 14:43:00 +01001762static const struct drm_display_mode shelly_sca07010_bfn_lnn_mode = {
1763 .clock = 33300,
1764 .hdisplay = 800,
1765 .hsync_start = 800 + 1,
1766 .hsync_end = 800 + 1 + 64,
1767 .htotal = 800 + 1 + 64 + 64,
1768 .vdisplay = 480,
1769 .vsync_start = 480 + 1,
1770 .vsync_end = 480 + 1 + 23,
1771 .vtotal = 480 + 1 + 23 + 22,
1772 .vrefresh = 60,
1773};
1774
1775static const struct panel_desc shelly_sca07010_bfn_lnn = {
1776 .modes = &shelly_sca07010_bfn_lnn_mode,
1777 .num_modes = 1,
1778 .size = {
1779 .width = 152,
1780 .height = 91,
1781 },
1782 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1783};
1784
Douglas Anderson9bb34c42016-06-10 10:02:07 -07001785static const struct drm_display_mode starry_kr122ea0sra_mode = {
1786 .clock = 147000,
1787 .hdisplay = 1920,
1788 .hsync_start = 1920 + 16,
1789 .hsync_end = 1920 + 16 + 16,
1790 .htotal = 1920 + 16 + 16 + 32,
1791 .vdisplay = 1200,
1792 .vsync_start = 1200 + 15,
1793 .vsync_end = 1200 + 15 + 2,
1794 .vtotal = 1200 + 15 + 2 + 18,
1795 .vrefresh = 60,
1796 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1797};
1798
1799static const struct panel_desc starry_kr122ea0sra = {
1800 .modes = &starry_kr122ea0sra_mode,
1801 .num_modes = 1,
1802 .size = {
1803 .width = 263,
1804 .height = 164,
1805 },
Brian Norrisc46b9242016-08-26 14:32:14 -07001806 .delay = {
1807 .prepare = 10 + 200,
1808 .enable = 50,
1809 .unprepare = 10 + 500,
1810 },
Douglas Anderson9bb34c42016-06-10 10:02:07 -07001811};
1812
Gary Bissonadb973e2016-12-02 09:52:08 +01001813static const struct display_timing tianma_tm070jdhg30_timing = {
1814 .pixelclock = { 62600000, 68200000, 78100000 },
1815 .hactive = { 1280, 1280, 1280 },
1816 .hfront_porch = { 15, 64, 159 },
1817 .hback_porch = { 5, 5, 5 },
1818 .hsync_len = { 1, 1, 256 },
1819 .vactive = { 800, 800, 800 },
1820 .vfront_porch = { 3, 40, 99 },
1821 .vback_porch = { 2, 2, 2 },
1822 .vsync_len = { 1, 1, 128 },
1823 .flags = DISPLAY_FLAGS_DE_HIGH,
1824};
1825
1826static const struct panel_desc tianma_tm070jdhg30 = {
1827 .timings = &tianma_tm070jdhg30_timing,
1828 .num_timings = 1,
1829 .bpc = 8,
1830 .size = {
1831 .width = 151,
1832 .height = 95,
1833 },
1834 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1835};
1836
Bhuvanchandra DV227e4f42016-05-05 11:47:07 +05301837static const struct drm_display_mode tpk_f07a_0102_mode = {
1838 .clock = 33260,
1839 .hdisplay = 800,
1840 .hsync_start = 800 + 40,
1841 .hsync_end = 800 + 40 + 128,
1842 .htotal = 800 + 40 + 128 + 88,
1843 .vdisplay = 480,
1844 .vsync_start = 480 + 10,
1845 .vsync_end = 480 + 10 + 2,
1846 .vtotal = 480 + 10 + 2 + 33,
1847 .vrefresh = 60,
1848};
1849
1850static const struct panel_desc tpk_f07a_0102 = {
1851 .modes = &tpk_f07a_0102_mode,
1852 .num_modes = 1,
1853 .size = {
1854 .width = 152,
1855 .height = 91,
1856 },
1857 .bus_flags = DRM_BUS_FLAG_PIXDATA_POSEDGE,
1858};
1859
1860static const struct drm_display_mode tpk_f10a_0102_mode = {
1861 .clock = 45000,
1862 .hdisplay = 1024,
1863 .hsync_start = 1024 + 176,
1864 .hsync_end = 1024 + 176 + 5,
1865 .htotal = 1024 + 176 + 5 + 88,
1866 .vdisplay = 600,
1867 .vsync_start = 600 + 20,
1868 .vsync_end = 600 + 20 + 5,
1869 .vtotal = 600 + 20 + 5 + 25,
1870 .vrefresh = 60,
1871};
1872
1873static const struct panel_desc tpk_f10a_0102 = {
1874 .modes = &tpk_f10a_0102_mode,
1875 .num_modes = 1,
1876 .size = {
1877 .width = 223,
1878 .height = 125,
1879 },
1880};
1881
Maciej S. Szmigiero06a9dc62016-02-13 22:52:03 +01001882static const struct display_timing urt_umsh_8596md_timing = {
1883 .pixelclock = { 33260000, 33260000, 33260000 },
1884 .hactive = { 800, 800, 800 },
1885 .hfront_porch = { 41, 41, 41 },
1886 .hback_porch = { 216 - 128, 216 - 128, 216 - 128 },
1887 .hsync_len = { 71, 128, 128 },
1888 .vactive = { 480, 480, 480 },
1889 .vfront_porch = { 10, 10, 10 },
1890 .vback_porch = { 35 - 2, 35 - 2, 35 - 2 },
1891 .vsync_len = { 2, 2, 2 },
1892 .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
1893 DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
1894};
1895
1896static const struct panel_desc urt_umsh_8596md_lvds = {
1897 .timings = &urt_umsh_8596md_timing,
1898 .num_timings = 1,
1899 .bpc = 6,
1900 .size = {
1901 .width = 152,
1902 .height = 91,
1903 },
1904 .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG,
1905};
1906
1907static const struct panel_desc urt_umsh_8596md_parallel = {
1908 .timings = &urt_umsh_8596md_timing,
1909 .num_timings = 1,
1910 .bpc = 6,
1911 .size = {
1912 .width = 152,
1913 .height = 91,
1914 },
1915 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
1916};
1917
Richard Genoude4bac402017-03-27 12:33:23 +02001918static const struct drm_display_mode winstar_wf35ltiacd_mode = {
1919 .clock = 6410,
1920 .hdisplay = 320,
1921 .hsync_start = 320 + 20,
1922 .hsync_end = 320 + 20 + 30,
1923 .htotal = 320 + 20 + 30 + 38,
1924 .vdisplay = 240,
1925 .vsync_start = 240 + 4,
1926 .vsync_end = 240 + 4 + 3,
1927 .vtotal = 240 + 4 + 3 + 15,
1928 .vrefresh = 60,
1929 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1930};
1931
1932static const struct panel_desc winstar_wf35ltiacd = {
1933 .modes = &winstar_wf35ltiacd_mode,
1934 .num_modes = 1,
1935 .bpc = 8,
1936 .size = {
1937 .width = 70,
1938 .height = 53,
1939 },
1940 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1941};
1942
Thierry Reding280921d2013-08-30 15:10:14 +02001943static const struct of_device_id platform_of_match[] = {
1944 {
Yannick Fertre966fea72017-03-28 11:44:49 +02001945 .compatible = "ampire,am-480272h3tmqw-t01h",
1946 .data = &ampire_am_480272h3tmqw_t01h,
1947 }, {
Philipp Zabel1c550fa12015-02-11 18:50:09 +01001948 .compatible = "ampire,am800480r3tmqwa1h",
1949 .data = &ampire_am800480r3tmqwa1h,
1950 }, {
Thierry Reding280921d2013-08-30 15:10:14 +02001951 .compatible = "auo,b101aw03",
1952 .data = &auo_b101aw03,
1953 }, {
Huang Lina531bc32015-02-28 10:18:58 +08001954 .compatible = "auo,b101ean01",
1955 .data = &auo_b101ean01,
1956 }, {
Rob Clarkdac746e2014-08-01 17:01:06 -04001957 .compatible = "auo,b101xtn01",
1958 .data = &auo_b101xtn01,
1959 }, {
Ajay Kumare35e3052014-09-01 15:40:02 +05301960 .compatible = "auo,b116xw03",
1961 .data = &auo_b116xw03,
1962 }, {
Ajay Kumar3e51d602014-07-31 23:12:12 +05301963 .compatible = "auo,b133htn01",
1964 .data = &auo_b133htn01,
1965 }, {
Stéphane Marchesina333f7a2014-05-23 19:27:59 -07001966 .compatible = "auo,b133xtn01",
1967 .data = &auo_b133xtn01,
1968 }, {
Lucas Stach697035c2016-11-30 14:09:55 +01001969 .compatible = "auo,g133han01",
1970 .data = &auo_g133han01,
1971 }, {
Lucas Stach8c31f602016-11-30 14:09:56 +01001972 .compatible = "auo,g185han01",
1973 .data = &auo_g185han01,
1974 }, {
Lucas Stach70c0d5b2017-06-08 20:07:58 +02001975 .compatible = "auo,p320hvn03",
1976 .data = &auo_p320hvn03,
1977 }, {
Haixia Shi7ee933a2016-10-11 14:59:16 -07001978 .compatible = "auo,t215hvn01",
1979 .data = &auo_t215hvn01,
1980 }, {
Philipp Zabeld47df632014-12-18 16:43:43 +01001981 .compatible = "avic,tm070ddh03",
1982 .data = &avic_tm070ddh03,
1983 }, {
Caesar Wangcac1a412016-12-14 11:19:56 +08001984 .compatible = "boe,nv101wxmn51",
1985 .data = &boe_nv101wxmn51,
1986 }, {
Randy Li2cb35c82016-09-20 03:02:51 +08001987 .compatible = "chunghwa,claa070wp03xg",
1988 .data = &chunghwa_claa070wp03xg,
1989 }, {
Stephen Warren4c930752014-01-07 16:46:26 -07001990 .compatible = "chunghwa,claa101wa01a",
1991 .data = &chunghwa_claa101wa01a
1992 }, {
Thierry Reding280921d2013-08-30 15:10:14 +02001993 .compatible = "chunghwa,claa101wb01",
1994 .data = &chunghwa_claa101wb01
1995 }, {
Stefan Agner26ab0062014-05-15 11:38:45 +02001996 .compatible = "edt,et057090dhu",
1997 .data = &edt_et057090dhu,
1998 }, {
Philipp Zabelfff5de42014-05-15 12:25:47 +02001999 .compatible = "edt,et070080dh6",
2000 .data = &edt_etm0700g0dh6,
2001 }, {
2002 .compatible = "edt,etm0700g0dh6",
2003 .data = &edt_etm0700g0dh6,
2004 }, {
Boris BREZILLON102932b2014-06-05 15:53:32 +02002005 .compatible = "foxlink,fl500wvr00-a0t",
2006 .data = &foxlink_fl500wvr00_a0t,
2007 }, {
Philipp Zabeld435a2a2014-11-19 10:29:55 +01002008 .compatible = "giantplus,gpg482739qs5",
2009 .data = &giantplus_gpg482739qs5
2010 }, {
Philipp Zabela8532052014-10-23 16:31:06 +02002011 .compatible = "hannstar,hsd070pww1",
2012 .data = &hannstar_hsd070pww1,
2013 }, {
Eric Nelsonc0d607e2015-04-13 15:09:26 -07002014 .compatible = "hannstar,hsd100pxn1",
2015 .data = &hannstar_hsd100pxn1,
2016 }, {
Lucas Stach61ac0bf2014-11-06 17:44:35 +01002017 .compatible = "hit,tx23d38vm0caa",
2018 .data = &hitachi_tx23d38vm0caa
2019 }, {
Nicolas Ferre41bcceb2015-03-19 14:43:01 +01002020 .compatible = "innolux,at043tn24",
2021 .data = &innolux_at043tn24,
2022 }, {
Riccardo Bortolato4fc24ab2016-04-20 15:37:15 +02002023 .compatible = "innolux,at070tn92",
2024 .data = &innolux_at070tn92,
2025 }, {
Michael Olbrich1e29b842016-08-15 14:32:02 +02002026 .compatible ="innolux,g101ice-l01",
2027 .data = &innolux_g101ice_l01
2028 }, {
Lucas Stachd731f662014-11-06 17:44:33 +01002029 .compatible ="innolux,g121i1-l01",
2030 .data = &innolux_g121i1_l01
2031 }, {
Akshay Bhatf8fa17b2015-11-18 15:57:47 -05002032 .compatible = "innolux,g121x1-l03",
2033 .data = &innolux_g121x1_l03,
2034 }, {
Thierry Reding0a2288c2014-07-03 14:02:59 +02002035 .compatible = "innolux,n116bge",
2036 .data = &innolux_n116bge,
2037 }, {
Alban Bedelea447392014-07-22 08:38:55 +02002038 .compatible = "innolux,n156bge-l21",
2039 .data = &innolux_n156bge_l21,
2040 }, {
Michael Grzeschikbccac3f2015-03-19 12:22:44 +01002041 .compatible = "innolux,zj070na-01p",
2042 .data = &innolux_zj070na_01p,
2043 }, {
Lucas Stach8def22e2015-12-02 19:41:11 +01002044 .compatible = "kyo,tcg121xglp",
2045 .data = &kyo_tcg121xglp,
2046 }, {
Heiko Schocherdd015002015-05-22 10:25:57 +02002047 .compatible = "lg,lb070wv8",
2048 .data = &lg_lb070wv8,
2049 }, {
Yakir Yangc5ece402016-06-28 12:51:15 +08002050 .compatible = "lg,lp079qx1-sp0v",
2051 .data = &lg_lp079qx1_sp0v,
2052 }, {
Yakir Yang0355dde2016-06-12 10:56:02 +08002053 .compatible = "lg,lp097qx1-spa1",
2054 .data = &lg_lp097qx1_spa1,
2055 }, {
Jitao Shi690d8fa2016-02-22 19:01:44 +08002056 .compatible = "lg,lp120up1",
2057 .data = &lg_lp120up1,
2058 }, {
Thierry Redingec7c5652013-11-15 15:59:32 +01002059 .compatible = "lg,lp129qe",
2060 .data = &lg_lp129qe,
2061 }, {
Lucas Stach01bacc132017-06-08 20:07:55 +02002062 .compatible = "nec,nl12880bc20-05",
2063 .data = &nec_nl12880bc20_05,
2064 }, {
jianwei wangc6e87f92015-07-29 16:30:02 +08002065 .compatible = "nec,nl4827hc19-05b",
2066 .data = &nec_nl4827hc19_05b,
2067 }, {
Maxime Riparde6c2f062016-09-06 16:46:17 +02002068 .compatible = "netron-dy,e231732",
2069 .data = &netron_dy_e231732,
2070 }, {
Lucas Stach4177fa62017-06-08 20:07:57 +02002071 .compatible = "nlt,nl192108ac18-02d",
2072 .data = &nlt_nl192108ac18_02d,
2073 }, {
Fabien Lahoudere05ec0e42016-10-17 11:38:01 +02002074 .compatible = "nvd,9128",
2075 .data = &nvd_9128,
2076 }, {
Gary Bissona99fb622015-06-10 18:44:23 +02002077 .compatible = "okaya,rs800480t-7x0gp",
2078 .data = &okaya_rs800480t_7x0gp,
2079 }, {
Maxime Ripardcf5c9e62016-03-23 17:38:34 +01002080 .compatible = "olimex,lcd-olinuxino-43-ts",
2081 .data = &olimex_lcd_olinuxino_43ts,
2082 }, {
Eric Anholte8b6f562016-03-24 17:23:48 -07002083 .compatible = "ontat,yx700wv03",
2084 .data = &ontat_yx700wv03,
2085 }, {
Philipp Zabel725c9d42015-02-11 18:50:11 +01002086 .compatible = "ortustech,com43h4m85ulc",
2087 .data = &ortustech_com43h4m85ulc,
2088 }, {
Josh Wud2a6f0f2015-10-08 17:42:41 +02002089 .compatible = "qiaodian,qd43003c0-40",
2090 .data = &qd43003c0_40,
2091 }, {
Yakir Yang0330eaf2016-06-12 10:56:13 +08002092 .compatible = "samsung,lsn122dl01-c01",
2093 .data = &samsung_lsn122dl01_c01,
2094 }, {
Marc Dietrich6d54e3d2013-12-21 21:38:12 +01002095 .compatible = "samsung,ltn101nt05",
2096 .data = &samsung_ltn101nt05,
2097 }, {
Stéphane Marchesin0c934302015-03-18 10:52:18 +01002098 .compatible = "samsung,ltn140at29-301",
2099 .data = &samsung_ltn140at29_301,
2100 }, {
Joshua Clayton592aa022016-07-06 15:59:16 -07002101 .compatible = "sharp,lq101k1ly04",
2102 .data = &sharp_lq101k1ly04,
2103 }, {
Yakir Yang739c7de2016-06-12 10:56:35 +08002104 .compatible = "sharp,lq123p1jx31",
2105 .data = &sharp_lq123p1jx31,
2106 }, {
Gustaf Lindström0f9cdd72016-10-04 17:29:21 +02002107 .compatible = "sharp,lq150x1lg11",
2108 .data = &sharp_lq150x1lg11,
2109 }, {
Boris BREZILLON9c6615b2015-03-19 14:43:00 +01002110 .compatible = "shelly,sca07010-bfn-lnn",
2111 .data = &shelly_sca07010_bfn_lnn,
2112 }, {
Douglas Anderson9bb34c42016-06-10 10:02:07 -07002113 .compatible = "starry,kr122ea0sra",
2114 .data = &starry_kr122ea0sra,
2115 }, {
Gary Bissonadb973e2016-12-02 09:52:08 +01002116 .compatible = "tianma,tm070jdhg30",
2117 .data = &tianma_tm070jdhg30,
2118 }, {
Bhuvanchandra DV227e4f42016-05-05 11:47:07 +05302119 .compatible = "tpk,f07a-0102",
2120 .data = &tpk_f07a_0102,
2121 }, {
2122 .compatible = "tpk,f10a-0102",
2123 .data = &tpk_f10a_0102,
2124 }, {
Maciej S. Szmigiero06a9dc62016-02-13 22:52:03 +01002125 .compatible = "urt,umsh-8596md-t",
2126 .data = &urt_umsh_8596md_parallel,
2127 }, {
2128 .compatible = "urt,umsh-8596md-1t",
2129 .data = &urt_umsh_8596md_parallel,
2130 }, {
2131 .compatible = "urt,umsh-8596md-7t",
2132 .data = &urt_umsh_8596md_parallel,
2133 }, {
2134 .compatible = "urt,umsh-8596md-11t",
2135 .data = &urt_umsh_8596md_lvds,
2136 }, {
2137 .compatible = "urt,umsh-8596md-19t",
2138 .data = &urt_umsh_8596md_lvds,
2139 }, {
2140 .compatible = "urt,umsh-8596md-20t",
2141 .data = &urt_umsh_8596md_parallel,
2142 }, {
Richard Genoude4bac402017-03-27 12:33:23 +02002143 .compatible = "winstar,wf35ltiacd",
2144 .data = &winstar_wf35ltiacd,
2145 }, {
Thierry Reding280921d2013-08-30 15:10:14 +02002146 /* sentinel */
2147 }
2148};
2149MODULE_DEVICE_TABLE(of, platform_of_match);
2150
2151static int panel_simple_platform_probe(struct platform_device *pdev)
2152{
2153 const struct of_device_id *id;
2154
2155 id = of_match_node(platform_of_match, pdev->dev.of_node);
2156 if (!id)
2157 return -ENODEV;
2158
2159 return panel_simple_probe(&pdev->dev, id->data);
2160}
2161
2162static int panel_simple_platform_remove(struct platform_device *pdev)
2163{
2164 return panel_simple_remove(&pdev->dev);
2165}
2166
Thierry Redingd02fd932014-04-29 17:21:21 +02002167static void panel_simple_platform_shutdown(struct platform_device *pdev)
2168{
2169 panel_simple_shutdown(&pdev->dev);
2170}
2171
Thierry Reding280921d2013-08-30 15:10:14 +02002172static struct platform_driver panel_simple_platform_driver = {
2173 .driver = {
2174 .name = "panel-simple",
Thierry Reding280921d2013-08-30 15:10:14 +02002175 .of_match_table = platform_of_match,
2176 },
2177 .probe = panel_simple_platform_probe,
2178 .remove = panel_simple_platform_remove,
Thierry Redingd02fd932014-04-29 17:21:21 +02002179 .shutdown = panel_simple_platform_shutdown,
Thierry Reding280921d2013-08-30 15:10:14 +02002180};
2181
Thierry Reding210fcd92013-11-22 19:27:11 +01002182struct panel_desc_dsi {
2183 struct panel_desc desc;
2184
Thierry Reding462658b2014-03-14 11:24:57 +01002185 unsigned long flags;
Thierry Reding210fcd92013-11-22 19:27:11 +01002186 enum mipi_dsi_pixel_format format;
2187 unsigned int lanes;
2188};
2189
Thierry Redingd718d792015-04-08 16:52:33 +02002190static const struct drm_display_mode auo_b080uan01_mode = {
2191 .clock = 154500,
2192 .hdisplay = 1200,
2193 .hsync_start = 1200 + 62,
2194 .hsync_end = 1200 + 62 + 4,
2195 .htotal = 1200 + 62 + 4 + 62,
2196 .vdisplay = 1920,
2197 .vsync_start = 1920 + 9,
2198 .vsync_end = 1920 + 9 + 2,
2199 .vtotal = 1920 + 9 + 2 + 8,
2200 .vrefresh = 60,
2201};
2202
2203static const struct panel_desc_dsi auo_b080uan01 = {
2204 .desc = {
2205 .modes = &auo_b080uan01_mode,
2206 .num_modes = 1,
2207 .bpc = 8,
2208 .size = {
2209 .width = 108,
2210 .height = 272,
2211 },
2212 },
2213 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
2214 .format = MIPI_DSI_FMT_RGB888,
2215 .lanes = 4,
2216};
2217
Chris Zhongc8521962015-11-20 16:15:37 +08002218static const struct drm_display_mode boe_tv080wum_nl0_mode = {
2219 .clock = 160000,
2220 .hdisplay = 1200,
2221 .hsync_start = 1200 + 120,
2222 .hsync_end = 1200 + 120 + 20,
2223 .htotal = 1200 + 120 + 20 + 21,
2224 .vdisplay = 1920,
2225 .vsync_start = 1920 + 21,
2226 .vsync_end = 1920 + 21 + 3,
2227 .vtotal = 1920 + 21 + 3 + 18,
2228 .vrefresh = 60,
2229 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
2230};
2231
2232static const struct panel_desc_dsi boe_tv080wum_nl0 = {
2233 .desc = {
2234 .modes = &boe_tv080wum_nl0_mode,
2235 .num_modes = 1,
2236 .size = {
2237 .width = 107,
2238 .height = 172,
2239 },
2240 },
2241 .flags = MIPI_DSI_MODE_VIDEO |
2242 MIPI_DSI_MODE_VIDEO_BURST |
2243 MIPI_DSI_MODE_VIDEO_SYNC_PULSE,
2244 .format = MIPI_DSI_FMT_RGB888,
2245 .lanes = 4,
2246};
2247
Alexandre Courbot712ac1b2014-01-21 18:57:10 +09002248static const struct drm_display_mode lg_ld070wx3_sl01_mode = {
2249 .clock = 71000,
2250 .hdisplay = 800,
2251 .hsync_start = 800 + 32,
2252 .hsync_end = 800 + 32 + 1,
2253 .htotal = 800 + 32 + 1 + 57,
2254 .vdisplay = 1280,
2255 .vsync_start = 1280 + 28,
2256 .vsync_end = 1280 + 28 + 1,
2257 .vtotal = 1280 + 28 + 1 + 14,
2258 .vrefresh = 60,
2259};
2260
2261static const struct panel_desc_dsi lg_ld070wx3_sl01 = {
2262 .desc = {
2263 .modes = &lg_ld070wx3_sl01_mode,
2264 .num_modes = 1,
Thierry Redingd7a839c2014-11-06 10:11:01 +01002265 .bpc = 8,
Alexandre Courbot712ac1b2014-01-21 18:57:10 +09002266 .size = {
2267 .width = 94,
2268 .height = 151,
2269 },
2270 },
Alexandre Courbot5e4cc272014-07-08 21:32:12 +09002271 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_CLOCK_NON_CONTINUOUS,
Alexandre Courbot712ac1b2014-01-21 18:57:10 +09002272 .format = MIPI_DSI_FMT_RGB888,
2273 .lanes = 4,
2274};
2275
Alexandre Courbot499ce852014-01-21 18:57:09 +09002276static const struct drm_display_mode lg_lh500wx1_sd03_mode = {
2277 .clock = 67000,
2278 .hdisplay = 720,
2279 .hsync_start = 720 + 12,
2280 .hsync_end = 720 + 12 + 4,
2281 .htotal = 720 + 12 + 4 + 112,
2282 .vdisplay = 1280,
2283 .vsync_start = 1280 + 8,
2284 .vsync_end = 1280 + 8 + 4,
2285 .vtotal = 1280 + 8 + 4 + 12,
2286 .vrefresh = 60,
2287};
2288
2289static const struct panel_desc_dsi lg_lh500wx1_sd03 = {
2290 .desc = {
2291 .modes = &lg_lh500wx1_sd03_mode,
2292 .num_modes = 1,
Thierry Redingd7a839c2014-11-06 10:11:01 +01002293 .bpc = 8,
Alexandre Courbot499ce852014-01-21 18:57:09 +09002294 .size = {
2295 .width = 62,
2296 .height = 110,
2297 },
2298 },
2299 .flags = MIPI_DSI_MODE_VIDEO,
2300 .format = MIPI_DSI_FMT_RGB888,
2301 .lanes = 4,
2302};
2303
Thierry Reding280921d2013-08-30 15:10:14 +02002304static const struct drm_display_mode panasonic_vvx10f004b00_mode = {
2305 .clock = 157200,
2306 .hdisplay = 1920,
2307 .hsync_start = 1920 + 154,
2308 .hsync_end = 1920 + 154 + 16,
2309 .htotal = 1920 + 154 + 16 + 32,
2310 .vdisplay = 1200,
2311 .vsync_start = 1200 + 17,
2312 .vsync_end = 1200 + 17 + 2,
2313 .vtotal = 1200 + 17 + 2 + 16,
2314 .vrefresh = 60,
2315};
2316
Thierry Reding210fcd92013-11-22 19:27:11 +01002317static const struct panel_desc_dsi panasonic_vvx10f004b00 = {
2318 .desc = {
2319 .modes = &panasonic_vvx10f004b00_mode,
2320 .num_modes = 1,
Thierry Redingd7a839c2014-11-06 10:11:01 +01002321 .bpc = 8,
Thierry Reding210fcd92013-11-22 19:27:11 +01002322 .size = {
2323 .width = 217,
2324 .height = 136,
2325 },
Thierry Reding280921d2013-08-30 15:10:14 +02002326 },
Alexandre Courbot5e4cc272014-07-08 21:32:12 +09002327 .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
2328 MIPI_DSI_CLOCK_NON_CONTINUOUS,
Thierry Reding210fcd92013-11-22 19:27:11 +01002329 .format = MIPI_DSI_FMT_RGB888,
2330 .lanes = 4,
2331};
2332
2333static const struct of_device_id dsi_of_match[] = {
2334 {
Thierry Redingd718d792015-04-08 16:52:33 +02002335 .compatible = "auo,b080uan01",
2336 .data = &auo_b080uan01
2337 }, {
Chris Zhongc8521962015-11-20 16:15:37 +08002338 .compatible = "boe,tv080wum-nl0",
2339 .data = &boe_tv080wum_nl0
2340 }, {
Alexandre Courbot712ac1b2014-01-21 18:57:10 +09002341 .compatible = "lg,ld070wx3-sl01",
2342 .data = &lg_ld070wx3_sl01
2343 }, {
Alexandre Courbot499ce852014-01-21 18:57:09 +09002344 .compatible = "lg,lh500wx1-sd03",
2345 .data = &lg_lh500wx1_sd03
2346 }, {
Thierry Reding210fcd92013-11-22 19:27:11 +01002347 .compatible = "panasonic,vvx10f004b00",
2348 .data = &panasonic_vvx10f004b00
2349 }, {
2350 /* sentinel */
2351 }
2352};
2353MODULE_DEVICE_TABLE(of, dsi_of_match);
2354
2355static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
2356{
2357 const struct panel_desc_dsi *desc;
2358 const struct of_device_id *id;
2359 int err;
2360
2361 id = of_match_node(dsi_of_match, dsi->dev.of_node);
2362 if (!id)
2363 return -ENODEV;
2364
2365 desc = id->data;
2366
2367 err = panel_simple_probe(&dsi->dev, &desc->desc);
2368 if (err < 0)
2369 return err;
2370
Thierry Reding462658b2014-03-14 11:24:57 +01002371 dsi->mode_flags = desc->flags;
Thierry Reding210fcd92013-11-22 19:27:11 +01002372 dsi->format = desc->format;
2373 dsi->lanes = desc->lanes;
2374
2375 return mipi_dsi_attach(dsi);
2376}
2377
2378static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
2379{
2380 int err;
2381
2382 err = mipi_dsi_detach(dsi);
2383 if (err < 0)
2384 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
2385
2386 return panel_simple_remove(&dsi->dev);
2387}
2388
Thierry Redingd02fd932014-04-29 17:21:21 +02002389static void panel_simple_dsi_shutdown(struct mipi_dsi_device *dsi)
2390{
2391 panel_simple_shutdown(&dsi->dev);
2392}
2393
Thierry Reding210fcd92013-11-22 19:27:11 +01002394static struct mipi_dsi_driver panel_simple_dsi_driver = {
2395 .driver = {
2396 .name = "panel-simple-dsi",
Thierry Reding210fcd92013-11-22 19:27:11 +01002397 .of_match_table = dsi_of_match,
2398 },
2399 .probe = panel_simple_dsi_probe,
2400 .remove = panel_simple_dsi_remove,
Thierry Redingd02fd932014-04-29 17:21:21 +02002401 .shutdown = panel_simple_dsi_shutdown,
Thierry Reding280921d2013-08-30 15:10:14 +02002402};
2403
2404static int __init panel_simple_init(void)
2405{
Thierry Reding210fcd92013-11-22 19:27:11 +01002406 int err;
2407
2408 err = platform_driver_register(&panel_simple_platform_driver);
2409 if (err < 0)
2410 return err;
2411
2412 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
2413 err = mipi_dsi_driver_register(&panel_simple_dsi_driver);
2414 if (err < 0)
2415 return err;
2416 }
2417
2418 return 0;
Thierry Reding280921d2013-08-30 15:10:14 +02002419}
2420module_init(panel_simple_init);
2421
2422static void __exit panel_simple_exit(void)
2423{
Thierry Reding210fcd92013-11-22 19:27:11 +01002424 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
2425 mipi_dsi_driver_unregister(&panel_simple_dsi_driver);
2426
Thierry Reding280921d2013-08-30 15:10:14 +02002427 platform_driver_unregister(&panel_simple_platform_driver);
2428}
2429module_exit(panel_simple_exit);
2430
2431MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
2432MODULE_DESCRIPTION("DRM Driver for Simple Panels");
2433MODULE_LICENSE("GPL and additional rights");