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