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 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 INIT_LIST_HEAD(&panel->list); 62 INIT_LIST_HEAD(&panel->followers); 63 mutex_init(&panel->follower_lock); 64 panel->dev = dev; 65 panel->funcs = funcs; 66 panel->connector_type = connector_type; 67 } 68 EXPORT_SYMBOL(drm_panel_init); 69 70 /** 71 * drm_panel_add - add a panel to the global registry 72 * @panel: panel to add 73 * 74 * Add a panel to the global registry so that it can be looked up by display 75 * drivers. 76 */ 77 void drm_panel_add(struct drm_panel *panel) 78 { 79 mutex_lock(&panel_lock); 80 list_add_tail(&panel->list, &panel_list); 81 mutex_unlock(&panel_lock); 82 } 83 EXPORT_SYMBOL(drm_panel_add); 84 85 /** 86 * drm_panel_remove - remove a panel from the global registry 87 * @panel: DRM panel 88 * 89 * Removes a panel from the global registry. 90 */ 91 void drm_panel_remove(struct drm_panel *panel) 92 { 93 mutex_lock(&panel_lock); 94 list_del_init(&panel->list); 95 mutex_unlock(&panel_lock); 96 } 97 EXPORT_SYMBOL(drm_panel_remove); 98 99 /** 100 * drm_panel_prepare - power on a panel 101 * @panel: DRM panel 102 * 103 * Calling this function will enable power and deassert any reset signals to 104 * the panel. After this has completed it is possible to communicate with any 105 * integrated circuitry via a command bus. 106 * 107 * Return: 0 on success or a negative error code on failure. 108 */ 109 int drm_panel_prepare(struct drm_panel *panel) 110 { 111 struct drm_panel_follower *follower; 112 int ret; 113 114 if (!panel) 115 return -EINVAL; 116 117 if (panel->prepared) { 118 dev_warn(panel->dev, "Skipping prepare of already prepared panel\n"); 119 return 0; 120 } 121 122 mutex_lock(&panel->follower_lock); 123 124 if (panel->funcs && panel->funcs->prepare) { 125 ret = panel->funcs->prepare(panel); 126 if (ret < 0) 127 goto exit; 128 } 129 panel->prepared = true; 130 131 list_for_each_entry(follower, &panel->followers, list) { 132 ret = follower->funcs->panel_prepared(follower); 133 if (ret < 0) 134 dev_info(panel->dev, "%ps failed: %d\n", 135 follower->funcs->panel_prepared, ret); 136 } 137 138 ret = 0; 139 exit: 140 mutex_unlock(&panel->follower_lock); 141 142 return ret; 143 } 144 EXPORT_SYMBOL(drm_panel_prepare); 145 146 /** 147 * drm_panel_unprepare - power off a panel 148 * @panel: DRM panel 149 * 150 * Calling this function will completely power off a panel (assert the panel's 151 * reset, turn off power supplies, ...). After this function has completed, it 152 * is usually no longer possible to communicate with the panel until another 153 * call to drm_panel_prepare(). 154 * 155 * Return: 0 on success or a negative error code on failure. 156 */ 157 int drm_panel_unprepare(struct drm_panel *panel) 158 { 159 struct drm_panel_follower *follower; 160 int ret; 161 162 if (!panel) 163 return -EINVAL; 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 0; 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 ret = 0; 196 exit: 197 mutex_unlock(&panel->follower_lock); 198 199 return ret; 200 } 201 EXPORT_SYMBOL(drm_panel_unprepare); 202 203 /** 204 * drm_panel_enable - enable a panel 205 * @panel: DRM panel 206 * 207 * Calling this function will cause the panel display drivers to be turned on 208 * and the backlight to be enabled. Content will be visible on screen after 209 * this call completes. 210 * 211 * Return: 0 on success or a negative error code on failure. 212 */ 213 int drm_panel_enable(struct drm_panel *panel) 214 { 215 int ret; 216 217 if (!panel) 218 return -EINVAL; 219 220 if (panel->enabled) { 221 dev_warn(panel->dev, "Skipping enable of already enabled panel\n"); 222 return 0; 223 } 224 225 if (panel->funcs && panel->funcs->enable) { 226 ret = panel->funcs->enable(panel); 227 if (ret < 0) 228 return ret; 229 } 230 panel->enabled = true; 231 232 ret = backlight_enable(panel->backlight); 233 if (ret < 0) 234 DRM_DEV_INFO(panel->dev, "failed to enable backlight: %d\n", 235 ret); 236 237 return 0; 238 } 239 EXPORT_SYMBOL(drm_panel_enable); 240 241 /** 242 * drm_panel_disable - disable a panel 243 * @panel: DRM panel 244 * 245 * This will typically turn off the panel's backlight or disable the display 246 * drivers. For smart panels it should still be possible to communicate with 247 * the integrated circuitry via any command bus after this call. 248 * 249 * Return: 0 on success or a negative error code on failure. 250 */ 251 int drm_panel_disable(struct drm_panel *panel) 252 { 253 int ret; 254 255 if (!panel) 256 return -EINVAL; 257 258 /* 259 * If you are seeing the warning below it likely means one of two things: 260 * - Your panel driver incorrectly calls drm_panel_disable() in its 261 * shutdown routine. You should delete this. 262 * - You are using panel-edp or panel-simple and your DRM modeset 263 * driver's shutdown() callback happened after the panel's shutdown(). 264 * In this case the warning is harmless though ideally you should 265 * figure out how to reverse the order of the shutdown() callbacks. 266 */ 267 if (!panel->enabled) { 268 dev_warn(panel->dev, "Skipping disable of already disabled panel\n"); 269 return 0; 270 } 271 272 ret = backlight_disable(panel->backlight); 273 if (ret < 0) 274 DRM_DEV_INFO(panel->dev, "failed to disable backlight: %d\n", 275 ret); 276 277 if (panel->funcs && panel->funcs->disable) { 278 ret = panel->funcs->disable(panel); 279 if (ret < 0) 280 return ret; 281 } 282 panel->enabled = false; 283 284 return 0; 285 } 286 EXPORT_SYMBOL(drm_panel_disable); 287 288 /** 289 * drm_panel_get_modes - probe the available display modes of a panel 290 * @panel: DRM panel 291 * @connector: DRM connector 292 * 293 * The modes probed from the panel are automatically added to the connector 294 * that the panel is attached to. 295 * 296 * Return: The number of modes available from the panel on success, or 0 on 297 * failure (no modes). 298 */ 299 int drm_panel_get_modes(struct drm_panel *panel, 300 struct drm_connector *connector) 301 { 302 if (!panel) 303 return 0; 304 305 if (panel->funcs && panel->funcs->get_modes) { 306 int num; 307 308 num = panel->funcs->get_modes(panel, connector); 309 if (num > 0) 310 return num; 311 } 312 313 return 0; 314 } 315 EXPORT_SYMBOL(drm_panel_get_modes); 316 317 #ifdef CONFIG_OF 318 /** 319 * of_drm_find_panel - look up a panel using a device tree node 320 * @np: device tree node of the panel 321 * 322 * Searches the set of registered panels for one that matches the given device 323 * tree node. If a matching panel is found, return a pointer to it. 324 * 325 * Return: A pointer to the panel registered for the specified device tree 326 * node or an ERR_PTR() if no panel matching the device tree node can be found. 327 * 328 * Possible error codes returned by this function: 329 * 330 * - EPROBE_DEFER: the panel device has not been probed yet, and the caller 331 * should retry later 332 * - ENODEV: the device is not available (status != "okay" or "ok") 333 */ 334 struct drm_panel *of_drm_find_panel(const struct device_node *np) 335 { 336 struct drm_panel *panel; 337 338 if (!of_device_is_available(np)) 339 return ERR_PTR(-ENODEV); 340 341 mutex_lock(&panel_lock); 342 343 list_for_each_entry(panel, &panel_list, list) { 344 if (panel->dev->of_node == np) { 345 mutex_unlock(&panel_lock); 346 return panel; 347 } 348 } 349 350 mutex_unlock(&panel_lock); 351 return ERR_PTR(-EPROBE_DEFER); 352 } 353 EXPORT_SYMBOL(of_drm_find_panel); 354 355 /** 356 * of_drm_get_panel_orientation - look up the orientation of the panel through 357 * the "rotation" binding from a device tree node 358 * @np: device tree node of the panel 359 * @orientation: orientation enum to be filled in 360 * 361 * Looks up the rotation of a panel in the device tree. The orientation of the 362 * panel is expressed as a property name "rotation" in the device tree. The 363 * rotation in the device tree is counter clockwise. 364 * 365 * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the 366 * rotation property doesn't exist. Return a negative error code on failure. 367 */ 368 int of_drm_get_panel_orientation(const struct device_node *np, 369 enum drm_panel_orientation *orientation) 370 { 371 int rotation, ret; 372 373 ret = of_property_read_u32(np, "rotation", &rotation); 374 if (ret == -EINVAL) { 375 /* Don't return an error if there's no rotation property. */ 376 *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN; 377 return 0; 378 } 379 380 if (ret < 0) 381 return ret; 382 383 if (rotation == 0) 384 *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; 385 else if (rotation == 90) 386 *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP; 387 else if (rotation == 180) 388 *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; 389 else if (rotation == 270) 390 *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP; 391 else 392 return -EINVAL; 393 394 return 0; 395 } 396 EXPORT_SYMBOL(of_drm_get_panel_orientation); 397 #endif 398 399 /** 400 * drm_is_panel_follower() - Check if the device is a panel follower 401 * @dev: The 'struct device' to check 402 * 403 * This checks to see if a device needs to be power sequenced together with 404 * a panel using the panel follower API. 405 * At the moment panels can only be followed on device tree enabled systems. 406 * The "panel" property of the follower points to the panel to be followed. 407 * 408 * Return: true if we should be power sequenced with a panel; false otherwise. 409 */ 410 bool drm_is_panel_follower(struct device *dev) 411 { 412 /* 413 * The "panel" property is actually a phandle, but for simplicity we 414 * don't bother trying to parse it here. We just need to know if the 415 * property is there. 416 */ 417 return of_property_present(dev->of_node, "panel"); 418 } 419 EXPORT_SYMBOL(drm_is_panel_follower); 420 421 /** 422 * drm_panel_add_follower() - Register something to follow panel state. 423 * @follower_dev: The 'struct device' for the follower. 424 * @follower: The panel follower descriptor for the follower. 425 * 426 * A panel follower is called right after preparing the panel and right before 427 * unpreparing the panel. It's primary intention is to power on an associated 428 * touchscreen, though it could be used for any similar devices. Multiple 429 * devices are allowed the follow the same panel. 430 * 431 * If a follower is added to a panel that's already been turned on, the 432 * follower's prepare callback is called right away. 433 * 434 * At the moment panels can only be followed on device tree enabled systems. 435 * The "panel" property of the follower points to the panel to be followed. 436 * 437 * Return: 0 or an error code. Note that -ENODEV means that we detected that 438 * follower_dev is not actually following a panel. The caller may 439 * choose to ignore this return value if following a panel is optional. 440 */ 441 int drm_panel_add_follower(struct device *follower_dev, 442 struct drm_panel_follower *follower) 443 { 444 struct device_node *panel_np; 445 struct drm_panel *panel; 446 int ret; 447 448 panel_np = of_parse_phandle(follower_dev->of_node, "panel", 0); 449 if (!panel_np) 450 return -ENODEV; 451 452 panel = of_drm_find_panel(panel_np); 453 of_node_put(panel_np); 454 if (IS_ERR(panel)) 455 return PTR_ERR(panel); 456 457 get_device(panel->dev); 458 follower->panel = panel; 459 460 mutex_lock(&panel->follower_lock); 461 462 list_add_tail(&follower->list, &panel->followers); 463 if (panel->prepared) { 464 ret = follower->funcs->panel_prepared(follower); 465 if (ret < 0) 466 dev_info(panel->dev, "%ps failed: %d\n", 467 follower->funcs->panel_prepared, ret); 468 } 469 470 mutex_unlock(&panel->follower_lock); 471 472 return 0; 473 } 474 EXPORT_SYMBOL(drm_panel_add_follower); 475 476 /** 477 * drm_panel_remove_follower() - Reverse drm_panel_add_follower(). 478 * @follower: The panel follower descriptor for the follower. 479 * 480 * Undo drm_panel_add_follower(). This includes calling the follower's 481 * unprepare function if we're removed from a panel that's currently prepared. 482 * 483 * Return: 0 or an error code. 484 */ 485 void drm_panel_remove_follower(struct drm_panel_follower *follower) 486 { 487 struct drm_panel *panel = follower->panel; 488 int ret; 489 490 mutex_lock(&panel->follower_lock); 491 492 if (panel->prepared) { 493 ret = follower->funcs->panel_unpreparing(follower); 494 if (ret < 0) 495 dev_info(panel->dev, "%ps failed: %d\n", 496 follower->funcs->panel_unpreparing, ret); 497 } 498 list_del_init(&follower->list); 499 500 mutex_unlock(&panel->follower_lock); 501 502 put_device(panel->dev); 503 } 504 EXPORT_SYMBOL(drm_panel_remove_follower); 505 506 static void drm_panel_remove_follower_void(void *follower) 507 { 508 drm_panel_remove_follower(follower); 509 } 510 511 /** 512 * devm_drm_panel_add_follower() - devm version of drm_panel_add_follower() 513 * @follower_dev: The 'struct device' for the follower. 514 * @follower: The panel follower descriptor for the follower. 515 * 516 * Handles calling drm_panel_remove_follower() using devm on the follower_dev. 517 * 518 * Return: 0 or an error code. 519 */ 520 int devm_drm_panel_add_follower(struct device *follower_dev, 521 struct drm_panel_follower *follower) 522 { 523 int ret; 524 525 ret = drm_panel_add_follower(follower_dev, follower); 526 if (ret) 527 return ret; 528 529 return devm_add_action_or_reset(follower_dev, 530 drm_panel_remove_follower_void, follower); 531 } 532 EXPORT_SYMBOL(devm_drm_panel_add_follower); 533 534 #if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE) 535 /** 536 * drm_panel_of_backlight - use backlight device node for backlight 537 * @panel: DRM panel 538 * 539 * Use this function to enable backlight handling if your panel 540 * uses device tree and has a backlight phandle. 541 * 542 * When the panel is enabled backlight will be enabled after a 543 * successful call to &drm_panel_funcs.enable() 544 * 545 * When the panel is disabled backlight will be disabled before the 546 * call to &drm_panel_funcs.disable(). 547 * 548 * A typical implementation for a panel driver supporting device tree 549 * will call this function at probe time. Backlight will then be handled 550 * transparently without requiring any intervention from the driver. 551 * drm_panel_of_backlight() must be called after the call to drm_panel_init(). 552 * 553 * Return: 0 on success or a negative error code on failure. 554 */ 555 int drm_panel_of_backlight(struct drm_panel *panel) 556 { 557 struct backlight_device *backlight; 558 559 if (!panel || !panel->dev) 560 return -EINVAL; 561 562 backlight = devm_of_find_backlight(panel->dev); 563 564 if (IS_ERR(backlight)) 565 return PTR_ERR(backlight); 566 567 panel->backlight = backlight; 568 return 0; 569 } 570 EXPORT_SYMBOL(drm_panel_of_backlight); 571 #endif 572 573 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 574 MODULE_DESCRIPTION("DRM panel infrastructure"); 575 MODULE_LICENSE("GPL and additional rights"); 576