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/backlight.h>
25 #include <linux/err.h>
26 #include <linux/export.h>
27 #include <linux/module.h>
28 #include <linux/of.h>
29
30 #include <drm/drm_crtc.h>
31 #include <drm/drm_panel.h>
32 #include <drm/drm_print.h>
33
34 static DEFINE_MUTEX(panel_lock);
35 static LIST_HEAD(panel_list);
36
37 /**
38 * DOC: drm panel
39 *
40 * The DRM panel helpers allow drivers to register panel objects with a
41 * central registry and provide functions to retrieve those panels in display
42 * drivers.
43 *
44 * For easy integration into drivers using the &drm_bridge infrastructure please
45 * take look at drm_panel_bridge_add() and devm_drm_panel_bridge_add().
46 */
47
48 /**
49 * drm_panel_init - initialize a panel
50 * @panel: DRM panel
51 * @dev: parent device of the panel
52 * @funcs: panel operations
53 * @connector_type: the connector type (DRM_MODE_CONNECTOR_*) corresponding to
54 * the panel interface (must NOT be DRM_MODE_CONNECTOR_Unknown)
55 *
56 * Initialize the panel structure for subsequent registration with
57 * drm_panel_add().
58 */
drm_panel_init(struct drm_panel * panel,struct device * dev,const struct drm_panel_funcs * funcs,int connector_type)59 void drm_panel_init(struct drm_panel *panel, struct device *dev,
60 const struct drm_panel_funcs *funcs, int connector_type)
61 {
62 if (connector_type == DRM_MODE_CONNECTOR_Unknown)
63 DRM_WARN("%s: %s: a valid connector type is required!\n", __func__, dev_name(dev));
64
65 INIT_LIST_HEAD(&panel->list);
66 INIT_LIST_HEAD(&panel->followers);
67 mutex_init(&panel->follower_lock);
68 panel->dev = dev;
69 panel->funcs = funcs;
70 panel->connector_type = connector_type;
71 }
72 EXPORT_SYMBOL(drm_panel_init);
73
74 /**
75 * drm_panel_add - add a panel to the global registry
76 * @panel: panel to add
77 *
78 * Add a panel to the global registry so that it can be looked
79 * up by display drivers. The panel to be added must have been
80 * allocated by devm_drm_panel_alloc().
81 */
drm_panel_add(struct drm_panel * panel)82 void drm_panel_add(struct drm_panel *panel)
83 {
84 mutex_lock(&panel_lock);
85 list_add_tail(&panel->list, &panel_list);
86 mutex_unlock(&panel_lock);
87 }
88 EXPORT_SYMBOL(drm_panel_add);
89
90 /**
91 * drm_panel_remove - remove a panel from the global registry
92 * @panel: DRM panel
93 *
94 * Removes a panel from the global registry.
95 */
drm_panel_remove(struct drm_panel * panel)96 void drm_panel_remove(struct drm_panel *panel)
97 {
98 mutex_lock(&panel_lock);
99 list_del_init(&panel->list);
100 mutex_unlock(&panel_lock);
101 }
102 EXPORT_SYMBOL(drm_panel_remove);
103
104 /**
105 * drm_panel_prepare - power on a panel
106 * @panel: DRM panel
107 *
108 * Calling this function will enable power and deassert any reset signals to
109 * the panel. After this has completed it is possible to communicate with any
110 * integrated circuitry via a command bus. This function cannot fail (as it is
111 * called from the pre_enable call chain). There will always be a call to
112 * drm_panel_disable() afterwards.
113 */
drm_panel_prepare(struct drm_panel * panel)114 void drm_panel_prepare(struct drm_panel *panel)
115 {
116 struct drm_panel_follower *follower;
117 int ret;
118
119 if (!panel)
120 return;
121
122 if (panel->prepared) {
123 dev_warn(panel->dev, "Skipping prepare of already prepared panel\n");
124 return;
125 }
126
127 mutex_lock(&panel->follower_lock);
128
129 if (panel->funcs && panel->funcs->prepare) {
130 ret = panel->funcs->prepare(panel);
131 if (ret < 0)
132 goto exit;
133 }
134 panel->prepared = true;
135
136 list_for_each_entry(follower, &panel->followers, list) {
137 ret = follower->funcs->panel_prepared(follower);
138 if (ret < 0)
139 dev_info(panel->dev, "%ps failed: %d\n",
140 follower->funcs->panel_prepared, ret);
141 }
142
143 exit:
144 mutex_unlock(&panel->follower_lock);
145 }
146 EXPORT_SYMBOL(drm_panel_prepare);
147
148 /**
149 * drm_panel_unprepare - power off a panel
150 * @panel: DRM panel
151 *
152 * Calling this function will completely power off a panel (assert the panel's
153 * reset, turn off power supplies, ...). After this function has completed, it
154 * is usually no longer possible to communicate with the panel until another
155 * call to drm_panel_prepare().
156 */
drm_panel_unprepare(struct drm_panel * panel)157 void drm_panel_unprepare(struct drm_panel *panel)
158 {
159 struct drm_panel_follower *follower;
160 int ret;
161
162 if (!panel)
163 return;
164
165 /*
166 * If you are seeing the warning below it likely means one of two things:
167 * - Your panel driver incorrectly calls drm_panel_unprepare() in its
168 * shutdown routine. You should delete this.
169 * - You are using panel-edp or panel-simple and your DRM modeset
170 * driver's shutdown() callback happened after the panel's shutdown().
171 * In this case the warning is harmless though ideally you should
172 * figure out how to reverse the order of the shutdown() callbacks.
173 */
174 if (!panel->prepared) {
175 dev_warn(panel->dev, "Skipping unprepare of already unprepared panel\n");
176 return;
177 }
178
179 mutex_lock(&panel->follower_lock);
180
181 list_for_each_entry(follower, &panel->followers, list) {
182 ret = follower->funcs->panel_unpreparing(follower);
183 if (ret < 0)
184 dev_info(panel->dev, "%ps failed: %d\n",
185 follower->funcs->panel_unpreparing, ret);
186 }
187
188 if (panel->funcs && panel->funcs->unprepare) {
189 ret = panel->funcs->unprepare(panel);
190 if (ret < 0)
191 goto exit;
192 }
193 panel->prepared = false;
194
195 exit:
196 mutex_unlock(&panel->follower_lock);
197 }
198 EXPORT_SYMBOL(drm_panel_unprepare);
199
200 /**
201 * drm_panel_enable - enable a panel
202 * @panel: DRM panel
203 *
204 * Calling this function will cause the panel display drivers to be turned on
205 * and the backlight to be enabled. Content will be visible on screen after
206 * this call completes. This function cannot fail (as it is called from the
207 * enable call chain). There will always be a call to drm_panel_disable()
208 * afterwards.
209 */
drm_panel_enable(struct drm_panel * panel)210 void drm_panel_enable(struct drm_panel *panel)
211 {
212 int ret;
213
214 if (!panel)
215 return;
216
217 if (panel->enabled) {
218 dev_warn(panel->dev, "Skipping enable of already enabled panel\n");
219 return;
220 }
221
222 if (panel->funcs && panel->funcs->enable) {
223 ret = panel->funcs->enable(panel);
224 if (ret < 0)
225 return;
226 }
227 panel->enabled = true;
228
229 ret = backlight_enable(panel->backlight);
230 if (ret < 0)
231 DRM_DEV_INFO(panel->dev, "failed to enable backlight: %d\n",
232 ret);
233 }
234 EXPORT_SYMBOL(drm_panel_enable);
235
236 /**
237 * drm_panel_disable - disable a panel
238 * @panel: DRM panel
239 *
240 * This will typically turn off the panel's backlight or disable the display
241 * drivers. For smart panels it should still be possible to communicate with
242 * the integrated circuitry via any command bus after this call.
243 */
drm_panel_disable(struct drm_panel * panel)244 void drm_panel_disable(struct drm_panel *panel)
245 {
246 int ret;
247
248 if (!panel)
249 return;
250
251 /*
252 * If you are seeing the warning below it likely means one of two things:
253 * - Your panel driver incorrectly calls drm_panel_disable() in its
254 * shutdown routine. You should delete this.
255 * - You are using panel-edp or panel-simple and your DRM modeset
256 * driver's shutdown() callback happened after the panel's shutdown().
257 * In this case the warning is harmless though ideally you should
258 * figure out how to reverse the order of the shutdown() callbacks.
259 */
260 if (!panel->enabled) {
261 dev_warn(panel->dev, "Skipping disable of already disabled panel\n");
262 return;
263 }
264
265 ret = backlight_disable(panel->backlight);
266 if (ret < 0)
267 DRM_DEV_INFO(panel->dev, "failed to disable backlight: %d\n",
268 ret);
269
270 if (panel->funcs && panel->funcs->disable) {
271 ret = panel->funcs->disable(panel);
272 if (ret < 0)
273 return;
274 }
275 panel->enabled = false;
276 }
277 EXPORT_SYMBOL(drm_panel_disable);
278
279 /**
280 * drm_panel_get_modes - probe the available display modes of a panel
281 * @panel: DRM panel
282 * @connector: DRM connector
283 *
284 * The modes probed from the panel are automatically added to the connector
285 * that the panel is attached to.
286 *
287 * Return: The number of modes available from the panel on success, or 0 on
288 * failure (no modes).
289 */
drm_panel_get_modes(struct drm_panel * panel,struct drm_connector * connector)290 int drm_panel_get_modes(struct drm_panel *panel,
291 struct drm_connector *connector)
292 {
293 if (!panel)
294 return 0;
295
296 if (panel->funcs && panel->funcs->get_modes) {
297 int num;
298
299 num = panel->funcs->get_modes(panel, connector);
300 if (num > 0)
301 return num;
302 }
303
304 return 0;
305 }
306 EXPORT_SYMBOL(drm_panel_get_modes);
307
__drm_panel_free(struct kref * kref)308 static void __drm_panel_free(struct kref *kref)
309 {
310 struct drm_panel *panel = container_of(kref, struct drm_panel, refcount);
311
312 kfree(panel->container);
313 }
314
315 /**
316 * drm_panel_get - Acquire a panel reference
317 * @panel: DRM panel
318 *
319 * This function increments the panel's refcount.
320 * Returns:
321 * Pointer to @panel
322 */
drm_panel_get(struct drm_panel * panel)323 struct drm_panel *drm_panel_get(struct drm_panel *panel)
324 {
325 if (!panel)
326 return panel;
327
328 kref_get(&panel->refcount);
329
330 return panel;
331 }
332 EXPORT_SYMBOL(drm_panel_get);
333
334 /**
335 * drm_panel_put - Release a panel reference
336 * @panel: DRM panel
337 *
338 * This function decrements the panel's reference count and frees the
339 * object if the reference count drops to zero.
340 */
drm_panel_put(struct drm_panel * panel)341 void drm_panel_put(struct drm_panel *panel)
342 {
343 if (panel)
344 kref_put(&panel->refcount, __drm_panel_free);
345 }
346 EXPORT_SYMBOL(drm_panel_put);
347
348 /**
349 * drm_panel_put_void - wrapper to drm_panel_put() taking a void pointer
350 *
351 * @data: pointer to @struct drm_panel, cast to a void pointer
352 *
353 * Wrapper of drm_panel_put() to be used when a function taking a void
354 * pointer is needed, for example as a devm action.
355 */
drm_panel_put_void(void * data)356 static void drm_panel_put_void(void *data)
357 {
358 struct drm_panel *panel = (struct drm_panel *)data;
359
360 drm_panel_put(panel);
361 }
362
__devm_drm_panel_alloc(struct device * dev,size_t size,size_t offset,const struct drm_panel_funcs * funcs,int connector_type)363 void *__devm_drm_panel_alloc(struct device *dev, size_t size, size_t offset,
364 const struct drm_panel_funcs *funcs,
365 int connector_type)
366 {
367 void *container;
368 struct drm_panel *panel;
369 int err;
370
371 if (!funcs) {
372 dev_warn(dev, "Missing funcs pointer\n");
373 return ERR_PTR(-EINVAL);
374 }
375
376 container = kzalloc(size, GFP_KERNEL);
377 if (!container)
378 return ERR_PTR(-ENOMEM);
379
380 panel = container + offset;
381 panel->container = container;
382 panel->funcs = funcs;
383 kref_init(&panel->refcount);
384
385 err = devm_add_action_or_reset(dev, drm_panel_put_void, panel);
386 if (err)
387 return ERR_PTR(err);
388
389 drm_panel_init(panel, dev, funcs, connector_type);
390
391 return container;
392 }
393 EXPORT_SYMBOL(__devm_drm_panel_alloc);
394
395 #ifdef CONFIG_OF
396 /**
397 * of_drm_find_panel - look up a panel using a device tree node
398 * @np: device tree node of the panel
399 *
400 * Searches the set of registered panels for one that matches the given device
401 * tree node. If a matching panel is found, return a pointer to it.
402 *
403 * Return: A pointer to the panel registered for the specified device tree
404 * node or an ERR_PTR() if no panel matching the device tree node can be found.
405 *
406 * Possible error codes returned by this function:
407 *
408 * - EPROBE_DEFER: the panel device has not been probed yet, and the caller
409 * should retry later
410 * - ENODEV: the device is not available (status != "okay" or "ok")
411 */
of_drm_find_panel(const struct device_node * np)412 struct drm_panel *of_drm_find_panel(const struct device_node *np)
413 {
414 struct drm_panel *panel;
415
416 if (!of_device_is_available(np))
417 return ERR_PTR(-ENODEV);
418
419 mutex_lock(&panel_lock);
420
421 list_for_each_entry(panel, &panel_list, list) {
422 if (panel->dev->of_node == np) {
423 mutex_unlock(&panel_lock);
424 return panel;
425 }
426 }
427
428 mutex_unlock(&panel_lock);
429 return ERR_PTR(-EPROBE_DEFER);
430 }
431 EXPORT_SYMBOL(of_drm_find_panel);
432
433 /**
434 * of_drm_get_panel_orientation - look up the orientation of the panel through
435 * the "rotation" binding from a device tree node
436 * @np: device tree node of the panel
437 * @orientation: orientation enum to be filled in
438 *
439 * Looks up the rotation of a panel in the device tree. The orientation of the
440 * panel is expressed as a property name "rotation" in the device tree. The
441 * rotation in the device tree is counter clockwise.
442 *
443 * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
444 * rotation property doesn't exist. Return a negative error code on failure.
445 */
of_drm_get_panel_orientation(const struct device_node * np,enum drm_panel_orientation * orientation)446 int of_drm_get_panel_orientation(const struct device_node *np,
447 enum drm_panel_orientation *orientation)
448 {
449 int rotation, ret;
450
451 ret = of_property_read_u32(np, "rotation", &rotation);
452 if (ret == -EINVAL) {
453 /* Don't return an error if there's no rotation property. */
454 *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
455 return 0;
456 }
457
458 if (ret < 0)
459 return ret;
460
461 if (rotation == 0)
462 *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
463 else if (rotation == 90)
464 *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
465 else if (rotation == 180)
466 *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
467 else if (rotation == 270)
468 *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
469 else
470 return -EINVAL;
471
472 return 0;
473 }
474 EXPORT_SYMBOL(of_drm_get_panel_orientation);
475 #endif
476
477 /* Find panel by fwnode. This should be identical to of_drm_find_panel(). */
find_panel_by_fwnode(const struct fwnode_handle * fwnode)478 static struct drm_panel *find_panel_by_fwnode(const struct fwnode_handle *fwnode)
479 {
480 struct drm_panel *panel;
481
482 if (!fwnode_device_is_available(fwnode))
483 return ERR_PTR(-ENODEV);
484
485 mutex_lock(&panel_lock);
486
487 list_for_each_entry(panel, &panel_list, list) {
488 if (dev_fwnode(panel->dev) == fwnode) {
489 mutex_unlock(&panel_lock);
490 return panel;
491 }
492 }
493
494 mutex_unlock(&panel_lock);
495
496 return ERR_PTR(-EPROBE_DEFER);
497 }
498
499 /* Find panel by follower device */
find_panel_by_dev(struct device * follower_dev)500 static struct drm_panel *find_panel_by_dev(struct device *follower_dev)
501 {
502 struct fwnode_handle *fwnode;
503 struct drm_panel *panel;
504
505 fwnode = fwnode_find_reference(dev_fwnode(follower_dev), "panel", 0);
506 if (IS_ERR(fwnode))
507 return ERR_PTR(-ENODEV);
508
509 panel = find_panel_by_fwnode(fwnode);
510 fwnode_handle_put(fwnode);
511
512 return panel;
513 }
514
515 /**
516 * drm_is_panel_follower() - Check if the device is a panel follower
517 * @dev: The 'struct device' to check
518 *
519 * This checks to see if a device needs to be power sequenced together with
520 * a panel using the panel follower API.
521 *
522 * The "panel" property of the follower points to the panel to be followed.
523 *
524 * Return: true if we should be power sequenced with a panel; false otherwise.
525 */
drm_is_panel_follower(struct device * dev)526 bool drm_is_panel_follower(struct device *dev)
527 {
528 /*
529 * The "panel" property is actually a phandle, but for simplicity we
530 * don't bother trying to parse it here. We just need to know if the
531 * property is there.
532 */
533 return device_property_present(dev, "panel");
534 }
535 EXPORT_SYMBOL(drm_is_panel_follower);
536
537 /**
538 * drm_panel_add_follower() - Register something to follow panel state.
539 * @follower_dev: The 'struct device' for the follower.
540 * @follower: The panel follower descriptor for the follower.
541 *
542 * A panel follower is called right after preparing the panel and right before
543 * unpreparing the panel. It's primary intention is to power on an associated
544 * touchscreen, though it could be used for any similar devices. Multiple
545 * devices are allowed the follow the same panel.
546 *
547 * If a follower is added to a panel that's already been turned on, the
548 * follower's prepare callback is called right away.
549 *
550 * The "panel" property of the follower points to the panel to be followed.
551 *
552 * Return: 0 or an error code. Note that -ENODEV means that we detected that
553 * follower_dev is not actually following a panel. The caller may
554 * choose to ignore this return value if following a panel is optional.
555 */
drm_panel_add_follower(struct device * follower_dev,struct drm_panel_follower * follower)556 int drm_panel_add_follower(struct device *follower_dev,
557 struct drm_panel_follower *follower)
558 {
559 struct drm_panel *panel;
560 int ret;
561
562 panel = find_panel_by_dev(follower_dev);
563 if (IS_ERR(panel))
564 return PTR_ERR(panel);
565
566 get_device(panel->dev);
567 follower->panel = panel;
568
569 mutex_lock(&panel->follower_lock);
570
571 list_add_tail(&follower->list, &panel->followers);
572 if (panel->prepared) {
573 ret = follower->funcs->panel_prepared(follower);
574 if (ret < 0)
575 dev_info(panel->dev, "%ps failed: %d\n",
576 follower->funcs->panel_prepared, ret);
577 }
578
579 mutex_unlock(&panel->follower_lock);
580
581 return 0;
582 }
583 EXPORT_SYMBOL(drm_panel_add_follower);
584
585 /**
586 * drm_panel_remove_follower() - Reverse drm_panel_add_follower().
587 * @follower: The panel follower descriptor for the follower.
588 *
589 * Undo drm_panel_add_follower(). This includes calling the follower's
590 * unprepare function if we're removed from a panel that's currently prepared.
591 *
592 * Return: 0 or an error code.
593 */
drm_panel_remove_follower(struct drm_panel_follower * follower)594 void drm_panel_remove_follower(struct drm_panel_follower *follower)
595 {
596 struct drm_panel *panel = follower->panel;
597 int ret;
598
599 mutex_lock(&panel->follower_lock);
600
601 if (panel->prepared) {
602 ret = follower->funcs->panel_unpreparing(follower);
603 if (ret < 0)
604 dev_info(panel->dev, "%ps failed: %d\n",
605 follower->funcs->panel_unpreparing, ret);
606 }
607 list_del_init(&follower->list);
608
609 mutex_unlock(&panel->follower_lock);
610
611 put_device(panel->dev);
612 }
613 EXPORT_SYMBOL(drm_panel_remove_follower);
614
drm_panel_remove_follower_void(void * follower)615 static void drm_panel_remove_follower_void(void *follower)
616 {
617 drm_panel_remove_follower(follower);
618 }
619
620 /**
621 * devm_drm_panel_add_follower() - devm version of drm_panel_add_follower()
622 * @follower_dev: The 'struct device' for the follower.
623 * @follower: The panel follower descriptor for the follower.
624 *
625 * Handles calling drm_panel_remove_follower() using devm on the follower_dev.
626 *
627 * Return: 0 or an error code.
628 */
devm_drm_panel_add_follower(struct device * follower_dev,struct drm_panel_follower * follower)629 int devm_drm_panel_add_follower(struct device *follower_dev,
630 struct drm_panel_follower *follower)
631 {
632 int ret;
633
634 ret = drm_panel_add_follower(follower_dev, follower);
635 if (ret)
636 return ret;
637
638 return devm_add_action_or_reset(follower_dev,
639 drm_panel_remove_follower_void, follower);
640 }
641 EXPORT_SYMBOL(devm_drm_panel_add_follower);
642
643 #if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
644 /**
645 * drm_panel_of_backlight - use backlight device node for backlight
646 * @panel: DRM panel
647 *
648 * Use this function to enable backlight handling if your panel
649 * uses device tree and has a backlight phandle.
650 *
651 * When the panel is enabled backlight will be enabled after a
652 * successful call to &drm_panel_funcs.enable()
653 *
654 * When the panel is disabled backlight will be disabled before the
655 * call to &drm_panel_funcs.disable().
656 *
657 * A typical implementation for a panel driver supporting device tree
658 * will call this function at probe time. Backlight will then be handled
659 * transparently without requiring any intervention from the driver.
660 * drm_panel_of_backlight() must be called after the call to drm_panel_init().
661 *
662 * Return: 0 on success or a negative error code on failure.
663 */
drm_panel_of_backlight(struct drm_panel * panel)664 int drm_panel_of_backlight(struct drm_panel *panel)
665 {
666 struct backlight_device *backlight;
667
668 if (!panel || !panel->dev)
669 return -EINVAL;
670
671 backlight = devm_of_find_backlight(panel->dev);
672
673 if (IS_ERR(backlight))
674 return PTR_ERR(backlight);
675
676 panel->backlight = backlight;
677 return 0;
678 }
679 EXPORT_SYMBOL(drm_panel_of_backlight);
680 #endif
681
682 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
683 MODULE_DESCRIPTION("DRM panel infrastructure");
684 MODULE_LICENSE("GPL and additional rights");
685