diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-06-28 17:59:10 +0800 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-06-28 17:59:10 +0800 |
commit | 8e9804557ca1188f3a9d9129180f46c2c73ba942 (patch) | |
tree | ce7acdbc7af509b5d863106c99b7c654418648cd /drivers/video/omap2/dss/hdmi.c | |
parent | a66e62ae56307e587e93d7ed4d83ea34c71d2eb9 (diff) | |
parent | 595470a7853848cb971d5ee3fed443b1e3aa0d1b (diff) | |
download | talos-op-linux-8e9804557ca1188f3a9d9129180f46c2c73ba942.tar.gz talos-op-linux-8e9804557ca1188f3a9d9129180f46c2c73ba942.zip |
Merge tag 'omapdss-for-3.11-1' of git://gitorious.org/linux-omap-dss2/linux into fbdev/for-next
OMAP display subsystem changes for 3.11 (part 1/2)
This is the first part of OMAP DSS changes for 3.11. This part contains fixes,
cleanups and reorganizations that are not directly related to the new DSS
device model that is added in part 2, although many of the reorganizations are
made to make the part 2 possible.
There should not be any functional changes visible to the user except the few
bug fixes.
The main new internal features:
- Display (dis)connect support, which allows us to explicitly (dis)connect a
whole display pipeline
- Panel list, which allows us to operate without the specific DSS bus
- Combine omap_dss_output to omap_dss_device, so that we have one generic
"entity" for display pipeline blocks
Diffstat (limited to 'drivers/video/omap2/dss/hdmi.c')
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 107 |
1 files changed, 55 insertions, 52 deletions
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a109934c0478..e1c0992b522b 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -70,7 +70,7 @@ static struct { int ls_oe_gpio; int hpd_gpio; - struct omap_dss_output output; + struct omap_dss_device output; } hdmi; /* @@ -328,6 +328,29 @@ static void hdmi_runtime_put(void) WARN_ON(r < 0 && r != -ENOSYS); } +static int hdmi_init_regulator(void) +{ + struct regulator *reg; + + if (hdmi.vdda_hdmi_dac_reg != NULL) + return 0; + + reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); + + /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ + if (IS_ERR(reg)) + reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); + + if (IS_ERR(reg)) { + DSSERR("can't get VDDA_HDMI_DAC regulator\n"); + return PTR_ERR(reg); + } + + hdmi.vdda_hdmi_dac_reg = reg; + + return 0; +} + static int hdmi_init_display(struct omap_dss_device *dssdev) { int r; @@ -342,22 +365,9 @@ static int hdmi_init_display(struct omap_dss_device *dssdev) dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); - if (hdmi.vdda_hdmi_dac_reg == NULL) { - struct regulator *reg; - - reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); - - /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ - if (IS_ERR(reg)) - reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); - - if (IS_ERR(reg)) { - DSSERR("can't get VDDA_HDMI_DAC regulator\n"); - return PTR_ERR(reg); - } - - hdmi.vdda_hdmi_dac_reg = reg; - } + r = hdmi_init_regulator(); + if (r) + return r; r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); if (r) @@ -455,12 +465,6 @@ end: return cm; } -unsigned long hdmi_get_pixel_clock(void) -{ - /* HDMI Pixel Clock in Mhz */ - return hdmi.ip_data.cfg.timings.pixel_clock * 1000; -} - static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, struct hdmi_pll_info *pi) { @@ -550,7 +554,7 @@ 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; + struct omap_overlay_manager *mgr = hdmi.output.manager; unsigned long phy; r = hdmi_power_on_core(dssdev); @@ -613,7 +617,7 @@ err_pll_enable: static void hdmi_power_off_full(struct omap_dss_device *dssdev) { - struct omap_overlay_manager *mgr = dssdev->output->manager; + struct omap_overlay_manager *mgr = hdmi.output.manager; dss_mgr_disable(mgr); @@ -653,6 +657,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev, if (t != NULL) hdmi.ip_data.cfg = *t; + dispc_set_tv_pclk(t->timings.pixel_clock * 1000); + mutex_unlock(&hdmi.lock); } @@ -700,7 +706,7 @@ bool omapdss_hdmi_detect(void) r = hdmi_runtime_get(); BUG_ON(r); - r = hdmi.ip_data.ops->detect(&hdmi.ip_data); + r = gpio_get_value(hdmi.hpd_gpio); hdmi_runtime_put(); mutex_unlock(&hdmi.lock); @@ -710,7 +716,7 @@ bool omapdss_hdmi_detect(void) int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) { - struct omap_dss_output *out = dssdev->output; + struct omap_dss_device *out = &hdmi.output; int r = 0; DSSDBG("ENTER hdmi_display_enable\n"); @@ -723,25 +729,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) goto err0; } - hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio; - - r = omap_dss_start_device(dssdev); - if (r) { - DSSERR("failed to start device\n"); - goto err0; - } - r = hdmi_power_on_full(dssdev); if (r) { DSSERR("failed to power on device\n"); - goto err1; + goto err0; } mutex_unlock(&hdmi.lock); return 0; -err1: - omap_dss_stop_device(dssdev); err0: mutex_unlock(&hdmi.lock); return r; @@ -755,8 +751,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev) hdmi_power_off_full(dssdev); - omap_dss_stop_device(dssdev); - mutex_unlock(&hdmi.lock); } @@ -768,8 +762,6 @@ int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev) 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"); @@ -1035,20 +1027,21 @@ static int hdmi_probe_pdata(struct platform_device *pdev) static void hdmi_init_output(struct platform_device *pdev) { - struct omap_dss_output *out = &hdmi.output; + struct omap_dss_device *out = &hdmi.output; - out->pdev = pdev; + out->dev = &pdev->dev; out->id = OMAP_DSS_OUTPUT_HDMI; - out->type = OMAP_DISPLAY_TYPE_HDMI; + out->output_type = OMAP_DISPLAY_TYPE_HDMI; out->name = "hdmi.0"; out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; + out->owner = THIS_MODULE; dss_register_output(out); } static void __exit hdmi_uninit_output(struct platform_device *pdev) { - struct omap_dss_output *out = &hdmi.output; + struct omap_dss_device *out = &hdmi.output; dss_unregister_output(out); } @@ -1071,6 +1064,12 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) if (IS_ERR(hdmi.ip_data.base_wp)) return PTR_ERR(hdmi.ip_data.base_wp); + hdmi.ip_data.irq = platform_get_irq(pdev, 0); + if (hdmi.ip_data.irq < 0) { + DSSERR("platform_get_irq failed\n"); + return -ENODEV; + } + r = hdmi_get_clocks(pdev); if (r) { DSSERR("can't get clocks\n"); @@ -1094,15 +1093,19 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) dss_debugfs_create_file("hdmi", hdmi_dump_regs); - r = hdmi_probe_pdata(pdev); - if (r) { - hdmi_panel_exit(); - hdmi_uninit_output(pdev); - pm_runtime_disable(&pdev->dev); - return r; + if (pdev->dev.platform_data) { + r = hdmi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; + +err_probe: + hdmi_panel_exit(); + hdmi_uninit_output(pdev); + pm_runtime_disable(&pdev->dev); + return r; } static int __exit hdmi_remove_child(struct device *dev, void *data) |