xref: /openbmc/linux/drivers/gpu/drm/omapdrm/dss/output.c (revision 9726bfcd)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4  * Author: Archit Taneja <archit@ti.com>
5  */
6 
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/platform_device.h>
10 #include <linux/slab.h>
11 #include <linux/of.h>
12 #include <linux/of_graph.h>
13 
14 #include <drm/drm_panel.h>
15 
16 #include "dss.h"
17 #include "omapdss.h"
18 
19 int omapdss_device_init_output(struct omap_dss_device *out)
20 {
21 	struct device_node *remote_node;
22 
23 	remote_node = of_graph_get_remote_node(out->dev->of_node, 0, 0);
24 	if (!remote_node) {
25 		dev_dbg(out->dev, "failed to find video sink\n");
26 		return 0;
27 	}
28 
29 	out->next = omapdss_find_device_by_node(remote_node);
30 	out->bridge = of_drm_find_bridge(remote_node);
31 	out->panel = of_drm_find_panel(remote_node);
32 	if (IS_ERR(out->panel))
33 		out->panel = NULL;
34 
35 	of_node_put(remote_node);
36 
37 	if (out->next && out->type != out->next->type) {
38 		dev_err(out->dev, "output type and display type don't match\n");
39 		omapdss_device_put(out->next);
40 		out->next = NULL;
41 		return -EINVAL;
42 	}
43 
44 	return out->next || out->bridge || out->panel ? 0 : -EPROBE_DEFER;
45 }
46 EXPORT_SYMBOL(omapdss_device_init_output);
47 
48 void omapdss_device_cleanup_output(struct omap_dss_device *out)
49 {
50 	if (out->next)
51 		omapdss_device_put(out->next);
52 }
53 EXPORT_SYMBOL(omapdss_device_cleanup_output);
54 
55 int dss_install_mgr_ops(struct dss_device *dss,
56 			const struct dss_mgr_ops *mgr_ops,
57 			struct omap_drm_private *priv)
58 {
59 	if (dss->mgr_ops)
60 		return -EBUSY;
61 
62 	dss->mgr_ops = mgr_ops;
63 	dss->mgr_ops_priv = priv;
64 
65 	return 0;
66 }
67 EXPORT_SYMBOL(dss_install_mgr_ops);
68 
69 void dss_uninstall_mgr_ops(struct dss_device *dss)
70 {
71 	dss->mgr_ops = NULL;
72 	dss->mgr_ops_priv = NULL;
73 }
74 EXPORT_SYMBOL(dss_uninstall_mgr_ops);
75 
76 void dss_mgr_set_timings(struct omap_dss_device *dssdev,
77 			 const struct videomode *vm)
78 {
79 	dssdev->dss->mgr_ops->set_timings(dssdev->dss->mgr_ops_priv,
80 					  dssdev->dispc_channel, vm);
81 }
82 EXPORT_SYMBOL(dss_mgr_set_timings);
83 
84 void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
85 		const struct dss_lcd_mgr_config *config)
86 {
87 	dssdev->dss->mgr_ops->set_lcd_config(dssdev->dss->mgr_ops_priv,
88 					     dssdev->dispc_channel, config);
89 }
90 EXPORT_SYMBOL(dss_mgr_set_lcd_config);
91 
92 int dss_mgr_enable(struct omap_dss_device *dssdev)
93 {
94 	return dssdev->dss->mgr_ops->enable(dssdev->dss->mgr_ops_priv,
95 					    dssdev->dispc_channel);
96 }
97 EXPORT_SYMBOL(dss_mgr_enable);
98 
99 void dss_mgr_disable(struct omap_dss_device *dssdev)
100 {
101 	dssdev->dss->mgr_ops->disable(dssdev->dss->mgr_ops_priv,
102 				      dssdev->dispc_channel);
103 }
104 EXPORT_SYMBOL(dss_mgr_disable);
105 
106 void dss_mgr_start_update(struct omap_dss_device *dssdev)
107 {
108 	dssdev->dss->mgr_ops->start_update(dssdev->dss->mgr_ops_priv,
109 					   dssdev->dispc_channel);
110 }
111 EXPORT_SYMBOL(dss_mgr_start_update);
112 
113 int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
114 		void (*handler)(void *), void *data)
115 {
116 	struct dss_device *dss = dssdev->dss;
117 
118 	return dss->mgr_ops->register_framedone_handler(dss->mgr_ops_priv,
119 							dssdev->dispc_channel,
120 							handler, data);
121 }
122 EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
123 
124 void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
125 		void (*handler)(void *), void *data)
126 {
127 	struct dss_device *dss = dssdev->dss;
128 
129 	dss->mgr_ops->unregister_framedone_handler(dss->mgr_ops_priv,
130 						   dssdev->dispc_channel,
131 						   handler, data);
132 }
133 EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
134