xref: /linux/drivers/gpu/drm/omapdrm/dss/output.c (revision a48bc6ac2c6cd85bc079fc859ab14ea844e812cd)
19960aa7cSTomi Valkeinen /*
2bb5cdf8dSAndrew F. Davis  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
39960aa7cSTomi Valkeinen  * Author: Archit Taneja <archit@ti.com>
49960aa7cSTomi Valkeinen  *
59960aa7cSTomi Valkeinen  * This program is free software; you can redistribute it and/or modify it
69960aa7cSTomi Valkeinen  * under the terms of the GNU General Public License version 2 as published by
79960aa7cSTomi Valkeinen  * the Free Software Foundation.
89960aa7cSTomi Valkeinen  *
99960aa7cSTomi Valkeinen  * This program is distributed in the hope that it will be useful, but WITHOUT
109960aa7cSTomi Valkeinen  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
119960aa7cSTomi Valkeinen  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
129960aa7cSTomi Valkeinen  * more details.
139960aa7cSTomi Valkeinen  *
149960aa7cSTomi Valkeinen  * You should have received a copy of the GNU General Public License along with
159960aa7cSTomi Valkeinen  * this program.  If not, see <http://www.gnu.org/licenses/>.
169960aa7cSTomi Valkeinen  */
179960aa7cSTomi Valkeinen 
189960aa7cSTomi Valkeinen #include <linux/kernel.h>
199960aa7cSTomi Valkeinen #include <linux/module.h>
209960aa7cSTomi Valkeinen #include <linux/platform_device.h>
219960aa7cSTomi Valkeinen #include <linux/slab.h>
229960aa7cSTomi Valkeinen #include <linux/of.h>
239960aa7cSTomi Valkeinen 
24845417b3SLaurent Pinchart #include "dss.h"
2532043da7SPeter Ujfalusi #include "omapdss.h"
269960aa7cSTomi Valkeinen 
279960aa7cSTomi Valkeinen static DEFINE_MUTEX(output_lock);
289960aa7cSTomi Valkeinen 
299960aa7cSTomi Valkeinen int omapdss_output_set_device(struct omap_dss_device *out,
309960aa7cSTomi Valkeinen 		struct omap_dss_device *dssdev)
319960aa7cSTomi Valkeinen {
329960aa7cSTomi Valkeinen 	int r;
339960aa7cSTomi Valkeinen 
349960aa7cSTomi Valkeinen 	mutex_lock(&output_lock);
359960aa7cSTomi Valkeinen 
369960aa7cSTomi Valkeinen 	if (out->dst) {
3739637e10STomi Valkeinen 		dev_err(out->dev,
3839637e10STomi Valkeinen 			"output already has device %s connected to it\n",
399960aa7cSTomi Valkeinen 			out->dst->name);
409960aa7cSTomi Valkeinen 		r = -EINVAL;
419960aa7cSTomi Valkeinen 		goto err;
429960aa7cSTomi Valkeinen 	}
439960aa7cSTomi Valkeinen 
449960aa7cSTomi Valkeinen 	if (out->output_type != dssdev->type) {
4539637e10STomi Valkeinen 		dev_err(out->dev, "output type and display type don't match\n");
469960aa7cSTomi Valkeinen 		r = -EINVAL;
479960aa7cSTomi Valkeinen 		goto err;
489960aa7cSTomi Valkeinen 	}
499960aa7cSTomi Valkeinen 
509960aa7cSTomi Valkeinen 	mutex_unlock(&output_lock);
519960aa7cSTomi Valkeinen 
529960aa7cSTomi Valkeinen 	return 0;
539960aa7cSTomi Valkeinen err:
549960aa7cSTomi Valkeinen 	mutex_unlock(&output_lock);
559960aa7cSTomi Valkeinen 
569960aa7cSTomi Valkeinen 	return r;
579960aa7cSTomi Valkeinen }
589960aa7cSTomi Valkeinen EXPORT_SYMBOL(omapdss_output_set_device);
599960aa7cSTomi Valkeinen 
609960aa7cSTomi Valkeinen int omapdss_output_unset_device(struct omap_dss_device *out)
619960aa7cSTomi Valkeinen {
629960aa7cSTomi Valkeinen 	int r;
639960aa7cSTomi Valkeinen 
649960aa7cSTomi Valkeinen 	mutex_lock(&output_lock);
659960aa7cSTomi Valkeinen 
669960aa7cSTomi Valkeinen 	if (!out->dst) {
6739637e10STomi Valkeinen 		dev_err(out->dev,
6839637e10STomi Valkeinen 			"output doesn't have a device connected to it\n");
699960aa7cSTomi Valkeinen 		r = -EINVAL;
709960aa7cSTomi Valkeinen 		goto err;
719960aa7cSTomi Valkeinen 	}
729960aa7cSTomi Valkeinen 
739960aa7cSTomi Valkeinen 	if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) {
7439637e10STomi Valkeinen 		dev_err(out->dev,
7539637e10STomi Valkeinen 			"device %s is not disabled, cannot unset device\n",
769960aa7cSTomi Valkeinen 			out->dst->name);
779960aa7cSTomi Valkeinen 		r = -EINVAL;
789960aa7cSTomi Valkeinen 		goto err;
799960aa7cSTomi Valkeinen 	}
809960aa7cSTomi Valkeinen 
819960aa7cSTomi Valkeinen 	mutex_unlock(&output_lock);
829960aa7cSTomi Valkeinen 
839960aa7cSTomi Valkeinen 	return 0;
849960aa7cSTomi Valkeinen err:
859960aa7cSTomi Valkeinen 	mutex_unlock(&output_lock);
869960aa7cSTomi Valkeinen 
879960aa7cSTomi Valkeinen 	return r;
889960aa7cSTomi Valkeinen }
899960aa7cSTomi Valkeinen EXPORT_SYMBOL(omapdss_output_unset_device);
909960aa7cSTomi Valkeinen 
91845417b3SLaurent Pinchart int dss_install_mgr_ops(struct dss_device *dss,
92845417b3SLaurent Pinchart 			const struct dss_mgr_ops *mgr_ops,
9364cb8179SLaurent Pinchart 			struct omap_drm_private *priv)
949960aa7cSTomi Valkeinen {
95845417b3SLaurent Pinchart 	if (dss->mgr_ops)
969960aa7cSTomi Valkeinen 		return -EBUSY;
979960aa7cSTomi Valkeinen 
98845417b3SLaurent Pinchart 	dss->mgr_ops = mgr_ops;
99845417b3SLaurent Pinchart 	dss->mgr_ops_priv = priv;
1009960aa7cSTomi Valkeinen 
1019960aa7cSTomi Valkeinen 	return 0;
1029960aa7cSTomi Valkeinen }
1039960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_install_mgr_ops);
1049960aa7cSTomi Valkeinen 
105845417b3SLaurent Pinchart void dss_uninstall_mgr_ops(struct dss_device *dss)
1069960aa7cSTomi Valkeinen {
107845417b3SLaurent Pinchart 	dss->mgr_ops = NULL;
108845417b3SLaurent Pinchart 	dss->mgr_ops_priv = NULL;
1099960aa7cSTomi Valkeinen }
1109960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_uninstall_mgr_ops);
1119960aa7cSTomi Valkeinen 
112*a48bc6acSLaurent Pinchart int dss_mgr_connect(struct omap_dss_device *dssdev)
1139960aa7cSTomi Valkeinen {
114845417b3SLaurent Pinchart 	return dssdev->dss->mgr_ops->connect(dssdev->dss->mgr_ops_priv,
115*a48bc6acSLaurent Pinchart 					     dssdev->dispc_channel, dssdev);
1169960aa7cSTomi Valkeinen }
1179960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_connect);
1189960aa7cSTomi Valkeinen 
119*a48bc6acSLaurent Pinchart void dss_mgr_disconnect(struct omap_dss_device *dssdev)
1209960aa7cSTomi Valkeinen {
121845417b3SLaurent Pinchart 	dssdev->dss->mgr_ops->disconnect(dssdev->dss->mgr_ops_priv,
122*a48bc6acSLaurent Pinchart 					 dssdev->dispc_channel, dssdev);
1239960aa7cSTomi Valkeinen }
1249960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_disconnect);
1259960aa7cSTomi Valkeinen 
12628d79f3eSLaurent Pinchart void dss_mgr_set_timings(struct omap_dss_device *dssdev,
12728d79f3eSLaurent Pinchart 			 const struct videomode *vm)
1289960aa7cSTomi Valkeinen {
129845417b3SLaurent Pinchart 	dssdev->dss->mgr_ops->set_timings(dssdev->dss->mgr_ops_priv,
130845417b3SLaurent Pinchart 					  dssdev->dispc_channel, vm);
1319960aa7cSTomi Valkeinen }
1329960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_set_timings);
1339960aa7cSTomi Valkeinen 
13428d79f3eSLaurent Pinchart void dss_mgr_set_lcd_config(struct omap_dss_device *dssdev,
1359960aa7cSTomi Valkeinen 		const struct dss_lcd_mgr_config *config)
1369960aa7cSTomi Valkeinen {
137845417b3SLaurent Pinchart 	dssdev->dss->mgr_ops->set_lcd_config(dssdev->dss->mgr_ops_priv,
13864cb8179SLaurent Pinchart 					     dssdev->dispc_channel, config);
1399960aa7cSTomi Valkeinen }
1409960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_set_lcd_config);
1419960aa7cSTomi Valkeinen 
14228d79f3eSLaurent Pinchart int dss_mgr_enable(struct omap_dss_device *dssdev)
1439960aa7cSTomi Valkeinen {
144845417b3SLaurent Pinchart 	return dssdev->dss->mgr_ops->enable(dssdev->dss->mgr_ops_priv,
145845417b3SLaurent Pinchart 					    dssdev->dispc_channel);
1469960aa7cSTomi Valkeinen }
1479960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_enable);
1489960aa7cSTomi Valkeinen 
14928d79f3eSLaurent Pinchart void dss_mgr_disable(struct omap_dss_device *dssdev)
1509960aa7cSTomi Valkeinen {
151845417b3SLaurent Pinchart 	dssdev->dss->mgr_ops->disable(dssdev->dss->mgr_ops_priv,
152845417b3SLaurent Pinchart 				      dssdev->dispc_channel);
1539960aa7cSTomi Valkeinen }
1549960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_disable);
1559960aa7cSTomi Valkeinen 
15628d79f3eSLaurent Pinchart void dss_mgr_start_update(struct omap_dss_device *dssdev)
1579960aa7cSTomi Valkeinen {
158845417b3SLaurent Pinchart 	dssdev->dss->mgr_ops->start_update(dssdev->dss->mgr_ops_priv,
159845417b3SLaurent Pinchart 					   dssdev->dispc_channel);
1609960aa7cSTomi Valkeinen }
1619960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_start_update);
1629960aa7cSTomi Valkeinen 
16328d79f3eSLaurent Pinchart int dss_mgr_register_framedone_handler(struct omap_dss_device *dssdev,
1649960aa7cSTomi Valkeinen 		void (*handler)(void *), void *data)
1659960aa7cSTomi Valkeinen {
166845417b3SLaurent Pinchart 	struct dss_device *dss = dssdev->dss;
167845417b3SLaurent Pinchart 
168845417b3SLaurent Pinchart 	return dss->mgr_ops->register_framedone_handler(dss->mgr_ops_priv,
16964cb8179SLaurent Pinchart 							dssdev->dispc_channel,
17028d79f3eSLaurent Pinchart 							handler, data);
1719960aa7cSTomi Valkeinen }
1729960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
1739960aa7cSTomi Valkeinen 
17428d79f3eSLaurent Pinchart void dss_mgr_unregister_framedone_handler(struct omap_dss_device *dssdev,
1759960aa7cSTomi Valkeinen 		void (*handler)(void *), void *data)
1769960aa7cSTomi Valkeinen {
177845417b3SLaurent Pinchart 	struct dss_device *dss = dssdev->dss;
178845417b3SLaurent Pinchart 
179845417b3SLaurent Pinchart 	dss->mgr_ops->unregister_framedone_handler(dss->mgr_ops_priv,
18064cb8179SLaurent Pinchart 						   dssdev->dispc_channel,
18128d79f3eSLaurent Pinchart 						   handler, data);
1829960aa7cSTomi Valkeinen }
1839960aa7cSTomi Valkeinen EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
184