diff options
-rw-r--r-- | Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt | 7 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt | 16 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/vendor-prefixes.txt | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_bridge.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_mipi_dsi.c | 127 | ||||
-rw-r--r-- | drivers/gpu/drm/panel/panel-simple.c | 81 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 8 | ||||
-rw-r--r-- | include/drm/drm_mipi_dsi.h | 26 |
8 files changed, 262 insertions, 16 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt new file mode 100644 index 000000000000..8c5de692c55c --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/lg,lp120up1.txt | |||
@@ -0,0 +1,7 @@ | |||
1 | LG 12.0" (1920x1280 pixels) TFT LCD panel | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "lg,lp120up1" | ||
5 | |||
6 | This binding is compatible with the simple-panel binding, which is specified | ||
7 | in simple-panel.txt in this directory. | ||
diff --git a/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt new file mode 100644 index 000000000000..088a6cea5015 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/urt,umsh-8596md.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | United Radiant Technology UMSH-8596MD-xT 7.0" WVGA TFT LCD panel | ||
2 | |||
3 | Supported are LVDS versions (-11T, -19T) and parallel ones | ||
4 | (-T, -1T, -7T, -20T). | ||
5 | |||
6 | Required properties: | ||
7 | - compatible: should be one of: | ||
8 | "urt,umsh-8596md-t", | ||
9 | "urt,umsh-8596md-1t", | ||
10 | "urt,umsh-8596md-7t", | ||
11 | "urt,umsh-8596md-11t", | ||
12 | "urt,umsh-8596md-19t", | ||
13 | "urt,umsh-8596md-20t". | ||
14 | |||
15 | This binding is compatible with the simple-panel binding, which is specified | ||
16 | in simple-panel.txt in this directory. | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 72e2c5a2b327..1bcef7300b37 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -240,6 +240,7 @@ tplink TP-LINK Technologies Co., Ltd. | |||
240 | tronfy Tronfy | 240 | tronfy Tronfy |
241 | truly Truly Semiconductors Limited | 241 | truly Truly Semiconductors Limited |
242 | upisemi uPI Semiconductor Corp. | 242 | upisemi uPI Semiconductor Corp. |
243 | urt United Radiant Technology Corporation | ||
243 | usi Universal Scientific Industrial Co., Ltd. | 244 | usi Universal Scientific Industrial Co., Ltd. |
244 | v3 V3 Semiconductor | 245 | v3 V3 Semiconductor |
245 | variscite Variscite Ltd. | 246 | variscite Variscite Ltd. |
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index bd93453afa61..b3654404abd0 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c | |||
@@ -186,7 +186,8 @@ void drm_bridge_disable(struct drm_bridge *bridge) | |||
186 | 186 | ||
187 | drm_bridge_disable(bridge->next); | 187 | drm_bridge_disable(bridge->next); |
188 | 188 | ||
189 | bridge->funcs->disable(bridge); | 189 | if (bridge->funcs->disable) |
190 | bridge->funcs->disable(bridge); | ||
190 | } | 191 | } |
191 | EXPORT_SYMBOL(drm_bridge_disable); | 192 | EXPORT_SYMBOL(drm_bridge_disable); |
192 | 193 | ||
@@ -206,7 +207,8 @@ void drm_bridge_post_disable(struct drm_bridge *bridge) | |||
206 | if (!bridge) | 207 | if (!bridge) |
207 | return; | 208 | return; |
208 | 209 | ||
209 | bridge->funcs->post_disable(bridge); | 210 | if (bridge->funcs->post_disable) |
211 | bridge->funcs->post_disable(bridge); | ||
210 | 212 | ||
211 | drm_bridge_post_disable(bridge->next); | 213 | drm_bridge_post_disable(bridge->next); |
212 | } | 214 | } |
@@ -256,7 +258,8 @@ void drm_bridge_pre_enable(struct drm_bridge *bridge) | |||
256 | 258 | ||
257 | drm_bridge_pre_enable(bridge->next); | 259 | drm_bridge_pre_enable(bridge->next); |
258 | 260 | ||
259 | bridge->funcs->pre_enable(bridge); | 261 | if (bridge->funcs->pre_enable) |
262 | bridge->funcs->pre_enable(bridge); | ||
260 | } | 263 | } |
261 | EXPORT_SYMBOL(drm_bridge_pre_enable); | 264 | EXPORT_SYMBOL(drm_bridge_pre_enable); |
262 | 265 | ||
@@ -276,7 +279,8 @@ void drm_bridge_enable(struct drm_bridge *bridge) | |||
276 | if (!bridge) | 279 | if (!bridge) |
277 | return; | 280 | return; |
278 | 281 | ||
279 | bridge->funcs->enable(bridge); | 282 | if (bridge->funcs->enable) |
283 | bridge->funcs->enable(bridge); | ||
280 | 284 | ||
281 | drm_bridge_enable(bridge->next); | 285 | drm_bridge_enable(bridge->next); |
282 | } | 286 | } |
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index 6e6a9c58d404..f5d80839a90c 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c | |||
@@ -47,7 +47,17 @@ | |||
47 | 47 | ||
48 | static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) | 48 | static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) |
49 | { | 49 | { |
50 | return of_driver_match_device(dev, drv); | 50 | struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); |
51 | |||
52 | /* attempt OF style match */ | ||
53 | if (of_driver_match_device(dev, drv)) | ||
54 | return 1; | ||
55 | |||
56 | /* compare DSI device and driver names */ | ||
57 | if (!strcmp(dsi->name, drv->name)) | ||
58 | return 1; | ||
59 | |||
60 | return 0; | ||
51 | } | 61 | } |
52 | 62 | ||
53 | static const struct dev_pm_ops mipi_dsi_device_pm_ops = { | 63 | static const struct dev_pm_ops mipi_dsi_device_pm_ops = { |
@@ -129,14 +139,20 @@ static int mipi_dsi_device_add(struct mipi_dsi_device *dsi) | |||
129 | return device_add(&dsi->dev); | 139 | return device_add(&dsi->dev); |
130 | } | 140 | } |
131 | 141 | ||
142 | #if IS_ENABLED(CONFIG_OF) | ||
132 | static struct mipi_dsi_device * | 143 | static struct mipi_dsi_device * |
133 | of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) | 144 | of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) |
134 | { | 145 | { |
135 | struct mipi_dsi_device *dsi; | ||
136 | struct device *dev = host->dev; | 146 | struct device *dev = host->dev; |
147 | struct mipi_dsi_device_info info = { }; | ||
137 | int ret; | 148 | int ret; |
138 | u32 reg; | 149 | u32 reg; |
139 | 150 | ||
151 | if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) { | ||
152 | dev_err(dev, "modalias failure on %s\n", node->full_name); | ||
153 | return ERR_PTR(-EINVAL); | ||
154 | } | ||
155 | |||
140 | ret = of_property_read_u32(node, "reg", ®); | 156 | ret = of_property_read_u32(node, "reg", ®); |
141 | if (ret) { | 157 | if (ret) { |
142 | dev_err(dev, "device node %s has no valid reg property: %d\n", | 158 | dev_err(dev, "device node %s has no valid reg property: %d\n", |
@@ -144,32 +160,111 @@ of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) | |||
144 | return ERR_PTR(-EINVAL); | 160 | return ERR_PTR(-EINVAL); |
145 | } | 161 | } |
146 | 162 | ||
147 | if (reg > 3) { | 163 | info.channel = reg; |
148 | dev_err(dev, "device node %s has invalid reg property: %u\n", | 164 | info.node = of_node_get(node); |
149 | node->full_name, reg); | 165 | |
166 | return mipi_dsi_device_register_full(host, &info); | ||
167 | } | ||
168 | #else | ||
169 | static struct mipi_dsi_device * | ||
170 | of_mipi_dsi_device_add(struct mipi_dsi_host *host, struct device_node *node) | ||
171 | { | ||
172 | return ERR_PTR(-ENODEV); | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | /** | ||
177 | * mipi_dsi_device_register_full - create a MIPI DSI device | ||
178 | * @host: DSI host to which this device is connected | ||
179 | * @info: pointer to template containing DSI device information | ||
180 | * | ||
181 | * Create a MIPI DSI device by using the device information provided by | ||
182 | * mipi_dsi_device_info template | ||
183 | * | ||
184 | * Returns: | ||
185 | * A pointer to the newly created MIPI DSI device, or, a pointer encoded | ||
186 | * with an error | ||
187 | */ | ||
188 | struct mipi_dsi_device * | ||
189 | mipi_dsi_device_register_full(struct mipi_dsi_host *host, | ||
190 | const struct mipi_dsi_device_info *info) | ||
191 | { | ||
192 | struct mipi_dsi_device *dsi; | ||
193 | struct device *dev = host->dev; | ||
194 | int ret; | ||
195 | |||
196 | if (!info) { | ||
197 | dev_err(dev, "invalid mipi_dsi_device_info pointer\n"); | ||
198 | return ERR_PTR(-EINVAL); | ||
199 | } | ||
200 | |||
201 | if (info->channel > 3) { | ||
202 | dev_err(dev, "invalid virtual channel: %u\n", info->channel); | ||
150 | return ERR_PTR(-EINVAL); | 203 | return ERR_PTR(-EINVAL); |
151 | } | 204 | } |
152 | 205 | ||
153 | dsi = mipi_dsi_device_alloc(host); | 206 | dsi = mipi_dsi_device_alloc(host); |
154 | if (IS_ERR(dsi)) { | 207 | if (IS_ERR(dsi)) { |
155 | dev_err(dev, "failed to allocate DSI device %s: %ld\n", | 208 | dev_err(dev, "failed to allocate DSI device %ld\n", |
156 | node->full_name, PTR_ERR(dsi)); | 209 | PTR_ERR(dsi)); |
157 | return dsi; | 210 | return dsi; |
158 | } | 211 | } |
159 | 212 | ||
160 | dsi->dev.of_node = of_node_get(node); | 213 | dsi->dev.of_node = info->node; |
161 | dsi->channel = reg; | 214 | dsi->channel = info->channel; |
215 | strlcpy(dsi->name, info->type, sizeof(dsi->name)); | ||
162 | 216 | ||
163 | ret = mipi_dsi_device_add(dsi); | 217 | ret = mipi_dsi_device_add(dsi); |
164 | if (ret) { | 218 | if (ret) { |
165 | dev_err(dev, "failed to add DSI device %s: %d\n", | 219 | dev_err(dev, "failed to add DSI device %d\n", ret); |
166 | node->full_name, ret); | ||
167 | kfree(dsi); | 220 | kfree(dsi); |
168 | return ERR_PTR(ret); | 221 | return ERR_PTR(ret); |
169 | } | 222 | } |
170 | 223 | ||
171 | return dsi; | 224 | return dsi; |
172 | } | 225 | } |
226 | EXPORT_SYMBOL(mipi_dsi_device_register_full); | ||
227 | |||
228 | /** | ||
229 | * mipi_dsi_device_unregister - unregister MIPI DSI device | ||
230 | * @dsi: DSI peripheral device | ||
231 | */ | ||
232 | void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi) | ||
233 | { | ||
234 | device_unregister(&dsi->dev); | ||
235 | } | ||
236 | EXPORT_SYMBOL(mipi_dsi_device_unregister); | ||
237 | |||
238 | static DEFINE_MUTEX(host_lock); | ||
239 | static LIST_HEAD(host_list); | ||
240 | |||
241 | /** | ||
242 | * of_find_mipi_dsi_host_by_node() - find the MIPI DSI host matching a | ||
243 | * device tree node | ||
244 | * @node: device tree node | ||
245 | * | ||
246 | * Returns: | ||
247 | * A pointer to the MIPI DSI host corresponding to @node or NULL if no | ||
248 | * such device exists (or has not been registered yet). | ||
249 | */ | ||
250 | struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node) | ||
251 | { | ||
252 | struct mipi_dsi_host *host; | ||
253 | |||
254 | mutex_lock(&host_lock); | ||
255 | |||
256 | list_for_each_entry(host, &host_list, list) { | ||
257 | if (host->dev->of_node == node) { | ||
258 | mutex_unlock(&host_lock); | ||
259 | return host; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | mutex_unlock(&host_lock); | ||
264 | |||
265 | return NULL; | ||
266 | } | ||
267 | EXPORT_SYMBOL(of_find_mipi_dsi_host_by_node); | ||
173 | 268 | ||
174 | int mipi_dsi_host_register(struct mipi_dsi_host *host) | 269 | int mipi_dsi_host_register(struct mipi_dsi_host *host) |
175 | { | 270 | { |
@@ -182,6 +277,10 @@ int mipi_dsi_host_register(struct mipi_dsi_host *host) | |||
182 | of_mipi_dsi_device_add(host, node); | 277 | of_mipi_dsi_device_add(host, node); |
183 | } | 278 | } |
184 | 279 | ||
280 | mutex_lock(&host_lock); | ||
281 | list_add_tail(&host->list, &host_list); | ||
282 | mutex_unlock(&host_lock); | ||
283 | |||
185 | return 0; | 284 | return 0; |
186 | } | 285 | } |
187 | EXPORT_SYMBOL(mipi_dsi_host_register); | 286 | EXPORT_SYMBOL(mipi_dsi_host_register); |
@@ -190,7 +289,7 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) | |||
190 | { | 289 | { |
191 | struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); | 290 | struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); |
192 | 291 | ||
193 | device_unregister(&dsi->dev); | 292 | mipi_dsi_device_unregister(dsi); |
194 | 293 | ||
195 | return 0; | 294 | return 0; |
196 | } | 295 | } |
@@ -198,6 +297,10 @@ static int mipi_dsi_remove_device_fn(struct device *dev, void *priv) | |||
198 | void mipi_dsi_host_unregister(struct mipi_dsi_host *host) | 297 | void mipi_dsi_host_unregister(struct mipi_dsi_host *host) |
199 | { | 298 | { |
200 | device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); | 299 | device_for_each_child(host->dev, NULL, mipi_dsi_remove_device_fn); |
300 | |||
301 | mutex_lock(&host_lock); | ||
302 | list_del_init(&host->list); | ||
303 | mutex_unlock(&host_lock); | ||
201 | } | 304 | } |
202 | EXPORT_SYMBOL(mipi_dsi_host_unregister); | 305 | EXPORT_SYMBOL(mipi_dsi_host_unregister); |
203 | 306 | ||
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 2164c999052c..ceb20486dacf 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c | |||
@@ -847,6 +847,7 @@ static const struct drm_display_mode innolux_g121x1_l03_mode = { | |||
847 | .vsync_end = 768 + 38 + 1, | 847 | .vsync_end = 768 + 38 + 1, |
848 | .vtotal = 768 + 38 + 1 + 0, | 848 | .vtotal = 768 + 38 + 1 + 0, |
849 | .vrefresh = 60, | 849 | .vrefresh = 60, |
850 | .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, | ||
850 | }; | 851 | }; |
851 | 852 | ||
852 | static const struct panel_desc innolux_g121x1_l03 = { | 853 | static const struct panel_desc innolux_g121x1_l03 = { |
@@ -982,6 +983,29 @@ static const struct panel_desc lg_lb070wv8 = { | |||
982 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, | 983 | .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, |
983 | }; | 984 | }; |
984 | 985 | ||
986 | static const struct drm_display_mode lg_lp120up1_mode = { | ||
987 | .clock = 162300, | ||
988 | .hdisplay = 1920, | ||
989 | .hsync_start = 1920 + 40, | ||
990 | .hsync_end = 1920 + 40 + 40, | ||
991 | .htotal = 1920 + 40 + 40+ 80, | ||
992 | .vdisplay = 1280, | ||
993 | .vsync_start = 1280 + 4, | ||
994 | .vsync_end = 1280 + 4 + 4, | ||
995 | .vtotal = 1280 + 4 + 4 + 12, | ||
996 | .vrefresh = 60, | ||
997 | }; | ||
998 | |||
999 | static const struct panel_desc lg_lp120up1 = { | ||
1000 | .modes = &lg_lp120up1_mode, | ||
1001 | .num_modes = 1, | ||
1002 | .bpc = 8, | ||
1003 | .size = { | ||
1004 | .width = 267, | ||
1005 | .height = 183, | ||
1006 | }, | ||
1007 | }; | ||
1008 | |||
985 | static const struct drm_display_mode lg_lp129qe_mode = { | 1009 | static const struct drm_display_mode lg_lp129qe_mode = { |
986 | .clock = 285250, | 1010 | .clock = 285250, |
987 | .hdisplay = 2560, | 1011 | .hdisplay = 2560, |
@@ -1177,6 +1201,42 @@ static const struct panel_desc shelly_sca07010_bfn_lnn = { | |||
1177 | .bus_format = MEDIA_BUS_FMT_RGB666_1X18, | 1201 | .bus_format = MEDIA_BUS_FMT_RGB666_1X18, |
1178 | }; | 1202 | }; |
1179 | 1203 | ||
1204 | static const struct display_timing urt_umsh_8596md_timing = { | ||
1205 | .pixelclock = { 33260000, 33260000, 33260000 }, | ||
1206 | .hactive = { 800, 800, 800 }, | ||
1207 | .hfront_porch = { 41, 41, 41 }, | ||
1208 | .hback_porch = { 216 - 128, 216 - 128, 216 - 128 }, | ||
1209 | .hsync_len = { 71, 128, 128 }, | ||
1210 | .vactive = { 480, 480, 480 }, | ||
1211 | .vfront_porch = { 10, 10, 10 }, | ||
1212 | .vback_porch = { 35 - 2, 35 - 2, 35 - 2 }, | ||
1213 | .vsync_len = { 2, 2, 2 }, | ||
1214 | .flags = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE | | ||
1215 | DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, | ||
1216 | }; | ||
1217 | |||
1218 | static const struct panel_desc urt_umsh_8596md_lvds = { | ||
1219 | .timings = &urt_umsh_8596md_timing, | ||
1220 | .num_timings = 1, | ||
1221 | .bpc = 6, | ||
1222 | .size = { | ||
1223 | .width = 152, | ||
1224 | .height = 91, | ||
1225 | }, | ||
1226 | .bus_format = MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, | ||
1227 | }; | ||
1228 | |||
1229 | static const struct panel_desc urt_umsh_8596md_parallel = { | ||
1230 | .timings = &urt_umsh_8596md_timing, | ||
1231 | .num_timings = 1, | ||
1232 | .bpc = 6, | ||
1233 | .size = { | ||
1234 | .width = 152, | ||
1235 | .height = 91, | ||
1236 | }, | ||
1237 | .bus_format = MEDIA_BUS_FMT_RGB666_1X18, | ||
1238 | }; | ||
1239 | |||
1180 | static const struct of_device_id platform_of_match[] = { | 1240 | static const struct of_device_id platform_of_match[] = { |
1181 | { | 1241 | { |
1182 | .compatible = "ampire,am800480r3tmqwa1h", | 1242 | .compatible = "ampire,am800480r3tmqwa1h", |
@@ -1257,6 +1317,9 @@ static const struct of_device_id platform_of_match[] = { | |||
1257 | .compatible = "lg,lb070wv8", | 1317 | .compatible = "lg,lb070wv8", |
1258 | .data = &lg_lb070wv8, | 1318 | .data = &lg_lb070wv8, |
1259 | }, { | 1319 | }, { |
1320 | .compatible = "lg,lp120up1", | ||
1321 | .data = &lg_lp120up1, | ||
1322 | }, { | ||
1260 | .compatible = "lg,lp129qe", | 1323 | .compatible = "lg,lp129qe", |
1261 | .data = &lg_lp129qe, | 1324 | .data = &lg_lp129qe, |
1262 | }, { | 1325 | }, { |
@@ -1281,6 +1344,24 @@ static const struct of_device_id platform_of_match[] = { | |||
1281 | .compatible = "shelly,sca07010-bfn-lnn", | 1344 | .compatible = "shelly,sca07010-bfn-lnn", |
1282 | .data = &shelly_sca07010_bfn_lnn, | 1345 | .data = &shelly_sca07010_bfn_lnn, |
1283 | }, { | 1346 | }, { |
1347 | .compatible = "urt,umsh-8596md-t", | ||
1348 | .data = &urt_umsh_8596md_parallel, | ||
1349 | }, { | ||
1350 | .compatible = "urt,umsh-8596md-1t", | ||
1351 | .data = &urt_umsh_8596md_parallel, | ||
1352 | }, { | ||
1353 | .compatible = "urt,umsh-8596md-7t", | ||
1354 | .data = &urt_umsh_8596md_parallel, | ||
1355 | }, { | ||
1356 | .compatible = "urt,umsh-8596md-11t", | ||
1357 | .data = &urt_umsh_8596md_lvds, | ||
1358 | }, { | ||
1359 | .compatible = "urt,umsh-8596md-19t", | ||
1360 | .data = &urt_umsh_8596md_lvds, | ||
1361 | }, { | ||
1362 | .compatible = "urt,umsh-8596md-20t", | ||
1363 | .data = &urt_umsh_8596md_parallel, | ||
1364 | }, { | ||
1284 | /* sentinel */ | 1365 | /* sentinel */ |
1285 | } | 1366 | } |
1286 | }; | 1367 | }; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index fb9672783fa7..e0170bf80bb0 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -1597,6 +1597,8 @@ struct drm_bridge_funcs { | |||
1597 | * | 1597 | * |
1598 | * The bridge can assume that the display pipe (i.e. clocks and timing | 1598 | * The bridge can assume that the display pipe (i.e. clocks and timing |
1599 | * signals) feeding it is still running when this callback is called. | 1599 | * signals) feeding it is still running when this callback is called. |
1600 | * | ||
1601 | * The disable callback is optional. | ||
1600 | */ | 1602 | */ |
1601 | void (*disable)(struct drm_bridge *bridge); | 1603 | void (*disable)(struct drm_bridge *bridge); |
1602 | 1604 | ||
@@ -1613,6 +1615,8 @@ struct drm_bridge_funcs { | |||
1613 | * The bridge must assume that the display pipe (i.e. clocks and timing | 1615 | * The bridge must assume that the display pipe (i.e. clocks and timing |
1614 | * singals) feeding it is no longer running when this callback is | 1616 | * singals) feeding it is no longer running when this callback is |
1615 | * called. | 1617 | * called. |
1618 | * | ||
1619 | * The post_disable callback is optional. | ||
1616 | */ | 1620 | */ |
1617 | void (*post_disable)(struct drm_bridge *bridge); | 1621 | void (*post_disable)(struct drm_bridge *bridge); |
1618 | 1622 | ||
@@ -1641,6 +1645,8 @@ struct drm_bridge_funcs { | |||
1641 | * will not yet be running when this callback is called. The bridge must | 1645 | * will not yet be running when this callback is called. The bridge must |
1642 | * not enable the display link feeding the next bridge in the chain (if | 1646 | * not enable the display link feeding the next bridge in the chain (if |
1643 | * there is one) when this callback is called. | 1647 | * there is one) when this callback is called. |
1648 | * | ||
1649 | * The pre_enable callback is optional. | ||
1644 | */ | 1650 | */ |
1645 | void (*pre_enable)(struct drm_bridge *bridge); | 1651 | void (*pre_enable)(struct drm_bridge *bridge); |
1646 | 1652 | ||
@@ -1658,6 +1664,8 @@ struct drm_bridge_funcs { | |||
1658 | * signals) feeding it is running when this callback is called. This | 1664 | * signals) feeding it is running when this callback is called. This |
1659 | * callback must enable the display link feeding the next bridge in the | 1665 | * callback must enable the display link feeding the next bridge in the |
1660 | * chain if there is one. | 1666 | * chain if there is one. |
1667 | * | ||
1668 | * The enable callback is optional. | ||
1661 | */ | 1669 | */ |
1662 | void (*enable)(struct drm_bridge *bridge); | 1670 | void (*enable)(struct drm_bridge *bridge); |
1663 | }; | 1671 | }; |
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h index 1b3b1f8c8cdf..7a9840f8b38e 100644 --- a/include/drm/drm_mipi_dsi.h +++ b/include/drm/drm_mipi_dsi.h | |||
@@ -96,14 +96,17 @@ struct mipi_dsi_host_ops { | |||
96 | * struct mipi_dsi_host - DSI host device | 96 | * struct mipi_dsi_host - DSI host device |
97 | * @dev: driver model device node for this DSI host | 97 | * @dev: driver model device node for this DSI host |
98 | * @ops: DSI host operations | 98 | * @ops: DSI host operations |
99 | * @list: list management | ||
99 | */ | 100 | */ |
100 | struct mipi_dsi_host { | 101 | struct mipi_dsi_host { |
101 | struct device *dev; | 102 | struct device *dev; |
102 | const struct mipi_dsi_host_ops *ops; | 103 | const struct mipi_dsi_host_ops *ops; |
104 | struct list_head list; | ||
103 | }; | 105 | }; |
104 | 106 | ||
105 | int mipi_dsi_host_register(struct mipi_dsi_host *host); | 107 | int mipi_dsi_host_register(struct mipi_dsi_host *host); |
106 | void mipi_dsi_host_unregister(struct mipi_dsi_host *host); | 108 | void mipi_dsi_host_unregister(struct mipi_dsi_host *host); |
109 | struct mipi_dsi_host *of_find_mipi_dsi_host_by_node(struct device_node *node); | ||
107 | 110 | ||
108 | /* DSI mode flags */ | 111 | /* DSI mode flags */ |
109 | 112 | ||
@@ -139,10 +142,28 @@ enum mipi_dsi_pixel_format { | |||
139 | MIPI_DSI_FMT_RGB565, | 142 | MIPI_DSI_FMT_RGB565, |
140 | }; | 143 | }; |
141 | 144 | ||
145 | #define DSI_DEV_NAME_SIZE 20 | ||
146 | |||
147 | /** | ||
148 | * struct mipi_dsi_device_info - template for creating a mipi_dsi_device | ||
149 | * @type: DSI peripheral chip type | ||
150 | * @channel: DSI virtual channel assigned to peripheral | ||
151 | * @node: pointer to OF device node or NULL | ||
152 | * | ||
153 | * This is populated and passed to mipi_dsi_device_new to create a new | ||
154 | * DSI device | ||
155 | */ | ||
156 | struct mipi_dsi_device_info { | ||
157 | char type[DSI_DEV_NAME_SIZE]; | ||
158 | u32 channel; | ||
159 | struct device_node *node; | ||
160 | }; | ||
161 | |||
142 | /** | 162 | /** |
143 | * struct mipi_dsi_device - DSI peripheral device | 163 | * struct mipi_dsi_device - DSI peripheral device |
144 | * @host: DSI host for this peripheral | 164 | * @host: DSI host for this peripheral |
145 | * @dev: driver model device node for this peripheral | 165 | * @dev: driver model device node for this peripheral |
166 | * @name: DSI peripheral chip type | ||
146 | * @channel: virtual channel assigned to the peripheral | 167 | * @channel: virtual channel assigned to the peripheral |
147 | * @format: pixel format for video mode | 168 | * @format: pixel format for video mode |
148 | * @lanes: number of active data lanes | 169 | * @lanes: number of active data lanes |
@@ -152,6 +173,7 @@ struct mipi_dsi_device { | |||
152 | struct mipi_dsi_host *host; | 173 | struct mipi_dsi_host *host; |
153 | struct device dev; | 174 | struct device dev; |
154 | 175 | ||
176 | char name[DSI_DEV_NAME_SIZE]; | ||
155 | unsigned int channel; | 177 | unsigned int channel; |
156 | unsigned int lanes; | 178 | unsigned int lanes; |
157 | enum mipi_dsi_pixel_format format; | 179 | enum mipi_dsi_pixel_format format; |
@@ -188,6 +210,10 @@ static inline int mipi_dsi_pixel_format_to_bpp(enum mipi_dsi_pixel_format fmt) | |||
188 | return -EINVAL; | 210 | return -EINVAL; |
189 | } | 211 | } |
190 | 212 | ||
213 | struct mipi_dsi_device * | ||
214 | mipi_dsi_device_register_full(struct mipi_dsi_host *host, | ||
215 | const struct mipi_dsi_device_info *info); | ||
216 | void mipi_dsi_device_unregister(struct mipi_dsi_device *dsi); | ||
191 | struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); | 217 | struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); |
192 | int mipi_dsi_attach(struct mipi_dsi_device *dsi); | 218 | int mipi_dsi_attach(struct mipi_dsi_device *dsi); |
193 | int mipi_dsi_detach(struct mipi_dsi_device *dsi); | 219 | int mipi_dsi_detach(struct mipi_dsi_device *dsi); |