From bf10a53765b4435a5349a92a5a51753902ed86f1 Mon Sep 17 00:00:00 2001 From: Hideki EIRAKU Date: Thu, 16 Aug 2012 19:13:20 +0900 Subject: [PATCH 01/20] fbdev: sh_mobile_lcdc: use dma_mmap_coherent fb_mmap() implemented in fbmem.c uses smem_start as the physical address of the frame buffer. In the sh_mobile_lcdc driver, the smem_start is a dma_addr_t that is not a physical address when IOMMU is enabled. dma_mmap_coherent() maps the address correctly. Signed-off-by: Hideki EIRAKU Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_lcdcfb.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 699487c287b2..bccfd7eff39b 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -1614,6 +1614,15 @@ static int sh_mobile_lcdc_overlay_blank(int blank, struct fb_info *info) return 1; } +static int +sh_mobile_lcdc_overlay_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct sh_mobile_lcdc_overlay *ovl = info->par; + + return dma_mmap_coherent(ovl->channel->lcdc->dev, vma, ovl->fb_mem, + ovl->dma_handle, ovl->fb_size); +} + static struct fb_ops sh_mobile_lcdc_overlay_ops = { .owner = THIS_MODULE, .fb_read = fb_sys_read, @@ -1626,6 +1635,7 @@ static struct fb_ops sh_mobile_lcdc_overlay_ops = { .fb_ioctl = sh_mobile_lcdc_overlay_ioctl, .fb_check_var = sh_mobile_lcdc_overlay_check_var, .fb_set_par = sh_mobile_lcdc_overlay_set_par, + .fb_mmap = sh_mobile_lcdc_overlay_mmap, }; static void @@ -2093,6 +2103,15 @@ static int sh_mobile_lcdc_blank(int blank, struct fb_info *info) return 0; } +static int +sh_mobile_lcdc_mmap(struct fb_info *info, struct vm_area_struct *vma) +{ + struct sh_mobile_lcdc_chan *ch = info->par; + + return dma_mmap_coherent(ch->lcdc->dev, vma, ch->fb_mem, + ch->dma_handle, ch->fb_size); +} + static struct fb_ops sh_mobile_lcdc_ops = { .owner = THIS_MODULE, .fb_setcolreg = sh_mobile_lcdc_setcolreg, @@ -2108,6 +2127,7 @@ static struct fb_ops sh_mobile_lcdc_ops = { .fb_release = sh_mobile_lcdc_release, .fb_check_var = sh_mobile_lcdc_check_var, .fb_set_par = sh_mobile_lcdc_set_par, + .fb_mmap = sh_mobile_lcdc_mmap, }; static void From 856e8dfe6efed7cf35bc6bf827f030a164bee083 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 13 Aug 2012 13:56:46 +0200 Subject: [PATCH 02/20] fbdev: sh_mobile_lcdc: Get display dimensions from the channel structure Get the display dimensions directly from the channel structure instead of recomputing them from the monitor specs or accessing the platform data. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_lcdcfb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index bccfd7eff39b..7375dbf08c78 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -586,8 +586,8 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch, * Just turn on, if we run a resume here, the * logo disappears. */ - info->var.width = monspec->max_x * 10; - info->var.height = monspec->max_y * 10; + info->var.width = ch->display.width; + info->var.height = ch->display.height; sh_mobile_lcdc_display_on(ch); } else { /* New monitor or have to wake up */ @@ -2248,8 +2248,8 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, */ var = &info->var; fb_videomode_to_var(var, mode); - var->width = ch->cfg->panel_cfg.width; - var->height = ch->cfg->panel_cfg.height; + var->width = ch->display.width; + var->height = ch->display.height; var->xres_virtual = ch->xres_virtual; var->yres_virtual = ch->yres_virtual; var->activate = FB_ACTIVATE_NOW; From 352d6138779e22c5340803d5a32fc332ad2e5e1d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 13 Aug 2012 13:56:46 +0200 Subject: [PATCH 03/20] fbdev: sh_mobile_lcdc: Rename mode argument to modes The sh_mobile_lcdc_channel_fb_init() mode argument is used to pass a list of modes, rename it to modes. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_lcdcfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 7375dbf08c78..82b53f7d11b9 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -2187,7 +2187,7 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch) static int __devinit sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, - const struct fb_videomode *mode, + const struct fb_videomode *modes, unsigned int num_modes) { struct sh_mobile_lcdc_priv *priv = ch->lcdc; @@ -2213,7 +2213,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, info->pseudo_palette = &ch->pseudo_palette; info->par = ch; - fb_videomode_to_modelist(mode, num_modes, &info->modelist); + fb_videomode_to_modelist(modes, num_modes, &info->modelist); ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0); if (ret < 0) { @@ -2247,7 +2247,7 @@ sh_mobile_lcdc_channel_fb_init(struct sh_mobile_lcdc_chan *ch, * default. */ var = &info->var; - fb_videomode_to_var(var, mode); + fb_videomode_to_var(var, modes); var->width = ch->display.width; var->height = ch->display.height; var->xres_virtual = ch->xres_virtual; From 0707330b337cec85d7b393303e82f0fad5dc4c00 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 13 Aug 2012 13:56:46 +0200 Subject: [PATCH 04/20] fbdev: sh_mobile_lcdc: Remove priv argument from channel and overlay init The channel and overlay init functions operate on a channel and an overlay, don't pass the priv parameter explicitly. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_lcdcfb.c | 35 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 82b53f7d11b9..c169581c3a72 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -2536,10 +2536,10 @@ static int __devinit sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan * } static int __devinit -sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv, - struct sh_mobile_lcdc_overlay *ovl) +sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_overlay *ovl) { const struct sh_mobile_lcdc_format_info *format; + struct device *dev = ovl->channel->lcdc->dev; int ret; if (ovl->cfg->fourcc == 0) @@ -2548,7 +2548,7 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv, /* Validate the format. */ format = sh_mobile_format_info(ovl->cfg->fourcc); if (format == NULL) { - dev_err(priv->dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc); + dev_err(dev, "Invalid FOURCC %08x\n", ovl->cfg->fourcc); return -EINVAL; } @@ -2576,10 +2576,10 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv, /* Allocate frame buffer memory. */ ovl->fb_size = ovl->cfg->max_xres * ovl->cfg->max_yres * format->bpp / 8 * 2; - ovl->fb_mem = dma_alloc_coherent(priv->dev, ovl->fb_size, - &ovl->dma_handle, GFP_KERNEL); + ovl->fb_mem = dma_alloc_coherent(dev, ovl->fb_size, &ovl->dma_handle, + GFP_KERNEL); if (!ovl->fb_mem) { - dev_err(priv->dev, "unable to allocate buffer\n"); + dev_err(dev, "unable to allocate buffer\n"); return -ENOMEM; } @@ -2591,11 +2591,11 @@ sh_mobile_lcdc_overlay_init(struct sh_mobile_lcdc_priv *priv, } static int __devinit -sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, - struct sh_mobile_lcdc_chan *ch) +sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch) { const struct sh_mobile_lcdc_format_info *format; const struct sh_mobile_lcdc_chan_cfg *cfg = ch->cfg; + struct device *dev = ch->lcdc->dev; const struct fb_videomode *max_mode; const struct fb_videomode *mode; unsigned int num_modes; @@ -2608,7 +2608,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, /* Validate the format. */ format = sh_mobile_format_info(cfg->fourcc); if (format == NULL) { - dev_err(priv->dev, "Invalid FOURCC %08x.\n", cfg->fourcc); + dev_err(dev, "Invalid FOURCC %08x.\n", cfg->fourcc); return -EINVAL; } @@ -2624,7 +2624,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, /* NV12/NV21 buffers must have even number of lines */ if ((cfg->fourcc == V4L2_PIX_FMT_NV12 || cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) { - dev_err(priv->dev, "yres must be multiple of 2 for " + dev_err(dev, "yres must be multiple of 2 for " "YCbCr420 mode.\n"); return -EINVAL; } @@ -2638,7 +2638,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, if (!max_size) max_size = MAX_XRES * MAX_YRES; else - dev_dbg(priv->dev, "Found largest videomode %ux%u\n", + dev_dbg(dev, "Found largest videomode %ux%u\n", max_mode->xres, max_mode->yres); if (cfg->lcd_modes == NULL) { @@ -2672,10 +2672,10 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, /* Allocate frame buffer memory. */ ch->fb_size = max_size * format->bpp / 8 * 2; - ch->fb_mem = dma_alloc_coherent(priv->dev, ch->fb_size, &ch->dma_handle, + ch->fb_mem = dma_alloc_coherent(dev, ch->fb_size, &ch->dma_handle, GFP_KERNEL); if (ch->fb_mem == NULL) { - dev_err(priv->dev, "unable to allocate buffer\n"); + dev_err(dev, "unable to allocate buffer\n"); return -ENOMEM; } @@ -2683,8 +2683,7 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv, if (cfg->tx_dev) { if (!cfg->tx_dev->dev.driver || !try_module_get(cfg->tx_dev->dev.driver->owner)) { - dev_warn(priv->dev, - "unable to get transmitter device\n"); + dev_warn(dev, "unable to get transmitter device\n"); return -EINVAL; } ch->tx_dev = platform_get_drvdata(cfg->tx_dev); @@ -2792,9 +2791,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); for (i = 0; i < num_channels; i++) { - struct sh_mobile_lcdc_chan *ch = priv->ch + i; + struct sh_mobile_lcdc_chan *ch = &priv->ch[i]; - error = sh_mobile_lcdc_channel_init(priv, ch); + error = sh_mobile_lcdc_channel_init(ch); if (error) goto err1; } @@ -2805,7 +2804,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) ovl->cfg = &pdata->overlays[i]; ovl->channel = &priv->ch[0]; - error = sh_mobile_lcdc_overlay_init(priv, ovl); + error = sh_mobile_lcdc_overlay_init(ovl); if (error) goto err1; } From 7a4fcf91c83ad76d30ee876615d5fd35ef907e32 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 13 Aug 2012 16:11:32 +0200 Subject: [PATCH 05/20] ARM: mach-shmobile: ag5evm: Add LCDC tx_dev field to platform data Reference the MIPI-DSI transceiver in the LCDC platform data and make sure it gets registered before the LCDC. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman --- arch/arm/mach-shmobile/board-ag5evm.c | 157 +++++++++++++------------- 1 file changed, 80 insertions(+), 77 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 25eb88a923e6..52b5e64eb6b9 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -213,6 +213,84 @@ static struct platform_device irda_device = { .num_resources = ARRAY_SIZE(irda_resources), }; +/* MIPI-DSI */ +static struct resource mipidsi0_resources[] = { + [0] = { + .name = "DSI0", + .start = 0xfeab0000, + .end = 0xfeab3fff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .name = "DSI0", + .start = 0xfeab4000, + .end = 0xfeab7fff, + .flags = IORESOURCE_MEM, + }, +}; + +static int sh_mipi_set_dot_clock(struct platform_device *pdev, + void __iomem *base, + int enable) +{ + struct clk *pck, *phy; + int ret; + + pck = clk_get(&pdev->dev, "dsip_clk"); + if (IS_ERR(pck)) { + ret = PTR_ERR(pck); + goto sh_mipi_set_dot_clock_pck_err; + } + + phy = clk_get(&pdev->dev, "dsiphy_clk"); + if (IS_ERR(phy)) { + ret = PTR_ERR(phy); + goto sh_mipi_set_dot_clock_phy_err; + } + + if (enable) { + clk_set_rate(pck, clk_round_rate(pck, 24000000)); + clk_set_rate(phy, clk_round_rate(pck, 510000000)); + clk_enable(pck); + clk_enable(phy); + } else { + clk_disable(pck); + clk_disable(phy); + } + + ret = 0; + + clk_put(phy); +sh_mipi_set_dot_clock_phy_err: + clk_put(pck); +sh_mipi_set_dot_clock_pck_err: + return ret; +} + +static struct sh_mobile_lcdc_info lcdc0_info; + +static struct sh_mipi_dsi_info mipidsi0_info = { + .data_format = MIPI_RGB888, + .lcd_chan = &lcdc0_info.ch[0], + .lane = 2, + .vsynw_offset = 20, + .clksrc = 1, + .flags = SH_MIPI_DSI_HSABM | + SH_MIPI_DSI_SYNC_PULSES_MODE | + SH_MIPI_DSI_HSbyteCLK, + .set_dot_clock = sh_mipi_set_dot_clock, +}; + +static struct platform_device mipidsi0_device = { + .name = "sh-mipi-dsi", + .num_resources = ARRAY_SIZE(mipidsi0_resources), + .resource = mipidsi0_resources, + .id = 0, + .dev = { + .platform_data = &mipidsi0_info, + }, +}; + static unsigned char lcd_backlight_seq[3][2] = { { 0x04, 0x07 }, { 0x23, 0x80 }, @@ -275,6 +353,7 @@ static struct sh_mobile_lcdc_info lcdc0_info = { .display_on = lcd_backlight_on, .display_off = lcd_backlight_reset, }, + .tx_dev = &mipidsi0_device, } }; @@ -302,82 +381,6 @@ static struct platform_device lcdc0_device = { }, }; -/* MIPI-DSI */ -static struct resource mipidsi0_resources[] = { - [0] = { - .name = "DSI0", - .start = 0xfeab0000, - .end = 0xfeab3fff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .name = "DSI0", - .start = 0xfeab4000, - .end = 0xfeab7fff, - .flags = IORESOURCE_MEM, - }, -}; - -static int sh_mipi_set_dot_clock(struct platform_device *pdev, - void __iomem *base, - int enable) -{ - struct clk *pck, *phy; - int ret; - - pck = clk_get(&pdev->dev, "dsip_clk"); - if (IS_ERR(pck)) { - ret = PTR_ERR(pck); - goto sh_mipi_set_dot_clock_pck_err; - } - - phy = clk_get(&pdev->dev, "dsiphy_clk"); - if (IS_ERR(phy)) { - ret = PTR_ERR(phy); - goto sh_mipi_set_dot_clock_phy_err; - } - - if (enable) { - clk_set_rate(pck, clk_round_rate(pck, 24000000)); - clk_set_rate(phy, clk_round_rate(pck, 510000000)); - clk_enable(pck); - clk_enable(phy); - } else { - clk_disable(pck); - clk_disable(phy); - } - - ret = 0; - - clk_put(phy); -sh_mipi_set_dot_clock_phy_err: - clk_put(pck); -sh_mipi_set_dot_clock_pck_err: - return ret; -} - -static struct sh_mipi_dsi_info mipidsi0_info = { - .data_format = MIPI_RGB888, - .lcd_chan = &lcdc0_info.ch[0], - .lane = 2, - .vsynw_offset = 20, - .clksrc = 1, - .flags = SH_MIPI_DSI_HSABM | - SH_MIPI_DSI_SYNC_PULSES_MODE | - SH_MIPI_DSI_HSbyteCLK, - .set_dot_clock = sh_mipi_set_dot_clock, -}; - -static struct platform_device mipidsi0_device = { - .name = "sh-mipi-dsi", - .num_resources = ARRAY_SIZE(mipidsi0_resources), - .resource = mipidsi0_resources, - .id = 0, - .dev = { - .platform_data = &mipidsi0_info, - }, -}; - /* Fixed 2.8V regulators to be used by SDHI0 */ static struct regulator_consumer_supply fixed2v8_power_consumers[] = { @@ -531,8 +534,8 @@ static struct platform_device *ag5evm_devices[] __initdata = { &fsi_device, &mmc_device, &irda_device, - &lcdc0_device, &mipidsi0_device, + &lcdc0_device, &sdhi0_device, &sdhi1_device, }; From 50b1a7447749ab137c4827c7758836471e663582 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:17:55 +0200 Subject: [PATCH 06/20] fbdev: sh_mipi_dsi: Add channel field to platform data The channel field stores the LCDC channel corresponding to the MIPI-DSI transmitter. The information is currently obtained through the lcd_chan field that will be removed. Signed-off-by: Laurent Pinchart --- include/video/sh_mipi_dsi.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index 06c67fbc4eee..eae71d94d241 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -48,6 +48,7 @@ struct sh_mobile_lcdc_chan_cfg; struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; struct sh_mobile_lcdc_chan_cfg *lcd_chan; + int channel; int lane; unsigned long flags; u32 clksrc; From 772f5d1b78f1427be0abe54dbde82c51678316b9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 07/20] ARM: mach-shmobile: Initiliaze the new sh_mipi_dsi_info channel field Signed-off-by: Laurent Pinchart Acked-by: Simon Horman --- arch/arm/mach-shmobile/board-ag5evm.c | 1 + arch/arm/mach-shmobile/board-ap4evb.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 52b5e64eb6b9..a38931f6b843 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -272,6 +272,7 @@ static struct sh_mobile_lcdc_info lcdc0_info; static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, .lcd_chan = &lcdc0_info.ch[0], + .channel = LCDC_CHAN_MAINLCD, .lane = 2, .vsynw_offset = 20, .clksrc = 1, diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 790dc68c4312..25a46b5ed9b2 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -557,6 +557,7 @@ static struct sh_mobile_lcdc_info lcdc_info; static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, .lcd_chan = &lcdc_info.ch[0], + .channel = LCDC_CHAN_MAINLCD, .lane = 2, .vsynw_offset = 17, .phyctrl = 0x6 << 8, From 86c82c43365b0c06002aa69a8185219be9437317 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 08/20] fbdev: sh_mipi_dsi: Use the sh_mipi_dsi_info channel field Get the LCDC channel selector from the sh_mipi_dsi_info channel field directly instead of accessing the LCDC platform data through the lcd_chan field. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mipi_dsi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 3951fdae5f68..7f6ce6515b6d 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -369,7 +369,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) /* setup LCD panel */ /* cf. drivers/video/omap/lcd_mipid.c */ - sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE); + sh_mipi_dcs(pdata->channel, MIPI_DCS_EXIT_SLEEP_MODE); msleep(120); /* * [7] - Page Address Mode @@ -381,11 +381,11 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) * [1] - Flip Horizontal * [0] - Flip Vertical */ - sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00); + sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_ADDRESS_MODE, 0x00); /* cf. set_data_lines() */ - sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT, + sh_mipi_dcs_param(pdata->channel, MIPI_DCS_SET_PIXEL_FORMAT, pixfmt << 4); - sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON); + sh_mipi_dcs(pdata->channel, MIPI_DCS_SET_DISPLAY_ON); /* Enable timeout counters */ iowrite32(0x00000f00, base + DSICTRL); From 8e2b2033db37ff4cec8caca3d0ef815e9aa84153 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 09/20] fbdev: sh_mipi_dsi: Use the LCDC entity default mode Configure the MIPI-DSI transmitter using the LCDC entity default mode instead of accessing the mode through the LCDC platform data. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mipi_dsi.c | 43 +++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index 7f6ce6515b6d..f88b2040eb5d 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -127,9 +127,10 @@ static void sh_mipi_shutdown(struct platform_device *pdev) sh_mipi_dsi_enable(mipi, false); } -static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) +static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode) { void __iomem *base = mipi->base; + struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt, linelength, vmctr2; u32 tmp, top, bottom, delay, div; @@ -146,77 +147,77 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) pctype = 0; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; - linelength = ch->lcd_modes[0].xres * 3; + linelength = mode->xres * 3; yuv = false; break; case MIPI_RGB565: pctype = 1; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; - linelength = ch->lcd_modes[0].xres * 2; + linelength = mode->xres * 2; yuv = false; break; case MIPI_RGB666_LP: pctype = 2; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; - linelength = ch->lcd_modes[0].xres * 3; + linelength = mode->xres * 3; yuv = false; break; case MIPI_RGB666: pctype = 3; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; - linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8; + linelength = (mode->xres * 18 + 7) / 8; yuv = false; break; case MIPI_BGR888: pctype = 8; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; - linelength = ch->lcd_modes[0].xres * 3; + linelength = mode->xres * 3; yuv = false; break; case MIPI_BGR565: pctype = 9; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; - linelength = ch->lcd_modes[0].xres * 2; + linelength = mode->xres * 2; yuv = false; break; case MIPI_BGR666_LP: pctype = 0xa; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; - linelength = ch->lcd_modes[0].xres * 3; + linelength = mode->xres * 3; yuv = false; break; case MIPI_BGR666: pctype = 0xb; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; - linelength = (ch->lcd_modes[0].xres * 18 + 7) / 8; + linelength = (mode->xres * 18 + 7) / 8; yuv = false; break; case MIPI_YUYV: pctype = 4; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; - linelength = ch->lcd_modes[0].xres * 2; + linelength = mode->xres * 2; yuv = true; break; case MIPI_UYVY: pctype = 5; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; - linelength = ch->lcd_modes[0].xres * 2; + linelength = mode->xres * 2; yuv = true; break; case MIPI_YUV420_L: pctype = 6; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; - linelength = (ch->lcd_modes[0].xres * 12 + 7) / 8; + linelength = (mode->xres * 12 + 7) / 8; yuv = true; break; case MIPI_YUV420: @@ -224,7 +225,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; /* Length of U/V line */ - linelength = (ch->lcd_modes[0].xres + 1) / 2; + linelength = (mode->xres + 1) / 2; yuv = true; break; default: @@ -293,7 +294,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) */ iowrite32(0x00000006, mipi->linkbase + DTCTR); /* VSYNC width = 2 (<< 17) */ - iowrite32((ch->lcd_modes[0].vsync_len << pdata->vsynw_offset) | + iowrite32((mode->vsync_len << pdata->vsynw_offset) | (pdata->clksrc << 16) | (pctype << 12) | datatype, mipi->linkbase + VMCTR1); @@ -327,7 +328,7 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) top = linelength << 16; /* RGBLEN */ bottom = 0x00000001; if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */ - bottom = (pdata->lane * ch->lcd_modes[0].hsync_len) - 10; + bottom = (pdata->lane * mode->hsync_len) - 10; iowrite32(top | bottom , mipi->linkbase + VMLEN1); /* @@ -347,18 +348,18 @@ static int sh_mipi_setup(struct sh_mipi *mipi, struct sh_mipi_dsi_info *pdata) div = 2; if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */ - top = ch->lcd_modes[0].hsync_len + ch->lcd_modes[0].left_margin; + top = mode->hsync_len + mode->left_margin; top = ((pdata->lane * top / div) - 10) << 16; } if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */ - bottom = ch->lcd_modes[0].right_margin; + bottom = mode->right_margin; bottom = (pdata->lane * bottom / div) - 12; } - bpp = linelength / ch->lcd_modes[0].xres; /* byte / pixel */ + bpp = linelength / mode->xres; /* byte / pixel */ if ((pdata->lane / div) > bpp) { - tmp = ch->lcd_modes[0].xres / bpp; /* output cycle */ - tmp = ch->lcd_modes[0].xres - tmp; /* (input - output) cycle */ + tmp = mode->xres / bpp; /* output cycle */ + tmp = mode->xres - tmp; /* (input - output) cycle */ delay = (pdata->lane * tmp); } @@ -405,7 +406,7 @@ static int mipi_display_on(struct sh_mobile_lcdc_entity *entity) if (ret < 0) goto mipi_display_on_fail1; - ret = sh_mipi_setup(mipi, pdata); + ret = sh_mipi_setup(mipi, &entity->def_mode); if (ret < 0) goto mipi_display_on_fail2; From 675f9280552c1a8f6e3b2bc2582325f5a9e192d2 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 10/20] fbdev: sh_mipi_dsi: Remove last reference to LCDC platform data The format check that references LCDC platform data isn't needed, as the mismatch between LCDC and MIPI-DSI platform it detects would result in a badly displayed image, which isn't worse than a complete failure to setup the transmitter. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mipi_dsi.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c index f88b2040eb5d..f4962292792c 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/sh_mipi_dsi.c @@ -131,10 +131,8 @@ static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode) { void __iomem *base = mipi->base; struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data; - struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan; u32 pctype, datatype, pixfmt, linelength, vmctr2; u32 tmp, top, bottom, delay, div; - bool yuv; int bpp; /* @@ -148,77 +146,66 @@ static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode) datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; - yuv = false; break; case MIPI_RGB565: pctype = 1; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; - yuv = false; break; case MIPI_RGB666_LP: pctype = 2; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; - yuv = false; break; case MIPI_RGB666: pctype = 3; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (mode->xres * 18 + 7) / 8; - yuv = false; break; case MIPI_BGR888: pctype = 8; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; - yuv = false; break; case MIPI_BGR565: pctype = 9; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; - yuv = false; break; case MIPI_BGR666_LP: pctype = 0xa; datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18; pixfmt = MIPI_DCS_PIXEL_FMT_24BIT; linelength = mode->xres * 3; - yuv = false; break; case MIPI_BGR666: pctype = 0xb; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18; pixfmt = MIPI_DCS_PIXEL_FMT_18BIT; linelength = (mode->xres * 18 + 7) / 8; - yuv = false; break; case MIPI_YUYV: pctype = 4; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; - yuv = true; break; case MIPI_UYVY: pctype = 5; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16; pixfmt = MIPI_DCS_PIXEL_FMT_16BIT; linelength = mode->xres * 2; - yuv = true; break; case MIPI_YUV420_L: pctype = 6; datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12; pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; linelength = (mode->xres * 12 + 7) / 8; - yuv = true; break; case MIPI_YUV420: pctype = 7; @@ -226,16 +213,11 @@ static int sh_mipi_setup(struct sh_mipi *mipi, const struct fb_videomode *mode) pixfmt = MIPI_DCS_PIXEL_FMT_12BIT; /* Length of U/V line */ linelength = (mode->xres + 1) / 2; - yuv = true; break; default: return -EINVAL; } - if ((yuv && ch->interface_type != YUV422) || - (!yuv && ch->interface_type != RGB24)) - return -EINVAL; - if (!pdata->lane) return -EINVAL; From 4b74fdeb24a5d1bcf35aad8b8e3bd068319a1125 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 11/20] ARM: mach-shmobile: Remove the unused sh_mipi_dsi_info lcd_chan field Signed-off-by: Laurent Pinchart Acked-by: Simon Horman --- arch/arm/mach-shmobile/board-ag5evm.c | 3 --- arch/arm/mach-shmobile/board-ap4evb.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index a38931f6b843..d787979a5310 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -267,11 +267,8 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev, return ret; } -static struct sh_mobile_lcdc_info lcdc0_info; - static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, - .lcd_chan = &lcdc0_info.ch[0], .channel = LCDC_CHAN_MAINLCD, .lane = 2, .vsynw_offset = 20, diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 25a46b5ed9b2..728ed4d026c7 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -552,11 +552,8 @@ static struct resource mipidsi0_resources[] = { }, }; -static struct sh_mobile_lcdc_info lcdc_info; - static struct sh_mipi_dsi_info mipidsi0_info = { .data_format = MIPI_RGB888, - .lcd_chan = &lcdc_info.ch[0], .channel = LCDC_CHAN_MAINLCD, .lane = 2, .vsynw_offset = 17, From 074d0da486e2a5b8e80c35070ede7104f302f6da Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 14 Aug 2012 12:21:17 +0200 Subject: [PATCH 12/20] fbdev: sh_mipi_dsi: Remove the unused sh_mipi_dsi_info lcd_chan field The field is unused, remove it from the structure. Signed-off-by: Laurent Pinchart --- include/video/sh_mipi_dsi.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h index eae71d94d241..a01f197e6ac1 100644 --- a/include/video/sh_mipi_dsi.h +++ b/include/video/sh_mipi_dsi.h @@ -25,8 +25,6 @@ enum sh_mipi_dsi_data_fmt { MIPI_YUV420, }; -struct sh_mobile_lcdc_chan_cfg; - #define SH_MIPI_DSI_HSABM (1 << 0) #define SH_MIPI_DSI_HBPBM (1 << 1) #define SH_MIPI_DSI_HFPBM (1 << 2) @@ -47,7 +45,6 @@ struct sh_mobile_lcdc_chan_cfg; struct sh_mipi_dsi_info { enum sh_mipi_dsi_data_fmt data_format; - struct sh_mobile_lcdc_chan_cfg *lcd_chan; int channel; int lane; unsigned long flags; From 656d4f332c02b14e62fe3f4247a1dcdc33961de6 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:10:03 +0200 Subject: [PATCH 13/20] fbdev: sh_mobile_lcdc: Store the backlight brightness internally There's no need to query the hardware for the currenty brightness value through a platform data callback when we can cache the value internally in the LCDC driver. Signed-off-by: Laurent Pinchart --- drivers/video/sh_mobile_lcdcfb.c | 3 ++- drivers/video/sh_mobile_lcdcfb.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index c169581c3a72..dd8dd41b4acd 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -2282,6 +2282,7 @@ static int sh_mobile_lcdc_update_bl(struct backlight_device *bdev) bdev->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK)) brightness = 0; + ch->bl_brightness = brightness; return ch->cfg->bl_info.set_brightness(brightness); } @@ -2289,7 +2290,7 @@ static int sh_mobile_lcdc_get_brightness(struct backlight_device *bdev) { struct sh_mobile_lcdc_chan *ch = bl_get_data(bdev); - return ch->cfg->bl_info.get_brightness(); + return ch->bl_brightness; } static int sh_mobile_lcdc_check_fb(struct backlight_device *bdev, diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h index 0f92f6544b94..f839adef1d90 100644 --- a/drivers/video/sh_mobile_lcdcfb.h +++ b/drivers/video/sh_mobile_lcdcfb.h @@ -94,6 +94,7 @@ struct sh_mobile_lcdc_chan { /* Backlight */ struct backlight_device *bl; + unsigned int bl_brightness; /* FB */ struct fb_info *info; From 4c108530dba393084766799422aea1631e0dec81 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:11:26 +0200 Subject: [PATCH 14/20] ARM: mach-shmobile: mackerel: Removed unused get_brightness callback Signed-off-by: Laurent Pinchart Acked-by: Simon Horman --- arch/arm/mach-shmobile/board-mackerel.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 0c27c810cf99..bfd2dc83d995 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c @@ -370,11 +370,6 @@ static int mackerel_set_brightness(int brightness) return 0; } -static int mackerel_get_brightness(void) -{ - return gpio_get_value(GPIO_PORT31); -} - static const struct sh_mobile_meram_cfg lcd_meram_cfg = { .icb[0] = { .meram_size = 0x40, @@ -403,7 +398,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { .name = "sh_mobile_lcdc_bl", .max_brightness = 1, .set_brightness = mackerel_set_brightness, - .get_brightness = mackerel_get_brightness, }, .meram_cfg = &lcd_meram_cfg, } From 1d33a5175135acf6cff0855659910013cb911391 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:12:20 +0200 Subject: [PATCH 15/20] sh: ap325rxa: Remove unused get_brightness LCDC callback Signed-off-by: Laurent Pinchart Acked-by: Paul Mundt --- arch/sh/boards/mach-ap325rxa/setup.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 9e963c1d1447..5620e33c18a0 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -179,11 +179,6 @@ static int ap320_wvga_set_brightness(int brightness) return 0; } -static int ap320_wvga_get_brightness(void) -{ - return gpio_get_value(GPIO_PTS3); -} - static void ap320_wvga_power_on(void) { msleep(100); @@ -232,7 +227,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { .name = "sh_mobile_lcdc_bl", .max_brightness = 1, .set_brightness = ap320_wvga_set_brightness, - .get_brightness = ap320_wvga_get_brightness, }, } }; From 6bc1e5eca24744898d93cbefe8f6091ecf1c4753 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:12:51 +0200 Subject: [PATCH 16/20] sh: ecovec24: Remove unused get_brightness LCDC callback Signed-off-by: Laurent Pinchart Acked-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 64559e8af14b..3fede4556c91 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -329,11 +329,6 @@ static int ecovec24_set_brightness(int brightness) return 0; } -static int ecovec24_get_brightness(void) -{ - return gpio_get_value(GPIO_PTR1); -} - static struct sh_mobile_lcdc_info lcdc_info = { .ch[0] = { .interface_type = RGB18, @@ -347,7 +342,6 @@ static struct sh_mobile_lcdc_info lcdc_info = { .name = "sh_mobile_lcdc_bl", .max_brightness = 1, .set_brightness = ecovec24_set_brightness, - .get_brightness = ecovec24_get_brightness, }, } }; From f70f4711df527b914486bf5381ec9a4911915c7d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:13:26 +0200 Subject: [PATCH 17/20] fbdev: sh_mobile_lcdc: Remove unused get_brightness pdata callback The callback isn't used anymore, remove it. Signed-off-by: Laurent Pinchart --- include/video/sh_mobile_lcdc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h index ff43ffc1aab2..2605fa8adb9c 100644 --- a/include/video/sh_mobile_lcdc.h +++ b/include/video/sh_mobile_lcdc.h @@ -163,7 +163,6 @@ struct sh_mobile_lcdc_bl_info { const char *name; int max_brightness; int (*set_brightness)(int brightness); - int (*get_brightness)(void); }; struct sh_mobile_lcdc_overlay_cfg { From 37f4dd13505bab9f2bbd2f66a2c9375e959452eb Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:25:27 +0200 Subject: [PATCH 18/20] ARM: mach-shmobile: ag5evm: Use the backlight API for brightness control Don't hook up brightness control in the display on/off operations, use the backlight API instead. Signed-off-by: Laurent Pinchart Acked-by: Simon Horman --- arch/arm/mach-shmobile/board-ag5evm.c | 45 +++++++++++++++++---------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index d787979a5310..032d10817e79 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -295,28 +295,38 @@ static unsigned char lcd_backlight_seq[3][2] = { { 0x03, 0x01 }, }; -static void lcd_backlight_on(void) +static int lcd_backlight_set_brightness(int brightness) { - struct i2c_adapter *a; + struct i2c_adapter *adap; struct i2c_msg msg; - int k; + unsigned int i; + int ret; + + if (brightness == 0) { + /* Reset the chip */ + gpio_set_value(GPIO_PORT235, 0); + mdelay(24); + gpio_set_value(GPIO_PORT235, 1); + return 0; + } + + adap = i2c_get_adapter(1); + if (adap == NULL) + return -ENODEV; - a = i2c_get_adapter(1); - for (k = 0; a && k < 3; k++) { + for (i = 0; i < ARRAY_SIZE(lcd_backlight_seq); i++) { msg.addr = 0x6d; - msg.buf = &lcd_backlight_seq[k][0]; + msg.buf = &lcd_backlight_seq[i][0]; msg.len = 2; msg.flags = 0; - if (i2c_transfer(a, &msg, 1) != 1) + + ret = i2c_transfer(adap, &msg, 1); + if (ret < 0) break; } -} -static void lcd_backlight_reset(void) -{ - gpio_set_value(GPIO_PORT235, 0); - mdelay(24); - gpio_set_value(GPIO_PORT235, 1); + i2c_put_adapter(adap); + return ret < 0 ? ret : 0; } /* LCDC0 */ @@ -348,8 +358,11 @@ static struct sh_mobile_lcdc_info lcdc0_info = { .panel_cfg = { .width = 44, .height = 79, - .display_on = lcd_backlight_on, - .display_off = lcd_backlight_reset, + }, + .bl_info = { + .name = "sh_mobile_lcdc_bl", + .max_brightness = 1, + .set_brightness = lcd_backlight_set_brightness, }, .tx_dev = &mipidsi0_device, } @@ -622,7 +635,7 @@ static void __init ag5evm_init(void) /* LCD backlight controller */ gpio_request(GPIO_PORT235, NULL); /* RESET */ gpio_direction_output(GPIO_PORT235, 0); - lcd_backlight_reset(); + lcd_backlight_set_brightness(0); /* enable SDHI0 on CN15 [SD I/F] */ gpio_request(GPIO_FN_SDHIWP0, NULL); From d072c35edcfabe3159766d55252e16ed7864873e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 15 Aug 2012 18:48:36 +0200 Subject: [PATCH 19/20] sh: kfr2r09: Use the backlight API for brightness control Don't hook up brightness control in the display on/off operations, use the backlight API instead. Signed-off-by: Laurent Pinchart Acked-by: Paul Mundt --- arch/sh/boards/mach-kfr2r09/lcd_wqvga.c | 16 +++------------- arch/sh/boards/mach-kfr2r09/setup.c | 7 +++++-- arch/sh/include/mach-kfr2r09/mach/kfr2r09.h | 6 ++---- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c index c148b36ecb65..c62050332629 100644 --- a/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c +++ b/arch/sh/boards/mach-kfr2r09/lcd_wqvga.c @@ -283,7 +283,7 @@ void kfr2r09_lcd_start(void *sohandle, struct sh_mobile_lcdc_sys_bus_ops *so) #define MAIN_MLED4 0x40 #define MAIN_MSW 0x80 -static int kfr2r09_lcd_backlight(int on) +int kfr2r09_lcd_set_brightness(int brightness) { struct i2c_adapter *a; struct i2c_msg msg; @@ -295,7 +295,7 @@ static int kfr2r09_lcd_backlight(int on) return -ENODEV; buf[0] = 0x00; - if (on) + if (brightness) buf[1] = CTRL_CPSW | CTRL_C10 | CTRL_CKSW; else buf[1] = 0; @@ -309,7 +309,7 @@ static int kfr2r09_lcd_backlight(int on) return -ENODEV; buf[0] = 0x01; - if (on) + if (brightness) buf[1] = MAIN_MSW | MAIN_MLED4 | 0x0c; else buf[1] = 0; @@ -324,13 +324,3 @@ static int kfr2r09_lcd_backlight(int on) return 0; } - -void kfr2r09_lcd_on(void) -{ - kfr2r09_lcd_backlight(1); -} - -void kfr2r09_lcd_off(void) -{ - kfr2r09_lcd_backlight(0); -} diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index f2a4304fbe23..ab502f12ef57 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c @@ -158,8 +158,11 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = { .height = 58, .setup_sys = kfr2r09_lcd_setup, .start_transfer = kfr2r09_lcd_start, - .display_on = kfr2r09_lcd_on, - .display_off = kfr2r09_lcd_off, + }, + .bl_info = { + .name = "sh_mobile_lcdc_bl", + .max_brightness = 1, + .set_brightness = kfr2r09_lcd_set_brightness, }, .sys_bus_cfg = { .ldmt2r = 0x07010904, diff --git a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h index ba3d93d333f8..c20c9e5f5eab 100644 --- a/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h +++ b/arch/sh/include/mach-kfr2r09/mach/kfr2r09.h @@ -4,15 +4,13 @@ #include