From 046bc5751d70c9d5356d725e3e16987ed98eb7c8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 22 Oct 2012 15:57:25 +0300 Subject: [PATCH 1/9] OMAPDSS: fix DPI & DSI init order DPI may use DSI PLL, so it depends on DSI. However, currently DPI driver is added first, which causes DPI initialization to fail when it tries to get the DSI PLL. This patch changes the init order to fix this. A better solution would be to separate DSI PLL and DSI drivers. They have dependencies, though, but we could still have DSI PLL as an independent entity that we could initialize before any of the output drivers. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index a2ea684169e9..b1a9ce1188fb 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -510,6 +510,9 @@ static int __init omap_dss_bus_register(void) /* INIT */ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_init_platform_driver, +#endif #ifdef CONFIG_OMAP2_DSS_DPI dpi_init_platform_driver, #endif @@ -522,15 +525,15 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = { #ifdef CONFIG_OMAP2_DSS_VENC venc_init_platform_driver, #endif -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_init_platform_driver, -#endif #ifdef CONFIG_OMAP4_DSS_HDMI hdmi_init_platform_driver, #endif }; static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { +#ifdef CONFIG_OMAP2_DSS_DSI + dsi_uninit_platform_driver, +#endif #ifdef CONFIG_OMAP2_DSS_DPI dpi_uninit_platform_driver, #endif @@ -543,9 +546,6 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { #ifdef CONFIG_OMAP2_DSS_VENC venc_uninit_platform_driver, #endif -#ifdef CONFIG_OMAP2_DSS_DSI - dsi_uninit_platform_driver, -#endif #ifdef CONFIG_OMAP4_DSS_HDMI hdmi_uninit_platform_driver, #endif From b7f1fe541b01f6edaff0a5dd48027de6ac711ab6 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 12 Oct 2012 15:21:44 +0300 Subject: [PATCH 2/9] OMAPDSS: DSI: skip odd dividers when pck >= 100MHz The DSI PLL and HSDivider can be used to generate the pixel clock for LCD overlay manager, which then goes to DPI output. On the DPI output pin the voltage of the signal is shifted from the OMAP's internal minimal voltage to 1.8V range. The shifting is not instant, and the higher the clock frequency, the less time there is to shift the signal to nominal voltage. If the HSDivider's divider is greater than one and odd, the resulting pixel clock does not have 50% duty cycle. For example, with a divider of 3, the duty cycle is 33%. When combining high frequency (in the area of 140MHz+) and non-50% duty cycle, it has been observed the the shifter does not have enough time to shift the voltage enough, and this leads to bad signal which is rejected by monitors. As a workaround this patch makes the divider calculation skip all odd dividers when the required pixel clock is over 100MHz. The limit of 100MHz is a guesstimate. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 2ba505b33153..ea5c6603a51d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1386,6 +1386,11 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, cur.dsi_pll_hsdiv_dispc_clk = cur.clkin4ddr / cur.regm_dispc; + if (cur.regm_dispc > 1 && + cur.regm_dispc % 2 != 0 && + req_pck >= 1000000) + continue; + /* this will narrow down the search a bit, * but still give pixclocks below what was * requested */ From 7a98786caa18eaa8a5e61382a575f0b6c8e81c01 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 12 Oct 2012 16:27:28 +0300 Subject: [PATCH 3/9] OMAPDSS: DSI: workaround for HSDiv problem It looks like on many OMAP versions powers for both HSClk and HSDiv to be enabled to have a functional HSDiv. This patch fixes the issue by forcing both powers on. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ea5c6603a51d..e773f44b523d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1741,6 +1741,12 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, DSSDBG("PLL init\n"); + /* + * It seems that on many OMAPs we need to enable both to have a + * functional HSDivider. + */ + enable_hsclk = enable_hsdiv = true; + if (dsi->vdds_dsi_reg == NULL) { struct regulator *vdds_dsi; From 930b027eb41e31e86618ecd06cf4acf1e44c136b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 15 Oct 2012 13:27:04 +0300 Subject: [PATCH 4/9] OMAPDSS: add dss_calc_clock_rates() back dss_calc_clock_rates() was removed earlier as it was not used, but it is needed for DSI PLL calculations, so this patch adds it back. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 23 +++++++++++++++++++++++ drivers/video/omap2/dss/dss.h | 1 + 2 files changed, 24 insertions(+) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 456118beb1f8..d40653bf7a6c 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -432,6 +432,29 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel) } } +/* calculate clock rates using dividers in cinfo */ +int dss_calc_clock_rates(struct dss_clock_info *cinfo) +{ + if (dss.dpll4_m4_ck) { + unsigned long prate; + + if (cinfo->fck_div > dss.feat->fck_div_max || + cinfo->fck_div == 0) + return -EINVAL; + + prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); + + cinfo->fck = prate / cinfo->fck_div * + dss.feat->dss_fck_multiplier; + } else { + if (cinfo->fck_div != 0) + return -EINVAL; + cinfo->fck = clk_get_rate(dss.dss_clk); + } + + return 0; +} + int dss_set_clock_div(struct dss_clock_info *cinfo) { if (dss.dpll4_m4_ck) { diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index ff7a55b54b8e..e637f8d9dcf3 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -296,6 +296,7 @@ void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); unsigned long dss_get_dpll4_rate(void); +int dss_calc_clock_rates(struct dss_clock_info *cinfo); int dss_set_clock_div(struct dss_clock_info *cinfo); int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, struct dispc_clock_info *dispc_cinfo); From 13a1a2b2a68d00d8d81417606571e004e10f6d91 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 22 Oct 2012 16:35:41 +0300 Subject: [PATCH 5/9] OMAPDSS: setup default dss fck We don't currently set the dss fck when starting up. This is not a problem, as we setup the fck later when configuring the pixel clocks. Or this is how it was for omap2, for the rest of the omaps this may not be so. For DSI, HDMI and also for DPI when using DSI PLL, we don't need to change the dss fck, and thus it may be left unconfigured. Usually the dss fck is already setup fine by default, but we can't trust this. This patch sets the dss fck to maximum at probe time. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dss.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index d40653bf7a6c..844bb1fda911 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -485,6 +485,36 @@ unsigned long dss_get_dpll4_rate(void) return 0; } +static int dss_setup_default_clock(void) +{ + unsigned long max_dss_fck, prate; + unsigned fck_div; + struct dss_clock_info dss_cinfo = { 0 }; + int r; + + if (dss.dpll4_m4_ck == NULL) + return 0; + + max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); + + prate = dss_get_dpll4_rate(); + + fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, + max_dss_fck); + + dss_cinfo.fck_div = fck_div; + + r = dss_calc_clock_rates(&dss_cinfo); + if (r) + return r; + + r = dss_set_clock_div(&dss_cinfo); + if (r) + return r; + + return 0; +} + int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, struct dispc_clock_info *dispc_cinfo) { @@ -892,6 +922,10 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) if (r) return r; + r = dss_setup_default_clock(); + if (r) + goto err_setup_clocks; + pm_runtime_enable(&pdev->dev); r = dss_runtime_get(); @@ -924,6 +958,7 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) err_runtime_get: pm_runtime_disable(&pdev->dev); +err_setup_clocks: dss_put_clocks(); return r; } From a5b8399fb6866be6ca065d8ab5eb7d8775d0ad26 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 22 Oct 2012 16:58:36 +0300 Subject: [PATCH 6/9] OMAPDSS: hide dss_select_dispc_clk_source() dss.c currently exposes functions to configure the dispc source clock and lcd source clock. There are configured separately from the output drivers. However, there is no safe way for the output drivers to handle dispc clock, as it's shared between the outputs. Thus, if, say, the DSI driver sets up DSI PLL and configures both the dispc and lcd clock sources to that DSI PLL, the resulting dispc clock could be too low for, say, HDMI. Thus the output drivers should really only be concerned about the lcd clock, which is what the output drivers actually use. There's lot to do to clean up the dss clock handling, but this patch takes one step forward and removes the use of dss_select_dispc_clk_source() from the output drivers. After this patch, the output drivers only configure the lcd source clock. On omap4+ the dispc src clock is never changed from the default PRCM source. On omap3, where the dispc and lcd clocks are actually the same, setting the lcd clock source sets the dispc clock source. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 6 ++++-- drivers/video/omap2/dss/dsi.c | 3 --- drivers/video/omap2/dss/dss.c | 8 ++++++-- drivers/video/omap2/dss/dss.h | 1 - drivers/video/omap2/dss/hdmi.c | 8 -------- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 11d64b09cffe..8b9be0d3f420 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -77,6 +77,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, unsigned long pck_req, unsigned long *fck, int *lck_div, int *pck_div) { + struct omap_overlay_manager *mgr = dssdev->output->manager; struct dsi_clock_info dsi_cinfo; struct dispc_clock_info dispc_cinfo; int r; @@ -90,7 +91,8 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, if (r) return r; - dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); + dss_select_lcd_clk_source(mgr->id, + dssdev->clocks.dispc.channel.lcd_clk_src); dpi.mgr_config.clock_info = dispc_cinfo; @@ -272,7 +274,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) dss_mgr_disable(mgr); if (dpi_use_dsi_pll(dssdev)) { - dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); + dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); dsi_pll_uninit(dpi.dsidev, true); dsi_runtime_put(dpi.dsidev); } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e773f44b523d..d9797da39e69 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4720,7 +4720,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) if (r) goto err1; - dss_select_dispc_clk_source(dssdev->clocks.dispc.dispc_fclk_src); dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); dss_select_lcd_clk_source(mgr->id, dssdev->clocks.dispc.channel.lcd_clk_src); @@ -4755,7 +4754,6 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) err3: dsi_cio_uninit(dsidev); err2: - dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); @@ -4782,7 +4780,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, dsi_vc_enable(dsidev, 2, 0); dsi_vc_enable(dsidev, 3, 0); - dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); dsi_cio_uninit(dsidev); diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 844bb1fda911..df3d89a8c8a9 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -304,7 +304,7 @@ static void dss_dump_regs(struct seq_file *s) #undef DUMPREG } -void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) +static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) { struct platform_device *dsidev; int b; @@ -375,8 +375,10 @@ void dss_select_lcd_clk_source(enum omap_channel channel, struct platform_device *dsidev; int b, ix, pos; - if (!dss_has_feature(FEAT_LCD_CLK_SRC)) + if (!dss_has_feature(FEAT_LCD_CLK_SRC)) { + dss_select_dispc_clk_source(clk_src); return; + } switch (clk_src) { case OMAP_DSS_CLK_SRC_FCK: @@ -935,6 +937,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev) /* Select DPLL */ REG_FLD_MOD(DSS_CONTROL, 0, 0, 0); + dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); + #ifdef CONFIG_OMAP2_DSS_VENC REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */ REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */ diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index e637f8d9dcf3..84a7f6a2bfc4 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -283,7 +283,6 @@ void dss_sdi_init(int datapairs); int dss_sdi_enable(void); void dss_sdi_disable(void); -void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src); void dss_select_dsi_clk_source(int dsi_module, enum omap_dss_clk_source clk_src); void dss_select_lcd_clk_source(enum omap_channel channel, diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 2aada9db0a04..a43ac3f2a48c 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -528,14 +528,6 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev) /* 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: From 8a3db406f5046dd14dff0e78cea0ba03efec3668 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 22 Oct 2012 16:03:39 +0300 Subject: [PATCH 7/9] OMAPDSS: DPI: use dpi.dsidev to see whether to use dsi pll Instead of using dpi_use_dsi_pll() to check if dsi pll is to be used, we can just check if dpi.dsidev != NULL. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 8b9be0d3f420..ca5f49c44ece 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) unsigned long pck; int r = 0; - if (dpi_use_dsi_pll(dssdev)) + if (dpi.dsidev) r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck, &lck_div, &pck_div); else @@ -216,7 +216,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) if (r) goto err_src_sel; - if (dpi_use_dsi_pll(dssdev)) { + if (dpi.dsidev) { r = dsi_runtime_get(dpi.dsidev); if (r) goto err_get_dsi; @@ -244,10 +244,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) err_mgr_enable: err_set_mode: - if (dpi_use_dsi_pll(dssdev)) + if (dpi.dsidev) dsi_pll_uninit(dpi.dsidev, true); err_dsi_pll_init: - if (dpi_use_dsi_pll(dssdev)) + if (dpi.dsidev) dsi_runtime_put(dpi.dsidev); err_get_dsi: err_src_sel: @@ -273,7 +273,7 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) dss_mgr_disable(mgr); - if (dpi_use_dsi_pll(dssdev)) { + if (dpi.dsidev) { dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); dsi_pll_uninit(dpi.dsidev, true); dsi_runtime_put(dpi.dsidev); @@ -319,7 +319,7 @@ int dpi_check_timings(struct omap_dss_device *dssdev, if (timings->pixel_clock == 0) return -EINVAL; - if (dpi_use_dsi_pll(dssdev)) { + if (dpi.dsidev) { struct dsi_clock_info dsi_cinfo; r = dsi_pll_calc_clock_div_pck(dpi.dsidev, timings->pixel_clock * 1000, From 6061675b3fc83d8d190b87b54f04f0c89f605149 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 30 Oct 2012 12:57:43 +0200 Subject: [PATCH 8/9] OMAPDSS: DPI: verify if DSI PLL is operational The SoCs that have DSI module should have a working DSI PLL. However, some rare boards have not connected the powers to the DSI PLL. This patch adds a function that tries to power up the DSI PLL, and reports if that doesn't succeed. DPI uses this function to fall back to PRCM clocks if DSI PLL doesn't work. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index ca5f49c44ece..6baeb04e60cc 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -361,6 +361,28 @@ void omapdss_dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) } EXPORT_SYMBOL(omapdss_dpi_set_data_lines); +static int __init dpi_verify_dsi_pll(struct platform_device *dsidev) +{ + int r; + + /* do initial setup with the PLL to see if it is operational */ + + r = dsi_runtime_get(dsidev); + if (r) + return r; + + r = dsi_pll_init(dsidev, 0, 1); + if (r) { + dsi_runtime_put(dsidev); + return r; + } + + dsi_pll_uninit(dsidev, true); + dsi_runtime_put(dsidev); + + return 0; +} + static int __init dpi_init_display(struct omap_dss_device *dssdev) { DSSDBG("init_display\n"); @@ -383,6 +405,11 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev) enum omap_dss_clk_source dispc_fclk_src = dssdev->clocks.dispc.dispc_fclk_src; dpi.dsidev = dpi_get_dsidev(dispc_fclk_src); + + if (dpi_verify_dsi_pll(dpi.dsidev)) { + dpi.dsidev = NULL; + DSSWARN("DSI PLL not operational\n"); + } } return 0; From 0e8276ef75f5c7811b038d1d23b2b42c16efc5ac Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 22 Oct 2012 16:12:58 +0300 Subject: [PATCH 9/9] OMAPDSS: DPI: always use DSI PLL if available We currently get the decision whether to use PRCM or DSI PLL clock for DPI from the board file. This is not a good way to handle it, and it won't work with device tree. This patch changes DPI to always use DSI PLL if it's available. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 64 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 6baeb04e60cc..1e103b3135b9 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -49,28 +49,30 @@ static struct { struct omap_dss_output output; } dpi; -static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) +static struct platform_device *dpi_get_dsidev(enum omap_channel channel) { - int dsi_module; - - dsi_module = clk == OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC ? 0 : 1; - - return dsi_get_dsidev_from_id(dsi_module); + switch (channel) { + case OMAP_DSS_CHANNEL_LCD: + return dsi_get_dsidev_from_id(0); + case OMAP_DSS_CHANNEL_LCD2: + return dsi_get_dsidev_from_id(1); + default: + return NULL; + } } -static bool dpi_use_dsi_pll(struct omap_dss_device *dssdev) +static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel) { - if (dssdev->clocks.dispc.dispc_fclk_src == - OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC || - dssdev->clocks.dispc.dispc_fclk_src == - OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC || - dssdev->clocks.dispc.channel.lcd_clk_src == - OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC || - dssdev->clocks.dispc.channel.lcd_clk_src == - OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC) - return true; - else - return false; + switch (channel) { + case OMAP_DSS_CHANNEL_LCD: + return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC; + case OMAP_DSS_CHANNEL_LCD2: + return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; + default: + /* this shouldn't happen */ + WARN_ON(1); + return OMAP_DSS_CLK_SRC_FCK; + } } static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, @@ -92,7 +94,7 @@ static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, return r; dss_select_lcd_clk_source(mgr->id, - dssdev->clocks.dispc.channel.lcd_clk_src); + dpi_get_alt_clk_src(mgr->id)); dpi.mgr_config.clock_info = dispc_cinfo; @@ -385,6 +387,8 @@ static int __init dpi_verify_dsi_pll(struct platform_device *dsidev) static int __init 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) && @@ -401,17 +405,23 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev) dpi.vdds_dsi_reg = vdds_dsi; } - if (dpi_use_dsi_pll(dssdev)) { - enum omap_dss_clk_source dispc_fclk_src = - dssdev->clocks.dispc.dispc_fclk_src; - dpi.dsidev = dpi_get_dsidev(dispc_fclk_src); + /* + * XXX We shouldn't need dssdev->channel for this. The dsi pll clock + * source for DPI is SoC integration detail, not something that should + * be configured in the dssdev + */ + dsidev = dpi_get_dsidev(dssdev->channel); - if (dpi_verify_dsi_pll(dpi.dsidev)) { - dpi.dsidev = NULL; - DSSWARN("DSI PLL not operational\n"); - } + if (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; }