Commit 19b4200d authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Tomi Valkeinen

drm/omap: Reverse direction of the DSS device enable/disable operations

The omapdrm and omapdss drivers are architectured based on display
pipelines made of multiple components handled from sink (display) to
source (DSS output). This is incompatible with the DRM bridge and panel
APIs that handle components from source to sink.

Reconcile the omapdrm and omapdss drivers with the DRM bridge and panel
model by reversing the direction of the DSS device .enable() and
.disable() operations. This completes the move to the DRM bridge model,
with the notable exception of the DSI pipelines that will require more
work.

We also adapt the omapdss shutdown handler dss_shutdown() to shut down
all active pipelines starting from the pipeline output device instead of
the display device.

As a consequence the for_each_dss_display() macro isn't used and can be
removed, and the omapdss_device_get_next() function underlying the macro
can be simplified to search for output devices only.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 3f3623dd
......@@ -35,26 +35,9 @@ static void tvc_disconnect(struct omap_dss_device *src,
{
}
static int tvc_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
return src->ops->enable(src);
}
static void tvc_disable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
src->ops->disable(src);
}
static const struct omap_dss_device_ops tvc_ops = {
.connect = tvc_connect,
.disconnect = tvc_disconnect,
.enable = tvc_enable,
.disable = tvc_disable,
};
static int tvc_probe(struct platform_device *pdev)
......@@ -85,13 +68,9 @@ static int tvc_probe(struct platform_device *pdev)
static int __exit tvc_remove(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *dssdev = &ddata->dssdev;
omapdss_device_unregister(&ddata->dssdev);
if (omapdss_device_is_enabled(dssdev))
tvc_disable(dssdev);
return 0;
}
......
......@@ -46,20 +46,6 @@ static void dvic_disconnect(struct omap_dss_device *src,
{
}
static int dvic_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
return src->ops->enable(src);
}
static void dvic_disable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
src->ops->disable(src);
}
static int dvic_ddc_read(struct i2c_adapter *adapter,
unsigned char *buf, u16 count, u8 offset)
{
......@@ -163,9 +149,6 @@ static const struct omap_dss_device_ops dvic_ops = {
.connect = dvic_connect,
.disconnect = dvic_disconnect,
.enable = dvic_enable,
.disable = dvic_disable,
.read_edid = dvic_read_edid,
.detect = dvic_detect,
......@@ -275,13 +258,9 @@ static int dvic_probe(struct platform_device *pdev)
static int __exit dvic_remove(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *dssdev = &ddata->dssdev;
omapdss_device_unregister(&ddata->dssdev);
if (omapdss_device_is_enabled(dssdev))
dvic_disable(dssdev);
i2c_put_adapter(ddata->i2c_adapter);
mutex_destroy(&ddata->hpd_lock);
......
......@@ -41,20 +41,6 @@ static void hdmic_disconnect(struct omap_dss_device *src,
{
}
static int hdmic_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
return src->ops->enable(src);
}
static void hdmic_disable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
src->ops->disable(src);
}
static bool hdmic_detect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
......@@ -89,9 +75,6 @@ static const struct omap_dss_device_ops hdmic_ops = {
.connect = hdmic_connect,
.disconnect = hdmic_disconnect,
.enable = hdmic_enable,
.disable = hdmic_disable,
.detect = hdmic_detect,
.register_hpd_cb = hdmic_register_hpd_cb,
.unregister_hpd_cb = hdmic_unregister_hpd_cb,
......@@ -172,13 +155,9 @@ static int hdmic_probe(struct platform_device *pdev)
static int __exit hdmic_remove(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct omap_dss_device *dssdev = &ddata->dssdev;
omapdss_device_unregister(&ddata->dssdev);
if (omapdss_device_is_enabled(dssdev))
hdmic_disable(dssdev);
return 0;
}
......
......@@ -41,39 +41,20 @@ static void opa362_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
}
static int opa362_enable(struct omap_dss_device *dssdev)
static void opa362_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
dev_dbg(dssdev->dev, "enable\n");
r = src->ops->enable(src);
if (r)
return r;
if (ddata->enable_gpio)
gpiod_set_value_cansleep(ddata->enable_gpio, 1);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static void opa362_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
dev_dbg(dssdev->dev, "disable\n");
if (ddata->enable_gpio)
gpiod_set_value_cansleep(ddata->enable_gpio, 0);
src->ops->disable(src);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static const struct omap_dss_device_ops opa362_ops = {
......@@ -132,9 +113,7 @@ static int __exit opa362_remove(struct platform_device *pdev)
omapdss_device_put(dssdev->next);
omapdss_device_unregister(&ddata->dssdev);
WARN_ON(omapdss_device_is_enabled(dssdev));
if (omapdss_device_is_enabled(dssdev))
opa362_disable(dssdev);
opa362_disable(dssdev);
return 0;
}
......
......@@ -36,35 +36,20 @@ static void tfp410_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
}
static int tfp410_enable(struct omap_dss_device *dssdev)
static void tfp410_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
if (ddata->pd_gpio)
gpiod_set_value_cansleep(ddata->pd_gpio, 0);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return 0;
}
static void tfp410_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->pd_gpio)
gpiod_set_value_cansleep(ddata->pd_gpio, 0);
src->ops->disable(src);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static const struct omap_dss_device_ops tfp410_ops = {
......@@ -126,9 +111,7 @@ static int __exit tfp410_remove(struct platform_device *pdev)
omapdss_device_put(dssdev->next);
omapdss_device_unregister(&ddata->dssdev);
WARN_ON(omapdss_device_is_enabled(dssdev));
if (omapdss_device_is_enabled(dssdev))
tfp410_disable(dssdev);
tfp410_disable(dssdev);
return 0;
}
......
......@@ -62,35 +62,6 @@ static void tpd_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
}
static int tpd_enable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
r = src->ops->enable(src);
if (r)
return r;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
return r;
}
static void tpd_disable(struct omap_dss_device *dssdev)
{
struct omap_dss_device *src = dssdev->src;
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
src->ops->disable(src);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static bool tpd_detect(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
......@@ -124,8 +95,6 @@ static void tpd_unregister_hpd_cb(struct omap_dss_device *dssdev)
static const struct omap_dss_device_ops tpd_ops = {
.connect = tpd_connect,
.disconnect = tpd_disconnect,
.enable = tpd_enable,
.disable = tpd_disable,
.detect = tpd_detect,
.register_hpd_cb = tpd_register_hpd_cb,
.unregister_hpd_cb = tpd_unregister_hpd_cb,
......@@ -225,10 +194,6 @@ static int __exit tpd_remove(struct platform_device *pdev)
omapdss_device_put(dssdev->next);
omapdss_device_unregister(&ddata->dssdev);
WARN_ON(omapdss_device_is_enabled(dssdev));
if (omapdss_device_is_enabled(dssdev))
tpd_disable(dssdev);
return 0;
}
......
......@@ -45,39 +45,27 @@ static void panel_dpi_disconnect(struct omap_dss_device *src,
{
}
static int panel_dpi_enable(struct omap_dss_device *dssdev)
static void panel_dpi_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
r = regulator_enable(ddata->vcc_supply);
if (r) {
src->ops->disable(src);
return r;
}
if (r)
return;
gpiod_set_value_cansleep(ddata->enable_gpio, 1);
backlight_enable(ddata->backlight);
return 0;
}
static void panel_dpi_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
backlight_disable(ddata->backlight);
gpiod_set_value_cansleep(ddata->enable_gpio, 0);
regulator_disable(ddata->vcc_supply);
src->ops->disable(src);
}
static void panel_dpi_get_timings(struct omap_dss_device *dssdev,
......
......@@ -315,12 +315,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
if (!ddata->ulps_enabled)
return 0;
r = src->ops->enable(src);
if (r) {
dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
goto err1;
}
src->ops->enable(src);
src->ops->dsi.enable_hs(src, ddata->channel, true);
r = _dsicm_enable_te(ddata, true);
......@@ -347,7 +342,7 @@ static int dsicm_exit_ulps(struct panel_drv_data *ddata)
enable_irq(gpiod_to_irq(ddata->ext_te_gpio));
ddata->ulps_enabled = false;
}
err1:
dsicm_queue_ulps_work(ddata);
return r;
......@@ -649,11 +644,7 @@ static int dsicm_power_on(struct panel_drv_data *ddata)
goto err_vddi;
}
r = src->ops->enable(src);
if (r) {
dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
goto err_vddi;
}
src->ops->enable(src);
dsicm_hw_reset(ddata);
......@@ -787,7 +778,7 @@ static void dsicm_disconnect(struct omap_dss_device *src,
src->ops->dsi.release_vc(src, ddata->channel);
}
static int dsicm_enable(struct omap_dss_device *dssdev)
static void dsicm_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
......@@ -808,11 +799,10 @@ static int dsicm_enable(struct omap_dss_device *dssdev)
dsicm_bl_power(ddata, true);
return 0;
return;
err:
dev_dbg(&ddata->pdev->dev, "enable failed\n");
dev_dbg(&ddata->pdev->dev, "enable failed (%d)\n", r);
mutex_unlock(&ddata->lock);
return r;
}
static void dsicm_disable(struct omap_dss_device *dssdev)
......
......@@ -123,31 +123,20 @@ static void lb035q02_disconnect(struct omap_dss_device *src,
{
}
static int lb035q02_enable(struct omap_dss_device *dssdev)
static void lb035q02_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
if (ddata->enable_gpio)
gpiod_set_value_cansleep(ddata->enable_gpio, 1);
return 0;
}
static void lb035q02_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->enable_gpio)
gpiod_set_value_cansleep(ddata->enable_gpio, 0);
src->ops->disable(src);
}
static void lb035q02_get_timings(struct omap_dss_device *dssdev,
......@@ -232,8 +221,7 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
if (omapdss_device_is_enabled(dssdev))
lb035q02_disable(dssdev);
lb035q02_disable(dssdev);
return 0;
}
......
......@@ -118,29 +118,18 @@ static void nec_8048_disconnect(struct omap_dss_device *src,
{
}
static int nec_8048_enable(struct omap_dss_device *dssdev)
static void nec_8048_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
gpiod_set_value_cansleep(ddata->res_gpio, 1);
return 0;
}
static void nec_8048_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
gpiod_set_value_cansleep(ddata->res_gpio, 0);
src->ops->disable(src);
}
static void nec_8048_get_timings(struct omap_dss_device *dssdev,
......@@ -223,8 +212,7 @@ static int nec_8048_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
if (omapdss_device_is_enabled(dssdev))
nec_8048_disable(dssdev);
nec_8048_disable(dssdev);
return 0;
}
......
......@@ -62,23 +62,22 @@ static void sharp_ls_disconnect(struct omap_dss_device *src,
{
}
static int sharp_ls_enable(struct omap_dss_device *dssdev)
static void sharp_ls_pre_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
if (ddata->vcc) {
r = regulator_enable(ddata->vcc);
if (r != 0)
return r;
if (r)
dev_err(dssdev->dev, "%s: failed to enable regulator\n",
__func__);
}
}
r = src->ops->enable(src);
if (r) {
regulator_disable(ddata->vcc);
return r;
}
static void sharp_ls_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
/* wait couple of vsyncs until enabling the LCD */
msleep(50);
......@@ -88,14 +87,11 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)
if (ddata->ini_gpio)
gpiod_set_value_cansleep(ddata->ini_gpio, 1);
return 0;
}
static void sharp_ls_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
if (ddata->ini_gpio)
gpiod_set_value_cansleep(ddata->ini_gpio, 0);
......@@ -104,10 +100,12 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)
gpiod_set_value_cansleep(ddata->resb_gpio, 0);
/* wait at least 5 vsyncs after disabling the LCD */
msleep(100);
}
src->ops->disable(src);
static void sharp_ls_post_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
if (ddata->vcc)
regulator_disable(ddata->vcc);
......@@ -125,8 +123,10 @@ static const struct omap_dss_device_ops sharp_ls_ops = {
.connect = sharp_ls_connect,
.disconnect = sharp_ls_disconnect,
.pre_enable = sharp_ls_pre_enable,
.enable = sharp_ls_enable,
.disable = sharp_ls_disable,
.post_disable = sharp_ls_post_disable,
.get_timings = sharp_ls_get_timings,
};
......@@ -230,8 +230,10 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)
omapdss_device_unregister(dssdev);
if (omapdss_device_is_enabled(dssdev))
if (omapdss_device_is_enabled(dssdev)) {
sharp_ls_disable(dssdev);
sharp_ls_post_disable(dssdev);
}
return 0;
}
......
......@@ -516,17 +516,9 @@ static void acx565akm_disconnect(struct omap_dss_device *src,
static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
dev_dbg(&ddata->spi->dev, "%s\n", __func__);
r = src->ops->enable(src);
if (r) {
pr_err("%s sdi enable failed\n", __func__);
return r;
}
/*FIXME tweak me */
msleep(50);
......@@ -562,7 +554,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)
static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
dev_dbg(dssdev->dev, "%s\n", __func__);
......@@ -585,20 +576,15 @@ static void acx565akm_panel_power_off(struct omap_dss_device *dssdev)
/* FIXME need to tweak this delay */
msleep(100);
src->ops->disable(src);
}
static int acx565akm_enable(struct omap_dss_device *dssdev)
static void acx565akm_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
int r;
mutex_lock(&ddata->mutex);
r = acx565akm_panel_power_on(dssdev);
acx565akm_panel_power_on(dssdev);
mutex_unlock(&ddata->mutex);
return r;
}
static void acx565akm_disable(struct omap_dss_device *dssdev)
......
......@@ -169,18 +169,12 @@ static void td028ttec1_panel_disconnect(struct omap_dss_device *src,
{
}
static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
static void td028ttec1_panel_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
int r = 0;
dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n",
dssdev->state);
dev_dbg(dssdev->dev, "%s: state %d\n", __func__, dssdev->state);
/* three times command zero */
r |= jbt_ret_write_0(ddata, 0x00);
......@@ -191,8 +185,8 @@ static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
usleep_range(1000, 2000);
if (r) {
dev_warn(dssdev->dev, "transfer error\n");
return -EIO;
dev_warn(dssdev->dev, "%s: transfer error\n", __func__);
return;
}
/* deep standby out */
......@@ -262,13 +256,13 @@ static int td028ttec1_panel_enable(struct omap_dss_device *dssdev)
r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON);
return r ? -EIO : 0;
if (r)
dev_err(dssdev->dev, "%s: write error\n", __func__);
}
static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n");
......@@ -276,8 +270,6 @@ static void td028ttec1_panel_disable(struct omap_dss_device *dssdev)
jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002);
jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN);
jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00);
src->ops->disable(src);
}
static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev,
......@@ -354,8 +346,7 @@ static int td028ttec1_panel_remove(struct spi_device *spi)
omapdss_device_unregister(dssdev);
if (omapdss_device_is_enabled(dssdev))
td028ttec1_panel_disable(dssdev);
td028ttec1_panel_disable(dssdev);
return 0;
}
......
......@@ -320,16 +320,11 @@ static void tpo_td043_disconnect(struct omap_dss_device *src,
{
}
static int tpo_td043_enable(struct omap_dss_device *dssdev)
static void tpo_td043_enable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
int r;
r = src->ops->enable(src);
if (r)
return r;
/*
* If we are resuming from system suspend, SPI clocks might not be
* enabled yet, so we'll program the LCD from SPI PM resume callback.
......@@ -337,20 +332,16 @@ static int tpo_td043_enable(struct omap_dss_device *dssdev)
if (!ddata->spi_suspended) {
r = tpo_td043_power_on(ddata);
if (r) {
src->ops->disable(src);
return r;
dev_err(&ddata->spi->dev, "%s: power on failed (%d)\n",
__func__, r);
return;
}
}
return 0;
}
static void tpo_td043_disable(struct omap_dss_device *dssdev)
{
struct panel_drv_data *ddata = to_panel_data(dssdev);
struct omap_dss_device *src = dssdev->src;
src->ops->disable(src);
if (!ddata->spi_suspended)
tpo_td043_power_off(ddata);
......
......@@ -126,13 +126,10 @@ struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
}
/*
* Search for the next device starting at @from. The type argument specfies
* which device types to consider when searching. Searching for multiple types
* is supported by and'ing their type flags. Release the reference to the @from
* device, and acquire a reference to the returned device if found.
* Search for the next output device starting at @from. Release the reference to
* the @from device, and acquire a reference to the returned device if found.
*/
struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
enum omap_dss_device_type type)
struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from)
{
struct omap_dss_device *dssdev;
struct list_head *list;
......@@ -160,15 +157,7 @@ struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
goto done;
}
/*
* Accept display entities if the display type is requested,
* and output entities if the output type is requested.
*/
if ((type & OMAP_DSS_DEVICE_TYPE_DISPLAY) &&
!dssdev->output_type)
goto done;
if ((type & OMAP_DSS_DEVICE_TYPE_OUTPUT) && dssdev->id &&
dssdev->next)
if (dssdev->id && dssdev->next)
goto done;
}
......@@ -183,7 +172,7 @@ struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
mutex_unlock(&omapdss_devices_lock);
return dssdev;
}
EXPORT_SYMBOL(omapdss_device_get_next);
EXPORT_SYMBOL(omapdss_device_next_output);
static bool omapdss_device_is_connected(struct omap_dss_device *dssdev)
{
......@@ -244,6 +233,58 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
}
EXPORT_SYMBOL_GPL(omapdss_device_disconnect);
void omapdss_device_pre_enable(struct omap_dss_device *dssdev)
{
if (!dssdev)
return;
omapdss_device_pre_enable(dssdev->next);
if (dssdev->ops->pre_enable)
dssdev->ops->pre_enable(dssdev);
}
EXPORT_SYMBOL_GPL(omapdss_device_pre_enable);
void omapdss_device_enable(struct omap_dss_device *dssdev)
{
if (!dssdev)
return;
if (dssdev->ops->enable)
dssdev->ops->enable(dssdev);
omapdss_device_enable(dssdev->next);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
}
EXPORT_SYMBOL_GPL(omapdss_device_enable);
void omapdss_device_disable(struct omap_dss_device *dssdev)
{
if (!dssdev)
return;
omapdss_device_disable(dssdev->next);
if (dssdev->ops->disable)
dssdev->ops->disable(dssdev);
}
EXPORT_SYMBOL_GPL(omapdss_device_disable);
void omapdss_device_post_disable(struct omap_dss_device *dssdev)
{
if (!dssdev)
return;
if (dssdev->ops->post_disable)
dssdev->ops->post_disable(dssdev);
omapdss_device_post_disable(dssdev->next);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
EXPORT_SYMBOL_GPL(omapdss_device_post_disable);
/* -----------------------------------------------------------------------------
* Components Handling
*/
......
......@@ -378,7 +378,7 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
}
static int dpi_display_enable(struct omap_dss_device *dssdev)
static void dpi_display_enable(struct omap_dss_device *dssdev)
{
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
struct omap_dss_device *out = &dpi->output;
......@@ -420,7 +420,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
mutex_unlock(&dpi->lock);
return 0;
return;
err_mgr_enable:
err_set_mode:
......@@ -434,7 +434,6 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
regulator_disable(dpi->vdds_dsi_reg);
err_reg_enable:
mutex_unlock(&dpi->lock);
return r;
}
static void dpi_display_disable(struct omap_dss_device *dssdev)
......
......@@ -4154,10 +4154,10 @@ static void dsi_display_uninit_dsi(struct dsi_data *dsi, bool disconnect_lanes,
dsi_pll_uninit(dsi, disconnect_lanes);
}
static int dsi_display_enable(struct omap_dss_device *dssdev)
static void dsi_display_enable(struct omap_dss_device *dssdev)
{
struct dsi_data *dsi = to_dsi_data(dssdev);
int r = 0;
int r;
DSSDBG("dsi_display_enable\n");
......@@ -4177,14 +4177,13 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
mutex_unlock(&dsi->lock);
return 0;
return;
err_init_dsi:
dsi_runtime_put(dsi);
err_get_dsi:
mutex_unlock(&dsi->lock);
DSSDBG("dsi_display_enable FAILED\n");
return r;
}
static void dsi_display_disable(struct omap_dss_device *dssdev,
......
......@@ -1560,7 +1560,7 @@ static void dss_shutdown(struct platform_device *pdev)
DSSDBG("shutdown\n");
for_each_dss_display(dssdev) {
for_each_dss_output(dssdev) {
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
dssdev->ops->disable(dssdev);
}
......
......@@ -312,11 +312,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
hdmi_wp_audio_enable(&hd->wp, false);
}
static int hdmi_display_enable(struct omap_dss_device *dssdev)
static void hdmi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
int r = 0;
int r;
DSSDBG("ENTER hdmi_display_enable\n");
......@@ -325,7 +325,7 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
r = hdmi_power_on_full(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
goto done;
}
if (hdmi->audio_configured) {
......@@ -345,12 +345,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
hdmi->display_enabled = true;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
done:
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_display_disable(struct omap_dss_device *dssdev)
......
......@@ -320,11 +320,11 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
}
static int hdmi_display_enable(struct omap_dss_device *dssdev)
static void hdmi_display_enable(struct omap_dss_device *dssdev)
{
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
unsigned long flags;
int r = 0;
int r;
DSSDBG("ENTER hdmi_display_enable\n");
......@@ -333,7 +333,7 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
r = hdmi_power_on_full(hdmi);
if (r) {
DSSERR("failed to power on device\n");
goto err0;
goto done;
}
if (hdmi->audio_configured) {
......@@ -353,12 +353,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
hdmi->display_enabled = true;
spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
done:
mutex_unlock(&hdmi->lock);
return 0;
err0:
mutex_unlock(&hdmi->lock);
return r;
}
static void hdmi_display_disable(struct omap_dss_device *dssdev)
......
......@@ -359,8 +359,10 @@ struct omap_dss_device_ops {
void (*disconnect)(struct omap_dss_device *dssdev,
struct omap_dss_device *dst);
int (*enable)(struct omap_dss_device *dssdev);
void (*pre_enable)(struct omap_dss_device *dssdev);
void (*enable)(struct omap_dss_device *dssdev);
void (*disable)(struct omap_dss_device *dssdev);
void (*post_disable)(struct omap_dss_device *dssdev);
int (*check_timings)(struct omap_dss_device *dssdev,
struct videomode *vm);
......@@ -397,11 +399,6 @@ enum omap_dss_device_ops_flag {
OMAP_DSS_DEVICE_OP_EDID = BIT(2),
};
enum omap_dss_device_type {
OMAP_DSS_DEVICE_TYPE_OUTPUT = (1 << 0),
OMAP_DSS_DEVICE_TYPE_DISPLAY = (1 << 1),
};
struct omap_dss_device {
struct device *dev;
......@@ -471,8 +468,6 @@ static inline bool omapdss_is_initialized(void)
return !!omapdss_get_dss();
}
#define for_each_dss_display(d) \
while ((d = omapdss_device_get_next(d, OMAP_DSS_DEVICE_TYPE_DISPLAY)) != NULL)
void omapdss_display_init(struct omap_dss_device *dssdev);
struct omap_dss_device *omapdss_display_get(struct omap_dss_device *output);
......@@ -482,20 +477,23 @@ struct omap_dss_device *omapdss_device_get(struct omap_dss_device *dssdev);
void omapdss_device_put(struct omap_dss_device *dssdev);
struct omap_dss_device *omapdss_find_device_by_port(struct device_node *src,
unsigned int port);
struct omap_dss_device *omapdss_device_get_next(struct omap_dss_device *from,
enum omap_dss_device_type type);
int omapdss_device_connect(struct dss_device *dss,
struct omap_dss_device *src,
struct omap_dss_device *dst);
void omapdss_device_disconnect(struct omap_dss_device *src,
struct omap_dss_device *dst);
void omapdss_device_pre_enable(struct omap_dss_device *dssdev);
void omapdss_device_enable(struct omap_dss_device *dssdev);
void omapdss_device_disable(struct omap_dss_device *dssdev);
void omapdss_device_post_disable(struct omap_dss_device *dssdev);
int omap_dss_get_num_overlay_managers(void);
int omap_dss_get_num_overlays(void);
#define for_each_dss_output(d) \
while ((d = omapdss_device_get_next(d, OMAP_DSS_DEVICE_TYPE_OUTPUT)) != NULL)
while ((d = omapdss_device_next_output(d)) != NULL)
struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device *from);
int omapdss_output_validate(struct omap_dss_device *out);
typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
......
......@@ -129,7 +129,7 @@ static void sdi_config_lcd_manager(struct sdi_device *sdi)
dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
}
static int sdi_display_enable(struct omap_dss_device *dssdev)
static void sdi_display_enable(struct omap_dss_device *dssdev)
{
struct sdi_device *sdi = dssdev_to_sdi(dssdev);
struct dispc_clock_info dispc_cinfo;
......@@ -138,7 +138,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
r = regulator_enable(sdi->vdds_sdi_reg);
if (r)
goto err_reg_enable;
return;
r = dispc_runtime_get(sdi->dss->dispc);
if (r)
......@@ -180,7 +180,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
if (r)
goto err_mgr_enable;
return 0;
return;
err_mgr_enable:
dss_sdi_disable(sdi->dss);
......@@ -190,8 +190,6 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)
dispc_runtime_put(sdi->dss->dispc);
err_get_dispc:
regulator_disable(sdi->vdds_sdi_reg);
err_reg_enable:
return r;
}
static void sdi_display_disable(struct omap_dss_device *dssdev)
......
......@@ -522,25 +522,17 @@ static void venc_power_off(struct venc_device *venc)
venc_runtime_put(venc);
}
static int venc_display_enable(struct omap_dss_device *dssdev)
static void venc_display_enable(struct omap_dss_device *dssdev)
{
struct venc_device *venc = dssdev_to_venc(dssdev);
int r;
DSSDBG("venc_display_enable\n");
mutex_lock(&venc->venc_lock);
r = venc_power_on(venc);
if (r)
goto err0;
mutex_unlock(&venc->venc_lock);
venc_power_on(venc);
return 0;
err0:
mutex_unlock(&venc->venc_lock);
return r;
}
static void venc_display_disable(struct omap_dss_device *dssdev)
......
......@@ -146,33 +146,60 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
static void omap_encoder_disable(struct drm_encoder *encoder)
{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
struct omap_dss_device *dssdev = omap_encoder->display;
struct omap_dss_device *dssdev = omap_encoder->output;
struct drm_device *dev = encoder->dev;
dev_dbg(dev->dev, "disable(%s)\n", dssdev->name);
dssdev->ops->disable(dssdev);
/*
* Disable the chain of external devices, starting at the one at the
* internal encoder's output.
*/
omapdss_device_disable(dssdev->next);
/*
* Disable the internal encoder. This will disable the DSS output. The
* DSI is treated as an exception as DSI pipelines still use the legacy
* flow where the pipeline output controls the encoder.
*/
if (dssdev->output_type != OMAP_DISPLAY_TYPE_DSI) {
dssdev->ops->disable(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
/*
* Perform the post-disable operations on the chain of external devices
* to complete the display pipeline disable.
*/
omapdss_device_post_disable(dssdev->next);
}
static void omap_encoder_enable(struct drm_encoder *encoder)
{
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
struct omap_dss_device *dssdev = omap_encoder->display;
struct omap_dss_device *dssdev = omap_encoder->output;
struct drm_device *dev = encoder->dev;
int r;
dev_dbg(dev->dev, "enable(%s)\n", dssdev->name);
r = dssdev->ops->enable(dssdev);
if (r) {
dev_err(dev->dev, "Failed to enable display '%s': %d\n",
dssdev->name, r);
return;
/* Prepare the chain of external devices for pipeline enable. */
omapdss_device_pre_enable(dssdev->next);
/*
* Enable the internal encoder. This will enable the DSS output. The
* DSI is treated as an exception as DSI pipelines still use the legacy
* flow where the pipeline output controls the encoder.
*/
if (dssdev->output_type != OMAP_DISPLAY_TYPE_DSI) {
dssdev->ops->enable(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
}
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
/*
* Enable the chain of external devices, starting at the one at the
* internal encoder's output.
*/
omapdss_device_enable(dssdev->next);
}
static int omap_encoder_atomic_check(struct drm_encoder *encoder,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment