From 998c336d4c7183301ed6a6ca93952f63e3cf694f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 30 May 2012 13:26:00 +0300 Subject: [PATCH 01/21] OMAPDSS: remove omap_dss_device's suspend/resume The panel drivers contain enable, disable, suspend and resume calls. The suspend and resume are effectively identical to disable and enable. This patch removes panel suspend and enable code from omapdss and the panel drivers, and replaces their use with enable and disable. Signed-off-by: Tomi Valkeinen --- .../video/omap2/displays/panel-acx565akm.c | 23 ------ .../video/omap2/displays/panel-generic-dpi.c | 36 ---------- .../omap2/displays/panel-lgphilips-lb035q02.c | 34 --------- drivers/video/omap2/displays/panel-n8x0.c | 50 ------------- .../omap2/displays/panel-nec-nl8048hl11-01b.c | 24 ------- drivers/video/omap2/displays/panel-picodlp.c | 44 ------------ .../omap2/displays/panel-sharp-ls037v7dw01.c | 17 ----- drivers/video/omap2/displays/panel-taal.c | 72 ------------------- drivers/video/omap2/displays/panel-tfp410.c | 33 --------- .../omap2/displays/panel-tpo-td043mtea1.c | 20 ------ drivers/video/omap2/dss/display.c | 15 +--- drivers/video/omap2/dss/hdmi_panel.c | 70 +++--------------- drivers/video/omap2/dss/venc_panel.c | 19 ----- drivers/video/omap2/omapfb/omapfb-main.c | 8 +-- include/video/omapdss.h | 3 - 15 files changed, 16 insertions(+), 452 deletions(-) diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index c835aa70f96f..65eb76c840a1 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c @@ -710,27 +710,6 @@ static void acx_panel_disable(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static int acx_panel_suspend(struct omap_dss_device *dssdev) -{ - dev_dbg(&dssdev->dev, "%s\n", __func__); - acx_panel_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - return 0; -} - -static int acx_panel_resume(struct omap_dss_device *dssdev) -{ - int r; - - dev_dbg(&dssdev->dev, "%s\n", __func__); - r = acx_panel_power_on(dssdev); - if (r) - return r; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return 0; -} - static void acx_panel_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -752,8 +731,6 @@ static struct omap_dss_driver acx_panel_driver = { .enable = acx_panel_enable, .disable = acx_panel_disable, - .suspend = acx_panel_suspend, - .resume = acx_panel_resume, .set_timings = acx_panel_set_timings, .check_timings = acx_panel_check_timings, diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c index 88295c526815..54ca8ae21078 100644 --- a/drivers/video/omap2/displays/panel-generic-dpi.c +++ b/drivers/video/omap2/displays/panel-generic-dpi.c @@ -688,40 +688,6 @@ static void generic_dpi_panel_disable(struct omap_dss_device *dssdev) mutex_unlock(&drv_data->lock); } -static int generic_dpi_panel_suspend(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); - - mutex_lock(&drv_data->lock); - - generic_dpi_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - mutex_unlock(&drv_data->lock); - - return 0; -} - -static int generic_dpi_panel_resume(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); - int r; - - mutex_lock(&drv_data->lock); - - r = generic_dpi_panel_power_on(dssdev); - if (r) - goto err; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - -err: - mutex_unlock(&drv_data->lock); - - return r; -} - static void generic_dpi_panel_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -769,8 +735,6 @@ static struct omap_dss_driver dpi_driver = { .enable = generic_dpi_panel_enable, .disable = generic_dpi_panel_disable, - .suspend = generic_dpi_panel_suspend, - .resume = generic_dpi_panel_resume, .set_timings = generic_dpi_panel_set_timings, .get_timings = generic_dpi_panel_get_timings, diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c index 90c1cabf244e..ace419b801eb 100644 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c @@ -143,46 +143,12 @@ static void lb035q02_panel_disable(struct omap_dss_device *dssdev) mutex_unlock(&ld->lock); } -static int lb035q02_panel_suspend(struct omap_dss_device *dssdev) -{ - struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); - - mutex_lock(&ld->lock); - - lb035q02_panel_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - mutex_unlock(&ld->lock); - return 0; -} - -static int lb035q02_panel_resume(struct omap_dss_device *dssdev) -{ - struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev); - int r; - - mutex_lock(&ld->lock); - - r = lb035q02_panel_power_on(dssdev); - if (r) - goto err; - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ld->lock); - return 0; -err: - mutex_unlock(&ld->lock); - return r; -} - static struct omap_dss_driver lb035q02_driver = { .probe = lb035q02_panel_probe, .remove = lb035q02_panel_remove, .enable = lb035q02_panel_enable, .disable = lb035q02_panel_disable, - .suspend = lb035q02_panel_suspend, - .resume = lb035q02_panel_resume, .driver = { .name = "lgphilips_lb035q02_panel", diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c index 3fc5ad081a21..265326955552 100644 --- a/drivers/video/omap2/displays/panel-n8x0.c +++ b/drivers/video/omap2/displays/panel-n8x0.c @@ -574,54 +574,6 @@ static void n8x0_panel_disable(struct omap_dss_device *dssdev) mutex_unlock(&ddata->lock); } -static int n8x0_panel_suspend(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - - dev_dbg(&dssdev->dev, "suspend\n"); - - mutex_lock(&ddata->lock); - - rfbi_bus_lock(); - - n8x0_panel_power_off(dssdev); - - rfbi_bus_unlock(); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - mutex_unlock(&ddata->lock); - - return 0; -} - -static int n8x0_panel_resume(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = get_drv_data(dssdev); - int r; - - dev_dbg(&dssdev->dev, "resume\n"); - - mutex_lock(&ddata->lock); - - rfbi_bus_lock(); - - r = n8x0_panel_power_on(dssdev); - - rfbi_bus_unlock(); - - if (r) { - mutex_unlock(&ddata->lock); - return r; - } - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ddata->lock); - - return 0; -} - static void n8x0_panel_get_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres) { @@ -683,8 +635,6 @@ static struct omap_dss_driver n8x0_panel_driver = { .enable = n8x0_panel_enable, .disable = n8x0_panel_disable, - .suspend = n8x0_panel_suspend, - .resume = n8x0_panel_resume, .update = n8x0_panel_update, .sync = n8x0_panel_sync, diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 908fd268f3dc..2a79c283bebe 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c @@ -236,28 +236,6 @@ static void nec_8048_panel_disable(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static int nec_8048_panel_suspend(struct omap_dss_device *dssdev) -{ - nec_8048_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - return 0; -} - -static int nec_8048_panel_resume(struct omap_dss_device *dssdev) -{ - int r; - - r = nec_8048_panel_power_on(dssdev); - if (r) - return r; - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - return 0; -} - static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev) { return 16; @@ -268,8 +246,6 @@ static struct omap_dss_driver nec_8048_driver = { .remove = nec_8048_panel_remove, .enable = nec_8048_panel_enable, .disable = nec_8048_panel_disable, - .suspend = nec_8048_panel_suspend, - .resume = nec_8048_panel_resume, .get_recommended_bpp = nec_8048_recommended_bpp, .driver = { diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c index 9df87640ddd2..e3a6c1996134 100644 --- a/drivers/video/omap2/displays/panel-picodlp.c +++ b/drivers/video/omap2/displays/panel-picodlp.c @@ -503,47 +503,6 @@ static void picodlp_panel_disable(struct omap_dss_device *dssdev) dev_dbg(&dssdev->dev, "disabling picodlp panel\n"); } -static int picodlp_panel_suspend(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); - - mutex_lock(&picod->lock); - /* Turn off DLP Power */ - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { - mutex_unlock(&picod->lock); - dev_err(&dssdev->dev, "unable to suspend picodlp panel," - " panel is not ACTIVE\n"); - return -EINVAL; - } - - picodlp_panel_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - mutex_unlock(&picod->lock); - - dev_dbg(&dssdev->dev, "suspending picodlp panel\n"); - return 0; -} - -static int picodlp_panel_resume(struct omap_dss_device *dssdev) -{ - struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); - int r; - - mutex_lock(&picod->lock); - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { - mutex_unlock(&picod->lock); - dev_err(&dssdev->dev, "unable to resume picodlp panel," - " panel is not ACTIVE\n"); - return -EINVAL; - } - - r = picodlp_panel_power_on(dssdev); - mutex_unlock(&picod->lock); - dev_dbg(&dssdev->dev, "resuming picodlp panel\n"); - return r; -} - static void picodlp_get_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres) { @@ -560,9 +519,6 @@ static struct omap_dss_driver picodlp_driver = { .get_resolution = picodlp_get_resolution, - .suspend = picodlp_panel_suspend, - .resume = picodlp_panel_resume, - .driver = { .name = "picodlp_panel", .owner = THIS_MODULE, diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index 1ec3b277ff15..cada8c621e01 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -194,29 +194,12 @@ static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static int sharp_ls_panel_suspend(struct omap_dss_device *dssdev) -{ - sharp_ls_power_off(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - return 0; -} - -static int sharp_ls_panel_resume(struct omap_dss_device *dssdev) -{ - int r; - r = sharp_ls_power_on(dssdev); - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - return r; -} - static struct omap_dss_driver sharp_ls_driver = { .probe = sharp_ls_panel_probe, .remove = __exit_p(sharp_ls_panel_remove), .enable = sharp_ls_panel_enable, .disable = sharp_ls_panel_disable, - .suspend = sharp_ls_panel_suspend, - .resume = sharp_ls_panel_resume, .driver = { .name = "sharp_ls_panel", diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index f2f644680ca8..a32407a5735a 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1245,76 +1245,6 @@ static void taal_disable(struct omap_dss_device *dssdev) mutex_unlock(&td->lock); } -static int taal_suspend(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - int r; - - dev_dbg(&dssdev->dev, "suspend\n"); - - mutex_lock(&td->lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { - r = -EINVAL; - goto err; - } - - taal_cancel_ulps_work(dssdev); - taal_cancel_esd_work(dssdev); - - dsi_bus_lock(dssdev); - - r = taal_wake_up(dssdev); - if (!r) - taal_power_off(dssdev); - - dsi_bus_unlock(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - mutex_unlock(&td->lock); - - return 0; -err: - mutex_unlock(&td->lock); - return r; -} - -static int taal_resume(struct omap_dss_device *dssdev) -{ - struct taal_data *td = dev_get_drvdata(&dssdev->dev); - int r; - - dev_dbg(&dssdev->dev, "resume\n"); - - mutex_lock(&td->lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { - r = -EINVAL; - goto err; - } - - dsi_bus_lock(dssdev); - - r = taal_power_on(dssdev); - - dsi_bus_unlock(dssdev); - - if (r) { - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - } else { - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - taal_queue_esd_work(dssdev); - } - - mutex_unlock(&td->lock); - - return r; -err: - mutex_unlock(&td->lock); - return r; -} - static void taal_framedone_cb(int err, void *data) { struct omap_dss_device *dssdev = data; @@ -1818,8 +1748,6 @@ static struct omap_dss_driver taal_driver = { .enable = taal_enable, .disable = taal_disable, - .suspend = taal_suspend, - .resume = taal_resume, .update = taal_update, .sync = taal_sync, diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c index 383811cf8648..8281baafe1ef 100644 --- a/drivers/video/omap2/displays/panel-tfp410.c +++ b/drivers/video/omap2/displays/panel-tfp410.c @@ -189,37 +189,6 @@ static void tfp410_disable(struct omap_dss_device *dssdev) mutex_unlock(&ddata->lock); } -static int tfp410_suspend(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - - mutex_lock(&ddata->lock); - - tfp410_power_off(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - mutex_unlock(&ddata->lock); - - return 0; -} - -static int tfp410_resume(struct omap_dss_device *dssdev) -{ - struct panel_drv_data *ddata = dev_get_drvdata(&dssdev->dev); - int r; - - mutex_lock(&ddata->lock); - - r = tfp410_power_on(dssdev); - if (r == 0) - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - - mutex_unlock(&ddata->lock); - - return r; -} - static void tfp410_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -355,8 +324,6 @@ static struct omap_dss_driver tfp410_driver = { .enable = tfp410_enable, .disable = tfp410_disable, - .suspend = tfp410_suspend, - .resume = tfp410_resume, .set_timings = tfp410_set_timings, .get_timings = tfp410_get_timings, diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index b5e6dbc59f0a..316b3da6d2cb 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -401,24 +401,6 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_DISABLED; } -static int tpo_td043_suspend(struct omap_dss_device *dssdev) -{ - dev_dbg(&dssdev->dev, "suspend\n"); - - tpo_td043_disable_dss(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - - return 0; -} - -static int tpo_td043_resume(struct omap_dss_device *dssdev) -{ - dev_dbg(&dssdev->dev, "resume\n"); - - return tpo_td043_enable_dss(dssdev); -} - static int tpo_td043_probe(struct omap_dss_device *dssdev) { struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); @@ -500,8 +482,6 @@ static struct omap_dss_driver tpo_td043_driver = { .enable = tpo_td043_enable, .disable = tpo_td043_disable, - .suspend = tpo_td043_suspend, - .resume = tpo_td043_resume, .set_mirror = tpo_td043_set_hmirror, .get_mirror = tpo_td043_get_hmirror, diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index ccf8550fafde..1e587306215f 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -449,7 +449,6 @@ void dss_uninit_device(struct platform_device *pdev, static int dss_suspend_device(struct device *dev, void *data) { - int r; struct omap_dss_device *dssdev = to_dss_device(dev); if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { @@ -457,15 +456,7 @@ static int dss_suspend_device(struct device *dev, void *data) return 0; } - if (!dssdev->driver->suspend) { - DSSERR("display '%s' doesn't implement suspend\n", - dssdev->name); - return -ENOSYS; - } - - r = dssdev->driver->suspend(dssdev); - if (r) - return r; + dssdev->driver->disable(dssdev); dssdev->activate_after_resume = true; @@ -492,8 +483,8 @@ static int dss_resume_device(struct device *dev, void *data) int r; struct omap_dss_device *dssdev = to_dss_device(dev); - if (dssdev->activate_after_resume && dssdev->driver->resume) { - r = dssdev->driver->resume(dssdev); + if (dssdev->activate_after_resume) { + r = dssdev->driver->enable(dssdev); if (r) return r; } diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c index 69fb115bab32..3f9a4b947a54 100644 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ b/drivers/video/omap2/dss/hdmi_panel.c @@ -280,58 +280,6 @@ static void hdmi_panel_disable(struct omap_dss_device *dssdev) mutex_unlock(&hdmi.lock); } -static int hdmi_panel_suspend(struct omap_dss_device *dssdev) -{ - int r = 0; - - mutex_lock(&hdmi.lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { - r = -EINVAL; - goto err; - } - - /* - * TODO: notify audio users that the display was suspended. For now, - * disable audio locally to not break our audio state machine. - */ - hdmi_panel_audio_disable(dssdev); - - dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; - omapdss_hdmi_display_disable(dssdev); - -err: - mutex_unlock(&hdmi.lock); - - return r; -} - -static int hdmi_panel_resume(struct omap_dss_device *dssdev) -{ - int r = 0; - - mutex_lock(&hdmi.lock); - - if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) { - r = -EINVAL; - goto err; - } - - r = omapdss_hdmi_display_enable(dssdev); - if (r) { - DSSERR("failed to power on\n"); - goto err; - } - /* TODO: notify audio users that the panel resumed. */ - - dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - -err: - mutex_unlock(&hdmi.lock); - - return r; -} - static void hdmi_get_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -379,10 +327,13 @@ static int hdmi_check_timings(struct omap_dss_device *dssdev, static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) { int r; + bool need_enable; mutex_lock(&hdmi.lock); - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; + + if (need_enable) { r = omapdss_hdmi_display_enable(dssdev); if (r) goto err; @@ -390,8 +341,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) r = omapdss_hdmi_read_edid(buf, len); - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || - dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + if (need_enable) omapdss_hdmi_display_disable(dssdev); err: mutex_unlock(&hdmi.lock); @@ -402,10 +352,13 @@ err: static bool hdmi_detect(struct omap_dss_device *dssdev) { int r; + bool need_enable; mutex_lock(&hdmi.lock); - if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) { + need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; + + if (need_enable) { r = omapdss_hdmi_display_enable(dssdev); if (r) goto err; @@ -413,8 +366,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev) r = omapdss_hdmi_detect(); - if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED || - dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) + if (need_enable) omapdss_hdmi_display_disable(dssdev); err: mutex_unlock(&hdmi.lock); @@ -427,8 +379,6 @@ static struct omap_dss_driver hdmi_driver = { .remove = hdmi_panel_remove, .enable = hdmi_panel_enable, .disable = hdmi_panel_disable, - .suspend = hdmi_panel_suspend, - .resume = hdmi_panel_resume, .get_timings = hdmi_get_timings, .set_timings = hdmi_set_timings, .check_timings = hdmi_check_timings, diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c index d55b8784ecfd..0d2b1a0834a0 100644 --- a/drivers/video/omap2/dss/venc_panel.c +++ b/drivers/video/omap2/dss/venc_panel.c @@ -157,12 +157,6 @@ static void venc_panel_disable(struct omap_dss_device *dssdev) if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) goto end; - if (dssdev->state == OMAP_DSS_DISPLAY_SUSPENDED) { - /* suspended is the same as disabled with venc */ - dssdev->state = OMAP_DSS_DISPLAY_DISABLED; - goto end; - } - omapdss_venc_display_disable(dssdev); dssdev->state = OMAP_DSS_DISPLAY_DISABLED; @@ -170,17 +164,6 @@ end: mutex_unlock(&venc_panel.lock); } -static int venc_panel_suspend(struct omap_dss_device *dssdev) -{ - venc_panel_disable(dssdev); - return 0; -} - -static int venc_panel_resume(struct omap_dss_device *dssdev) -{ - return venc_panel_enable(dssdev); -} - static void venc_panel_set_timings(struct omap_dss_device *dssdev, struct omap_video_timings *timings) { @@ -222,8 +205,6 @@ static struct omap_dss_driver venc_driver = { .enable = venc_panel_enable, .disable = venc_panel_disable, - .suspend = venc_panel_suspend, - .resume = venc_panel_resume, .get_resolution = omapdss_default_get_resolution, .get_recommended_bpp = omapdss_default_get_recommended_bpp, diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index bc225e46fdd2..ba4630830e09 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1258,11 +1258,10 @@ static int omapfb_blank(int blank, struct fb_info *fbi) switch (blank) { case FB_BLANK_UNBLANK: - if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) + if (display->state == OMAP_DSS_DISPLAY_ACTIVE) goto exit; - if (display->driver->resume) - r = display->driver->resume(display); + r = display->driver->enable(display); if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && d->update_mode == OMAPFB_AUTO_UPDATE && @@ -1283,8 +1282,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi) if (d->auto_update_work_enabled) omapfb_stop_auto_update(fbdev, display); - if (display->driver->suspend) - r = display->driver->suspend(display); + display->driver->disable(display); break; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 88c829466fc1..cdfb22e7fe80 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -158,7 +158,6 @@ enum omap_display_caps { enum omap_dss_display_state { OMAP_DSS_DISPLAY_DISABLED = 0, OMAP_DSS_DISPLAY_ACTIVE, - OMAP_DSS_DISPLAY_SUSPENDED, }; enum omap_dss_audio_state { @@ -686,8 +685,6 @@ struct omap_dss_driver { int (*enable)(struct omap_dss_device *display); void (*disable)(struct omap_dss_device *display); - int (*suspend)(struct omap_dss_device *display); - int (*resume)(struct omap_dss_device *display); int (*run_test)(struct omap_dss_device *display, int test); int (*update)(struct omap_dss_device *dssdev, From b2c7d54f72c1c588e8851c882f0465705f5e9e55 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 18 Oct 2012 13:46:29 +0300 Subject: [PATCH 02/21] OMAPDSS: get the dss version from core pdev The output drivers get the omapdss hw version from the platform data for their respective output device. This doesn't work with DT, as there's no platform data for them. Add a new function, omapdss_get_version(), which returns the dss version from the core device, which will have platform data on DT also. The function is exported so that users of omapdss can also use it. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 9 ++++++++- drivers/video/omap2/dss/dispc.c | 3 +-- drivers/video/omap2/dss/dss.c | 3 +-- drivers/video/omap2/dss/hdmi.c | 3 +-- include/video/omapdss.h | 2 ++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 00aa026e307c..685d9a957b19 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -58,6 +58,13 @@ const char *dss_get_default_display_name(void) return core.default_display_name; } +enum omapdss_version omapdss_get_version(void) +{ + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data; + return pdata->version; +} +EXPORT_SYMBOL(omapdss_get_version); + /* REGULATORS */ struct regulator *dss_get_vdds_dsi(void) @@ -232,7 +239,7 @@ static int __init omap_dss_probe(struct platform_device *pdev) core.pdev = pdev; - dss_features_init(pdata->version); + dss_features_init(omapdss_get_version()); dss_apply_init(); diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 6dd9eb4a2c5b..817d671e2baa 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -4098,7 +4098,6 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = { static int __init dispc_init_features(struct platform_device *pdev) { - struct omap_dss_board_info *pdata = pdev->dev.platform_data; const struct dispc_features *src; struct dispc_features *dst; @@ -4108,7 +4107,7 @@ static int __init dispc_init_features(struct platform_device *pdev) return -ENOMEM; } - switch (pdata->version) { + switch (omapdss_get_version()) { case OMAPDSS_VER_OMAP24xx: src = &omap24xx_dispc_feats; break; diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 37ee465c1a0e..d90de37288c4 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -793,7 +793,6 @@ static const struct dss_features omap54xx_dss_feats __initconst = { static int __init dss_init_features(struct platform_device *pdev) { - struct omap_dss_board_info *pdata = pdev->dev.platform_data; const struct dss_features *src; struct dss_features *dst; @@ -803,7 +802,7 @@ static int __init dss_init_features(struct platform_device *pdev) return -ENOMEM; } - switch (pdata->version) { + switch (omapdss_get_version()) { case OMAPDSS_VER_OMAP24xx: src = &omap24xx_dss_feats; break; diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index adcc906d12f8..c1c54883fbe7 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -323,7 +323,6 @@ static void hdmi_runtime_put(void) static int __init hdmi_init_display(struct omap_dss_device *dssdev) { - struct omap_dss_board_info *pdata = hdmi.pdev->dev.platform_data; int r; struct gpio gpios[] = { @@ -334,7 +333,7 @@ static int __init hdmi_init_display(struct omap_dss_device *dssdev) DSSDBG("init_display\n"); - dss_init_hdmi_ip_ops(&hdmi.ip_data, pdata->version); + dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); if (hdmi.vdda_hdmi_dac_reg == NULL) { struct regulator *reg; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index cdfb22e7fe80..eac5f2562253 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -742,6 +742,8 @@ struct omap_dss_driver { }; +enum omapdss_version omapdss_get_version(void); + int omap_dss_register_driver(struct omap_dss_driver *); void omap_dss_unregister_driver(struct omap_dss_driver *); From dba01625a3c94e58b98f3f2d7058237a5ea02fa2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Oct 2012 16:28:23 +0300 Subject: [PATCH 03/21] OMAPDSS: remove dispc_irq_handler declaration dss.h contains dispc_irq_handler declaration, even if the function is dispc.c internal. Remove the declaration. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index fb891656f1f8..00e0a36723b9 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -398,7 +398,6 @@ void dpi_uninit_platform_driver(void) __exit; int dispc_init_platform_driver(void) __init; void dispc_uninit_platform_driver(void) __exit; void dispc_dump_clocks(struct seq_file *s); -void dispc_irq_handler(void); int dispc_runtime_get(void); void dispc_runtime_put(void); From c31cba8af8c2fde418c146e3ead341d5053f3225 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Oct 2012 11:50:10 +0300 Subject: [PATCH 04/21] OMAPDSS: DISPC: fix dispc_mgr_lclk_rate for DIGIT output dispc_mgr_lclk_rate() cannot currently be called with DIGIT channel parameter, even if dispc_ovl_lclk_rate() can. Fix this by making dispc_mgr_lclk_rate() handle DIGIT channel also. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 49 +++++++++++++++++---------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 817d671e2baa..198e321d9cfd 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3167,28 +3167,32 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) unsigned long r; u32 l; - l = dispc_read_reg(DISPC_DIVISORo(channel)); + if (dss_mgr_is_lcd(channel)) { + l = dispc_read_reg(DISPC_DIVISORo(channel)); - lcd = FLD_GET(l, 23, 16); + lcd = FLD_GET(l, 23, 16); - switch (dss_get_lcd_clk_source(channel)) { - case OMAP_DSS_CLK_SRC_FCK: - r = clk_get_rate(dispc.dss_clk); - break; - case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: - dsidev = dsi_get_dsidev_from_id(0); - r = dsi_get_pll_hsdiv_dispc_rate(dsidev); - break; - case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: - dsidev = dsi_get_dsidev_from_id(1); - r = dsi_get_pll_hsdiv_dispc_rate(dsidev); - break; - default: - BUG(); - return 0; + switch (dss_get_lcd_clk_source(channel)) { + case OMAP_DSS_CLK_SRC_FCK: + r = clk_get_rate(dispc.dss_clk); + break; + case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: + dsidev = dsi_get_dsidev_from_id(0); + r = dsi_get_pll_hsdiv_dispc_rate(dsidev); + break; + case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: + dsidev = dsi_get_dsidev_from_id(1); + r = dsi_get_pll_hsdiv_dispc_rate(dsidev); + break; + default: + BUG(); + return 0; + } + + return r / lcd; + } else { + return dispc_fclk_rate(); } - - return r / lcd; } unsigned long dispc_mgr_pclk_rate(enum omap_channel channel) @@ -3247,12 +3251,9 @@ static unsigned long dispc_plane_lclk_rate(enum omap_plane plane) { enum omap_channel channel = dispc_ovl_get_channel_out(plane); - if (dss_mgr_is_lcd(channel)) - return dispc_mgr_lclk_rate(channel); - else - return dispc_fclk_rate(); - + return dispc_mgr_lclk_rate(channel); } + static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel) { int lcd, pcd; From 2bbcce5e0b47e0de83a1b799b9e164f8c5b9b634 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 29 Oct 2012 12:40:46 +0200 Subject: [PATCH 05/21] OMAPDSS: export dss_get_def_display_name() Export dss_get_def_display_name() with the name of omapdss_get_def_display_name() so that omapfb can use it after the next patch which moves default display handling to omapfb. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 3 ++- drivers/video/omap2/dss/display.c | 2 +- drivers/video/omap2/dss/dpi.c | 2 +- drivers/video/omap2/dss/dsi.c | 2 +- drivers/video/omap2/dss/dss.h | 1 - drivers/video/omap2/dss/hdmi.c | 2 +- drivers/video/omap2/dss/rfbi.c | 2 +- drivers/video/omap2/dss/sdi.c | 2 +- drivers/video/omap2/dss/venc.c | 2 +- include/video/omapdss.h | 1 + 10 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 685d9a957b19..a2ea684169e9 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -53,10 +53,11 @@ static char *def_disp_name; module_param_named(def_disp, def_disp_name, charp, 0); MODULE_PARM_DESC(def_disp, "default display name"); -const char *dss_get_default_display_name(void) +const char *omapdss_get_default_display_name(void) { return core.default_display_name; } +EXPORT_SYMBOL(omapdss_get_default_display_name); enum omapdss_version omapdss_get_version(void) { diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 1e587306215f..90edd718e9e7 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -394,7 +394,7 @@ int dss_init_device(struct platform_device *pdev, { struct device_attribute *attr; int i, r; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); bool force; force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0; diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 56748cf8760e..11d64b09cffe 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -389,7 +389,7 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev) static struct omap_dss_device * __init dpi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 7d0db2bf2fc6..2ba505b33153 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -5100,7 +5100,7 @@ static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *p { struct omap_dss_board_info *pdata = pdev->dev.platform_data; struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 00e0a36723b9..d468743a209e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -160,7 +160,6 @@ struct seq_file; struct platform_device; /* core */ -const char *dss_get_default_display_name(void); struct bus_type *dss_get_bus(void); struct regulator *dss_get_vdds_dsi(void); struct regulator *dss_get_vdds_sdi(void); diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index c1c54883fbe7..54931f14c099 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -910,7 +910,7 @@ int hdmi_audio_config(struct omap_dss_audio *audio) static struct omap_dss_device * __init hdmi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 7282e5af3e1a..7bfeb13cf3d0 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -950,7 +950,7 @@ static int __init rfbi_init_display(struct omap_dss_device *dssdev) static struct omap_dss_device * __init rfbi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 7760851f6e5d..882ce89765e7 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -205,7 +205,7 @@ static int __init sdi_init_display(struct omap_dss_device *dssdev) static struct omap_dss_device * __init sdi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 56efa3bb465d..e8fddc9012cb 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -744,7 +744,7 @@ static void venc_put_clocks(void) static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; - const char *def_disp_name = dss_get_default_display_name(); + const char *def_disp_name = omapdss_get_default_display_name(); struct omap_dss_device *def_dssdev; int i; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index eac5f2562253..bf2c68ad1995 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -753,6 +753,7 @@ void omap_dss_put_device(struct omap_dss_device *dssdev); struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from); struct omap_dss_device *omap_dss_find_device(void *data, int (*match)(struct omap_dss_device *dssdev, void *data)); +const char *omapdss_get_default_display_name(void); int omap_dss_start_device(struct omap_dss_device *dssdev); void omap_dss_stop_device(struct omap_dss_device *dssdev); From 5d89bcc341771d95e3a2996218e5949a6627f59e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 6 Aug 2012 15:27:17 +0300 Subject: [PATCH 06/21] OMAPDSS: remove initial display code from omapdss Currently omapdss driver sets up the initial connections between overlays, overlay manager and a panel, based on default display parameter coming from the board file or via module parameters. This is unnecessary, as it's the higher level component that should decide what display to use and how. This patch removes the code from omapdss, and implements similar code to omapfb. The def_disp module parameter and the default display platform_data parameter are kept in omapdss, but omapdss doesn't do anything with them. It will just return the default display name with dss_get_default_display_name() call, which omapfb uses. This is done to keep the backward compatibility. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/display.c | 78 +++--------------------- drivers/video/omap2/omapfb/omapfb-main.c | 77 +++++++++++++++++++---- 2 files changed, 73 insertions(+), 82 deletions(-) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 90edd718e9e7..6d33112c599c 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -320,86 +320,21 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev, } EXPORT_SYMBOL(omapdss_default_get_timings); -/* - * Connect dssdev to a manager if the manager is free or if force is specified. - * Connect all overlays to that manager if they are free or if force is - * specified. - */ -static int dss_init_connections(struct omap_dss_device *dssdev, bool force) +int dss_init_device(struct platform_device *pdev, + struct omap_dss_device *dssdev) { + struct device_attribute *attr; struct omap_dss_output *out; - struct omap_overlay_manager *mgr; int i, r; out = omapdss_get_output_from_dssdev(dssdev); - WARN_ON(dssdev->output); - WARN_ON(out->device); - r = omapdss_output_set_device(out, dssdev); if (r) { DSSERR("failed to connect output to new device\n"); return r; } - mgr = omap_dss_get_overlay_manager(dssdev->channel); - - if (mgr->output && !force) - return 0; - - if (mgr->output) - mgr->unset_output(mgr); - - r = mgr->set_output(mgr, out); - if (r) { - DSSERR("failed to connect manager to output of new device\n"); - - /* remove the output-device connection we just made */ - omapdss_output_unset_device(out); - return r; - } - - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { - struct omap_overlay *ovl = omap_dss_get_overlay(i); - - if (!ovl->manager || force) { - if (ovl->manager) - ovl->unset_manager(ovl); - - r = ovl->set_manager(ovl, mgr); - if (r) { - DSSERR("failed to set initial overlay\n"); - return r; - } - } - } - - return 0; -} - -static void dss_uninit_connections(struct omap_dss_device *dssdev) -{ - if (dssdev->output) { - struct omap_overlay_manager *mgr = dssdev->output->manager; - - if (mgr) - mgr->unset_output(mgr); - - omapdss_output_unset_device(dssdev->output); - } -} - -int dss_init_device(struct platform_device *pdev, - struct omap_dss_device *dssdev) -{ - struct device_attribute *attr; - int i, r; - const char *def_disp_name = omapdss_get_default_display_name(); - bool force; - - force = def_disp_name && strcmp(def_disp_name, dssdev->name) == 0; - dss_init_connections(dssdev, force); - /* create device sysfs files */ i = 0; while ((attr = display_sysfs_attrs[i++]) != NULL) { @@ -410,7 +345,7 @@ int dss_init_device(struct platform_device *pdev, device_remove_file(&dssdev->dev, attr); } - dss_uninit_connections(dssdev); + omapdss_output_unset_device(dssdev->output); DSSERR("failed to create sysfs file\n"); return r; @@ -424,7 +359,7 @@ int dss_init_device(struct platform_device *pdev, while ((attr = display_sysfs_attrs[i++]) != NULL) device_remove_file(&dssdev->dev, attr); - dss_uninit_connections(dssdev); + omapdss_output_unset_device(dssdev->output); DSSERR("failed to create sysfs display link\n"); return r; @@ -444,7 +379,8 @@ void dss_uninit_device(struct platform_device *pdev, while ((attr = display_sysfs_attrs[i++]) != NULL) device_remove_file(&dssdev->dev, attr); - dss_uninit_connections(dssdev); + if (dssdev->output) + omapdss_output_unset_device(dssdev->output); } static int dss_suspend_device(struct device *dev, void *data) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index ba4630830e09..af2844a34644 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2369,15 +2369,52 @@ static int omapfb_init_display(struct omapfb2_device *fbdev, return 0; } +static int omapfb_init_connections(struct omapfb2_device *fbdev, + struct omap_dss_device *dssdev) +{ + int i, r; + struct omap_overlay_manager *mgr = NULL; + + for (i = 0; i < fbdev->num_managers; i++) { + mgr = fbdev->managers[i]; + + if (dssdev->channel == mgr->id) + break; + } + + if (i == fbdev->num_managers) + return -ENODEV; + + if (mgr->output) + mgr->unset_output(mgr); + + r = mgr->set_output(mgr, dssdev->output); + if (r) + return r; + + for (i = 0; i < fbdev->num_overlays; i++) { + struct omap_overlay *ovl = fbdev->overlays[i]; + + if (ovl->manager) + ovl->unset_manager(ovl); + + r = ovl->set_manager(ovl, mgr); + if (r) + dev_warn(fbdev->dev, + "failed to connect overlay %s to manager %s\n", + ovl->name, mgr->name); + } + + return 0; +} + static int __init omapfb_probe(struct platform_device *pdev) { struct omapfb2_device *fbdev = NULL; int r = 0; int i; - struct omap_overlay *ovl; struct omap_dss_device *def_display; struct omap_dss_device *dssdev; - struct omap_dss_device *ovl_device; DBG("omapfb_probe\n"); @@ -2445,15 +2482,33 @@ static int __init omapfb_probe(struct platform_device *pdev) for (i = 0; i < fbdev->num_managers; i++) fbdev->managers[i] = omap_dss_get_overlay_manager(i); - /* gfx overlay should be the default one. find a display - * connected to that, and use it as default display */ - ovl = omap_dss_get_overlay(0); - ovl_device = ovl->get_device(ovl); - if (ovl_device) { - def_display = ovl_device; - } else { - dev_warn(&pdev->dev, "cannot find default display\n"); - def_display = NULL; + def_display = NULL; + + for (i = 0; i < fbdev->num_displays; ++i) { + struct omap_dss_device *dssdev; + const char *def_name; + + def_name = omapdss_get_default_display_name(); + + dssdev = fbdev->displays[i].dssdev; + + if (def_name == NULL || + (dssdev->name && strcmp(def_name, dssdev->name) == 0)) { + def_display = dssdev; + break; + } + } + + if (def_display == NULL) { + dev_err(fbdev->dev, "failed to find default display\n"); + r = -EINVAL; + goto cleanup; + } + + r = omapfb_init_connections(fbdev, def_display); + if (r) { + dev_err(fbdev->dev, "failed to init overlay connections\n"); + goto cleanup; } if (def_mode && strlen(def_mode) > 0) { From 392faa0e1a8de2529183b62409f90997a2c80d3f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 Oct 2012 15:37:22 +0300 Subject: [PATCH 07/21] OMAPDSS: DISPC: use dss_feat_get_num_ovls() Use dss_feat_get_num_ovls() in dispc.c instead of omap_dss_get_num_overlays() to remove the dependency to overlay.c. Note that we still have uses of omap_dss_get_num_overlays() in dispc.c, but these will be moved out in the future patches. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 198e321d9cfd..392445aa2daf 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1046,7 +1046,7 @@ static void dispc_configure_burst_sizes(void) const int burst_size = BURST_SIZE_X8; /* Configure burst size always to maximum size */ - for (i = 0; i < omap_dss_get_num_overlays(); ++i) + for (i = 0; i < dss_feat_get_num_ovls(); ++i) dispc_ovl_set_burst_size(i, burst_size); } @@ -1250,7 +1250,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, if (use_fifomerge) { total_fifo_size = 0; - for (i = 0; i < omap_dss_get_num_overlays(); ++i) + for (i = 0; i < dss_feat_get_num_ovls(); ++i) total_fifo_size += dispc_ovl_get_fifo_size(i); } else { total_fifo_size = ovl_fifo_size; From 3a979f8ad2014f6bff862b01d21ce151aa47968a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Oct 2012 14:14:38 +0300 Subject: [PATCH 08/21] OMAPDSS: DISPC: rename dispc_mgr_enable/disable to _sync The current dispc_mgr_enable/disable function are blocking, and do a bit too much for omapdrm. We'll expose new enable & disable functions that will just set the bits in the registers in the following patches. This patch renames the current functions to *_sync, to make it clear that they are blocking, and also to free up the dispc_mgr_enable/disable names for these new functions. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 6 +++--- drivers/video/omap2/dss/dispc.c | 4 ++-- drivers/video/omap2/dss/dss.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 7a61a2f7765d..6a214439762e 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -772,7 +772,7 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) if (!dss_data.irq_enabled && need_isr()) dss_register_vsync_isr(); - dispc_mgr_enable(mgr->id); + dispc_mgr_enable_sync(mgr->id); mgr_clear_shadow_dirty(mgr); @@ -1027,7 +1027,7 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) spin_unlock_irqrestore(&data_lock, flags); if (!mgr_manual_update(mgr)) - dispc_mgr_enable(mgr->id); + dispc_mgr_enable_sync(mgr->id); out: mutex_unlock(&apply_lock); @@ -1052,7 +1052,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) goto out; if (!mgr_manual_update(mgr)) - dispc_mgr_disable(mgr->id); + dispc_mgr_disable_sync(mgr->id); spin_lock_irqsave(&data_lock, flags); diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 392445aa2daf..600a4121c6d5 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2755,7 +2755,7 @@ static void dispc_mgr_disable_digit_out(void) DSSERR("failed to unregister %x isr\n", irq_mask); } -void dispc_mgr_enable(enum omap_channel channel) +void dispc_mgr_enable_sync(enum omap_channel channel) { if (dss_mgr_is_lcd(channel)) dispc_mgr_enable_lcd_out(channel); @@ -2765,7 +2765,7 @@ void dispc_mgr_enable(enum omap_channel channel) WARN_ON(1); } -void dispc_mgr_disable(enum omap_channel channel) +void dispc_mgr_disable_sync(enum omap_channel channel) { if (dss_mgr_is_lcd(channel)) dispc_mgr_disable_lcd_out(channel); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index d468743a209e..687eddfc2eb3 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -436,8 +436,8 @@ u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel); bool dispc_mgr_go_busy(enum omap_channel channel); void dispc_mgr_go(enum omap_channel channel); bool dispc_mgr_is_enabled(enum omap_channel channel); -void dispc_mgr_enable(enum omap_channel channel); -void dispc_mgr_disable(enum omap_channel channel); +void dispc_mgr_enable_sync(enum omap_channel channel); +void dispc_mgr_disable_sync(enum omap_channel channel); bool dispc_mgr_is_channel_enabled(enum omap_channel channel); void dispc_mgr_set_lcd_config(enum omap_channel channel, const struct dss_lcd_mgr_config *config); From f1a813d35f5aa53290814b2c646972b4e89c733e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Oct 2012 14:16:06 +0300 Subject: [PATCH 09/21] OMAPDSS: DISPC: make _enable_mgr_out public as "dispc_mgr_enable" We need a low level manager-enable function for omapdrm. We have that function as dispc internal func, _enable_mgr_out(). This patch exposes that function, and renames it to dispc_mgr_enable(). Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 10 +++++----- drivers/video/omap2/dss/dss.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 600a4121c6d5..b5cdbaf61f07 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2595,7 +2595,7 @@ static void dispc_mgr_disable_isr(void *data, u32 mask) complete(compl); } -static void _enable_mgr_out(enum omap_channel channel, bool enable) +void dispc_mgr_enable(enum omap_channel channel, bool enable) { mgr_fld_write(channel, DISPC_MGR_FLD_ENABLE, enable); /* flush posted write */ @@ -2609,7 +2609,7 @@ bool dispc_mgr_is_enabled(enum omap_channel channel) static void dispc_mgr_enable_lcd_out(enum omap_channel channel) { - _enable_mgr_out(channel, true); + dispc_mgr_enable(channel, true); } static void dispc_mgr_disable_lcd_out(enum omap_channel channel) @@ -2633,7 +2633,7 @@ static void dispc_mgr_disable_lcd_out(enum omap_channel channel) if (r) DSSERR("failed to register FRAMEDONE isr\n"); - _enable_mgr_out(channel, false); + dispc_mgr_enable(channel, false); /* if we couldn't register for framedone, just sleep and exit */ if (r) { @@ -2685,7 +2685,7 @@ static void dispc_mgr_enable_digit_out(void) return; } - _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, true); + dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, true); /* wait for the first evsync */ if (!wait_for_completion_timeout(&vsync_compl, msecs_to_jiffies(100))) @@ -2735,7 +2735,7 @@ static void dispc_mgr_disable_digit_out(void) if (r) DSSERR("failed to register %x isr\n", irq_mask); - _enable_mgr_out(OMAP_DSS_CHANNEL_DIGIT, false); + dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, false); /* if we couldn't register the irq, just sleep and exit */ if (r) { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 687eddfc2eb3..85c6fc8cec1d 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -435,6 +435,7 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel); u32 dispc_mgr_get_sync_lost_irq(enum omap_channel channel); bool dispc_mgr_go_busy(enum omap_channel channel); void dispc_mgr_go(enum omap_channel channel); +void dispc_mgr_enable(enum omap_channel channel, bool enable); bool dispc_mgr_is_enabled(enum omap_channel channel); void dispc_mgr_enable_sync(enum omap_channel channel); void dispc_mgr_disable_sync(enum omap_channel channel); From 04bd8ac14e6c0d4f75be0950c14f9791ffdc76d7 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Oct 2012 14:13:15 +0300 Subject: [PATCH 10/21] OMAPDSS: add dispc_ovl_enabled() Add new dispc function, dispc_ovl_enabled(). This returns if the overlay enable bit is set in the registers. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 5 +++++ drivers/video/omap2/dss/dss.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b5cdbaf61f07..3fd60ce3d718 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2589,6 +2589,11 @@ int dispc_ovl_enable(enum omap_plane plane, bool enable) return 0; } +bool dispc_ovl_enabled(enum omap_plane plane) +{ + return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0); +} + static void dispc_mgr_disable_isr(void *data, u32 mask) { struct completion *compl = data; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 85c6fc8cec1d..e3e5a63dacec 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -427,6 +427,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi, bool replication, const struct omap_video_timings *mgr_timings, bool mem_to_mem); int dispc_ovl_enable(enum omap_plane plane, bool enable); +bool dispc_ovl_enabled(enum omap_plane plane); void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel); From 4e0397cfa78913f3da08c0aa8076b6b0a3b262a0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 10 Oct 2012 15:13:14 +0300 Subject: [PATCH 11/21] OMAPDSS: DISPC: Add IRQ enable/status helpers DISPC irqs need to be handled from the compat layer and also in the future by the omapdrm. To make this possible, this patchs adds a set of helper functions, so that the irqs can be managed without direct register reads/writes. The following functions are added, and all the current direct reg reads/writes are changed to use these. u32 dispc_read_irqstatus(void); void dispc_clear_irqstatus(u32 mask); u32 dispc_read_irqenable(void); void dispc_write_irqenable(u32 mask); Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 44 ++++++++++++++++++++++++--------- drivers/video/omap2/dss/dss.h | 4 +++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 3fd60ce3d718..d2948732843b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -497,7 +497,7 @@ static void dispc_restore_context(void) if (dss_has_feature(FEAT_MGR_LCD3)) RR(CONTROL3); /* clear spurious SYNC_LOST_DIGIT interrupts */ - dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT); + dispc_clear_irqstatus(DISPC_IRQ_SYNC_LOST_DIGIT); /* * enable last so IRQs won't trigger before @@ -3627,11 +3627,35 @@ int dispc_mgr_get_clock_div(enum omap_channel channel, return 0; } +u32 dispc_read_irqstatus(void) +{ + return dispc_read_reg(DISPC_IRQSTATUS); +} + +void dispc_clear_irqstatus(u32 mask) +{ + dispc_write_reg(DISPC_IRQSTATUS, mask); +} + +u32 dispc_read_irqenable(void) +{ + return dispc_read_reg(DISPC_IRQENABLE); +} + +void dispc_write_irqenable(u32 mask) +{ + u32 old_mask = dispc_read_reg(DISPC_IRQENABLE); + + /* clear the irqstatus for newly enabled irqs */ + dispc_clear_irqstatus((mask ^ old_mask) & mask); + + dispc_write_reg(DISPC_IRQENABLE, mask); +} + /* dispc.irq_lock has to be locked by the caller */ static void _omap_dispc_set_irqs(void) { u32 mask; - u32 old_mask; int i; struct omap_dispc_isr_data *isr_data; @@ -3646,11 +3670,7 @@ static void _omap_dispc_set_irqs(void) mask |= isr_data->mask; } - old_mask = dispc_read_reg(DISPC_IRQENABLE); - /* clear the irqstatus for newly enabled irqs */ - dispc_write_reg(DISPC_IRQSTATUS, (mask ^ old_mask) & mask); - - dispc_write_reg(DISPC_IRQENABLE, mask); + dispc_write_irqenable(mask); } int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask) @@ -3777,8 +3797,8 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *arg) spin_lock(&dispc.irq_lock); - irqstatus = dispc_read_reg(DISPC_IRQSTATUS); - irqenable = dispc_read_reg(DISPC_IRQENABLE); + irqstatus = dispc_read_irqstatus(); + irqenable = dispc_read_irqenable(); /* IRQ is not for us */ if (!(irqstatus & irqenable)) { @@ -3797,9 +3817,9 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *arg) /* Ack the interrupt. Do it here before clocks are possibly turned * off */ - dispc_write_reg(DISPC_IRQSTATUS, irqstatus); + dispc_clear_irqstatus(irqstatus); /* flush posted write */ - dispc_read_reg(DISPC_IRQSTATUS); + dispc_read_irqstatus(); /* make a copy and unlock, so that isrs can unregister * themselves */ @@ -4008,7 +4028,7 @@ static void _omap_dispc_initialize_irq(void) /* there's SYNC_LOST_DIGIT waiting after enabling the DSS, * so clear it */ - dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS)); + dispc_clear_irqstatus(dispc_read_irqstatus()); _omap_dispc_set_irqs(); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index e3e5a63dacec..d614fda9275c 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -397,6 +397,10 @@ void dpi_uninit_platform_driver(void) __exit; int dispc_init_platform_driver(void) __init; void dispc_uninit_platform_driver(void) __exit; void dispc_dump_clocks(struct seq_file *s); +u32 dispc_read_irqstatus(void); +void dispc_clear_irqstatus(u32 mask); +u32 dispc_read_irqenable(void); +void dispc_write_irqenable(u32 mask); int dispc_runtime_get(void); void dispc_runtime_put(void); From bb426fc96316b20876acc3289c5115f00918c2bb Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Oct 2012 17:42:10 +0300 Subject: [PATCH 12/21] OMAPDSS: HDMI: split power_on/off to two parts There's currently just one power-on function for HDMI, which enables the IP and the video output. When reading EDID or detecting if a monitor is connected, we don't need the video output. Enabling the video output for these operations is not a big problem in itself, but the quick enable/disable cycles caused by the operations seem to cause sync lost errors from time to time. Also, this makes it possible to read the EDID before the full video path has been set up. This patch splits the hdmi_power_on into two parts, hdmi_power_on_core and hdmi_power_on_full. The "full" version does what hdmi_power_on does currently, and hdmi_power_on_core only enables the core IP. Similar changes are made for power_off. Note that these don't allow the HDMI IP to be first enabled, and later enable the video output, but the HDMI IP will first need to be powered off before calling the full version. So this is rather limited implementation, but it fills the needs for reading EDID. Signed-off-by: Tomi Valkeinen Cc: Ricardo Neri --- drivers/video/omap2/dss/hdmi.c | 75 +++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 54931f14c099..1226044e5508 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -500,12 +500,9 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); } -static int hdmi_power_on(struct omap_dss_device *dssdev) +static int hdmi_power_on_core(struct omap_dss_device *dssdev) { int r; - struct omap_video_timings *p; - struct omap_overlay_manager *mgr = dssdev->output->manager; - unsigned long phy; gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); gpio_set_value(hdmi.ls_oe_gpio, 1); @@ -521,6 +518,46 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) if (r) goto err_runtime_get; + /* Make selection of HDMI in DSS */ + dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); + + /* Select the dispc clock source as PRCM clock, to ensure that it is not + * DSI PLL source as the clock selected by DSI PLL might not be + * sufficient for the resolution selected / that can be changed + * dynamically by user. This can be moved to single location , say + * Boardfile. + */ + dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); + + return 0; + +err_runtime_get: + regulator_disable(hdmi.vdda_hdmi_dac_reg); +err_vdac_enable: + gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); + gpio_set_value(hdmi.ls_oe_gpio, 0); + return r; +} + +static void hdmi_power_off_core(struct omap_dss_device *dssdev) +{ + hdmi_runtime_put(); + regulator_disable(hdmi.vdda_hdmi_dac_reg); + gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); + gpio_set_value(hdmi.ls_oe_gpio, 0); +} + +static int hdmi_power_on_full(struct omap_dss_device *dssdev) +{ + int r; + struct omap_video_timings *p; + struct omap_overlay_manager *mgr = dssdev->output->manager; + unsigned long phy; + + r = hdmi_power_on_core(dssdev); + if (r) + return r; + dss_mgr_disable(mgr); p = &hdmi.ip_data.cfg.timings; @@ -548,17 +585,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) hdmi.ip_data.ops->video_configure(&hdmi.ip_data); - /* Make selection of HDMI in DSS */ - dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); - - /* Select the dispc clock source as PRCM clock, to ensure that it is not - * DSI PLL source as the clock selected by DSI PLL might not be - * sufficient for the resolution selected / that can be changed - * dynamically by user. This can be moved to single location , say - * Boardfile. - */ - dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); - /* bypass TV gamma table */ dispc_enable_gamma_table(0); @@ -582,16 +608,11 @@ err_vid_enable: err_phy_enable: hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); err_pll_enable: - hdmi_runtime_put(); -err_runtime_get: - regulator_disable(hdmi.vdda_hdmi_dac_reg); -err_vdac_enable: - gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); - gpio_set_value(hdmi.ls_oe_gpio, 0); + hdmi_power_off_core(dssdev); return -EIO; } -static void hdmi_power_off(struct omap_dss_device *dssdev) +static void hdmi_power_off_full(struct omap_dss_device *dssdev) { struct omap_overlay_manager *mgr = dssdev->output->manager; @@ -600,12 +621,8 @@ static void hdmi_power_off(struct omap_dss_device *dssdev) hdmi.ip_data.ops->video_disable(&hdmi.ip_data); hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); - hdmi_runtime_put(); - regulator_disable(hdmi.vdda_hdmi_dac_reg); - - gpio_set_value(hdmi.ct_cp_hpd_gpio, 0); - gpio_set_value(hdmi.ls_oe_gpio, 0); + hdmi_power_off_core(dssdev); } int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, @@ -713,7 +730,7 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } - r = hdmi_power_on(dssdev); + r = hdmi_power_on_full(dssdev); if (r) { DSSERR("failed to power on device\n"); goto err1; @@ -735,7 +752,7 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) mutex_lock(&hdmi.lock); - hdmi_power_off(dssdev); + hdmi_power_off_full(dssdev); omap_dss_stop_device(dssdev); From 4489823ca755dd9931d7f71e5c0a437952a6fdec Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Oct 2012 17:42:27 +0300 Subject: [PATCH 13/21] OMAPDSS: HDMI: use core power on/off with edid & detect This patch makes use of the hdmi_power_[on|off]_core() functions added in the previous patch. The functions are used when reading EDID or detecting if a monitor is connected. Signed-off-by: Tomi Valkeinen Cc: Ricardo Neri --- drivers/video/omap2/dss/dss.h | 2 ++ drivers/video/omap2/dss/hdmi.c | 35 ++++++++++++++++++++++++++++ drivers/video/omap2/dss/hdmi_panel.c | 8 +++---- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index d614fda9275c..ff7a55b54b8e 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -509,6 +509,8 @@ static inline unsigned long hdmi_get_pixel_clock(void) #endif int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev); void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev); +int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev); +void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev); void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, struct omap_video_timings *timings); int omapdss_hdmi_display_check_timing(struct omap_dss_device *dssdev, diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 1226044e5508..81b9fc48295f 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -759,6 +759,41 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) mutex_unlock(&hdmi.lock); } +int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + DSSDBG("ENTER omapdss_hdmi_core_enable\n"); + + mutex_lock(&hdmi.lock); + + hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio; + + r = hdmi_power_on_core(dssdev); + if (r) { + DSSERR("failed to power on device\n"); + goto err0; + } + + mutex_unlock(&hdmi.lock); + return 0; + +err0: + mutex_unlock(&hdmi.lock); + return r; +} + +void omapdss_hdmi_core_disable(struct omap_dss_device *dssdev) +{ + DSSDBG("Enter omapdss_hdmi_core_disable\n"); + + mutex_lock(&hdmi.lock); + + hdmi_power_off_core(dssdev); + + mutex_unlock(&hdmi.lock); +} + static int hdmi_get_clocks(struct platform_device *pdev) { struct clk *clk; diff --git a/drivers/video/omap2/dss/hdmi_panel.c b/drivers/video/omap2/dss/hdmi_panel.c index 3f9a4b947a54..a385b69a018e 100644 --- a/drivers/video/omap2/dss/hdmi_panel.c +++ b/drivers/video/omap2/dss/hdmi_panel.c @@ -334,7 +334,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; if (need_enable) { - r = omapdss_hdmi_display_enable(dssdev); + r = omapdss_hdmi_core_enable(dssdev); if (r) goto err; } @@ -342,7 +342,7 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev, u8 *buf, int len) r = omapdss_hdmi_read_edid(buf, len); if (need_enable) - omapdss_hdmi_display_disable(dssdev); + omapdss_hdmi_core_disable(dssdev); err: mutex_unlock(&hdmi.lock); @@ -359,7 +359,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev) need_enable = dssdev->state == OMAP_DSS_DISPLAY_DISABLED; if (need_enable) { - r = omapdss_hdmi_display_enable(dssdev); + r = omapdss_hdmi_core_enable(dssdev); if (r) goto err; } @@ -367,7 +367,7 @@ static bool hdmi_detect(struct omap_dss_device *dssdev) r = omapdss_hdmi_detect(); if (need_enable) - omapdss_hdmi_display_disable(dssdev); + omapdss_hdmi_core_disable(dssdev); err: mutex_unlock(&hdmi.lock); From 7a7ce2c771fe7ebcc6ff0ab2bf09b0014087ab9c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 24 Oct 2012 11:55:39 +0300 Subject: [PATCH 14/21] OMAPDSS: HDMI: add 1920x1200 video mode Add 1920x1200 video mode to hdmi driver's static modelist. Signed-off-by: Tomi Valkeinen Cc: Ricardo Neri --- drivers/video/omap2/dss/hdmi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 81b9fc48295f..9f5c4c25532e 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -295,6 +295,12 @@ static const struct hdmi_config vesa_timings[] = { false, }, { 0x55, HDMI_DVI }, }, + { + { 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, + OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, + false, }, + { 0x44, HDMI_DVI }, + }, }; static int hdmi_runtime_get(void) From f236b892b1cb736edbb9b61ace60ca4dd862e53a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 24 Oct 2012 11:55:54 +0300 Subject: [PATCH 15/21] OMAPDSS: HDMI: make hdmi pclk check more permissive The hdmi driver tries to find the given video timings from its static list of timings, to find the required ID for the mode. The check tries to find exact match for the pixel clock, among other checks. with omapfb driver there can be some amount of error in the give pixel clock, as the pixel clock is converted between Hz and ps, thus the hdmi's check fails to find the mode. This patch makes the check more allowing, by rounding the pixel clocks to nearest MHz. Signed-off-by: Tomi Valkeinen Cc: Ricardo Neri --- drivers/video/omap2/dss/hdmi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 9f5c4c25532e..03440e6c3f1b 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -404,7 +404,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1, { int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; - if ((timing2->pixel_clock == timing1->pixel_clock) && + if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == + DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && (timing2->x_res == timing1->x_res) && (timing2->y_res == timing1->y_res)) { From 2b5c0d4fd246a3ec0ab79c6518860c673c4515ef Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 8 Oct 2012 15:38:25 +0300 Subject: [PATCH 16/21] OMAPFB: remove use of extended edid block It seems that using the second EDID block causes more problems than is of any help. The first mode in the extended block will get FB_MODE_IS_FIRST set, which will override the first mode from the first EDID block, thus making the default videomode selection not to work properly. This patch removes the use of the extended edid block for now. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-main.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index af2844a34644..24c339df0b88 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2272,9 +2272,6 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, fb_edid_to_monspecs(edid, specs); - if (edid[126] > 0) - fb_edid_add_monspecs(edid + 0x80, specs); - best_xres = 0; best_idx = -1; From 5e18e3527c5e7af6ccde475cfea5bfe6f1f0f0da Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 12 Oct 2012 15:44:29 +0300 Subject: [PATCH 17/21] OMAPFB: improve mode selection from EDID The current omapfb code goes over all the modes found from the monitors EDID data, and searches for a mode that is compatible with the DSS hardware and has the highest x-res. While this works ok as such, it proves problematic when using DSI PLL for pixel clock. Calculating DSI PLL dividers is not the fastest of the operations, and while doing it for one mode is usually ok, doing it for 20 modes is noticable. Also, the first mode given in the EDID data should be the native mode of the monitor, and thus also the best mode, so if that can be used, no need to look further. This patch changes the code to use the first mode that is compatible with the DSS hardware. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 24c339df0b88..be9096ced793 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2256,7 +2256,7 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, { struct fb_monspecs *specs; u8 *edid; - int r, i, best_xres, best_idx, len; + int r, i, best_idx, len; if (!display->driver->read_edid) return -ENODEV; @@ -2272,7 +2272,6 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, fb_edid_to_monspecs(edid, specs); - best_xres = 0; best_idx = -1; for (i = 0; i < specs->modedb_len; ++i) { @@ -2288,16 +2287,20 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, if (m->xres == 2880 || m->xres == 1440) continue; + if (m->vmode & FB_VMODE_INTERLACED || + m->vmode & FB_VMODE_DOUBLE) + continue; + fb_videomode_to_omap_timings(m, display, &t); r = display->driver->check_timings(display, &t); - if (r == 0 && best_xres < m->xres) { - best_xres = m->xres; + if (r == 0) { best_idx = i; + break; } } - if (best_xres == 0) { + if (best_idx == -1) { r = -ENOENT; goto err2; } From 901e5fe5a47d360a8ad6b5fbbe37e107ddb11662 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 30 Nov 2011 17:34:52 +0200 Subject: [PATCH 18/21] OMAPDSS: fix DSI2 PLL clk names dss_generic_clk_source_names is missing the names for clocks from DSI2 PLL. Add them. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index d90de37288c4..456118beb1f8 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -97,6 +97,8 @@ static const char * const dss_generic_clk_source_names[] = { [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC] = "DSI_PLL_HSDIV_DISPC", [OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI] = "DSI_PLL_HSDIV_DSI", [OMAP_DSS_CLK_SRC_FCK] = "DSS_FCK", + [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC] = "DSI_PLL2_HSDIV_DISPC", + [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", }; static inline void dss_write_reg(const struct dss_reg idx, u32 val) From 4c6c65b013a20054585dfca5cfbf3a2f6393ab50 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 24 Oct 2012 09:20:40 +0300 Subject: [PATCH 19/21] OMAPDSS: DISPC: fix loop in error handler The dispc's error handler has a loop inside another loop, and both use the same loop variable. This is clearly wrong, and this patch makes a new variable for the inner loop. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d2948732843b..070ce306da17 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3901,6 +3901,7 @@ static void dispc_error_worker(struct work_struct *work) bit = mgr_desc[i].sync_lost_irq; if (bit & errors) { + int j; struct omap_dss_device *dssdev = mgr->get_device(mgr); bool enable; @@ -3911,9 +3912,9 @@ static void dispc_error_worker(struct work_struct *work) enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE; dssdev->driver->disable(dssdev); - for (i = 0; i < omap_dss_get_num_overlays(); ++i) { + for (j = 0; j < omap_dss_get_num_overlays(); ++j) { struct omap_overlay *ovl; - ovl = omap_dss_get_overlay(i); + ovl = omap_dss_get_overlay(j); if (ovl->id != OMAP_DSS_GFX && ovl->manager == mgr) From b276dd091673589450d56812ffcfddca961c1a41 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 15 Jun 2012 15:34:24 +0300 Subject: [PATCH 20/21] OMAPDSS: DISPC: remove dssdev depependency from error handler The dispc error handler tries to "fix" issues by disabling and enabling panel. This is problematic, as we're trying to remove the dependency from omapdss to the omap_dss_devices. It's also racy, and doesn't really fix anything. This patch removes the use of omap_dss_device from the error handler, and just disables and enables the associated overlay manager. This should produce similar results as the previous solution, without using dssdev. However, the error handling is still horrible. But the problem boils down to one question, to which I don't have a clear answer: what to do when a HW error happens? Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 070ce306da17..05def42e528b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3902,15 +3902,12 @@ static void dispc_error_worker(struct work_struct *work) if (bit & errors) { int j; - struct omap_dss_device *dssdev = mgr->get_device(mgr); - bool enable; DSSERR("SYNC_LOST on channel %s, restarting the output " "with video overlays disabled\n", mgr->name); - enable = dssdev->state == OMAP_DSS_DISPLAY_ACTIVE; - dssdev->driver->disable(dssdev); + dss_mgr_disable(mgr); for (j = 0; j < omap_dss_get_num_overlays(); ++j) { struct omap_overlay *ovl; @@ -3918,14 +3915,10 @@ static void dispc_error_worker(struct work_struct *work) if (ovl->id != OMAP_DSS_GFX && ovl->manager == mgr) - dispc_ovl_enable(ovl->id, false); + ovl->disable(ovl); } - dispc_mgr_go(mgr->id); - msleep(50); - - if (enable) - dssdev->driver->enable(dssdev); + dss_mgr_enable(mgr); } } @@ -3933,13 +3926,9 @@ static void dispc_error_worker(struct work_struct *work) DSSERR("OCP_ERR\n"); for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { struct omap_overlay_manager *mgr; - struct omap_dss_device *dssdev; mgr = omap_dss_get_overlay_manager(i); - dssdev = mgr->get_device(mgr); - - if (dssdev && dssdev->driver) - dssdev->driver->disable(dssdev); + dss_mgr_disable(mgr); } } From ffc81fc5f3f6070820cb7ef885daa37545291e97 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Oct 2012 12:14:12 +0300 Subject: [PATCH 21/21] OMAPDSS: split hdmi muxing function Split the omap4_hdmi_mux_pads() function into two parts, one handles the tpd12s015 gpio muxing, the other handles the hdmi pins. This is clearer, as hdmi and tpd12s015 are separate devices, and it also allows us to mux those separately with DT. Signed-off-by: Tomi Valkeinen Cc: Ricardo Neri Acked-by: Tony Lindgren --- arch/arm/mach-omap2/display.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c index 28f508724a56..282c814ea2e2 100644 --- a/arch/arm/mach-omap2/display.c +++ b/arch/arm/mach-omap2/display.c @@ -100,17 +100,20 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initconst = { { "dss_hdmi", "omapdss_hdmi", -1 }, }; -static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) +static void __init omap4_tpd12s015_mux_pads(void) { - u32 reg; - u16 control_i2c_1; - omap_mux_init_signal("hdmi_cec", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_ddc_scl", OMAP_PIN_INPUT_PULLUP); omap_mux_init_signal("hdmi_ddc_sda", OMAP_PIN_INPUT_PULLUP); +} + +static void __init omap4_hdmi_mux_pads(enum omap_hdmi_flags flags) +{ + u32 reg; + u16 control_i2c_1; /* * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and @@ -161,8 +164,10 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes) int __init omap_hdmi_init(enum omap_hdmi_flags flags) { - if (cpu_is_omap44xx()) + if (cpu_is_omap44xx()) { omap4_hdmi_mux_pads(flags); + omap4_tpd12s015_mux_pads(); + } return 0; }