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