diff options
author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-06-28 13:59:10 +0400 |
---|---|---|
committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2013-06-28 13:59:10 +0400 |
commit | 8e9804557ca1188f3a9d9129180f46c2c73ba942 (patch) | |
tree | ce7acdbc7af509b5d863106c99b7c654418648cd /drivers/video/omap2/dss/dpi.c | |
parent | a66e62ae56307e587e93d7ed4d83ea34c71d2eb9 (diff) | |
parent | 595470a7853848cb971d5ee3fed443b1e3aa0d1b (diff) | |
download | linux-8e9804557ca1188f3a9d9129180f46c2c73ba942.tar.xz |
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/dpi.c')
-rw-r--r-- | drivers/video/omap2/dss/dpi.c | 131 |
1 files changed, 69 insertions, 62 deletions
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 757b57f7275a..892a2b207ee4 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -37,6 +37,8 @@ #include "dss_features.h" static struct { + struct platform_device *pdev; + struct regulator *vdds_dsi_reg; struct platform_device *dsidev; @@ -46,7 +48,7 @@ static struct { struct dss_lcd_mgr_config mgr_config; int data_lines; - struct omap_dss_output output; + struct omap_dss_device output; } dpi; static struct platform_device *dpi_get_dsidev(enum omap_channel channel) @@ -345,7 +347,7 @@ static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr) int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { - struct omap_dss_output *out = &dpi.output; + struct omap_dss_device *out = &dpi.output; int r; mutex_lock(&dpi.lock); @@ -362,12 +364,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) goto err_no_out_mgr; } - r = omap_dss_start_device(dssdev); - if (r) { - DSSERR("failed to start device\n"); - goto err_start_dev; - } - if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { r = regulator_enable(dpi.vdds_dsi_reg); if (r) @@ -422,8 +418,6 @@ err_get_dispc: if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) regulator_disable(dpi.vdds_dsi_reg); err_reg_enable: - omap_dss_stop_device(dssdev); -err_start_dev: err_no_out_mgr: err_no_reg: mutex_unlock(&dpi.lock); @@ -450,8 +444,6 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) regulator_disable(dpi.vdds_dsi_reg); - omap_dss_stop_device(dssdev); - mutex_unlock(&dpi.lock); } EXPORT_SYMBOL(omapdss_dpi_display_disable); @@ -542,6 +534,50 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev) return 0; } +static int dpi_init_regulator(void) +{ + struct regulator *vdds_dsi; + + if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) + return 0; + + if (dpi.vdds_dsi_reg) + return 0; + + vdds_dsi = dss_get_vdds_dsi(); + + if (IS_ERR(vdds_dsi)) { + vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); + if (IS_ERR(vdds_dsi)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(vdds_dsi); + } + } + + dpi.vdds_dsi_reg = vdds_dsi; + + return 0; +} + +static void dpi_init_pll(void) +{ + struct platform_device *dsidev; + + if (dpi.dsidev) + return; + + dsidev = dpi_get_dsidev(dpi.output.dispc_channel); + if (!dsidev) + return; + + if (dpi_verify_dsi_pll(dsidev)) { + DSSWARN("DSI PLL not operational\n"); + return; + } + + dpi.dsidev = dsidev; +} + /* * Return a hardcoded channel for the DPI output. This should work for * current use cases, but this can be later expanded to either resolve @@ -572,41 +608,6 @@ static enum omap_channel dpi_get_channel(void) } } -static int dpi_init_display(struct omap_dss_device *dssdev) -{ - struct platform_device *dsidev; - - DSSDBG("init_display\n"); - - if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && - dpi.vdds_dsi_reg == NULL) { - struct regulator *vdds_dsi; - - vdds_dsi = dss_get_vdds_dsi(); - - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); - } - - dpi.vdds_dsi_reg = vdds_dsi; - } - - dsidev = dpi_get_dsidev(dpi.output.dispc_channel); - - if (dsidev && dpi_verify_dsi_pll(dsidev)) { - dsidev = NULL; - DSSWARN("DSI PLL not operational\n"); - } - - if (dsidev) - DSSDBG("using DSI PLL for DPI clock\n"); - - dpi.dsidev = dsidev; - - return 0; -} - static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; @@ -646,19 +647,18 @@ static int dpi_probe_pdata(struct platform_device *dpidev) if (!plat_dssdev) return 0; + r = dpi_init_regulator(); + if (r) + return r; + + dpi_init_pll(); + dssdev = dss_alloc_and_init_device(&dpidev->dev); if (!dssdev) return -ENOMEM; dss_copy_device_pdata(dssdev, plat_dssdev); - r = dpi_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - r = omapdss_output_set_device(&dpi.output, dssdev); if (r) { DSSERR("failed to connect output to new device: %s\n", @@ -680,20 +680,21 @@ static int dpi_probe_pdata(struct platform_device *dpidev) static void dpi_init_output(struct platform_device *pdev) { - struct omap_dss_output *out = &dpi.output; + struct omap_dss_device *out = &dpi.output; - out->pdev = pdev; + out->dev = &pdev->dev; out->id = OMAP_DSS_OUTPUT_DPI; - out->type = OMAP_DISPLAY_TYPE_DPI; + out->output_type = OMAP_DISPLAY_TYPE_DPI; out->name = "dpi.0"; out->dispc_channel = dpi_get_channel(); + out->owner = THIS_MODULE; dss_register_output(out); } static void __exit dpi_uninit_output(struct platform_device *pdev) { - struct omap_dss_output *out = &dpi.output; + struct omap_dss_device *out = &dpi.output; dss_unregister_output(out); } @@ -702,17 +703,23 @@ static int omap_dpi_probe(struct platform_device *pdev) { int r; + dpi.pdev = pdev; + mutex_init(&dpi.lock); dpi_init_output(pdev); - r = dpi_probe_pdata(pdev); - if (r) { - dpi_uninit_output(pdev); - return r; + if (pdev->dev.platform_data) { + r = dpi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; + +err_probe: + dpi_uninit_output(pdev); + return r; } static int __exit omap_dpi_remove(struct platform_device *pdev) |