18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation 78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license, 88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the 128c2ecf20Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 138c2ecf20Sopenharmony_ci * of the Software. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 188c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 198c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 208c2ecf20Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 218c2ecf20Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 228c2ecf20Sopenharmony_ci */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#ifndef __DRM_PANEL_H__ 258c2ecf20Sopenharmony_ci#define __DRM_PANEL_H__ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include <linux/err.h> 288c2ecf20Sopenharmony_ci#include <linux/errno.h> 298c2ecf20Sopenharmony_ci#include <linux/list.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct backlight_device; 328c2ecf20Sopenharmony_cistruct device_node; 338c2ecf20Sopenharmony_cistruct drm_connector; 348c2ecf20Sopenharmony_cistruct drm_device; 358c2ecf20Sopenharmony_cistruct drm_panel; 368c2ecf20Sopenharmony_cistruct display_timing; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_cienum drm_panel_orientation; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/** 418c2ecf20Sopenharmony_ci * struct drm_panel_funcs - perform operations on a given panel 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * The .prepare() function is typically called before the display controller 448c2ecf20Sopenharmony_ci * starts to transmit video data. Panel drivers can use this to turn the panel 458c2ecf20Sopenharmony_ci * on and wait for it to become ready. If additional configuration is required 468c2ecf20Sopenharmony_ci * (via a control bus such as I2C, SPI or DSI for example) this is a good time 478c2ecf20Sopenharmony_ci * to do that. 488c2ecf20Sopenharmony_ci * 498c2ecf20Sopenharmony_ci * After the display controller has started transmitting video data, it's safe 508c2ecf20Sopenharmony_ci * to call the .enable() function. This will typically enable the backlight to 518c2ecf20Sopenharmony_ci * make the image on screen visible. Some panels require a certain amount of 528c2ecf20Sopenharmony_ci * time or frames before the image is displayed. This function is responsible 538c2ecf20Sopenharmony_ci * for taking this into account before enabling the backlight to avoid visual 548c2ecf20Sopenharmony_ci * glitches. 558c2ecf20Sopenharmony_ci * 568c2ecf20Sopenharmony_ci * Before stopping video transmission from the display controller it can be 578c2ecf20Sopenharmony_ci * necessary to turn off the panel to avoid visual glitches. This is done in 588c2ecf20Sopenharmony_ci * the .disable() function. Analogously to .enable() this typically involves 598c2ecf20Sopenharmony_ci * turning off the backlight and waiting for some time to make sure no image 608c2ecf20Sopenharmony_ci * is visible on the panel. It is then safe for the display controller to 618c2ecf20Sopenharmony_ci * cease transmission of video data. 628c2ecf20Sopenharmony_ci * 638c2ecf20Sopenharmony_ci * To save power when no video data is transmitted, a driver can power down 648c2ecf20Sopenharmony_ci * the panel. This is the job of the .unprepare() function. 658c2ecf20Sopenharmony_ci * 668c2ecf20Sopenharmony_ci * Backlight can be handled automatically if configured using 678c2ecf20Sopenharmony_ci * drm_panel_of_backlight(). Then the driver does not need to implement the 688c2ecf20Sopenharmony_ci * functionality to enable/disable backlight. 698c2ecf20Sopenharmony_ci */ 708c2ecf20Sopenharmony_cistruct drm_panel_funcs { 718c2ecf20Sopenharmony_ci /** 728c2ecf20Sopenharmony_ci * @prepare: 738c2ecf20Sopenharmony_ci * 748c2ecf20Sopenharmony_ci * Turn on panel and perform set up. 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * This function is optional. 778c2ecf20Sopenharmony_ci */ 788c2ecf20Sopenharmony_ci int (*prepare)(struct drm_panel *panel); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci /** 818c2ecf20Sopenharmony_ci * @enable: 828c2ecf20Sopenharmony_ci * 838c2ecf20Sopenharmony_ci * Enable panel (turn on back light, etc.). 848c2ecf20Sopenharmony_ci * 858c2ecf20Sopenharmony_ci * This function is optional. 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_ci int (*enable)(struct drm_panel *panel); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci /** 908c2ecf20Sopenharmony_ci * @disable: 918c2ecf20Sopenharmony_ci * 928c2ecf20Sopenharmony_ci * Disable panel (turn off back light, etc.). 938c2ecf20Sopenharmony_ci * 948c2ecf20Sopenharmony_ci * This function is optional. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_ci int (*disable)(struct drm_panel *panel); 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci /** 998c2ecf20Sopenharmony_ci * @unprepare: 1008c2ecf20Sopenharmony_ci * 1018c2ecf20Sopenharmony_ci * Turn off panel. 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * This function is optional. 1048c2ecf20Sopenharmony_ci */ 1058c2ecf20Sopenharmony_ci int (*unprepare)(struct drm_panel *panel); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci /** 1088c2ecf20Sopenharmony_ci * @get_modes: 1098c2ecf20Sopenharmony_ci * 1108c2ecf20Sopenharmony_ci * Add modes to the connector that the panel is attached to 1118c2ecf20Sopenharmony_ci * and returns the number of modes added. 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * This function is mandatory. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ci int (*get_modes)(struct drm_panel *panel, 1168c2ecf20Sopenharmony_ci struct drm_connector *connector); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci /** 1198c2ecf20Sopenharmony_ci * @get_timings: 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * Copy display timings into the provided array and return 1228c2ecf20Sopenharmony_ci * the number of display timings available. 1238c2ecf20Sopenharmony_ci * 1248c2ecf20Sopenharmony_ci * This function is optional. 1258c2ecf20Sopenharmony_ci */ 1268c2ecf20Sopenharmony_ci int (*get_timings)(struct drm_panel *panel, unsigned int num_timings, 1278c2ecf20Sopenharmony_ci struct display_timing *timings); 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci/** 1318c2ecf20Sopenharmony_ci * struct drm_panel - DRM panel object 1328c2ecf20Sopenharmony_ci */ 1338c2ecf20Sopenharmony_cistruct drm_panel { 1348c2ecf20Sopenharmony_ci /** 1358c2ecf20Sopenharmony_ci * @dev: 1368c2ecf20Sopenharmony_ci * 1378c2ecf20Sopenharmony_ci * Parent device of the panel. 1388c2ecf20Sopenharmony_ci */ 1398c2ecf20Sopenharmony_ci struct device *dev; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci /** 1428c2ecf20Sopenharmony_ci * @backlight: 1438c2ecf20Sopenharmony_ci * 1448c2ecf20Sopenharmony_ci * Backlight device, used to turn on backlight after the call 1458c2ecf20Sopenharmony_ci * to enable(), and to turn off backlight before the call to 1468c2ecf20Sopenharmony_ci * disable(). 1478c2ecf20Sopenharmony_ci * backlight is set by drm_panel_of_backlight() and drivers 1488c2ecf20Sopenharmony_ci * shall not assign it. 1498c2ecf20Sopenharmony_ci */ 1508c2ecf20Sopenharmony_ci struct backlight_device *backlight; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci /** 1538c2ecf20Sopenharmony_ci * @funcs: 1548c2ecf20Sopenharmony_ci * 1558c2ecf20Sopenharmony_ci * Operations that can be performed on the panel. 1568c2ecf20Sopenharmony_ci */ 1578c2ecf20Sopenharmony_ci const struct drm_panel_funcs *funcs; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci /** 1608c2ecf20Sopenharmony_ci * @connector_type: 1618c2ecf20Sopenharmony_ci * 1628c2ecf20Sopenharmony_ci * Type of the panel as a DRM_MODE_CONNECTOR_* value. This is used to 1638c2ecf20Sopenharmony_ci * initialise the drm_connector corresponding to the panel with the 1648c2ecf20Sopenharmony_ci * correct connector type. 1658c2ecf20Sopenharmony_ci */ 1668c2ecf20Sopenharmony_ci int connector_type; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /** 1698c2ecf20Sopenharmony_ci * @list: 1708c2ecf20Sopenharmony_ci * 1718c2ecf20Sopenharmony_ci * Panel entry in registry. 1728c2ecf20Sopenharmony_ci */ 1738c2ecf20Sopenharmony_ci struct list_head list; 1748c2ecf20Sopenharmony_ci}; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_civoid drm_panel_init(struct drm_panel *panel, struct device *dev, 1778c2ecf20Sopenharmony_ci const struct drm_panel_funcs *funcs, 1788c2ecf20Sopenharmony_ci int connector_type); 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_civoid drm_panel_add(struct drm_panel *panel); 1818c2ecf20Sopenharmony_civoid drm_panel_remove(struct drm_panel *panel); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ciint drm_panel_prepare(struct drm_panel *panel); 1848c2ecf20Sopenharmony_ciint drm_panel_unprepare(struct drm_panel *panel); 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ciint drm_panel_enable(struct drm_panel *panel); 1878c2ecf20Sopenharmony_ciint drm_panel_disable(struct drm_panel *panel); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ciint drm_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector); 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci#if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL) 1928c2ecf20Sopenharmony_cistruct drm_panel *of_drm_find_panel(const struct device_node *np); 1938c2ecf20Sopenharmony_ciint of_drm_get_panel_orientation(const struct device_node *np, 1948c2ecf20Sopenharmony_ci enum drm_panel_orientation *orientation); 1958c2ecf20Sopenharmony_ci#else 1968c2ecf20Sopenharmony_cistatic inline struct drm_panel *of_drm_find_panel(const struct device_node *np) 1978c2ecf20Sopenharmony_ci{ 1988c2ecf20Sopenharmony_ci return ERR_PTR(-ENODEV); 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic inline int of_drm_get_panel_orientation(const struct device_node *np, 2028c2ecf20Sopenharmony_ci enum drm_panel_orientation *orientation) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci return -ENODEV; 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ci#endif 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_DRM_PANEL) && (IS_BUILTIN(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ 2098c2ecf20Sopenharmony_ci (IS_MODULE(CONFIG_DRM) && IS_MODULE(CONFIG_BACKLIGHT_CLASS_DEVICE))) 2108c2ecf20Sopenharmony_ciint drm_panel_of_backlight(struct drm_panel *panel); 2118c2ecf20Sopenharmony_ci#else 2128c2ecf20Sopenharmony_cistatic inline int drm_panel_of_backlight(struct drm_panel *panel) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci return 0; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci#endif 2178c2ecf20Sopenharmony_ci 2188c2ecf20Sopenharmony_ci#endif 219