summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorWayne Zou <b36644@freescale.com>2011-12-01 19:56:27 +0800
committerJason Liu <r64343@freescale.com>2012-01-09 21:09:22 +0800
commit66bc92e9bf07326c0b1a64bcb96954e7adc8545b (patch)
treeee6fc5428e8ca89ad9990061f5b9dd2f60a96b4a /drivers/video
parenta09b6069d2ea99fec9edb99e6b57b44388b2598b (diff)
ENGR00163669-3 mipi_dsi: Add blank/unblank support for mipi dsi display
mipi_dsi: Add blank/unblank support for mipi dsi display Signed-off-by: Wayne Zou <b36644@freescale.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/mxc/mipi_dsi.c183
-rw-r--r--drivers/video/mxc/mipi_dsi.h10
-rw-r--r--drivers/video/mxc/mxcfb_hx8369_wvga.c6
3 files changed, 127 insertions, 72 deletions
diff --git a/drivers/video/mxc/mipi_dsi.c b/drivers/video/mxc/mipi_dsi.c
index 757f65cd60e2..c236ee7434ec 100644
--- a/drivers/video/mxc/mipi_dsi.c
+++ b/drivers/video/mxc/mipi_dsi.c
@@ -50,6 +50,8 @@
#define PHY_HS2LP_MAXTIME (0x40)
#define PHY_STOP_WAIT_TIME (0x20)
#define DSI_CLKMGR_CFG_CLK_DIV (0x107)
+#define MIPI_MUX_CTRL(v) (((v) & 0x3) << 4)
+#define IOMUXC_GPR3_OFFSET (0xc)
#define MIPI_LCD_SLEEP_MODE_DELAY (120)
static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
@@ -95,7 +97,6 @@ static const struct _mipi_dsi_phy_pll_clk mipi_dsi_phy_pll_clk_table[] = {
{180, 0x24}, /* 160-180MHz */
{160, 0x04}, /* 150-160MHz */
};
-static int dsi_power_on;
static int valid_mode(int pixel_fmt)
{
@@ -119,20 +120,10 @@ static inline void mipi_dsi_write_register(struct mipi_dsi_info *mipi_dsi,
u32 reg, u32 val)
{
iowrite32(val, mipi_dsi->mmio_base + reg);
- msleep(1);
dev_dbg(&mipi_dsi->pdev->dev, "\t\twrite_reg:0x%02x, val:0x%08x.\n",
reg, val);
}
-static void mipi_dsi_dump_registers(struct mipi_dsi_info *mipi_dsi)
-{
- int i;
- u32 val;
-
- for (i = MIPI_DSI_VERSION; i <= MIPI_DSI_PHY_TST_CTRL1; i += 4)
- mipi_dsi_read_register(mipi_dsi, i, &val);
-}
-
int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
u8 data_type, const u32 *buf, int len)
{
@@ -200,7 +191,7 @@ int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
int read_len = 0;
if (!len) {
- mipi_dbg("%s,%d: error!\n", __func__, __LINE__);
+ mipi_dbg("%s, len = 0 invalid error!\n", __func__);
return -EINVAL;
}
@@ -387,11 +378,6 @@ static void mipi_dsi_enable_controller(struct mipi_dsi_info *mipi_dsi,
mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
mipi_dsi->dphy_pll_config);
-
- val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
- DSI_VID_MODE_CFG_EN_LP_MODE;
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
- dsi_power_on = 1;
} else {
mipi_dsi_dphy_init(mipi_dsi, DSI_PHY_CLK_INIT_COMMAND,
mipi_dsi->dphy_pll_config);
@@ -429,12 +415,44 @@ static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
return IRQ_HANDLED;
}
-static void mipi_dsi_power_on(struct mipi_dsi_info *mipi_dsi)
+static inline void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
+ bool cmd_mode)
+{
+ u32 val;
+
+ if (cmd_mode) {
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_RESET);
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
+ val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, 0);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_POWERUP);
+ } else {
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_RESET);
+ /* Disable Command mode when tranfering video data */
+ mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
+ val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
+ val = DSI_VID_MODE_CFG_EN | DSI_VID_MODE_CFG_EN_BURSTMODE |
+ DSI_VID_MODE_CFG_EN_LP_MODE;
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PWR_UP,
+ DSI_PWRUP_POWERUP);
+ mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
+ DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
+ }
+}
+
+static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
{
int err;
- u32 val;
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
- if (!dsi_power_on) {
+ if (!mipi_dsi->dsi_power_on) {
+ clk_enable(mipi_dsi->dphy_clk);
mipi_dsi_enable_controller(mipi_dsi, false);
err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
NULL, 0);
@@ -443,46 +461,38 @@ static void mipi_dsi_power_on(struct mipi_dsi_info *mipi_dsi)
"MIPI DSI DCS Command sleep-in error!\n");
}
msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+ mipi_dsi_set_mode(mipi_dsi, false);
+ mipi_dsi->dsi_power_on = 1;
}
- dsi_power_on = 1;
- /* Disable Command mode when tranfering video data */
- mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
- val &= ~MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
-
- mipi_dsi_read_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, &val);
- val |= DSI_VID_MODE_CFG_EN;
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
- DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
-
- mipi_dsi_dump_registers(mipi_dsi);
+ return 0;
}
-static void mipi_dsi_power_off(struct mipi_dsi_info *mipi_dsi)
+void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
{
int err;
- u32 val;
-
- if (dsi_power_on) {
- mipi_dsi_read_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, &val);
- val |= MIPI_DSI_CMD_MODE_CFG_EN_CMD_MODE;
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_CMD_MODE_CFG, val);
- mipi_dsi_read_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, &val);
- val &= ~DSI_VID_MODE_CFG_EN;
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_VID_MODE_CFG, val);
+ struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
+ if (mipi_dsi->dsi_power_on) {
+ mipi_dsi_set_mode(mipi_dsi, true);
err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
NULL, 0);
if (err) {
dev_err(&mipi_dsi->pdev->dev,
"MIPI DSI DCS Command display on error!\n");
}
+ /* To allow time for the supply voltages
+ * and clock circuits to stabilize.
+ */
+ msleep(5);
+ /* video stream timing on */
+ mipi_dsi_set_mode(mipi_dsi, false);
msleep(MIPI_LCD_SLEEP_MODE_DELAY);
+ mipi_dsi_set_mode(mipi_dsi, true);
mipi_dsi_disable_controller(mipi_dsi);
- dsi_power_on = 0;
+ mipi_dsi->dsi_power_on = 0;
+ clk_disable(mipi_dsi->dphy_clk);
}
}
@@ -550,16 +560,6 @@ static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
dev_dbg(dev, "dphy_pll_config:0x%x.\n", mipi_dsi->dphy_pll_config);
mipi_dsi_enable_controller(mipi_dsi, true);
-
- err = mipi_dsi->lcd_callback->mipi_lcd_setup(mipi_dsi);
- if (err < 0) {
- dev_err(dev, "failed to init mipi lcd.\n");
- return err;
- }
-
- mipi_dsi_write_register(mipi_dsi, MIPI_DSI_PHY_IF_CTRL,
- DSI_PHY_IF_CTRL_TX_REQ_CLK_HS);
-
return 0;
}
@@ -569,16 +569,36 @@ static int mipi_dsi_fb_event(struct notifier_block *nb,
struct mipi_dsi_info *mipi_dsi =
container_of(nb, struct mipi_dsi_info, nb);
struct fb_event *fbevent = data;
+ struct fb_info *fbi = fbevent->info;
+ char *id_di[] = {
+ "DISP4 BG",
+ "DISP4 BG - DI1",
+ };
+ char *id;
+ int err;
- switch (event) {
- case FB_EVENT_FB_REGISTERED:
- break;
+ id = id_di[mipi_dsi->disp_id];
+ *(id + 4) = mipi_dsi->ipu_id ? '4' : '3';
+ if (strcmp(id_di[mipi_dsi->disp_id], fbi->fix.id))
+ return 0;
+ switch (event) {
case FB_EVENT_BLANK:
- if (*((int *)fbevent->data) == FB_BLANK_UNBLANK)
- mipi_dsi_power_on(mipi_dsi);
- else
- mipi_dsi_power_off(mipi_dsi);
+ if (*((int *)fbevent->data) == FB_BLANK_UNBLANK) {
+ if (!mipi_dsi->lcd_inited) {
+ err = mipi_dsi->lcd_callback->mipi_lcd_setup(
+ mipi_dsi);
+ if (err < 0) {
+ dev_err(&mipi_dsi->pdev->dev,
+ "failed to init mipi lcd.");
+ return err;
+ }
+ mipi_dsi_set_mode(mipi_dsi, false);
+ mipi_dsi->dsi_power_on = 1;
+ mipi_dsi->lcd_inited = 1;
+ }
+ mipi_dsi_power_on(mipi_dsi->disp_mipi);
+ }
break;
default:
@@ -592,6 +612,8 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
struct mxc_dispdrv_setting *setting)
{
int err;
+ void __iomem *reg_base;
+ u32 val;
char dphy_clk[] = "mipi_pllref_clk";
struct resource *res;
struct resource *res_irq;
@@ -611,6 +633,9 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
return -EINVAL;
}
+ if ((1 != pdata->ipu_id) || (1 != pdata->disp_id))
+ dev_warn(dev, "only work bidirection mode on IPU1-DI1\n");
+
mipi_dsi->lcd_panel = kstrdup(pdata->lcd_panel, GFP_KERNEL);
if (!mipi_dsi->lcd_panel)
return -ENOMEM;
@@ -623,14 +648,14 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
res = platform_get_resource(mipi_dsi->pdev, IORESOURCE_MEM, 0);
if (!res) {
- mipi_dbg("%s,%d: error!\n", __func__, __LINE__);
+ dev_err(dev, "get platform resource 0 error\n");
return -ENODEV;
}
res = request_mem_region(res->start, resource_size(res),
mipi_dsi->pdev->name);
if (!res) {
- mipi_dbg("%s,%d: error!\n", __func__, __LINE__);
+ dev_err(dev, "request mem region error\n");
return -EBUSY;
}
mipi_dsi->mmio_base = ioremap(res->start, resource_size(res));
@@ -640,6 +665,24 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
goto err_ioremap;
}
+ res = platform_get_resource(mipi_dsi->pdev, IORESOURCE_MEM, 1);
+ if (!res) {
+ dev_err(dev, "get platform resource 1 error\n");
+ err = -ENODEV;
+ goto err_get_res1;
+ }
+
+ reg_base = ioremap(res->start, resource_size(res));
+ if (!reg_base) {
+ dev_err(dev, "Cannot map iomuxc registers\n");
+ err = -EIO;
+ goto err_ioremap_iomuxc;
+ }
+ val = ioread32(reg_base + IOMUXC_GPR3_OFFSET);
+ val |= MIPI_MUX_CTRL((pdata->ipu_id << 1) | (pdata->disp_id));
+ iowrite32(val, reg_base + IOMUXC_GPR3_OFFSET);
+ iounmap(reg_base);
+
res_irq = platform_get_resource(mipi_dsi->pdev, IORESOURCE_IRQ, 0);
if (!res_irq) {
dev_err(dev, "failed to acquire irq resource\n");
@@ -656,7 +699,7 @@ static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
}
err = clk_enable(mipi_dsi->dphy_clk);
if (err)
- mipi_dbg("%s,%d: error!\n", __func__, __LINE__);
+ dev_err(dev, "clk_enable error:%d!\n", err);
dev_dbg(dev, "got resources: regs %p, irq:%d\n",
mipi_dsi->mmio_base, mipi_dsi->irq);
@@ -799,6 +842,8 @@ err_ioreg:
clk_put(mipi_dsi->dphy_clk);
err_clk:
err_get_irq:
+err_get_res1:
+err_ioremap_iomuxc:
iounmap(mipi_dsi->mmio_base);
err_ioremap:
release_mem_region(res->start, resource_size(res));
@@ -816,7 +861,7 @@ static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
disable_irq(mipi_dsi->irq);
free_irq(mipi_dsi->irq, mipi_dsi);
- mipi_dsi_power_off(mipi_dsi);
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
fb_unregister_client(&mipi_dsi->nb);
if (mipi_dsi->bl)
backlight_device_unregister(mipi_dsi->bl);
@@ -826,7 +871,6 @@ static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
regulator_put(mipi_dsi->core_regulator);
if (mipi_dsi->io_regulator)
regulator_put(mipi_dsi->io_regulator);
- clk_disable(mipi_dsi->dphy_clk);
clk_put(mipi_dsi->dphy_clk);
iounmap(mipi_dsi->mmio_base);
release_mem_region(res->start, resource_size(res));
@@ -836,6 +880,8 @@ static struct mxc_dispdrv_driver mipi_dsi_drv = {
.name = DISPDRV_MIPI,
.init = mipi_dsi_disp_init,
.deinit = mipi_dsi_disp_deinit,
+ .enable = mipi_dsi_power_on,
+ .disable = mipi_dsi_power_off,
};
/**
@@ -861,7 +907,8 @@ static int mipi_dsi_probe(struct platform_device *pdev)
mipi_dsi->pdev = pdev;
mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
if (IS_ERR(mipi_dsi->disp_mipi)) {
- mipi_dbg("%s,%d: error!\n", __func__, __LINE__);
+ dev_err(&pdev->dev, "mxc_dispdrv_register error:%ld!\n",
+ PTR_ERR(mipi_dsi->disp_mipi));
ret = -ENOMEM;
goto register_failed;
}
@@ -882,7 +929,7 @@ static void mipi_dsi_shutdown(struct platform_device *pdev)
{
struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);
- mipi_dsi_power_off(mipi_dsi);
+ mipi_dsi_power_off(mipi_dsi->disp_mipi);
if (mipi_dsi->lcd_power)
mipi_dsi->lcd_power(false);
if (mipi_dsi->backlight_power)
diff --git a/drivers/video/mxc/mipi_dsi.h b/drivers/video/mxc/mipi_dsi.h
index 2dfa49fdc638..3e9c47d4e9dd 100644
--- a/drivers/video/mxc/mipi_dsi.h
+++ b/drivers/video/mxc/mipi_dsi.h
@@ -61,18 +61,20 @@ struct mipi_dsi_match_lcd {
/* driver private data */
struct mipi_dsi_info {
+ struct platform_device *pdev;
+ void __iomem *mmio_base;
+ int dsi_power_on;
+ int lcd_inited;
+ u32 dphy_pll_config;
int ipu_id;
int disp_id;
char *lcd_panel;
int irq;
- u32 dphy_pll_config;
struct clk *dphy_clk;
- void __iomem *mmio_base;
- struct platform_device *pdev;
struct mxc_dispdrv_handle *disp_mipi;
- struct notifier_block nb;
struct fb_videomode *mode;
struct mipi_lcd_config *lcd_config;
+ struct notifier_block nb;
/* board related power control */
struct backlight_device *bl;
struct regulator *io_regulator;
diff --git a/drivers/video/mxc/mxcfb_hx8369_wvga.c b/drivers/video/mxc/mxcfb_hx8369_wvga.c
index f9e5de4a4097..2d89aa0b1a5b 100644
--- a/drivers/video/mxc/mxcfb_hx8369_wvga.c
+++ b/drivers/video/mxc/mxcfb_hx8369_wvga.c
@@ -352,9 +352,15 @@ static int mipid_bl_get_brightness(struct backlight_device *bl)
return hx8369bl_brightness;
}
+static int mipi_bl_check_fb(struct backlight_device *bl, struct fb_info *fbi)
+{
+ return 0;
+}
+
static const struct backlight_ops mipid_lcd_bl_ops = {
.update_status = mipid_bl_update_status,
.get_brightness = mipid_bl_get_brightness,
+ .check_fb = mipi_bl_check_fb,
};
static int mipid_init_backlight(struct mipi_dsi_info *mipi_dsi)