summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorWayne Zou <b36644@freescale.com>2013-02-25 16:35:09 +0800
committerWayne Zou <b36644@freescale.com>2013-02-27 09:30:56 +0800
commit2fb57cd27a9ce4facacd84687cf534fc0194dbe9 (patch)
tree03503f353d739c3b7d07928928758de77317ecf3 /drivers/video
parent85b80e70a92ad66b86dc0a1636c59145b9fbf39c (diff)
ENGR00251830 LDB: Fix the bug of LDB separate mode for dual LVDS display
Fix the bug of LDB separate mode for dual LVDS display on i.mx6. For 'ldb=sep0' option on kernel command line, it means that LVDS0 is the primary display. While 'ldb=sep1' means that LVDS1 is the primary display. For LDB separate mode, the Display Interface(disp_id) should be configured differently on the platform layer. That is, IPU DI0 to LVDS1 or IPU DI1 to LVDS0 configuration should be avoided. Signed-off-by: Wayne Zou <b36644@freescale.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/mxc/ldb.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.c
index 695ff3389fce..19de5c541fdd 100644
--- a/drivers/video/mxc/ldb.c
+++ b/drivers/video/mxc/ldb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2012-2013 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -238,6 +238,8 @@ static int ldb_disp_setup(struct mxc_dispdrv_handle *disp, struct fb_info *fbi)
val = readl(ldb->control_reg);
val |= ldb->setting[setting_idx].ch_val;
writel(val, ldb->control_reg);
+ dev_dbg(&ldb->pdev->dev, "LDB setup, control reg:0x%x\n",
+ readl(ldb->control_reg));
/* vsync setup */
reg = readl(ldb->control_reg);
@@ -321,6 +323,9 @@ int ldb_fb_event(struct notifier_block *nb, unsigned long val, void *v)
data = readl(ldb->control_reg);
data &= ~ldb->setting[index].ch_mask;
writel(data, ldb->control_reg);
+ dev_dbg(&ldb->pdev->dev,
+ "LDB blank, control reg:0x%x\n",
+ readl(ldb->control_reg));
}
}
break;
@@ -411,6 +416,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
uint32_t base_addr;
uint32_t reg, setting_idx;
uint32_t ch_mask = 0, ch_val = 0;
+ uint32_t ipu_id, disp_id;
/* if input format not valid, make RGB666 as default*/
if (!valid_mode(setting->if_fmt)) {
@@ -479,6 +485,28 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
plat_data->disp_id, ret, ret);
plat_data->disp_id = ret;
}
+ } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))
+ && (cpu_is_mx6q() || cpu_is_mx6dl())) {
+ if (plat_data->disp_id == plat_data->sec_disp_id) {
+ dev_err(&ldb->pdev->dev,
+ "For LVDS separate mode,"
+ "two DIs should be different!\n");
+ return -EINVAL;
+ }
+
+ if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1))
+ || ((plat_data->disp_id) &&
+ (ldb->mode == LDB_SEP0))) {
+ dev_dbg(&ldb->pdev->dev,
+ "LVDS separate mode:"
+ "swap DI configuration!\n");
+ ipu_id = plat_data->ipu_id;
+ disp_id = plat_data->disp_id;
+ plat_data->ipu_id = plat_data->sec_ipu_id;
+ plat_data->disp_id = plat_data->sec_disp_id;
+ plat_data->sec_ipu_id = ipu_id;
+ plat_data->sec_disp_id = disp_id;
+ }
}
if (ldb->mode == LDB_SPL_DI0) {
@@ -679,19 +707,8 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
ldb->setting[setting_idx].ch_mask = ch_mask;
ldb->setting[setting_idx].ch_val = ch_val;
- if (cpu_is_mx6q() || cpu_is_mx6dl()) {
- if ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)) {
- reg = readl(ldb->control_reg);
- reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
- reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI1;
- writel(reg, ldb->control_reg);
- ldb->setting[setting_idx].ch_mask = setting->disp_id ?
- LDB_CH1_MODE_MASK : LDB_CH0_MODE_MASK;
- ldb->setting[setting_idx].ch_val = setting->disp_id ?
- LDB_CH1_MODE_EN_TO_DI1 : LDB_CH0_MODE_EN_TO_DI0;
- }
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb);
- }
/*
* ldb_di0_clk -> ipux_di0_clk