1 | /* |
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/debugfs.h> |
25 | #include <linux/delay.h> |
26 | #include <linux/gpio/consumer.h> |
27 | #include <linux/iopoll.h> |
28 | #include <linux/module.h> |
29 | #include <linux/of_platform.h> |
30 | #include <linux/platform_device.h> |
31 | #include <linux/pm_runtime.h> |
32 | #include <linux/regulator/consumer.h> |
33 | |
34 | #include <video/display_timing.h> |
35 | #include <video/of_display_timing.h> |
36 | #include <video/videomode.h> |
37 | |
38 | #include <drm/display/drm_dp_aux_bus.h> |
39 | #include <drm/display/drm_dp_helper.h> |
40 | #include <drm/drm_crtc.h> |
41 | #include <drm/drm_device.h> |
42 | #include <drm/drm_edid.h> |
43 | #include <drm/drm_panel.h> |
44 | |
45 | /** |
46 | * struct panel_delay - Describes delays for a simple panel. |
47 | */ |
48 | struct panel_delay { |
49 | /** |
50 | * @hpd_reliable: Time for HPD to be reliable |
51 | * |
52 | * The time (in milliseconds) that it takes after powering the panel |
53 | * before the HPD signal is reliable. Ideally this is 0 but some panels, |
54 | * board designs, or bad pulldown configs can cause a glitch here. |
55 | * |
56 | * NOTE: on some old panel data this number appears to be much too big. |
57 | * Presumably some old panels simply didn't have HPD hooked up and put |
58 | * the hpd_absent here because this field predates the |
59 | * hpd_absent. While that works, it's non-ideal. |
60 | */ |
61 | unsigned int hpd_reliable; |
62 | |
63 | /** |
64 | * @hpd_absent: Time to wait if HPD isn't hooked up. |
65 | * |
66 | * Add this to the prepare delay if we know Hot Plug Detect isn't used. |
67 | * |
68 | * This is T3-max on eDP timing diagrams or the delay from power on |
69 | * until HPD is guaranteed to be asserted. |
70 | */ |
71 | unsigned int hpd_absent; |
72 | |
73 | /** |
74 | * @powered_on_to_enable: Time between panel powered on and enable. |
75 | * |
76 | * The minimum time, in milliseconds, that needs to have passed |
77 | * between when panel powered on and enable may begin. |
78 | * |
79 | * This is (T3+T4+T5+T6+T8)-min on eDP timing diagrams or after the |
80 | * power supply enabled until we can turn the backlight on and see |
81 | * valid data. |
82 | * |
83 | * This doesn't normally need to be set if timings are already met by |
84 | * prepare_to_enable or enable. |
85 | */ |
86 | unsigned int powered_on_to_enable; |
87 | |
88 | /** |
89 | * @prepare_to_enable: Time between prepare and enable. |
90 | * |
91 | * The minimum time, in milliseconds, that needs to have passed |
92 | * between when prepare finished and enable may begin. If at |
93 | * enable time less time has passed since prepare finished, |
94 | * the driver waits for the remaining time. |
95 | * |
96 | * If a fixed enable delay is also specified, we'll start |
97 | * counting before delaying for the fixed delay. |
98 | * |
99 | * If a fixed prepare delay is also specified, we won't start |
100 | * counting until after the fixed delay. We can't overlap this |
101 | * fixed delay with the min time because the fixed delay |
102 | * doesn't happen at the end of the function if a HPD GPIO was |
103 | * specified. |
104 | * |
105 | * In other words: |
106 | * prepare() |
107 | * ... |
108 | * // do fixed prepare delay |
109 | * // wait for HPD GPIO if applicable |
110 | * // start counting for prepare_to_enable |
111 | * |
112 | * enable() |
113 | * // do fixed enable delay |
114 | * // enforce prepare_to_enable min time |
115 | * |
116 | * This is not specified in a standard way on eDP timing diagrams. |
117 | * It is effectively the time from HPD going high till you can |
118 | * turn on the backlight. |
119 | */ |
120 | unsigned int prepare_to_enable; |
121 | |
122 | /** |
123 | * @enable: Time for the panel to display a valid frame. |
124 | * |
125 | * The time (in milliseconds) that it takes for the panel to |
126 | * display the first valid frame after starting to receive |
127 | * video data. |
128 | * |
129 | * This is (T6-min + max(T7-max, T8-min)) on eDP timing diagrams or |
130 | * the delay after link training finishes until we can turn the |
131 | * backlight on and see valid data. |
132 | */ |
133 | unsigned int enable; |
134 | |
135 | /** |
136 | * @disable: Time for the panel to turn the display off. |
137 | * |
138 | * The time (in milliseconds) that it takes for the panel to |
139 | * turn the display off (no content is visible). |
140 | * |
141 | * This is T9-min (delay from backlight off to end of valid video |
142 | * data) on eDP timing diagrams. It is not common to set. |
143 | */ |
144 | unsigned int disable; |
145 | |
146 | /** |
147 | * @unprepare: Time to power down completely. |
148 | * |
149 | * The time (in milliseconds) that it takes for the panel |
150 | * to power itself down completely. |
151 | * |
152 | * This time is used to prevent a future "prepare" from |
153 | * starting until at least this many milliseconds has passed. |
154 | * If at prepare time less time has passed since unprepare |
155 | * finished, the driver waits for the remaining time. |
156 | * |
157 | * This is T12-min on eDP timing diagrams. |
158 | */ |
159 | unsigned int unprepare; |
160 | }; |
161 | |
162 | /** |
163 | * struct panel_desc - Describes a simple panel. |
164 | */ |
165 | struct panel_desc { |
166 | /** |
167 | * @modes: Pointer to array of fixed modes appropriate for this panel. |
168 | * |
169 | * If only one mode then this can just be the address of the mode. |
170 | * NOTE: cannot be used with "timings" and also if this is specified |
171 | * then you cannot override the mode in the device tree. |
172 | */ |
173 | const struct drm_display_mode *modes; |
174 | |
175 | /** @num_modes: Number of elements in modes array. */ |
176 | unsigned int num_modes; |
177 | |
178 | /** |
179 | * @timings: Pointer to array of display timings |
180 | * |
181 | * NOTE: cannot be used with "modes" and also these will be used to |
182 | * validate a device tree override if one is present. |
183 | */ |
184 | const struct display_timing *timings; |
185 | |
186 | /** @num_timings: Number of elements in timings array. */ |
187 | unsigned int num_timings; |
188 | |
189 | /** @bpc: Bits per color. */ |
190 | unsigned int bpc; |
191 | |
192 | /** @size: Structure containing the physical size of this panel. */ |
193 | struct { |
194 | /** |
195 | * @size.width: Width (in mm) of the active display area. |
196 | */ |
197 | unsigned int width; |
198 | |
199 | /** |
200 | * @size.height: Height (in mm) of the active display area. |
201 | */ |
202 | unsigned int height; |
203 | } size; |
204 | |
205 | /** @delay: Structure containing various delay values for this panel. */ |
206 | struct panel_delay delay; |
207 | }; |
208 | |
209 | /** |
210 | * struct edp_panel_entry - Maps panel ID to delay / panel name. |
211 | */ |
212 | struct edp_panel_entry { |
213 | /** @panel_id: 32-bit ID for panel, encoded with drm_edid_encode_panel_id(). */ |
214 | u32 panel_id; |
215 | |
216 | /** @delay: The power sequencing delays needed for this panel. */ |
217 | const struct panel_delay *delay; |
218 | |
219 | /** @name: Name of this panel (for printing to logs). */ |
220 | const char *name; |
221 | |
222 | /** @override_edid_mode: Override the mode obtained by edid. */ |
223 | const struct drm_display_mode *override_edid_mode; |
224 | }; |
225 | |
226 | struct panel_edp { |
227 | struct drm_panel base; |
228 | bool enabled; |
229 | bool no_hpd; |
230 | |
231 | bool prepared; |
232 | |
233 | ktime_t prepared_time; |
234 | ktime_t powered_on_time; |
235 | ktime_t unprepared_time; |
236 | |
237 | const struct panel_desc *desc; |
238 | |
239 | struct regulator *supply; |
240 | struct i2c_adapter *ddc; |
241 | struct drm_dp_aux *aux; |
242 | |
243 | struct gpio_desc *enable_gpio; |
244 | struct gpio_desc *hpd_gpio; |
245 | |
246 | const struct edp_panel_entry *detected_panel; |
247 | |
248 | struct edid *edid; |
249 | |
250 | struct drm_display_mode override_mode; |
251 | |
252 | enum drm_panel_orientation orientation; |
253 | }; |
254 | |
255 | static inline struct panel_edp *to_panel_edp(struct drm_panel *panel) |
256 | { |
257 | return container_of(panel, struct panel_edp, base); |
258 | } |
259 | |
260 | static unsigned int panel_edp_get_timings_modes(struct panel_edp *panel, |
261 | struct drm_connector *connector) |
262 | { |
263 | struct drm_display_mode *mode; |
264 | unsigned int i, num = 0; |
265 | |
266 | for (i = 0; i < panel->desc->num_timings; i++) { |
267 | const struct display_timing *dt = &panel->desc->timings[i]; |
268 | struct videomode vm; |
269 | |
270 | videomode_from_timing(dt, vm: &vm); |
271 | mode = drm_mode_create(dev: connector->dev); |
272 | if (!mode) { |
273 | dev_err(panel->base.dev, "failed to add mode %ux%u\n" , |
274 | dt->hactive.typ, dt->vactive.typ); |
275 | continue; |
276 | } |
277 | |
278 | drm_display_mode_from_videomode(vm: &vm, dmode: mode); |
279 | |
280 | mode->type |= DRM_MODE_TYPE_DRIVER; |
281 | |
282 | if (panel->desc->num_timings == 1) |
283 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
284 | |
285 | drm_mode_probed_add(connector, mode); |
286 | num++; |
287 | } |
288 | |
289 | return num; |
290 | } |
291 | |
292 | static unsigned int panel_edp_get_display_modes(struct panel_edp *panel, |
293 | struct drm_connector *connector) |
294 | { |
295 | struct drm_display_mode *mode; |
296 | unsigned int i, num = 0; |
297 | |
298 | for (i = 0; i < panel->desc->num_modes; i++) { |
299 | const struct drm_display_mode *m = &panel->desc->modes[i]; |
300 | |
301 | mode = drm_mode_duplicate(dev: connector->dev, mode: m); |
302 | if (!mode) { |
303 | dev_err(panel->base.dev, "failed to add mode %ux%u@%u\n" , |
304 | m->hdisplay, m->vdisplay, |
305 | drm_mode_vrefresh(m)); |
306 | continue; |
307 | } |
308 | |
309 | mode->type |= DRM_MODE_TYPE_DRIVER; |
310 | |
311 | if (panel->desc->num_modes == 1) |
312 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
313 | |
314 | drm_mode_set_name(mode); |
315 | |
316 | drm_mode_probed_add(connector, mode); |
317 | num++; |
318 | } |
319 | |
320 | return num; |
321 | } |
322 | |
323 | static int panel_edp_override_edid_mode(struct panel_edp *panel, |
324 | struct drm_connector *connector, |
325 | const struct drm_display_mode *override_mode) |
326 | { |
327 | struct drm_display_mode *mode; |
328 | |
329 | mode = drm_mode_duplicate(dev: connector->dev, mode: override_mode); |
330 | if (!mode) { |
331 | dev_err(panel->base.dev, "failed to add additional mode\n" ); |
332 | return 0; |
333 | } |
334 | |
335 | mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
336 | drm_mode_set_name(mode); |
337 | drm_mode_probed_add(connector, mode); |
338 | return 1; |
339 | } |
340 | |
341 | static int panel_edp_get_non_edid_modes(struct panel_edp *panel, |
342 | struct drm_connector *connector) |
343 | { |
344 | struct drm_display_mode *mode; |
345 | bool has_override = panel->override_mode.type; |
346 | unsigned int num = 0; |
347 | |
348 | if (!panel->desc) |
349 | return 0; |
350 | |
351 | if (has_override) { |
352 | mode = drm_mode_duplicate(dev: connector->dev, |
353 | mode: &panel->override_mode); |
354 | if (mode) { |
355 | drm_mode_probed_add(connector, mode); |
356 | num = 1; |
357 | } else { |
358 | dev_err(panel->base.dev, "failed to add override mode\n" ); |
359 | } |
360 | } |
361 | |
362 | /* Only add timings if override was not there or failed to validate */ |
363 | if (num == 0 && panel->desc->num_timings) |
364 | num = panel_edp_get_timings_modes(panel, connector); |
365 | |
366 | /* |
367 | * Only add fixed modes if timings/override added no mode. |
368 | * |
369 | * We should only ever have either the display timings specified |
370 | * or a fixed mode. Anything else is rather bogus. |
371 | */ |
372 | WARN_ON(panel->desc->num_timings && panel->desc->num_modes); |
373 | if (num == 0) |
374 | num = panel_edp_get_display_modes(panel, connector); |
375 | |
376 | connector->display_info.bpc = panel->desc->bpc; |
377 | connector->display_info.width_mm = panel->desc->size.width; |
378 | connector->display_info.height_mm = panel->desc->size.height; |
379 | |
380 | return num; |
381 | } |
382 | |
383 | static void panel_edp_wait(ktime_t start_ktime, unsigned int min_ms) |
384 | { |
385 | ktime_t now_ktime, min_ktime; |
386 | |
387 | if (!min_ms) |
388 | return; |
389 | |
390 | min_ktime = ktime_add(start_ktime, ms_to_ktime(min_ms)); |
391 | now_ktime = ktime_get_boottime(); |
392 | |
393 | if (ktime_before(cmp1: now_ktime, cmp2: min_ktime)) |
394 | msleep(msecs: ktime_to_ms(ktime_sub(min_ktime, now_ktime)) + 1); |
395 | } |
396 | |
397 | static int panel_edp_disable(struct drm_panel *panel) |
398 | { |
399 | struct panel_edp *p = to_panel_edp(panel); |
400 | |
401 | if (!p->enabled) |
402 | return 0; |
403 | |
404 | if (p->desc->delay.disable) |
405 | msleep(msecs: p->desc->delay.disable); |
406 | |
407 | p->enabled = false; |
408 | |
409 | return 0; |
410 | } |
411 | |
412 | static int panel_edp_suspend(struct device *dev) |
413 | { |
414 | struct panel_edp *p = dev_get_drvdata(dev); |
415 | |
416 | drm_dp_dpcd_set_powered(aux: p->aux, powered: false); |
417 | gpiod_set_value_cansleep(desc: p->enable_gpio, value: 0); |
418 | regulator_disable(regulator: p->supply); |
419 | p->unprepared_time = ktime_get_boottime(); |
420 | |
421 | return 0; |
422 | } |
423 | |
424 | static int panel_edp_unprepare(struct drm_panel *panel) |
425 | { |
426 | struct panel_edp *p = to_panel_edp(panel); |
427 | int ret; |
428 | |
429 | /* Unpreparing when already unprepared is a no-op */ |
430 | if (!p->prepared) |
431 | return 0; |
432 | |
433 | ret = pm_runtime_put_sync_suspend(dev: panel->dev); |
434 | if (ret < 0) |
435 | return ret; |
436 | p->prepared = false; |
437 | |
438 | return 0; |
439 | } |
440 | |
441 | static int panel_edp_get_hpd_gpio(struct device *dev, struct panel_edp *p) |
442 | { |
443 | p->hpd_gpio = devm_gpiod_get_optional(dev, con_id: "hpd" , flags: GPIOD_IN); |
444 | if (IS_ERR(ptr: p->hpd_gpio)) |
445 | return dev_err_probe(dev, err: PTR_ERR(ptr: p->hpd_gpio), |
446 | fmt: "failed to get 'hpd' GPIO\n" ); |
447 | |
448 | return 0; |
449 | } |
450 | |
451 | static bool panel_edp_can_read_hpd(struct panel_edp *p) |
452 | { |
453 | return !p->no_hpd && (p->hpd_gpio || (p->aux && p->aux->wait_hpd_asserted)); |
454 | } |
455 | |
456 | static int panel_edp_prepare_once(struct panel_edp *p) |
457 | { |
458 | struct device *dev = p->base.dev; |
459 | unsigned int delay; |
460 | int err; |
461 | int hpd_asserted; |
462 | unsigned long hpd_wait_us; |
463 | |
464 | panel_edp_wait(start_ktime: p->unprepared_time, min_ms: p->desc->delay.unprepare); |
465 | |
466 | err = regulator_enable(regulator: p->supply); |
467 | if (err < 0) { |
468 | dev_err(dev, "failed to enable supply: %d\n" , err); |
469 | return err; |
470 | } |
471 | |
472 | gpiod_set_value_cansleep(desc: p->enable_gpio, value: 1); |
473 | drm_dp_dpcd_set_powered(aux: p->aux, powered: true); |
474 | |
475 | p->powered_on_time = ktime_get_boottime(); |
476 | |
477 | delay = p->desc->delay.hpd_reliable; |
478 | if (p->no_hpd) |
479 | delay = max(delay, p->desc->delay.hpd_absent); |
480 | if (delay) |
481 | msleep(msecs: delay); |
482 | |
483 | if (panel_edp_can_read_hpd(p)) { |
484 | if (p->desc->delay.hpd_absent) |
485 | hpd_wait_us = p->desc->delay.hpd_absent * 1000UL; |
486 | else |
487 | hpd_wait_us = 2000000; |
488 | |
489 | if (p->hpd_gpio) { |
490 | err = readx_poll_timeout(gpiod_get_value_cansleep, |
491 | p->hpd_gpio, hpd_asserted, |
492 | hpd_asserted, 1000, hpd_wait_us); |
493 | if (hpd_asserted < 0) |
494 | err = hpd_asserted; |
495 | } else { |
496 | err = p->aux->wait_hpd_asserted(p->aux, hpd_wait_us); |
497 | } |
498 | |
499 | if (err) { |
500 | if (err != -ETIMEDOUT) |
501 | dev_err(dev, |
502 | "error waiting for hpd GPIO: %d\n" , err); |
503 | goto error; |
504 | } |
505 | } |
506 | |
507 | p->prepared_time = ktime_get_boottime(); |
508 | |
509 | return 0; |
510 | |
511 | error: |
512 | drm_dp_dpcd_set_powered(aux: p->aux, powered: false); |
513 | gpiod_set_value_cansleep(desc: p->enable_gpio, value: 0); |
514 | regulator_disable(regulator: p->supply); |
515 | p->unprepared_time = ktime_get_boottime(); |
516 | |
517 | return err; |
518 | } |
519 | |
520 | /* |
521 | * Some panels simply don't always come up and need to be power cycled to |
522 | * work properly. We'll allow for a handful of retries. |
523 | */ |
524 | #define MAX_PANEL_PREPARE_TRIES 5 |
525 | |
526 | static int panel_edp_resume(struct device *dev) |
527 | { |
528 | struct panel_edp *p = dev_get_drvdata(dev); |
529 | int ret; |
530 | int try; |
531 | |
532 | for (try = 0; try < MAX_PANEL_PREPARE_TRIES; try++) { |
533 | ret = panel_edp_prepare_once(p); |
534 | if (ret != -ETIMEDOUT) |
535 | break; |
536 | } |
537 | |
538 | if (ret == -ETIMEDOUT) |
539 | dev_err(dev, "Prepare timeout after %d tries\n" , try); |
540 | else if (try) |
541 | dev_warn(dev, "Prepare needed %d retries\n" , try); |
542 | |
543 | return ret; |
544 | } |
545 | |
546 | static int panel_edp_prepare(struct drm_panel *panel) |
547 | { |
548 | struct panel_edp *p = to_panel_edp(panel); |
549 | int ret; |
550 | |
551 | /* Preparing when already prepared is a no-op */ |
552 | if (p->prepared) |
553 | return 0; |
554 | |
555 | ret = pm_runtime_get_sync(dev: panel->dev); |
556 | if (ret < 0) { |
557 | pm_runtime_put_autosuspend(dev: panel->dev); |
558 | return ret; |
559 | } |
560 | |
561 | p->prepared = true; |
562 | |
563 | return 0; |
564 | } |
565 | |
566 | static int panel_edp_enable(struct drm_panel *panel) |
567 | { |
568 | struct panel_edp *p = to_panel_edp(panel); |
569 | unsigned int delay; |
570 | |
571 | if (p->enabled) |
572 | return 0; |
573 | |
574 | delay = p->desc->delay.enable; |
575 | |
576 | /* |
577 | * If there is a "prepare_to_enable" delay then that's supposed to be |
578 | * the delay from HPD going high until we can turn the backlight on. |
579 | * However, we can only count this if HPD is readable by the panel |
580 | * driver. |
581 | * |
582 | * If we aren't handling the HPD pin ourselves then the best we |
583 | * can do is assume that HPD went high immediately before we were |
584 | * called (and link training took zero time). Note that "no-hpd" |
585 | * actually counts as handling HPD ourselves since we're doing the |
586 | * worst case delay (in prepare) ourselves. |
587 | * |
588 | * NOTE: if we ever end up in this "if" statement then we're |
589 | * guaranteed that the panel_edp_wait() call below will do no delay. |
590 | * It already handles that case, though, so we don't need any special |
591 | * code for it. |
592 | */ |
593 | if (p->desc->delay.prepare_to_enable && |
594 | !panel_edp_can_read_hpd(p) && !p->no_hpd) |
595 | delay = max(delay, p->desc->delay.prepare_to_enable); |
596 | |
597 | if (delay) |
598 | msleep(msecs: delay); |
599 | |
600 | panel_edp_wait(start_ktime: p->prepared_time, min_ms: p->desc->delay.prepare_to_enable); |
601 | |
602 | panel_edp_wait(start_ktime: p->powered_on_time, min_ms: p->desc->delay.powered_on_to_enable); |
603 | |
604 | p->enabled = true; |
605 | |
606 | return 0; |
607 | } |
608 | |
609 | static int panel_edp_get_modes(struct drm_panel *panel, |
610 | struct drm_connector *connector) |
611 | { |
612 | struct panel_edp *p = to_panel_edp(panel); |
613 | int num = 0; |
614 | bool has_hard_coded_modes = p->desc->num_timings || p->desc->num_modes; |
615 | bool has_override_edid_mode = p->detected_panel && |
616 | p->detected_panel != ERR_PTR(error: -EINVAL) && |
617 | p->detected_panel->override_edid_mode; |
618 | |
619 | /* probe EDID if a DDC bus is available */ |
620 | if (p->ddc) { |
621 | pm_runtime_get_sync(dev: panel->dev); |
622 | |
623 | if (!p->edid) |
624 | p->edid = drm_get_edid(connector, adapter: p->ddc); |
625 | /* |
626 | * If both edid and hard-coded modes exists, skip edid modes to |
627 | * avoid multiple preferred modes. |
628 | */ |
629 | if (p->edid && !has_hard_coded_modes) { |
630 | if (has_override_edid_mode) { |
631 | /* |
632 | * override_edid_mode is specified. Use |
633 | * override_edid_mode instead of from edid. |
634 | */ |
635 | num += panel_edp_override_edid_mode(panel: p, connector, |
636 | override_mode: p->detected_panel->override_edid_mode); |
637 | } else { |
638 | num += drm_add_edid_modes(connector, edid: p->edid); |
639 | } |
640 | } |
641 | |
642 | pm_runtime_mark_last_busy(dev: panel->dev); |
643 | pm_runtime_put_autosuspend(dev: panel->dev); |
644 | } |
645 | |
646 | if (has_hard_coded_modes) |
647 | num += panel_edp_get_non_edid_modes(panel: p, connector); |
648 | else if (!num) |
649 | dev_warn(p->base.dev, "No display modes\n" ); |
650 | |
651 | /* |
652 | * TODO: Remove once all drm drivers call |
653 | * drm_connector_set_orientation_from_panel() |
654 | */ |
655 | drm_connector_set_panel_orientation(connector, panel_orientation: p->orientation); |
656 | |
657 | return num; |
658 | } |
659 | |
660 | static int panel_edp_get_timings(struct drm_panel *panel, |
661 | unsigned int num_timings, |
662 | struct display_timing *timings) |
663 | { |
664 | struct panel_edp *p = to_panel_edp(panel); |
665 | unsigned int i; |
666 | |
667 | if (p->desc->num_timings < num_timings) |
668 | num_timings = p->desc->num_timings; |
669 | |
670 | if (timings) |
671 | for (i = 0; i < num_timings; i++) |
672 | timings[i] = p->desc->timings[i]; |
673 | |
674 | return p->desc->num_timings; |
675 | } |
676 | |
677 | static enum drm_panel_orientation panel_edp_get_orientation(struct drm_panel *panel) |
678 | { |
679 | struct panel_edp *p = to_panel_edp(panel); |
680 | |
681 | return p->orientation; |
682 | } |
683 | |
684 | static int detected_panel_show(struct seq_file *s, void *data) |
685 | { |
686 | struct drm_panel *panel = s->private; |
687 | struct panel_edp *p = to_panel_edp(panel); |
688 | |
689 | if (IS_ERR(ptr: p->detected_panel)) |
690 | seq_puts(m: s, s: "UNKNOWN\n" ); |
691 | else if (!p->detected_panel) |
692 | seq_puts(m: s, s: "HARDCODED\n" ); |
693 | else |
694 | seq_printf(m: s, fmt: "%s\n" , p->detected_panel->name); |
695 | |
696 | return 0; |
697 | } |
698 | |
699 | DEFINE_SHOW_ATTRIBUTE(detected_panel); |
700 | |
701 | static void panel_edp_debugfs_init(struct drm_panel *panel, struct dentry *root) |
702 | { |
703 | debugfs_create_file(name: "detected_panel" , mode: 0600, parent: root, data: panel, fops: &detected_panel_fops); |
704 | } |
705 | |
706 | static const struct drm_panel_funcs panel_edp_funcs = { |
707 | .disable = panel_edp_disable, |
708 | .unprepare = panel_edp_unprepare, |
709 | .prepare = panel_edp_prepare, |
710 | .enable = panel_edp_enable, |
711 | .get_modes = panel_edp_get_modes, |
712 | .get_orientation = panel_edp_get_orientation, |
713 | .get_timings = panel_edp_get_timings, |
714 | .debugfs_init = panel_edp_debugfs_init, |
715 | }; |
716 | |
717 | #define PANEL_EDP_BOUNDS_CHECK(to_check, bounds, field) \ |
718 | (to_check->field.typ >= bounds->field.min && \ |
719 | to_check->field.typ <= bounds->field.max) |
720 | static void panel_edp_parse_panel_timing_node(struct device *dev, |
721 | struct panel_edp *panel, |
722 | const struct display_timing *ot) |
723 | { |
724 | const struct panel_desc *desc = panel->desc; |
725 | struct videomode vm; |
726 | unsigned int i; |
727 | |
728 | if (WARN_ON(desc->num_modes)) { |
729 | dev_err(dev, "Reject override mode: panel has a fixed mode\n" ); |
730 | return; |
731 | } |
732 | if (WARN_ON(!desc->num_timings)) { |
733 | dev_err(dev, "Reject override mode: no timings specified\n" ); |
734 | return; |
735 | } |
736 | |
737 | for (i = 0; i < panel->desc->num_timings; i++) { |
738 | const struct display_timing *dt = &panel->desc->timings[i]; |
739 | |
740 | if (!PANEL_EDP_BOUNDS_CHECK(ot, dt, hactive) || |
741 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, hfront_porch) || |
742 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, hback_porch) || |
743 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, hsync_len) || |
744 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, vactive) || |
745 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, vfront_porch) || |
746 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, vback_porch) || |
747 | !PANEL_EDP_BOUNDS_CHECK(ot, dt, vsync_len)) |
748 | continue; |
749 | |
750 | if (ot->flags != dt->flags) |
751 | continue; |
752 | |
753 | videomode_from_timing(dt: ot, vm: &vm); |
754 | drm_display_mode_from_videomode(vm: &vm, dmode: &panel->override_mode); |
755 | panel->override_mode.type |= DRM_MODE_TYPE_DRIVER | |
756 | DRM_MODE_TYPE_PREFERRED; |
757 | break; |
758 | } |
759 | |
760 | if (WARN_ON(!panel->override_mode.type)) |
761 | dev_err(dev, "Reject override mode: No display_timing found\n" ); |
762 | } |
763 | |
764 | static const struct edp_panel_entry *find_edp_panel(u32 panel_id); |
765 | |
766 | static int generic_edp_panel_probe(struct device *dev, struct panel_edp *panel) |
767 | { |
768 | struct panel_desc *desc; |
769 | u32 panel_id; |
770 | char vend[4]; |
771 | u16 product_id; |
772 | u32 reliable_ms = 0; |
773 | u32 absent_ms = 0; |
774 | int ret; |
775 | |
776 | desc = devm_kzalloc(dev, size: sizeof(*desc), GFP_KERNEL); |
777 | if (!desc) |
778 | return -ENOMEM; |
779 | panel->desc = desc; |
780 | |
781 | /* |
782 | * Read the dts properties for the initial probe. These are used by |
783 | * the runtime resume code which will get called by the |
784 | * pm_runtime_get_sync() call below. |
785 | */ |
786 | of_property_read_u32(np: dev->of_node, propname: "hpd-reliable-delay-ms" , out_value: &reliable_ms); |
787 | desc->delay.hpd_reliable = reliable_ms; |
788 | of_property_read_u32(np: dev->of_node, propname: "hpd-absent-delay-ms" , out_value: &absent_ms); |
789 | desc->delay.hpd_absent = absent_ms; |
790 | |
791 | /* Power the panel on so we can read the EDID */ |
792 | ret = pm_runtime_get_sync(dev); |
793 | if (ret < 0) { |
794 | dev_err(dev, "Couldn't power on panel to read EDID: %d\n" , ret); |
795 | goto exit; |
796 | } |
797 | |
798 | panel_id = drm_edid_get_panel_id(adapter: panel->ddc); |
799 | if (!panel_id) { |
800 | dev_err(dev, "Couldn't identify panel via EDID\n" ); |
801 | ret = -EIO; |
802 | goto exit; |
803 | } |
804 | drm_edid_decode_panel_id(panel_id, vend, product_id: &product_id); |
805 | |
806 | panel->detected_panel = find_edp_panel(panel_id); |
807 | |
808 | /* |
809 | * We're using non-optimized timings and want it really obvious that |
810 | * someone needs to add an entry to the table, so we'll do a WARN_ON |
811 | * splat. |
812 | */ |
813 | if (WARN_ON(!panel->detected_panel)) { |
814 | dev_warn(dev, |
815 | "Unknown panel %s %#06x, using conservative timings\n" , |
816 | vend, product_id); |
817 | |
818 | /* |
819 | * It's highly likely that the panel will work if we use very |
820 | * conservative timings, so let's do that. We already know that |
821 | * the HPD-related delays must have worked since we got this |
822 | * far, so we really just need the "unprepare" / "enable" |
823 | * delays. We don't need "prepare_to_enable" since that |
824 | * overlaps the "enable" delay anyway. |
825 | * |
826 | * Nearly all panels have a "unprepare" delay of 500 ms though |
827 | * there are a few with 1000. Let's stick 2000 in just to be |
828 | * super conservative. |
829 | * |
830 | * An "enable" delay of 80 ms seems the most common, but we'll |
831 | * throw in 200 ms to be safe. |
832 | */ |
833 | desc->delay.unprepare = 2000; |
834 | desc->delay.enable = 200; |
835 | |
836 | panel->detected_panel = ERR_PTR(error: -EINVAL); |
837 | } else { |
838 | dev_info(dev, "Detected %s %s (%#06x)\n" , |
839 | vend, panel->detected_panel->name, product_id); |
840 | |
841 | /* Update the delay; everything else comes from EDID */ |
842 | desc->delay = *panel->detected_panel->delay; |
843 | } |
844 | |
845 | ret = 0; |
846 | exit: |
847 | pm_runtime_mark_last_busy(dev); |
848 | pm_runtime_put_autosuspend(dev); |
849 | |
850 | return ret; |
851 | } |
852 | |
853 | static int panel_edp_probe(struct device *dev, const struct panel_desc *desc, |
854 | struct drm_dp_aux *aux) |
855 | { |
856 | struct panel_edp *panel; |
857 | struct display_timing dt; |
858 | struct device_node *ddc; |
859 | int err; |
860 | |
861 | panel = devm_kzalloc(dev, size: sizeof(*panel), GFP_KERNEL); |
862 | if (!panel) |
863 | return -ENOMEM; |
864 | |
865 | panel->enabled = false; |
866 | panel->prepared_time = 0; |
867 | panel->desc = desc; |
868 | panel->aux = aux; |
869 | |
870 | panel->no_hpd = of_property_read_bool(np: dev->of_node, propname: "no-hpd" ); |
871 | if (!panel->no_hpd) { |
872 | err = panel_edp_get_hpd_gpio(dev, p: panel); |
873 | if (err) |
874 | return err; |
875 | } |
876 | |
877 | panel->supply = devm_regulator_get(dev, id: "power" ); |
878 | if (IS_ERR(ptr: panel->supply)) |
879 | return PTR_ERR(ptr: panel->supply); |
880 | |
881 | panel->enable_gpio = devm_gpiod_get_optional(dev, con_id: "enable" , |
882 | flags: GPIOD_OUT_LOW); |
883 | if (IS_ERR(ptr: panel->enable_gpio)) |
884 | return dev_err_probe(dev, err: PTR_ERR(ptr: panel->enable_gpio), |
885 | fmt: "failed to request GPIO\n" ); |
886 | |
887 | err = of_drm_get_panel_orientation(np: dev->of_node, orientation: &panel->orientation); |
888 | if (err) { |
889 | dev_err(dev, "%pOF: failed to get orientation %d\n" , dev->of_node, err); |
890 | return err; |
891 | } |
892 | |
893 | ddc = of_parse_phandle(np: dev->of_node, phandle_name: "ddc-i2c-bus" , index: 0); |
894 | if (ddc) { |
895 | panel->ddc = of_find_i2c_adapter_by_node(node: ddc); |
896 | of_node_put(node: ddc); |
897 | |
898 | if (!panel->ddc) |
899 | return -EPROBE_DEFER; |
900 | } else if (aux) { |
901 | panel->ddc = &aux->ddc; |
902 | } |
903 | |
904 | if (!of_get_display_timing(np: dev->of_node, name: "panel-timing" , dt: &dt)) |
905 | panel_edp_parse_panel_timing_node(dev, panel, ot: &dt); |
906 | |
907 | dev_set_drvdata(dev, data: panel); |
908 | |
909 | drm_panel_init(panel: &panel->base, dev, funcs: &panel_edp_funcs, DRM_MODE_CONNECTOR_eDP); |
910 | |
911 | err = drm_panel_of_backlight(panel: &panel->base); |
912 | if (err) |
913 | goto err_finished_ddc_init; |
914 | |
915 | /* |
916 | * We use runtime PM for prepare / unprepare since those power the panel |
917 | * on and off and those can be very slow operations. This is important |
918 | * to optimize powering the panel on briefly to read the EDID before |
919 | * fully enabling the panel. |
920 | */ |
921 | pm_runtime_enable(dev); |
922 | pm_runtime_set_autosuspend_delay(dev, delay: 1000); |
923 | pm_runtime_use_autosuspend(dev); |
924 | |
925 | if (of_device_is_compatible(device: dev->of_node, "edp-panel" )) { |
926 | err = generic_edp_panel_probe(dev, panel); |
927 | if (err) { |
928 | dev_err_probe(dev, err, |
929 | fmt: "Couldn't detect panel nor find a fallback\n" ); |
930 | goto err_finished_pm_runtime; |
931 | } |
932 | /* generic_edp_panel_probe() replaces desc in the panel */ |
933 | desc = panel->desc; |
934 | } else if (desc->bpc != 6 && desc->bpc != 8 && desc->bpc != 10) { |
935 | dev_warn(dev, "Expected bpc in {6,8,10} but got: %u\n" , desc->bpc); |
936 | } |
937 | |
938 | if (!panel->base.backlight && panel->aux) { |
939 | pm_runtime_get_sync(dev); |
940 | err = drm_panel_dp_aux_backlight(panel: &panel->base, aux: panel->aux); |
941 | pm_runtime_mark_last_busy(dev); |
942 | pm_runtime_put_autosuspend(dev); |
943 | if (err) |
944 | goto err_finished_pm_runtime; |
945 | } |
946 | |
947 | drm_panel_add(panel: &panel->base); |
948 | |
949 | return 0; |
950 | |
951 | err_finished_pm_runtime: |
952 | pm_runtime_dont_use_autosuspend(dev); |
953 | pm_runtime_disable(dev); |
954 | err_finished_ddc_init: |
955 | if (panel->ddc && (!panel->aux || panel->ddc != &panel->aux->ddc)) |
956 | put_device(dev: &panel->ddc->dev); |
957 | |
958 | return err; |
959 | } |
960 | |
961 | static void panel_edp_remove(struct device *dev) |
962 | { |
963 | struct panel_edp *panel = dev_get_drvdata(dev); |
964 | |
965 | drm_panel_remove(panel: &panel->base); |
966 | drm_panel_disable(panel: &panel->base); |
967 | drm_panel_unprepare(panel: &panel->base); |
968 | |
969 | pm_runtime_dont_use_autosuspend(dev); |
970 | pm_runtime_disable(dev); |
971 | if (panel->ddc && (!panel->aux || panel->ddc != &panel->aux->ddc)) |
972 | put_device(dev: &panel->ddc->dev); |
973 | |
974 | kfree(objp: panel->edid); |
975 | panel->edid = NULL; |
976 | } |
977 | |
978 | static void panel_edp_shutdown(struct device *dev) |
979 | { |
980 | struct panel_edp *panel = dev_get_drvdata(dev); |
981 | |
982 | drm_panel_disable(panel: &panel->base); |
983 | drm_panel_unprepare(panel: &panel->base); |
984 | } |
985 | |
986 | static const struct display_timing auo_b101ean01_timing = { |
987 | .pixelclock = { 65300000, 72500000, 75000000 }, |
988 | .hactive = { 1280, 1280, 1280 }, |
989 | .hfront_porch = { 18, 119, 119 }, |
990 | .hback_porch = { 21, 21, 21 }, |
991 | .hsync_len = { 32, 32, 32 }, |
992 | .vactive = { 800, 800, 800 }, |
993 | .vfront_porch = { 4, 4, 4 }, |
994 | .vback_porch = { 8, 8, 8 }, |
995 | .vsync_len = { 18, 20, 20 }, |
996 | }; |
997 | |
998 | static const struct panel_desc auo_b101ean01 = { |
999 | .timings = &auo_b101ean01_timing, |
1000 | .num_timings = 1, |
1001 | .bpc = 6, |
1002 | .size = { |
1003 | .width = 217, |
1004 | .height = 136, |
1005 | }, |
1006 | }; |
1007 | |
1008 | static const struct drm_display_mode auo_b116xak01_mode = { |
1009 | .clock = 69300, |
1010 | .hdisplay = 1366, |
1011 | .hsync_start = 1366 + 48, |
1012 | .hsync_end = 1366 + 48 + 32, |
1013 | .htotal = 1366 + 48 + 32 + 10, |
1014 | .vdisplay = 768, |
1015 | .vsync_start = 768 + 4, |
1016 | .vsync_end = 768 + 4 + 6, |
1017 | .vtotal = 768 + 4 + 6 + 15, |
1018 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1019 | }; |
1020 | |
1021 | static const struct panel_desc auo_b116xak01 = { |
1022 | .modes = &auo_b116xak01_mode, |
1023 | .num_modes = 1, |
1024 | .bpc = 6, |
1025 | .size = { |
1026 | .width = 256, |
1027 | .height = 144, |
1028 | }, |
1029 | .delay = { |
1030 | .hpd_absent = 200, |
1031 | .unprepare = 500, |
1032 | .enable = 50, |
1033 | }, |
1034 | }; |
1035 | |
1036 | static const struct drm_display_mode auo_b133han05_mode = { |
1037 | .clock = 142600, |
1038 | .hdisplay = 1920, |
1039 | .hsync_start = 1920 + 58, |
1040 | .hsync_end = 1920 + 58 + 42, |
1041 | .htotal = 1920 + 58 + 42 + 60, |
1042 | .vdisplay = 1080, |
1043 | .vsync_start = 1080 + 3, |
1044 | .vsync_end = 1080 + 3 + 5, |
1045 | .vtotal = 1080 + 3 + 5 + 54, |
1046 | }; |
1047 | |
1048 | static const struct panel_desc auo_b133han05 = { |
1049 | .modes = &auo_b133han05_mode, |
1050 | .num_modes = 1, |
1051 | .bpc = 8, |
1052 | .size = { |
1053 | .width = 293, |
1054 | .height = 165, |
1055 | }, |
1056 | .delay = { |
1057 | .hpd_reliable = 100, |
1058 | .enable = 20, |
1059 | .unprepare = 50, |
1060 | }, |
1061 | }; |
1062 | |
1063 | static const struct drm_display_mode auo_b133htn01_mode = { |
1064 | .clock = 150660, |
1065 | .hdisplay = 1920, |
1066 | .hsync_start = 1920 + 172, |
1067 | .hsync_end = 1920 + 172 + 80, |
1068 | .htotal = 1920 + 172 + 80 + 60, |
1069 | .vdisplay = 1080, |
1070 | .vsync_start = 1080 + 25, |
1071 | .vsync_end = 1080 + 25 + 10, |
1072 | .vtotal = 1080 + 25 + 10 + 10, |
1073 | }; |
1074 | |
1075 | static const struct panel_desc auo_b133htn01 = { |
1076 | .modes = &auo_b133htn01_mode, |
1077 | .num_modes = 1, |
1078 | .bpc = 6, |
1079 | .size = { |
1080 | .width = 293, |
1081 | .height = 165, |
1082 | }, |
1083 | .delay = { |
1084 | .hpd_reliable = 105, |
1085 | .enable = 20, |
1086 | .unprepare = 50, |
1087 | }, |
1088 | }; |
1089 | |
1090 | static const struct drm_display_mode auo_b133xtn01_mode = { |
1091 | .clock = 69500, |
1092 | .hdisplay = 1366, |
1093 | .hsync_start = 1366 + 48, |
1094 | .hsync_end = 1366 + 48 + 32, |
1095 | .htotal = 1366 + 48 + 32 + 20, |
1096 | .vdisplay = 768, |
1097 | .vsync_start = 768 + 3, |
1098 | .vsync_end = 768 + 3 + 6, |
1099 | .vtotal = 768 + 3 + 6 + 13, |
1100 | }; |
1101 | |
1102 | static const struct panel_desc auo_b133xtn01 = { |
1103 | .modes = &auo_b133xtn01_mode, |
1104 | .num_modes = 1, |
1105 | .bpc = 6, |
1106 | .size = { |
1107 | .width = 293, |
1108 | .height = 165, |
1109 | }, |
1110 | }; |
1111 | |
1112 | static const struct drm_display_mode auo_b140han06_mode = { |
1113 | .clock = 141000, |
1114 | .hdisplay = 1920, |
1115 | .hsync_start = 1920 + 16, |
1116 | .hsync_end = 1920 + 16 + 16, |
1117 | .htotal = 1920 + 16 + 16 + 152, |
1118 | .vdisplay = 1080, |
1119 | .vsync_start = 1080 + 3, |
1120 | .vsync_end = 1080 + 3 + 14, |
1121 | .vtotal = 1080 + 3 + 14 + 19, |
1122 | }; |
1123 | |
1124 | static const struct panel_desc auo_b140han06 = { |
1125 | .modes = &auo_b140han06_mode, |
1126 | .num_modes = 1, |
1127 | .bpc = 8, |
1128 | .size = { |
1129 | .width = 309, |
1130 | .height = 174, |
1131 | }, |
1132 | .delay = { |
1133 | .hpd_reliable = 100, |
1134 | .enable = 20, |
1135 | .unprepare = 50, |
1136 | }, |
1137 | }; |
1138 | |
1139 | static const struct drm_display_mode boe_nv101wxmn51_modes[] = { |
1140 | { |
1141 | .clock = 71900, |
1142 | .hdisplay = 1280, |
1143 | .hsync_start = 1280 + 48, |
1144 | .hsync_end = 1280 + 48 + 32, |
1145 | .htotal = 1280 + 48 + 32 + 80, |
1146 | .vdisplay = 800, |
1147 | .vsync_start = 800 + 3, |
1148 | .vsync_end = 800 + 3 + 5, |
1149 | .vtotal = 800 + 3 + 5 + 24, |
1150 | }, |
1151 | { |
1152 | .clock = 57500, |
1153 | .hdisplay = 1280, |
1154 | .hsync_start = 1280 + 48, |
1155 | .hsync_end = 1280 + 48 + 32, |
1156 | .htotal = 1280 + 48 + 32 + 80, |
1157 | .vdisplay = 800, |
1158 | .vsync_start = 800 + 3, |
1159 | .vsync_end = 800 + 3 + 5, |
1160 | .vtotal = 800 + 3 + 5 + 24, |
1161 | }, |
1162 | }; |
1163 | |
1164 | static const struct panel_desc boe_nv101wxmn51 = { |
1165 | .modes = boe_nv101wxmn51_modes, |
1166 | .num_modes = ARRAY_SIZE(boe_nv101wxmn51_modes), |
1167 | .bpc = 8, |
1168 | .size = { |
1169 | .width = 217, |
1170 | .height = 136, |
1171 | }, |
1172 | .delay = { |
1173 | /* TODO: should be hpd-absent and no-hpd should be set? */ |
1174 | .hpd_reliable = 210, |
1175 | .enable = 50, |
1176 | .unprepare = 160, |
1177 | }, |
1178 | }; |
1179 | |
1180 | static const struct drm_display_mode boe_nv110wtm_n61_modes[] = { |
1181 | { |
1182 | .clock = 207800, |
1183 | .hdisplay = 2160, |
1184 | .hsync_start = 2160 + 48, |
1185 | .hsync_end = 2160 + 48 + 32, |
1186 | .htotal = 2160 + 48 + 32 + 100, |
1187 | .vdisplay = 1440, |
1188 | .vsync_start = 1440 + 3, |
1189 | .vsync_end = 1440 + 3 + 6, |
1190 | .vtotal = 1440 + 3 + 6 + 31, |
1191 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, |
1192 | }, |
1193 | { |
1194 | .clock = 138500, |
1195 | .hdisplay = 2160, |
1196 | .hsync_start = 2160 + 48, |
1197 | .hsync_end = 2160 + 48 + 32, |
1198 | .htotal = 2160 + 48 + 32 + 100, |
1199 | .vdisplay = 1440, |
1200 | .vsync_start = 1440 + 3, |
1201 | .vsync_end = 1440 + 3 + 6, |
1202 | .vtotal = 1440 + 3 + 6 + 31, |
1203 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, |
1204 | }, |
1205 | }; |
1206 | |
1207 | static const struct panel_desc boe_nv110wtm_n61 = { |
1208 | .modes = boe_nv110wtm_n61_modes, |
1209 | .num_modes = ARRAY_SIZE(boe_nv110wtm_n61_modes), |
1210 | .bpc = 8, |
1211 | .size = { |
1212 | .width = 233, |
1213 | .height = 155, |
1214 | }, |
1215 | .delay = { |
1216 | .hpd_absent = 200, |
1217 | .prepare_to_enable = 80, |
1218 | .enable = 50, |
1219 | .unprepare = 500, |
1220 | }, |
1221 | }; |
1222 | |
1223 | /* Also used for boe_nv133fhm_n62 */ |
1224 | static const struct drm_display_mode boe_nv133fhm_n61_modes = { |
1225 | .clock = 147840, |
1226 | .hdisplay = 1920, |
1227 | .hsync_start = 1920 + 48, |
1228 | .hsync_end = 1920 + 48 + 32, |
1229 | .htotal = 1920 + 48 + 32 + 200, |
1230 | .vdisplay = 1080, |
1231 | .vsync_start = 1080 + 3, |
1232 | .vsync_end = 1080 + 3 + 6, |
1233 | .vtotal = 1080 + 3 + 6 + 31, |
1234 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC, |
1235 | }; |
1236 | |
1237 | /* Also used for boe_nv133fhm_n62 */ |
1238 | static const struct panel_desc boe_nv133fhm_n61 = { |
1239 | .modes = &boe_nv133fhm_n61_modes, |
1240 | .num_modes = 1, |
1241 | .bpc = 6, |
1242 | .size = { |
1243 | .width = 294, |
1244 | .height = 165, |
1245 | }, |
1246 | .delay = { |
1247 | /* |
1248 | * When power is first given to the panel there's a short |
1249 | * spike on the HPD line. It was explained that this spike |
1250 | * was until the TCON data download was complete. On |
1251 | * one system this was measured at 8 ms. We'll put 15 ms |
1252 | * in the prepare delay just to be safe. That means: |
1253 | * - If HPD isn't hooked up you still have 200 ms delay. |
1254 | * - If HPD is hooked up we won't try to look at it for the |
1255 | * first 15 ms. |
1256 | */ |
1257 | .hpd_reliable = 15, |
1258 | .hpd_absent = 200, |
1259 | |
1260 | .unprepare = 500, |
1261 | }, |
1262 | }; |
1263 | |
1264 | static const struct drm_display_mode boe_nv140fhmn49_modes[] = { |
1265 | { |
1266 | .clock = 148500, |
1267 | .hdisplay = 1920, |
1268 | .hsync_start = 1920 + 48, |
1269 | .hsync_end = 1920 + 48 + 32, |
1270 | .htotal = 2200, |
1271 | .vdisplay = 1080, |
1272 | .vsync_start = 1080 + 3, |
1273 | .vsync_end = 1080 + 3 + 5, |
1274 | .vtotal = 1125, |
1275 | }, |
1276 | }; |
1277 | |
1278 | static const struct panel_desc boe_nv140fhmn49 = { |
1279 | .modes = boe_nv140fhmn49_modes, |
1280 | .num_modes = ARRAY_SIZE(boe_nv140fhmn49_modes), |
1281 | .bpc = 6, |
1282 | .size = { |
1283 | .width = 309, |
1284 | .height = 174, |
1285 | }, |
1286 | .delay = { |
1287 | /* TODO: should be hpd-absent and no-hpd should be set? */ |
1288 | .hpd_reliable = 210, |
1289 | .enable = 50, |
1290 | .unprepare = 160, |
1291 | }, |
1292 | }; |
1293 | |
1294 | static const struct drm_display_mode innolux_n116bca_ea1_mode = { |
1295 | .clock = 76420, |
1296 | .hdisplay = 1366, |
1297 | .hsync_start = 1366 + 136, |
1298 | .hsync_end = 1366 + 136 + 30, |
1299 | .htotal = 1366 + 136 + 30 + 60, |
1300 | .vdisplay = 768, |
1301 | .vsync_start = 768 + 8, |
1302 | .vsync_end = 768 + 8 + 12, |
1303 | .vtotal = 768 + 8 + 12 + 12, |
1304 | .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, |
1305 | }; |
1306 | |
1307 | static const struct panel_desc innolux_n116bca_ea1 = { |
1308 | .modes = &innolux_n116bca_ea1_mode, |
1309 | .num_modes = 1, |
1310 | .bpc = 6, |
1311 | .size = { |
1312 | .width = 256, |
1313 | .height = 144, |
1314 | }, |
1315 | .delay = { |
1316 | .hpd_absent = 200, |
1317 | .enable = 80, |
1318 | .disable = 50, |
1319 | .unprepare = 500, |
1320 | }, |
1321 | }; |
1322 | |
1323 | /* |
1324 | * Datasheet specifies that at 60 Hz refresh rate: |
1325 | * - total horizontal time: { 1506, 1592, 1716 } |
1326 | * - total vertical time: { 788, 800, 868 } |
1327 | * |
1328 | * ...but doesn't go into exactly how that should be split into a front |
1329 | * porch, back porch, or sync length. For now we'll leave a single setting |
1330 | * here which allows a bit of tweaking of the pixel clock at the expense of |
1331 | * refresh rate. |
1332 | */ |
1333 | static const struct display_timing innolux_n116bge_timing = { |
1334 | .pixelclock = { 72600000, 76420000, 80240000 }, |
1335 | .hactive = { 1366, 1366, 1366 }, |
1336 | .hfront_porch = { 136, 136, 136 }, |
1337 | .hback_porch = { 60, 60, 60 }, |
1338 | .hsync_len = { 30, 30, 30 }, |
1339 | .vactive = { 768, 768, 768 }, |
1340 | .vfront_porch = { 8, 8, 8 }, |
1341 | .vback_porch = { 12, 12, 12 }, |
1342 | .vsync_len = { 12, 12, 12 }, |
1343 | .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW, |
1344 | }; |
1345 | |
1346 | static const struct panel_desc innolux_n116bge = { |
1347 | .timings = &innolux_n116bge_timing, |
1348 | .num_timings = 1, |
1349 | .bpc = 6, |
1350 | .size = { |
1351 | .width = 256, |
1352 | .height = 144, |
1353 | }, |
1354 | }; |
1355 | |
1356 | static const struct drm_display_mode innolux_n125hce_gn1_mode = { |
1357 | .clock = 162000, |
1358 | .hdisplay = 1920, |
1359 | .hsync_start = 1920 + 40, |
1360 | .hsync_end = 1920 + 40 + 40, |
1361 | .htotal = 1920 + 40 + 40 + 80, |
1362 | .vdisplay = 1080, |
1363 | .vsync_start = 1080 + 4, |
1364 | .vsync_end = 1080 + 4 + 4, |
1365 | .vtotal = 1080 + 4 + 4 + 24, |
1366 | }; |
1367 | |
1368 | static const struct panel_desc innolux_n125hce_gn1 = { |
1369 | .modes = &innolux_n125hce_gn1_mode, |
1370 | .num_modes = 1, |
1371 | .bpc = 8, |
1372 | .size = { |
1373 | .width = 276, |
1374 | .height = 155, |
1375 | }, |
1376 | }; |
1377 | |
1378 | static const struct drm_display_mode innolux_p120zdg_bf1_mode = { |
1379 | .clock = 206016, |
1380 | .hdisplay = 2160, |
1381 | .hsync_start = 2160 + 48, |
1382 | .hsync_end = 2160 + 48 + 32, |
1383 | .htotal = 2160 + 48 + 32 + 80, |
1384 | .vdisplay = 1440, |
1385 | .vsync_start = 1440 + 3, |
1386 | .vsync_end = 1440 + 3 + 10, |
1387 | .vtotal = 1440 + 3 + 10 + 27, |
1388 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, |
1389 | }; |
1390 | |
1391 | static const struct panel_desc innolux_p120zdg_bf1 = { |
1392 | .modes = &innolux_p120zdg_bf1_mode, |
1393 | .num_modes = 1, |
1394 | .bpc = 8, |
1395 | .size = { |
1396 | .width = 254, |
1397 | .height = 169, |
1398 | }, |
1399 | .delay = { |
1400 | .hpd_absent = 200, |
1401 | .unprepare = 500, |
1402 | }, |
1403 | }; |
1404 | |
1405 | static const struct drm_display_mode ivo_m133nwf4_r0_mode = { |
1406 | .clock = 138778, |
1407 | .hdisplay = 1920, |
1408 | .hsync_start = 1920 + 24, |
1409 | .hsync_end = 1920 + 24 + 48, |
1410 | .htotal = 1920 + 24 + 48 + 88, |
1411 | .vdisplay = 1080, |
1412 | .vsync_start = 1080 + 3, |
1413 | .vsync_end = 1080 + 3 + 12, |
1414 | .vtotal = 1080 + 3 + 12 + 17, |
1415 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, |
1416 | }; |
1417 | |
1418 | static const struct panel_desc ivo_m133nwf4_r0 = { |
1419 | .modes = &ivo_m133nwf4_r0_mode, |
1420 | .num_modes = 1, |
1421 | .bpc = 8, |
1422 | .size = { |
1423 | .width = 294, |
1424 | .height = 165, |
1425 | }, |
1426 | .delay = { |
1427 | .hpd_absent = 200, |
1428 | .unprepare = 500, |
1429 | }, |
1430 | }; |
1431 | |
1432 | static const struct drm_display_mode kingdisplay_kd116n21_30nv_a010_mode = { |
1433 | .clock = 81000, |
1434 | .hdisplay = 1366, |
1435 | .hsync_start = 1366 + 40, |
1436 | .hsync_end = 1366 + 40 + 32, |
1437 | .htotal = 1366 + 40 + 32 + 62, |
1438 | .vdisplay = 768, |
1439 | .vsync_start = 768 + 5, |
1440 | .vsync_end = 768 + 5 + 5, |
1441 | .vtotal = 768 + 5 + 5 + 122, |
1442 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1443 | }; |
1444 | |
1445 | static const struct panel_desc kingdisplay_kd116n21_30nv_a010 = { |
1446 | .modes = &kingdisplay_kd116n21_30nv_a010_mode, |
1447 | .num_modes = 1, |
1448 | .bpc = 6, |
1449 | .size = { |
1450 | .width = 256, |
1451 | .height = 144, |
1452 | }, |
1453 | .delay = { |
1454 | .hpd_absent = 200, |
1455 | }, |
1456 | }; |
1457 | |
1458 | static const struct drm_display_mode lg_lp079qx1_sp0v_mode = { |
1459 | .clock = 200000, |
1460 | .hdisplay = 1536, |
1461 | .hsync_start = 1536 + 12, |
1462 | .hsync_end = 1536 + 12 + 16, |
1463 | .htotal = 1536 + 12 + 16 + 48, |
1464 | .vdisplay = 2048, |
1465 | .vsync_start = 2048 + 8, |
1466 | .vsync_end = 2048 + 8 + 4, |
1467 | .vtotal = 2048 + 8 + 4 + 8, |
1468 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1469 | }; |
1470 | |
1471 | static const struct panel_desc lg_lp079qx1_sp0v = { |
1472 | .modes = &lg_lp079qx1_sp0v_mode, |
1473 | .num_modes = 1, |
1474 | .size = { |
1475 | .width = 129, |
1476 | .height = 171, |
1477 | }, |
1478 | }; |
1479 | |
1480 | static const struct drm_display_mode lg_lp097qx1_spa1_mode = { |
1481 | .clock = 205210, |
1482 | .hdisplay = 2048, |
1483 | .hsync_start = 2048 + 150, |
1484 | .hsync_end = 2048 + 150 + 5, |
1485 | .htotal = 2048 + 150 + 5 + 5, |
1486 | .vdisplay = 1536, |
1487 | .vsync_start = 1536 + 3, |
1488 | .vsync_end = 1536 + 3 + 1, |
1489 | .vtotal = 1536 + 3 + 1 + 9, |
1490 | }; |
1491 | |
1492 | static const struct panel_desc lg_lp097qx1_spa1 = { |
1493 | .modes = &lg_lp097qx1_spa1_mode, |
1494 | .num_modes = 1, |
1495 | .size = { |
1496 | .width = 208, |
1497 | .height = 147, |
1498 | }, |
1499 | }; |
1500 | |
1501 | static const struct drm_display_mode lg_lp120up1_mode = { |
1502 | .clock = 162300, |
1503 | .hdisplay = 1920, |
1504 | .hsync_start = 1920 + 40, |
1505 | .hsync_end = 1920 + 40 + 40, |
1506 | .htotal = 1920 + 40 + 40 + 80, |
1507 | .vdisplay = 1280, |
1508 | .vsync_start = 1280 + 4, |
1509 | .vsync_end = 1280 + 4 + 4, |
1510 | .vtotal = 1280 + 4 + 4 + 12, |
1511 | }; |
1512 | |
1513 | static const struct panel_desc lg_lp120up1 = { |
1514 | .modes = &lg_lp120up1_mode, |
1515 | .num_modes = 1, |
1516 | .bpc = 8, |
1517 | .size = { |
1518 | .width = 267, |
1519 | .height = 183, |
1520 | }, |
1521 | }; |
1522 | |
1523 | static const struct drm_display_mode lg_lp129qe_mode = { |
1524 | .clock = 285250, |
1525 | .hdisplay = 2560, |
1526 | .hsync_start = 2560 + 48, |
1527 | .hsync_end = 2560 + 48 + 32, |
1528 | .htotal = 2560 + 48 + 32 + 80, |
1529 | .vdisplay = 1700, |
1530 | .vsync_start = 1700 + 3, |
1531 | .vsync_end = 1700 + 3 + 10, |
1532 | .vtotal = 1700 + 3 + 10 + 36, |
1533 | }; |
1534 | |
1535 | static const struct panel_desc lg_lp129qe = { |
1536 | .modes = &lg_lp129qe_mode, |
1537 | .num_modes = 1, |
1538 | .bpc = 8, |
1539 | .size = { |
1540 | .width = 272, |
1541 | .height = 181, |
1542 | }, |
1543 | }; |
1544 | |
1545 | static const struct drm_display_mode neweast_wjfh116008a_modes[] = { |
1546 | { |
1547 | .clock = 138500, |
1548 | .hdisplay = 1920, |
1549 | .hsync_start = 1920 + 48, |
1550 | .hsync_end = 1920 + 48 + 32, |
1551 | .htotal = 1920 + 48 + 32 + 80, |
1552 | .vdisplay = 1080, |
1553 | .vsync_start = 1080 + 3, |
1554 | .vsync_end = 1080 + 3 + 5, |
1555 | .vtotal = 1080 + 3 + 5 + 23, |
1556 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1557 | }, { |
1558 | .clock = 110920, |
1559 | .hdisplay = 1920, |
1560 | .hsync_start = 1920 + 48, |
1561 | .hsync_end = 1920 + 48 + 32, |
1562 | .htotal = 1920 + 48 + 32 + 80, |
1563 | .vdisplay = 1080, |
1564 | .vsync_start = 1080 + 3, |
1565 | .vsync_end = 1080 + 3 + 5, |
1566 | .vtotal = 1080 + 3 + 5 + 23, |
1567 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1568 | } |
1569 | }; |
1570 | |
1571 | static const struct panel_desc neweast_wjfh116008a = { |
1572 | .modes = neweast_wjfh116008a_modes, |
1573 | .num_modes = 2, |
1574 | .bpc = 6, |
1575 | .size = { |
1576 | .width = 260, |
1577 | .height = 150, |
1578 | }, |
1579 | .delay = { |
1580 | .hpd_reliable = 110, |
1581 | .enable = 20, |
1582 | .unprepare = 500, |
1583 | }, |
1584 | }; |
1585 | |
1586 | static const struct drm_display_mode samsung_lsn122dl01_c01_mode = { |
1587 | .clock = 271560, |
1588 | .hdisplay = 2560, |
1589 | .hsync_start = 2560 + 48, |
1590 | .hsync_end = 2560 + 48 + 32, |
1591 | .htotal = 2560 + 48 + 32 + 80, |
1592 | .vdisplay = 1600, |
1593 | .vsync_start = 1600 + 2, |
1594 | .vsync_end = 1600 + 2 + 5, |
1595 | .vtotal = 1600 + 2 + 5 + 57, |
1596 | }; |
1597 | |
1598 | static const struct panel_desc samsung_lsn122dl01_c01 = { |
1599 | .modes = &samsung_lsn122dl01_c01_mode, |
1600 | .num_modes = 1, |
1601 | .size = { |
1602 | .width = 263, |
1603 | .height = 164, |
1604 | }, |
1605 | }; |
1606 | |
1607 | static const struct drm_display_mode samsung_ltn140at29_301_mode = { |
1608 | .clock = 76300, |
1609 | .hdisplay = 1366, |
1610 | .hsync_start = 1366 + 64, |
1611 | .hsync_end = 1366 + 64 + 48, |
1612 | .htotal = 1366 + 64 + 48 + 128, |
1613 | .vdisplay = 768, |
1614 | .vsync_start = 768 + 2, |
1615 | .vsync_end = 768 + 2 + 5, |
1616 | .vtotal = 768 + 2 + 5 + 17, |
1617 | }; |
1618 | |
1619 | static const struct panel_desc samsung_ltn140at29_301 = { |
1620 | .modes = &samsung_ltn140at29_301_mode, |
1621 | .num_modes = 1, |
1622 | .bpc = 6, |
1623 | .size = { |
1624 | .width = 320, |
1625 | .height = 187, |
1626 | }, |
1627 | }; |
1628 | |
1629 | static const struct drm_display_mode sharp_ld_d5116z01b_mode = { |
1630 | .clock = 168480, |
1631 | .hdisplay = 1920, |
1632 | .hsync_start = 1920 + 48, |
1633 | .hsync_end = 1920 + 48 + 32, |
1634 | .htotal = 1920 + 48 + 32 + 80, |
1635 | .vdisplay = 1280, |
1636 | .vsync_start = 1280 + 3, |
1637 | .vsync_end = 1280 + 3 + 10, |
1638 | .vtotal = 1280 + 3 + 10 + 57, |
1639 | .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, |
1640 | }; |
1641 | |
1642 | static const struct panel_desc sharp_ld_d5116z01b = { |
1643 | .modes = &sharp_ld_d5116z01b_mode, |
1644 | .num_modes = 1, |
1645 | .bpc = 8, |
1646 | .size = { |
1647 | .width = 260, |
1648 | .height = 120, |
1649 | }, |
1650 | }; |
1651 | |
1652 | static const struct display_timing sharp_lq123p1jx31_timing = { |
1653 | .pixelclock = { 252750000, 252750000, 266604720 }, |
1654 | .hactive = { 2400, 2400, 2400 }, |
1655 | .hfront_porch = { 48, 48, 48 }, |
1656 | .hback_porch = { 80, 80, 84 }, |
1657 | .hsync_len = { 32, 32, 32 }, |
1658 | .vactive = { 1600, 1600, 1600 }, |
1659 | .vfront_porch = { 3, 3, 3 }, |
1660 | .vback_porch = { 33, 33, 120 }, |
1661 | .vsync_len = { 10, 10, 10 }, |
1662 | .flags = DISPLAY_FLAGS_VSYNC_LOW | DISPLAY_FLAGS_HSYNC_LOW, |
1663 | }; |
1664 | |
1665 | static const struct panel_desc sharp_lq123p1jx31 = { |
1666 | .timings = &sharp_lq123p1jx31_timing, |
1667 | .num_timings = 1, |
1668 | .bpc = 8, |
1669 | .size = { |
1670 | .width = 259, |
1671 | .height = 173, |
1672 | }, |
1673 | .delay = { |
1674 | .hpd_reliable = 110, |
1675 | .enable = 50, |
1676 | .unprepare = 550, |
1677 | }, |
1678 | }; |
1679 | |
1680 | static const struct drm_display_mode sharp_lq140m1jw46_mode[] = { |
1681 | { |
1682 | .clock = 346500, |
1683 | .hdisplay = 1920, |
1684 | .hsync_start = 1920 + 48, |
1685 | .hsync_end = 1920 + 48 + 32, |
1686 | .htotal = 1920 + 48 + 32 + 80, |
1687 | .vdisplay = 1080, |
1688 | .vsync_start = 1080 + 3, |
1689 | .vsync_end = 1080 + 3 + 5, |
1690 | .vtotal = 1080 + 3 + 5 + 69, |
1691 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1692 | }, { |
1693 | .clock = 144370, |
1694 | .hdisplay = 1920, |
1695 | .hsync_start = 1920 + 48, |
1696 | .hsync_end = 1920 + 48 + 32, |
1697 | .htotal = 1920 + 48 + 32 + 80, |
1698 | .vdisplay = 1080, |
1699 | .vsync_start = 1080 + 3, |
1700 | .vsync_end = 1080 + 3 + 5, |
1701 | .vtotal = 1080 + 3 + 5 + 69, |
1702 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1703 | }, |
1704 | }; |
1705 | |
1706 | static const struct panel_desc sharp_lq140m1jw46 = { |
1707 | .modes = sharp_lq140m1jw46_mode, |
1708 | .num_modes = ARRAY_SIZE(sharp_lq140m1jw46_mode), |
1709 | .bpc = 8, |
1710 | .size = { |
1711 | .width = 309, |
1712 | .height = 174, |
1713 | }, |
1714 | .delay = { |
1715 | .hpd_absent = 80, |
1716 | .enable = 50, |
1717 | .unprepare = 500, |
1718 | }, |
1719 | }; |
1720 | |
1721 | static const struct drm_display_mode starry_kr122ea0sra_mode = { |
1722 | .clock = 147000, |
1723 | .hdisplay = 1920, |
1724 | .hsync_start = 1920 + 16, |
1725 | .hsync_end = 1920 + 16 + 16, |
1726 | .htotal = 1920 + 16 + 16 + 32, |
1727 | .vdisplay = 1200, |
1728 | .vsync_start = 1200 + 15, |
1729 | .vsync_end = 1200 + 15 + 2, |
1730 | .vtotal = 1200 + 15 + 2 + 18, |
1731 | .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, |
1732 | }; |
1733 | |
1734 | static const struct panel_desc starry_kr122ea0sra = { |
1735 | .modes = &starry_kr122ea0sra_mode, |
1736 | .num_modes = 1, |
1737 | .size = { |
1738 | .width = 263, |
1739 | .height = 164, |
1740 | }, |
1741 | .delay = { |
1742 | /* TODO: should be hpd-absent and no-hpd should be set? */ |
1743 | .hpd_reliable = 10 + 200, |
1744 | .enable = 50, |
1745 | .unprepare = 10 + 500, |
1746 | }, |
1747 | }; |
1748 | |
1749 | static const struct of_device_id platform_of_match[] = { |
1750 | { |
1751 | /* Must be first */ |
1752 | .compatible = "edp-panel" , |
1753 | }, { |
1754 | .compatible = "auo,b101ean01" , |
1755 | .data = &auo_b101ean01, |
1756 | }, { |
1757 | .compatible = "auo,b116xa01" , |
1758 | .data = &auo_b116xak01, |
1759 | }, { |
1760 | .compatible = "auo,b133han05" , |
1761 | .data = &auo_b133han05, |
1762 | }, { |
1763 | .compatible = "auo,b133htn01" , |
1764 | .data = &auo_b133htn01, |
1765 | }, { |
1766 | .compatible = "auo,b133xtn01" , |
1767 | .data = &auo_b133xtn01, |
1768 | }, { |
1769 | .compatible = "auo,b140han06" , |
1770 | .data = &auo_b140han06, |
1771 | }, { |
1772 | .compatible = "boe,nv101wxmn51" , |
1773 | .data = &boe_nv101wxmn51, |
1774 | }, { |
1775 | .compatible = "boe,nv110wtm-n61" , |
1776 | .data = &boe_nv110wtm_n61, |
1777 | }, { |
1778 | .compatible = "boe,nv133fhm-n61" , |
1779 | .data = &boe_nv133fhm_n61, |
1780 | }, { |
1781 | .compatible = "boe,nv133fhm-n62" , |
1782 | .data = &boe_nv133fhm_n61, |
1783 | }, { |
1784 | .compatible = "boe,nv140fhmn49" , |
1785 | .data = &boe_nv140fhmn49, |
1786 | }, { |
1787 | .compatible = "innolux,n116bca-ea1" , |
1788 | .data = &innolux_n116bca_ea1, |
1789 | }, { |
1790 | .compatible = "innolux,n116bge" , |
1791 | .data = &innolux_n116bge, |
1792 | }, { |
1793 | .compatible = "innolux,n125hce-gn1" , |
1794 | .data = &innolux_n125hce_gn1, |
1795 | }, { |
1796 | .compatible = "innolux,p120zdg-bf1" , |
1797 | .data = &innolux_p120zdg_bf1, |
1798 | }, { |
1799 | .compatible = "ivo,m133nwf4-r0" , |
1800 | .data = &ivo_m133nwf4_r0, |
1801 | }, { |
1802 | .compatible = "kingdisplay,kd116n21-30nv-a010" , |
1803 | .data = &kingdisplay_kd116n21_30nv_a010, |
1804 | }, { |
1805 | .compatible = "lg,lp079qx1-sp0v" , |
1806 | .data = &lg_lp079qx1_sp0v, |
1807 | }, { |
1808 | .compatible = "lg,lp097qx1-spa1" , |
1809 | .data = &lg_lp097qx1_spa1, |
1810 | }, { |
1811 | .compatible = "lg,lp120up1" , |
1812 | .data = &lg_lp120up1, |
1813 | }, { |
1814 | .compatible = "lg,lp129qe" , |
1815 | .data = &lg_lp129qe, |
1816 | }, { |
1817 | .compatible = "neweast,wjfh116008a" , |
1818 | .data = &neweast_wjfh116008a, |
1819 | }, { |
1820 | .compatible = "samsung,lsn122dl01-c01" , |
1821 | .data = &samsung_lsn122dl01_c01, |
1822 | }, { |
1823 | .compatible = "samsung,ltn140at29-301" , |
1824 | .data = &samsung_ltn140at29_301, |
1825 | }, { |
1826 | .compatible = "sharp,ld-d5116z01b" , |
1827 | .data = &sharp_ld_d5116z01b, |
1828 | }, { |
1829 | .compatible = "sharp,lq123p1jx31" , |
1830 | .data = &sharp_lq123p1jx31, |
1831 | }, { |
1832 | .compatible = "sharp,lq140m1jw46" , |
1833 | .data = &sharp_lq140m1jw46, |
1834 | }, { |
1835 | .compatible = "starry,kr122ea0sra" , |
1836 | .data = &starry_kr122ea0sra, |
1837 | }, { |
1838 | /* sentinel */ |
1839 | } |
1840 | }; |
1841 | MODULE_DEVICE_TABLE(of, platform_of_match); |
1842 | |
1843 | static const struct panel_delay delay_200_500_p2e80 = { |
1844 | .hpd_absent = 200, |
1845 | .unprepare = 500, |
1846 | .prepare_to_enable = 80, |
1847 | }; |
1848 | |
1849 | static const struct panel_delay delay_200_500_e50_p2e80 = { |
1850 | .hpd_absent = 200, |
1851 | .unprepare = 500, |
1852 | .enable = 50, |
1853 | .prepare_to_enable = 80, |
1854 | }; |
1855 | |
1856 | static const struct panel_delay delay_200_500_p2e100 = { |
1857 | .hpd_absent = 200, |
1858 | .unprepare = 500, |
1859 | .prepare_to_enable = 100, |
1860 | }; |
1861 | |
1862 | static const struct panel_delay delay_200_500_e50 = { |
1863 | .hpd_absent = 200, |
1864 | .unprepare = 500, |
1865 | .enable = 50, |
1866 | }; |
1867 | |
1868 | static const struct panel_delay delay_200_500_e80 = { |
1869 | .hpd_absent = 200, |
1870 | .unprepare = 500, |
1871 | .enable = 80, |
1872 | }; |
1873 | |
1874 | static const struct panel_delay delay_200_500_e80_d50 = { |
1875 | .hpd_absent = 200, |
1876 | .unprepare = 500, |
1877 | .enable = 80, |
1878 | .disable = 50, |
1879 | }; |
1880 | |
1881 | static const struct panel_delay delay_100_500_e200 = { |
1882 | .hpd_absent = 100, |
1883 | .unprepare = 500, |
1884 | .enable = 200, |
1885 | }; |
1886 | |
1887 | static const struct panel_delay delay_200_500_e200 = { |
1888 | .hpd_absent = 200, |
1889 | .unprepare = 500, |
1890 | .enable = 200, |
1891 | }; |
1892 | |
1893 | static const struct panel_delay delay_200_500_e200_d200 = { |
1894 | .hpd_absent = 200, |
1895 | .unprepare = 500, |
1896 | .enable = 200, |
1897 | .disable = 200, |
1898 | }; |
1899 | |
1900 | static const struct panel_delay delay_200_500_e200_d10 = { |
1901 | .hpd_absent = 200, |
1902 | .unprepare = 500, |
1903 | .enable = 200, |
1904 | .disable = 10, |
1905 | }; |
1906 | |
1907 | static const struct panel_delay delay_200_150_e200 = { |
1908 | .hpd_absent = 200, |
1909 | .unprepare = 150, |
1910 | .enable = 200, |
1911 | }; |
1912 | |
1913 | static const struct panel_delay delay_200_500_e50_po2e200 = { |
1914 | .hpd_absent = 200, |
1915 | .unprepare = 500, |
1916 | .enable = 50, |
1917 | .powered_on_to_enable = 200, |
1918 | }; |
1919 | |
1920 | #define EDP_PANEL_ENTRY(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name) \ |
1921 | { \ |
1922 | .name = _name, \ |
1923 | .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ |
1924 | product_id), \ |
1925 | .delay = _delay \ |
1926 | } |
1927 | |
1928 | #define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \ |
1929 | { \ |
1930 | .name = _name, \ |
1931 | .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ |
1932 | product_id), \ |
1933 | .delay = _delay, \ |
1934 | .override_edid_mode = _mode \ |
1935 | } |
1936 | |
1937 | /* |
1938 | * This table is used to figure out power sequencing delays for panels that |
1939 | * are detected by EDID. Entries here may point to entries in the |
1940 | * platform_of_match table (if a panel is listed in both places). |
1941 | * |
1942 | * Sort first by vendor, then by product ID. |
1943 | */ |
1944 | static const struct edp_panel_entry edp_panels[] = { |
1945 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x105c, &delay_200_500_e50, "B116XTN01.0" ), |
1946 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0" ), |
1947 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x125c, &delay_200_500_e50, "Unknown" ), |
1948 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x145c, &delay_200_500_e50, "B116XAB01.4" ), |
1949 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1" ), |
1950 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6" ), |
1951 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x208d, &delay_200_500_e50, "B140HTN02.1" ), |
1952 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3" ), |
1953 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x239b, &delay_200_500_e50, "B116XAN06.1" ), |
1954 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x255c, &delay_200_500_e50, "B116XTN02.5" ), |
1955 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x403d, &delay_200_500_e50, "B140HAN04.0" ), |
1956 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01.0" ), |
1957 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x435c, &delay_200_500_e50, "Unknown" ), |
1958 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x582d, &delay_200_500_e50, "B133UAN01.0" ), |
1959 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1" ), |
1960 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x635c, &delay_200_500_e50, "B116XAN06.3" ), |
1961 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x639c, &delay_200_500_e50, "B140HAK02.7" ), |
1962 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x723c, &delay_200_500_e50, "B140XTN07.2" ), |
1963 | EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0" ), |
1964 | EDP_PANEL_ENTRY('A', 'U', 'O', 0xf390, &delay_200_500_e50, "B140XTN07.7" ), |
1965 | |
1966 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0607, &delay_200_500_e200, "Unknown" ), |
1967 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0608, &delay_200_500_e50, "NT116WHM-N11" ), |
1968 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0668, &delay_200_500_e200, "Unknown" ), |
1969 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x068f, &delay_200_500_e200, "Unknown" ), |
1970 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x06e5, &delay_200_500_e200, "Unknown" ), |
1971 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0705, &delay_200_500_e200, "Unknown" ), |
1972 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0715, &delay_200_150_e200, "NT116WHM-N21" ), |
1973 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0717, &delay_200_500_e50_po2e200, "NV133FHM-N42" ), |
1974 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0731, &delay_200_500_e80, "NT116WHM-N42" ), |
1975 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0741, &delay_200_500_e200, "NT116WHM-N44" ), |
1976 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0744, &delay_200_500_e200, "Unknown" ), |
1977 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x074c, &delay_200_500_e200, "Unknown" ), |
1978 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0751, &delay_200_500_e200, "Unknown" ), |
1979 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0754, &delay_200_500_e50_po2e200, "NV116WHM-N45" ), |
1980 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0771, &delay_200_500_e200, "Unknown" ), |
1981 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01" ), |
1982 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0797, &delay_200_500_e200, "Unknown" ), |
1983 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61" ), |
1984 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d3, &delay_200_500_e200, "Unknown" ), |
1985 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x07f6, &delay_200_500_e200, "NT140FHM-N44" ), |
1986 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x07f8, &delay_200_500_e200, "Unknown" ), |
1987 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0813, &delay_200_500_e200, "Unknown" ), |
1988 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0827, &delay_200_500_e50_p2e80, "NT140WHM-N44 V8.0" ), |
1989 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62" ), |
1990 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0843, &delay_200_500_e200, "Unknown" ), |
1991 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x08b2, &delay_200_500_e200, "NT140WHM-N49" ), |
1992 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0848, &delay_200_500_e200, "Unknown" ), |
1993 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0849, &delay_200_500_e200, "Unknown" ), |
1994 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x09c3, &delay_200_500_e50, "NT116WHM-N21,836X2" ), |
1995 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x094b, &delay_200_500_e50, "NT116WHM-N21" ), |
1996 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0951, &delay_200_500_e80, "NV116WHM-N47" ), |
1997 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x095f, &delay_200_500_e50, "NE135FBM-N41 v8.1" ), |
1998 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x096e, &delay_200_500_e50_po2e200, "NV116WHM-T07 V8.0" ), |
1999 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0979, &delay_200_500_e50, "NV116WHM-N49 V8.0" ), |
2000 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61" ), |
2001 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0993, &delay_200_500_e80, "NV116WHM-T14 V8.0" ), |
2002 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x09ad, &delay_200_500_e80, "NV116WHM-N47" ), |
2003 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x09ae, &delay_200_500_e200, "NT140FHM-N45" ), |
2004 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x09dd, &delay_200_500_e50, "NT116WHM-N21" ), |
2005 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a36, &delay_200_500_e200, "Unknown" ), |
2006 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a3e, &delay_200_500_e80, "NV116WHM-N49" ), |
2007 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45" ), |
2008 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0ac5, &delay_200_500_e50, "NV116WHM-N4C" ), |
2009 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b34, &delay_200_500_e80, "NV122WUM-N41" ), |
2010 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b43, &delay_200_500_e200, "NV140FHM-T09" ), |
2011 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0b56, &delay_200_500_e80, "NT140FHM-N47" ), |
2012 | EDP_PANEL_ENTRY('B', 'O', 'E', 0x0c20, &delay_200_500_e80, "NT140FHM-N47" ), |
2013 | |
2014 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1130, &delay_200_500_e50, "N116BGE-EB2" ), |
2015 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1132, &delay_200_500_e80_d50, "N116BGE-EA2" ), |
2016 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1138, &innolux_n116bca_ea1.delay, "N116BCA-EA1-RC4" ), |
2017 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1139, &delay_200_500_e80_d50, "N116BGE-EA2" ), |
2018 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1141, &delay_200_500_e80_d50, "Unknown" ), |
2019 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1145, &delay_200_500_e80_d50, "N116BCN-EB1" ), |
2020 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x114a, &delay_200_500_e80_d50, "Unknown" ), |
2021 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x114c, &innolux_n116bca_ea1.delay, "N116BCA-EA1" ), |
2022 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1152, &delay_200_500_e80_d50, "N116BCN-EA1" ), |
2023 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1153, &delay_200_500_e80_d50, "N116BGE-EA2" ), |
2024 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1154, &delay_200_500_e80_d50, "N116BCA-EA2" ), |
2025 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1156, &delay_200_500_e80_d50, "Unknown" ), |
2026 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1157, &delay_200_500_e80_d50, "N116BGE-EA2" ), |
2027 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x115b, &delay_200_500_e80_d50, "N116BCN-EB1" ), |
2028 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1247, &delay_200_500_e80_d50, "N120ACA-EA1" ), |
2029 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x142b, &delay_200_500_e80_d50, "N140HCA-EAC" ), |
2030 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x142e, &delay_200_500_e80_d50, "N140BGA-EA4" ), |
2031 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x144f, &delay_200_500_e80_d50, "N140HGA-EA1" ), |
2032 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x1468, &delay_200_500_e80, "N140HGA-EA1" ), |
2033 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d4, &delay_200_500_e80_d50, "N140HCA-EAC" ), |
2034 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x14d6, &delay_200_500_e80_d50, "N140BGA-EA4" ), |
2035 | EDP_PANEL_ENTRY('C', 'M', 'N', 0x14e5, &delay_200_500_e80_d50, "N140HGA-EA1" ), |
2036 | |
2037 | EDP_PANEL_ENTRY('C', 'S', 'O', 0x1200, &delay_200_500_e50, "MNC207QS1-1" ), |
2038 | |
2039 | EDP_PANEL_ENTRY('H', 'K', 'C', 0x2d51, &delay_200_500_e200, "Unknown" ), |
2040 | EDP_PANEL_ENTRY('H', 'K', 'C', 0x2d5b, &delay_200_500_e200, "Unknown" ), |
2041 | EDP_PANEL_ENTRY('H', 'K', 'C', 0x2d5c, &delay_200_500_e200, "MB116AN01-2" ), |
2042 | |
2043 | EDP_PANEL_ENTRY('I', 'V', 'O', 0x048e, &delay_200_500_e200_d10, "M116NWR6 R5" ), |
2044 | EDP_PANEL_ENTRY('I', 'V', 'O', 0x057d, &delay_200_500_e200, "R140NWF5 RH" ), |
2045 | EDP_PANEL_ENTRY('I', 'V', 'O', 0x854a, &delay_200_500_p2e100, "M133NW4J" ), |
2046 | EDP_PANEL_ENTRY('I', 'V', 'O', 0x854b, &delay_200_500_p2e100, "R133NW4K-R0" ), |
2047 | EDP_PANEL_ENTRY('I', 'V', 'O', 0x8c4d, &delay_200_150_e200, "R140NWFM R1" ), |
2048 | |
2049 | EDP_PANEL_ENTRY('K', 'D', 'B', 0x044f, &delay_200_500_e80_d50, "Unknown" ), |
2050 | EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, &kingdisplay_kd116n21_30nv_a010.delay, "116N21-30NV-A010" ), |
2051 | EDP_PANEL_ENTRY('K', 'D', 'B', 0x1118, &delay_200_500_e50, "KD116N29-30NK-A005" ), |
2052 | EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, &delay_200_500_e80_d50, "116N29-30NK-C007" ), |
2053 | |
2054 | EDP_PANEL_ENTRY('K', 'D', 'C', 0x044f, &delay_200_500_e50, "KD116N9-30NH-F3" ), |
2055 | EDP_PANEL_ENTRY('K', 'D', 'C', 0x05f1, &delay_200_500_e80_d50, "KD116N5-30NV-G7" ), |
2056 | EDP_PANEL_ENTRY('K', 'D', 'C', 0x0809, &delay_200_500_e50, "KD116N2930A15" ), |
2057 | |
2058 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x0000, &delay_200_500_e200_d200, "Unknown" ), |
2059 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x048d, &delay_200_500_e200_d200, "Unknown" ), |
2060 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x0497, &delay_200_500_e200_d200, "LP116WH7-SPB1" ), |
2061 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x052c, &delay_200_500_e200_d200, "LP133WF2-SPL7" ), |
2062 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x0537, &delay_200_500_e200_d200, "Unknown" ), |
2063 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x054a, &delay_200_500_e200_d200, "LP116WH8-SPC1" ), |
2064 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x0567, &delay_200_500_e200_d200, "Unknown" ), |
2065 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x05af, &delay_200_500_e200_d200, "Unknown" ), |
2066 | EDP_PANEL_ENTRY('L', 'G', 'D', 0x05f1, &delay_200_500_e200_d200, "Unknown" ), |
2067 | |
2068 | EDP_PANEL_ENTRY('S', 'D', 'C', 0x416d, &delay_100_500_e200, "ATNA45AF01" ), |
2069 | |
2070 | EDP_PANEL_ENTRY('S', 'H', 'P', 0x1511, &delay_200_500_e50, "LQ140M1JW48" ), |
2071 | EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, &sharp_lq140m1jw46.delay, "LQ140M1JW46" ), |
2072 | EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, &delay_200_500_p2e100, "LQ116M1JW10" ), |
2073 | |
2074 | EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, &delay_100_500_e200, "2081116HHD028001-51D" ), |
2075 | |
2076 | { /* sentinal */ } |
2077 | }; |
2078 | |
2079 | static const struct edp_panel_entry *find_edp_panel(u32 panel_id) |
2080 | { |
2081 | const struct edp_panel_entry *panel; |
2082 | |
2083 | if (!panel_id) |
2084 | return NULL; |
2085 | |
2086 | for (panel = edp_panels; panel->panel_id; panel++) |
2087 | if (panel->panel_id == panel_id) |
2088 | return panel; |
2089 | |
2090 | return NULL; |
2091 | } |
2092 | |
2093 | static int panel_edp_platform_probe(struct platform_device *pdev) |
2094 | { |
2095 | const struct of_device_id *id; |
2096 | |
2097 | /* Skip one since "edp-panel" is only supported on DP AUX bus */ |
2098 | id = of_match_node(matches: platform_of_match + 1, node: pdev->dev.of_node); |
2099 | if (!id) |
2100 | return -ENODEV; |
2101 | |
2102 | return panel_edp_probe(dev: &pdev->dev, desc: id->data, NULL); |
2103 | } |
2104 | |
2105 | static void panel_edp_platform_remove(struct platform_device *pdev) |
2106 | { |
2107 | panel_edp_remove(dev: &pdev->dev); |
2108 | } |
2109 | |
2110 | static void panel_edp_platform_shutdown(struct platform_device *pdev) |
2111 | { |
2112 | panel_edp_shutdown(dev: &pdev->dev); |
2113 | } |
2114 | |
2115 | static const struct dev_pm_ops panel_edp_pm_ops = { |
2116 | SET_RUNTIME_PM_OPS(panel_edp_suspend, panel_edp_resume, NULL) |
2117 | SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, |
2118 | pm_runtime_force_resume) |
2119 | }; |
2120 | |
2121 | static struct platform_driver panel_edp_platform_driver = { |
2122 | .driver = { |
2123 | .name = "panel-edp" , |
2124 | .of_match_table = platform_of_match, |
2125 | .pm = &panel_edp_pm_ops, |
2126 | }, |
2127 | .probe = panel_edp_platform_probe, |
2128 | .remove_new = panel_edp_platform_remove, |
2129 | .shutdown = panel_edp_platform_shutdown, |
2130 | }; |
2131 | |
2132 | static int panel_edp_dp_aux_ep_probe(struct dp_aux_ep_device *aux_ep) |
2133 | { |
2134 | const struct of_device_id *id; |
2135 | |
2136 | id = of_match_node(matches: platform_of_match, node: aux_ep->dev.of_node); |
2137 | if (!id) |
2138 | return -ENODEV; |
2139 | |
2140 | return panel_edp_probe(dev: &aux_ep->dev, desc: id->data, aux: aux_ep->aux); |
2141 | } |
2142 | |
2143 | static void panel_edp_dp_aux_ep_remove(struct dp_aux_ep_device *aux_ep) |
2144 | { |
2145 | panel_edp_remove(dev: &aux_ep->dev); |
2146 | } |
2147 | |
2148 | static void panel_edp_dp_aux_ep_shutdown(struct dp_aux_ep_device *aux_ep) |
2149 | { |
2150 | panel_edp_shutdown(dev: &aux_ep->dev); |
2151 | } |
2152 | |
2153 | static struct dp_aux_ep_driver panel_edp_dp_aux_ep_driver = { |
2154 | .driver = { |
2155 | .name = "panel-simple-dp-aux" , |
2156 | .of_match_table = platform_of_match, /* Same as platform one! */ |
2157 | .pm = &panel_edp_pm_ops, |
2158 | }, |
2159 | .probe = panel_edp_dp_aux_ep_probe, |
2160 | .remove = panel_edp_dp_aux_ep_remove, |
2161 | .shutdown = panel_edp_dp_aux_ep_shutdown, |
2162 | }; |
2163 | |
2164 | static int __init panel_edp_init(void) |
2165 | { |
2166 | int err; |
2167 | |
2168 | err = platform_driver_register(&panel_edp_platform_driver); |
2169 | if (err < 0) |
2170 | return err; |
2171 | |
2172 | err = dp_aux_dp_driver_register(&panel_edp_dp_aux_ep_driver); |
2173 | if (err < 0) |
2174 | goto err_did_platform_register; |
2175 | |
2176 | return 0; |
2177 | |
2178 | err_did_platform_register: |
2179 | platform_driver_unregister(&panel_edp_platform_driver); |
2180 | |
2181 | return err; |
2182 | } |
2183 | module_init(panel_edp_init); |
2184 | |
2185 | static void __exit panel_edp_exit(void) |
2186 | { |
2187 | dp_aux_dp_driver_unregister(aux_ep_drv: &panel_edp_dp_aux_ep_driver); |
2188 | platform_driver_unregister(&panel_edp_platform_driver); |
2189 | } |
2190 | module_exit(panel_edp_exit); |
2191 | |
2192 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>" ); |
2193 | MODULE_DESCRIPTION("DRM Driver for Simple eDP Panels" ); |
2194 | MODULE_LICENSE("GPL and additional rights" ); |
2195 | |