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/notifier.h>
31
32 /* A hardware display blank change occurred */
33 #define DRM_PANEL_EVENT_BLANK 0x01
34 /* A hardware display blank early change occurred */
35 #define DRM_PANEL_EARLY_EVENT_BLANK 0x02
36
37 enum {
38 /* panel: power on */
39 DRM_PANEL_BLANK_UNBLANK,
40 /* panel: power off */
41 DRM_PANEL_BLANK_POWERDOWN,
42 /* panel: low power mode */
43 DRM_PANEL_BLANK_LP,
44 /* fps change */
45 DRM_PANEL_BLANK_FPS_CHANGE,
46 };
47
48 struct drm_panel_notifier {
49 int refresh_rate;
50 void *data;
51 uint32_t id;
52 };
53
54 struct device_node;
55 struct drm_connector;
56 struct drm_device;
57 struct drm_panel;
58 struct display_timing;
59
60 /**
61 * struct drm_panel_funcs - perform operations on a given panel
62 *
63 * The .prepare() function is typically called before the display controller
64 * starts to transmit video data. Panel drivers can use this to turn the panel
65 * on and wait for it to become ready. If additional configuration is required
66 * (via a control bus such as I2C, SPI or DSI for example) this is a good time
67 * to do that.
68 *
69 * After the display controller has started transmitting video data, it's safe
70 * to call the .enable() function. This will typically enable the backlight to
71 * make the image on screen visible. Some panels require a certain amount of
72 * time or frames before the image is displayed. This function is responsible
73 * for taking this into account before enabling the backlight to avoid visual
74 * glitches.
75 *
76 * Before stopping video transmission from the display controller it can be
77 * necessary to turn off the panel to avoid visual glitches. This is done in
78 * the .disable() function. Analogously to .enable() this typically involves
79 * turning off the backlight and waiting for some time to make sure no image
80 * is visible on the panel. It is then safe for the display controller to
81 * cease transmission of video data.
82 *
83 * To save power when no video data is transmitted, a driver can power down
84 * the panel. This is the job of the .unprepare() function.
85 */
86 struct drm_panel_funcs {
87 /**
88 * @prepare:
89 *
90 * Turn on panel and perform set up.
91 */
92 int (*prepare)(struct drm_panel *panel);
93
94 /**
95 * @enable:
96 *
97 * Enable panel (turn on back light, etc.).
98 */
99 int (*enable)(struct drm_panel *panel);
100
101 /**
102 * @disable:
103 *
104 * Disable panel (turn off back light, etc.).
105 */
106 int (*disable)(struct drm_panel *panel);
107
108 /**
109 * @unprepare:
110 *
111 * Turn off panel.
112 */
113 int (*unprepare)(struct drm_panel *panel);
114
115 /**
116 * @get_modes:
117 *
118 * Add modes to the connector that the panel is attached to and
119 * return the number of modes added.
120 */
121 int (*get_modes)(struct drm_panel *panel);
122
123 /**
124 * @get_timings:
125 *
126 * Copy display timings into the provided array and return
127 * the number of display timings available.
128 */
129 int (*get_timings)(struct drm_panel *panel, unsigned int num_timings,
130 struct display_timing *timings);
131 };
132
133 /**
134 * struct drm_panel - DRM panel object
135 */
136 struct drm_panel {
137 /**
138 * @drm:
139 *
140 * DRM device owning the panel.
141 */
142 struct drm_device *drm;
143
144 /**
145 * @connector:
146 *
147 * DRM connector that the panel is attached to.
148 */
149 struct drm_connector *connector;
150
151 /**
152 * @dev:
153 *
154 * Parent device of the panel.
155 */
156 struct device *dev;
157
158 /**
159 * @funcs:
160 *
161 * Operations that can be performed on the panel.
162 */
163 const struct drm_panel_funcs *funcs;
164
165 /**
166 * @list:
167 *
168 * Panel entry in registry.
169 */
170 struct list_head list;
171
172 /**
173 * @nh:
174 *
175 * panel notifier list head
176 */
177 struct blocking_notifier_head nh;
178 };
179
180 void drm_panel_init(struct drm_panel *panel);
181
182 int drm_panel_add(struct drm_panel *panel);
183 void drm_panel_remove(struct drm_panel *panel);
184
185 int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector);
186 void drm_panel_detach(struct drm_panel *panel);
187
188 int drm_panel_notifier_register(struct drm_panel *panel,
189 struct notifier_block *nb);
190 int drm_panel_notifier_unregister(struct drm_panel *panel,
191 struct notifier_block *nb);
192 int drm_panel_notifier_call_chain(struct drm_panel *panel,
193 unsigned long val, void *v);
194
195 int drm_panel_prepare(struct drm_panel *panel);
196 int drm_panel_unprepare(struct drm_panel *panel);
197
198 int drm_panel_enable(struct drm_panel *panel);
199 int drm_panel_disable(struct drm_panel *panel);
200
201 int drm_panel_get_modes(struct drm_panel *panel);
202
203 #if defined(CONFIG_OF) && defined(CONFIG_DRM_PANEL)
204 struct drm_panel *of_drm_find_panel(const struct device_node *np);
205 #else
of_drm_find_panel(const struct device_node * np)206 static inline struct drm_panel *of_drm_find_panel(const struct device_node *np)
207 {
208 return ERR_PTR(-ENODEV);
209 }
210 #endif
211
212 #endif
213