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