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 #ifndef __DRM_PANEL_H__ 25 #define __DRM_PANEL_H__ 26 27 #include <linux/err.h> 28 #include <linux/errno.h> 29 #include <linux/list.h> 30 #include <linux/mutex.h> 31 32 struct backlight_device; 33 struct dentry; 34 struct device_node; 35 struct drm_connector; 36 struct drm_device; 37 struct drm_panel_follower; 38 struct drm_panel; 39 struct display_timing; 40 41 enum drm_panel_orientation; 42 43 /** 44 * struct drm_panel_funcs - perform operations on a given panel 45 * 46 * The .prepare() function is typically called before the display controller 47 * starts to transmit video data. Panel drivers can use this to turn the panel 48 * on and wait for it to become ready. If additional configuration is required 49 * (via a control bus such as I2C, SPI or DSI for example) this is a good time 50 * to do that. 51 * 52 * After the display controller has started transmitting video data, it's safe 53 * to call the .enable() function. This will typically enable the backlight to 54 * make the image on screen visible. Some panels require a certain amount of 55 * time or frames before the image is displayed. This function is responsible 56 * for taking this into account before enabling the backlight to avoid visual 57 * glitches. 58 * 59 * Before stopping video transmission from the display controller it can be 60 * necessary to turn off the panel to avoid visual glitches. This is done in 61 * the .disable() function. Analogously to .enable() this typically involves 62 * turning off the backlight and waiting for some time to make sure no image 63 * is visible on the panel. It is then safe for the display controller to 64 * cease transmission of video data. 65 * 66 * To save power when no video data is transmitted, a driver can power down 67 * the panel. This is the job of the .unprepare() function. 68 * 69 * Backlight can be handled automatically if configured using 70 * drm_panel_of_backlight() or drm_panel_dp_aux_backlight(). Then the driver 71 * does not need to implement the functionality to enable/disable backlight. 72 */ 73 struct drm_panel_funcs { 74 /** 75 * @prepare: 76 * 77 * Turn on panel and perform set up. 78 * 79 * This function is optional. 80 */ 81 int (*prepare)(struct drm_panel *panel); 82 83 /** 84 * @enable: 85 * 86 * Enable panel (turn on back light, etc.). 87 * 88 * This function is optional. 89 */ 90 int (*enable)(struct drm_panel *panel); 91 92 /** 93 * @disable: 94 * 95 * Disable panel (turn off back light, etc.). 96 * 97 * This function is optional. 98 */ 99 int (*disable)(struct drm_panel *panel); 100 101 /** 102 * @unprepare: 103 * 104 * Turn off panel. 105 * 106 * This function is optional. 107 */ 108 int (*unprepare)(struct drm_panel *panel); 109 110 /** 111 * @get_modes: 112 * 113 * Add modes to the connector that the panel is attached to 114 * and returns the number of modes added. 115 * 116 * This function is mandatory. 117 */ 118 int (*get_modes)(struct drm_panel *panel, 119 struct drm_connector *connector); 120 121 /** 122 * @get_orientation: 123 * 124 * Return the panel orientation set by device tree or EDID. 125 * 126 * This function is optional. 127 */ 128 enum drm_panel_orientation (*get_orientation)(struct drm_panel *panel); 129 130 /** 131 * @get_timings: 132 * 133 * Copy display timings into the provided array and return 134 * the number of display timings available. 135 * 136 * This function is optional. 137 */ 138 int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, 139 struct display_timing *timings); 140 141 /** 142 * @debugfs_init: 143 * 144 * Allows panels to create panels-specific debugfs files. 145 */ 146 void (*debugfs_init)(struct drm_panel *panel, struct dentry *root); 147 }; 148 149 struct drm_panel_follower_funcs { 150 /** 151 * @panel_prepared: 152 * 153 * Called after the panel has been powered on. 154 */ 155 int (*panel_prepared)(struct drm_panel_follower *follower); 156 157 /** 158 * @panel_unpreparing: 159 * 160 * Called before the panel is powered off. 161 */ 162 int (*panel_unpreparing)(struct drm_panel_follower *follower); 163 }; 164 165 struct drm_panel_follower { 166 /** 167 * @funcs: 168 * 169 * Dependent device callbacks; should be initted by the caller. 170 */ 171 const struct drm_panel_follower_funcs *funcs; 172 173 /** 174 * @list 175 * 176 * Used for linking into panel's list; set by drm_panel_add_follower(). 177 */ 178 struct list_head list; 179 180 /** 181 * @panel 182 * 183 * The panel we're dependent on; set by drm_panel_add_follower(). 184 */ 185 struct drm_panel *panel; 186 }; 187 188 /** 189 * struct drm_panel - DRM panel object 190 */ 191 struct drm_panel { 192 /** 193 * @dev: 194 * 195 * Parent device of the panel. 196 */ 197 struct device *dev; 198 199 /** 200 * @backlight: 201 * 202 * Backlight device, used to turn on backlight after the call 203 * to enable(), and to turn off backlight before the call to 204 * disable(). 205 * backlight is set by drm_panel_of_backlight() or 206 * drm_panel_dp_aux_backlight() and drivers shall not assign it. 207 */ 208 struct backlight_device *backlight; 209 210 /** 211 * @funcs: 212 * 213 * Operations that can be performed on the panel. 214 */ 215 const struct drm_panel_funcs *funcs; 216 217 /** 218 * @connector_type: 219 * 220 * Type of the panel as a DRM_MODE_CONNECTOR_* value. This is used to 221 * initialise the drm_connector corresponding to the panel with the 222 * correct connector type. 223 */ 224 int connector_type; 225 226 /** 227 * @list: 228 * 229 * Panel entry in registry. 230 */ 231 struct list_head list; 232 233 /** 234 * @followers: 235 * 236 * A list of struct drm_panel_follower dependent on this panel. 237 */ 238 struct list_head followers; 239 240 /** 241 * @follower_lock: 242 * 243 * Lock for followers list. 244 */ 245 struct mutex follower_lock; 246 247 /** 248 * @prepare_prev_first: 249 * 250 * The previous controller should be prepared first, before the prepare 251 * for the panel is called. This is largely required for DSI panels 252 * where the DSI host controller should be initialised to LP-11 before 253 * the panel is powered up. 254 */ 255 bool prepare_prev_first; 256 257 /** 258 * @prepared: 259 * 260 * If true then the panel has been prepared. 261 */ 262 bool prepared; 263 264 /** 265 * @enabled: 266 * 267 * If true then the panel has been enabled. 268 */ 269 bool enabled; 270 }; 271 272 void drm_panel_init(struct drm_panel *panel, struct device *dev, 273 const struct drm_panel_funcs *funcs, 274 int connector_type); 275 276 void drm_panel_add(struct drm_panel *panel); 277 void drm_panel_remove(struct drm_panel *panel); 278 279 int drm_panel_prepare(struct drm_panel *panel); 280 int drm_panel_unprepare(struct drm_panel *panel); 281 282 int drm_panel_enable(struct drm_panel *panel); 283 int drm_panel_disable(struct drm_panel *panel); 284 285 int drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector); 286 287 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL) 288 struct drm_panel *of_drm_find_panel(const struct device_node *np); 289 int of_drm_get_panel_orientation(const struct device_node *np, 290 enum drm_panel_orientation *orientation); 291 #else 292 static inline struct drm_panel *of_drm_find_panel(const struct device_node *np) 293 { 294 return ERR_PTR(-ENODEV); 295 } 296 297 static inline int of_drm_get_panel_orientation(const struct device_node *np, 298 enum drm_panel_orientation *orientation) 299 { 300 return -ENODEV; 301 } 302 #endif 303 304 #if defined(CONFIG_DRM_PANEL) 305 bool drm_is_panel_follower(struct device *dev); 306 int drm_panel_add_follower(struct device *follower_dev, 307 struct drm_panel_follower *follower); 308 void drm_panel_remove_follower(struct drm_panel_follower *follower); 309 int devm_drm_panel_add_follower(struct device *follower_dev, 310 struct drm_panel_follower *follower); 311 #else 312 static inline bool drm_is_panel_follower(struct device *dev) 313 { 314 return false; 315 } 316 317 static inline int drm_panel_add_follower(struct device *follower_dev, 318 struct drm_panel_follower *follower) 319 { 320 return -ENODEV; 321 } 322 323 static inline void drm_panel_remove_follower(struct drm_panel_follower *follower) { } 324 static inline int devm_drm_panel_add_follower(struct device *follower_dev, 325 struct drm_panel_follower *follower) 326 { 327 return -ENODEV; 328 } 329 #endif 330 331 #if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ 332 (IS_MODULE(CONFIG_DRM) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) 333 int drm_panel_of_backlight(struct drm_panel *panel); 334 #else 335 static inline int drm_panel_of_backlight(struct drm_panel *panel) 336 { 337 return 0; 338 } 339 #endif 340 341 #endif 342