summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.c68
-rw-r--r--drivers/video/fbdev/msm/mdss_dsi.h32
2 files changed, 77 insertions, 23 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c
index ceb25b1224bc..0012c00a9067 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.c
+++ b/drivers/video/fbdev/msm/mdss_dsi.c
@@ -59,7 +59,29 @@ static void mdss_dsi_config_clk_src(struct platform_device *pdev)
return;
}
- if (!mdss_dsi_is_hw_config_dual(sdata)) {
+ if (mdss_dsi_is_pll_src_default(sdata)) {
+ /*
+ * Default Mapping:
+ * 1. dual-dsi/single-dsi:
+ * DSI0 <--> PLL0
+ * DSI1 <--> PLL1
+ * 2. split-dsi:
+ * DSI0 <--> PLL0
+ * DSI1 <--> PLL0
+ */
+ sdata->byte0_parent = sdata->ext_byte0_clk;
+ sdata->pixel0_parent = sdata->ext_pixel0_clk;
+
+ if (mdss_dsi_is_hw_config_split(sdata)) {
+ sdata->byte1_parent = sdata->byte0_parent;
+ sdata->pixel1_parent = sdata->pixel0_parent;
+ } else {
+ sdata->byte1_parent = sdata->ext_byte1_clk;
+ sdata->pixel1_parent = sdata->ext_pixel1_clk;
+ }
+ pr_debug("%s: default: DSI0 <--> PLL0, DSI1 <--> %s", __func__,
+ mdss_dsi_is_hw_config_split(sdata) ? "PLL0" : "PLL1");
+ } else {
/*
* For split-dsi and single-dsi use cases, map the PLL source
* based on the pll source configuration. It is possible that
@@ -72,25 +94,13 @@ static void mdss_dsi_config_clk_src(struct platform_device *pdev)
pr_debug("%s: single source: PLL0", __func__);
sdata->byte0_parent = sdata->ext_byte0_clk;
sdata->pixel0_parent = sdata->ext_pixel0_clk;
- } else {
+ } else if (mdss_dsi_is_pll_src_pll1(sdata)) {
pr_debug("%s: single source: PLL1", __func__);
sdata->byte0_parent = sdata->ext_byte1_clk;
sdata->pixel0_parent = sdata->ext_pixel1_clk;
}
sdata->byte1_parent = sdata->byte0_parent;
sdata->pixel1_parent = sdata->pixel0_parent;
- } else {
- /*
- * For dual-dsi use cases, map:
- * DSI0 <--> PLL0
- * DSI1 <--> PLL1
- */
- pr_debug("%s: dual-dsi: DSI0 <--> PLL0, DSI1 <--> PLL1",
- __func__);
- sdata->byte0_parent = sdata->ext_byte0_clk;
- sdata->byte1_parent = sdata->ext_byte1_clk;
- sdata->pixel0_parent = sdata->ext_pixel0_clk;
- sdata->pixel1_parent = sdata->ext_pixel1_clk;
}
return;
@@ -2284,6 +2294,12 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev)
disable_irq(gpio_to_irq(ctrl_pdata->disp_te_gpio));
}
pr_debug("%s: Dsi Ctrl->%d initialized\n", __func__, index);
+
+ if (index == 0)
+ ctrl_pdata->shared_data->dsi0_active = true;
+ else
+ ctrl_pdata->shared_data->dsi1_active = true;
+
return 0;
error_pan_node:
@@ -2499,7 +2515,7 @@ static void mdss_dsi_parse_pll_src_cfg(struct platform_device *pdev)
const char *data;
struct dsi_shared_data *sdata = mdss_dsi_res->shared_data;
- sdata->pll_src_config = PLL_SRC_0;
+ sdata->pll_src_config = PLL_SRC_DEFAULT;
data = of_get_property(pdev->dev.of_node, "pll-src-config", NULL);
if (data) {
if (!strcmp(data, "PLL0"))
@@ -2507,11 +2523,10 @@ static void mdss_dsi_parse_pll_src_cfg(struct platform_device *pdev)
else if (!strcmp(data, "PLL1"))
sdata->pll_src_config = PLL_SRC_1;
else
- pr_err("%s: invalid pll src config %s. Using PLL_SRC_0 as default\n",
+ pr_err("%s: invalid pll src config %s\n",
__func__, data);
} else {
- pr_debug("%s: PLL src config not present. Using PLL0 by default\n",
- __func__);
+ pr_debug("%s: PLL src config not specified\n", __func__);
}
pr_debug("%s: pll_src_config = %d", __func__, sdata->pll_src_config);
@@ -2531,7 +2546,6 @@ static int mdss_dsi_validate_pll_src_config(struct dsi_shared_data *sdata)
* - For single dsi, it is not possible to source the clocks for
* DSI0 from PLL1.
*/
-
if (mdss_dsi_is_hw_config_split(sdata) &&
mdss_dsi_is_pll_src_pll1(sdata)) {
pr_err("%s: unsupported PLL config: using PLL1 for split-dsi\n",
@@ -2540,7 +2554,21 @@ static int mdss_dsi_validate_pll_src_config(struct dsi_shared_data *sdata)
goto error;
}
- /* todo: enforce remaining checks */
+ if (mdss_dsi_is_hw_config_dual(sdata) &&
+ !mdss_dsi_is_pll_src_default(sdata)) {
+ pr_debug("%s: pll src config not applicable for dual-dsi\n",
+ __func__);
+ sdata->pll_src_config = PLL_SRC_DEFAULT;
+ }
+
+ if (mdss_dsi_is_hw_config_single(sdata) &&
+ mdss_dsi_is_dsi0_active(sdata) &&
+ mdss_dsi_is_pll_src_pll1(sdata)) {
+ pr_err("%s: unsupported PLL config: using PLL1 for DSI1\n",
+ __func__);
+ rc = -EINVAL;
+ goto error;
+ }
error:
return rc;
diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h
index 05148337e762..2600590a24af 100644
--- a/drivers/video/fbdev/msm/mdss_dsi.h
+++ b/drivers/video/fbdev/msm/mdss_dsi.h
@@ -228,6 +228,8 @@ struct dsi_shared_data {
bool timing_db_mode;
bool cmd_clk_ln_recovery_en;
+ bool dsi0_active;
+ bool dsi1_active;
/* DSI bus clocks */
struct clk *mdp_core_clk;
@@ -284,6 +286,7 @@ enum mdss_dsi_hw_config {
* @PLL_SRC_1: The link clocks are sourced out of PLL1.
*/
enum mdss_dsi_pll_src_config {
+ PLL_SRC_DEFAULT,
PLL_SRC_0,
PLL_SRC_1,
};
@@ -594,19 +597,32 @@ static inline bool mdss_dsi_is_hw_config_dual(struct dsi_shared_data *sdata)
return mdss_dsi_get_hw_config(sdata) == DUAL_DSI;
}
-static inline u32 mdss_dsi_get_pll_src_config(struct dsi_shared_data *sdata)
+static inline bool mdss_dsi_get_pll_src_config(struct dsi_shared_data *sdata)
{
return sdata->pll_src_config;
}
/*
+ * mdss_dsi_is_pll_src_default: Check if the DSI device uses default PLL src
+ * For single-dsi and dual-dsi configuration, PLL source need not be
+ * explicitly specified. In this case, the default PLL source configuration
+ * is assumed.
+ *
+ * @sdata: pointer to DSI shared data structure
+ */
+static inline bool mdss_dsi_is_pll_src_default(struct dsi_shared_data *sdata)
+{
+ return sdata->pll_src_config == PLL_SRC_DEFAULT;
+}
+
+/*
* mdss_dsi_is_pll_src_pll0: Check if the PLL source for a DSI device is PLL0
* The function is only valid if the DSI configuration is single/split DSI.
* Not valid for dual DSI configuration.
*
* @sdata: pointer to DSI shared data structure
*/
-static inline u32 mdss_dsi_is_pll_src_pll0(struct dsi_shared_data *sdata)
+static inline bool mdss_dsi_is_pll_src_pll0(struct dsi_shared_data *sdata)
{
return sdata->pll_src_config == PLL_SRC_0;
}
@@ -618,11 +634,21 @@ static inline u32 mdss_dsi_is_pll_src_pll0(struct dsi_shared_data *sdata)
*
* @sdata: pointer to DSI shared data structure
*/
-static inline u32 mdss_dsi_is_pll_src_pll1(struct dsi_shared_data *sdata)
+static inline bool mdss_dsi_is_pll_src_pll1(struct dsi_shared_data *sdata)
{
return sdata->pll_src_config == PLL_SRC_1;
}
+static inline bool mdss_dsi_is_dsi0_active(struct dsi_shared_data *sdata)
+{
+ return sdata->dsi0_active;
+}
+
+static inline bool mdss_dsi_is_dsi1_active(struct dsi_shared_data *sdata)
+{
+ return sdata->dsi1_active;
+}
+
static inline bool mdss_dsi_sync_wait_enable(struct mdss_dsi_ctrl_pdata *ctrl)
{
return ctrl->cmd_sync_wait_broadcast;