mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-11-24 20:38:08 +02:00
jz4740_fb: Disable lcd when it's blanked.
This commit is contained in:
parent
bcdf5a8733
commit
6f76581889
@ -55,12 +55,14 @@ static int gpm940b0_set_power(struct lcd_device *lcd, int power)
|
|||||||
|
|
||||||
switch (power) {
|
switch (power) {
|
||||||
case FB_BLANK_UNBLANK:
|
case FB_BLANK_UNBLANK:
|
||||||
|
mdelay(20);
|
||||||
gpm940b0->enabled = 1;
|
gpm940b0->enabled = 1;
|
||||||
gpm940b0_power_enable(gpm940b0);
|
gpm940b0_power_enable(gpm940b0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
gpm940b0->enabled = 0;
|
gpm940b0->enabled = 0;
|
||||||
gpm940b0_power_disable(gpm940b0);
|
gpm940b0_power_disable(gpm940b0);
|
||||||
|
mdelay(20);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
#include <linux/jz4740_fb.h>
|
#include <linux/jz4740_fb.h>
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
|
||||||
|
#include <asm/mach-jz4740/gpio.h>
|
||||||
|
|
||||||
#define JZ_REG_LCD_CFG 0x00
|
#define JZ_REG_LCD_CFG 0x00
|
||||||
#define JZ_REG_LCD_VSYNC 0x04
|
#define JZ_REG_LCD_VSYNC 0x04
|
||||||
@ -98,6 +101,8 @@
|
|||||||
|
|
||||||
#define JZ_LCD_SYNC_MASK 0x3ff
|
#define JZ_LCD_SYNC_MASK 0x3ff
|
||||||
|
|
||||||
|
#define JZ_LCD_STATE_DISABLED BIT(0)
|
||||||
|
|
||||||
struct jzfb_framedesc {
|
struct jzfb_framedesc {
|
||||||
uint32_t next;
|
uint32_t next;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
@ -120,7 +125,11 @@ struct jzfb {
|
|||||||
dma_addr_t vidmem_phys;
|
dma_addr_t vidmem_phys;
|
||||||
struct jzfb_framedesc *framedesc;
|
struct jzfb_framedesc *framedesc;
|
||||||
|
|
||||||
|
struct clk *ldclk;
|
||||||
|
struct clk *lpclk;
|
||||||
|
|
||||||
uint32_t pseudo_palette[16];
|
uint32_t pseudo_palette[16];
|
||||||
|
unsigned is_enabled:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fb_fix_screeninfo jzfb_fix __devinitdata = {
|
static struct fb_fix_screeninfo jzfb_fix __devinitdata = {
|
||||||
@ -133,8 +142,23 @@ static struct fb_fix_screeninfo jzfb_fix __devinitdata = {
|
|||||||
.accel = FB_ACCEL_NONE,
|
.accel = FB_ACCEL_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const static struct jz_gpio_bulk_request jz_lcd_pins[] = {
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_PCLK),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_HSYNC),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_VSYNC),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA0),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA1),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA2),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA3),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA4),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA5),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA6),
|
||||||
|
JZ_GPIO_BULK_PIN(LCD_DATA7),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
|
int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
|
||||||
unsigned transp, struct fb_info *fb)
|
unsigned transp, struct fb_info *fb)
|
||||||
{
|
{
|
||||||
((uint32_t*)fb->pseudo_palette)[regno] = red << 16 | green << 8 | blue;
|
((uint32_t*)fb->pseudo_palette)[regno] = red << 16 | green << 8 | blue;
|
||||||
return 0;
|
return 0;
|
||||||
@ -142,14 +166,14 @@ int jzfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
|
|||||||
|
|
||||||
static int jzfb_get_controller_bpp(struct jzfb *jzfb)
|
static int jzfb_get_controller_bpp(struct jzfb *jzfb)
|
||||||
{
|
{
|
||||||
switch(jzfb->pdata->bpp) {
|
switch(jzfb->pdata->bpp) {
|
||||||
case 18:
|
case 18:
|
||||||
case 24:
|
case 24:
|
||||||
return 32;
|
return 32;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return jzfb->pdata->bpp;
|
return jzfb->pdata->bpp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
|
static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
|
||||||
@ -159,7 +183,7 @@ static int jzfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (fb->var.bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
|
if (fb->var.bits_per_pixel != jzfb_get_controller_bpp(jzfb) &&
|
||||||
fb->var.bits_per_pixel != jzfb->pdata->bpp)
|
fb->var.bits_per_pixel != jzfb->pdata->bpp)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
|
for (i = 0; i < jzfb->pdata->num_modes; ++i, ++mode) {
|
||||||
@ -278,6 +302,50 @@ static int jzfb_set_par(struct fb_info *info)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int jzfb_blank(int blank_mode, struct fb_info *info)
|
||||||
|
{
|
||||||
|
struct jzfb* jzfb = info->par;
|
||||||
|
uint32_t ctrl = readl(jzfb->base + JZ_REG_LCD_CTRL);
|
||||||
|
|
||||||
|
switch (blank_mode) {
|
||||||
|
case FB_BLANK_UNBLANK:
|
||||||
|
if (jzfb->is_enabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
jz_gpio_bulk_resume(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
|
||||||
|
clk_enable(jzfb->ldclk);
|
||||||
|
clk_enable(jzfb->lpclk);
|
||||||
|
|
||||||
|
writel(0, jzfb->base + JZ_REG_LCD_STATE);
|
||||||
|
|
||||||
|
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
|
||||||
|
|
||||||
|
ctrl |= JZ_LCD_CTRL_ENABLE;
|
||||||
|
ctrl &= ~JZ_LCD_CTRL_DISABLE;
|
||||||
|
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
|
||||||
|
|
||||||
|
jzfb->is_enabled = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (!jzfb->is_enabled)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ctrl |= JZ_LCD_CTRL_DISABLE;
|
||||||
|
writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);
|
||||||
|
do {
|
||||||
|
ctrl = readl(jzfb->base + JZ_REG_LCD_STATE);
|
||||||
|
} while (!(ctrl & JZ_LCD_STATE_DISABLED));
|
||||||
|
|
||||||
|
clk_disable(jzfb->lpclk);
|
||||||
|
clk_disable(jzfb->ldclk);
|
||||||
|
jz_gpio_bulk_suspend(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
|
||||||
|
jzfb->is_enabled = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int jzfb_alloc_vidmem(struct jzfb *jzfb)
|
static int jzfb_alloc_vidmem(struct jzfb *jzfb)
|
||||||
{
|
{
|
||||||
@ -299,16 +367,16 @@ static int jzfb_alloc_vidmem(struct jzfb *jzfb)
|
|||||||
|
|
||||||
jzfb->devmem_size = devmem_size;
|
jzfb->devmem_size = devmem_size;
|
||||||
jzfb->devmem = dma_alloc_coherent(&jzfb->pdev->dev,
|
jzfb->devmem = dma_alloc_coherent(&jzfb->pdev->dev,
|
||||||
PAGE_ALIGN(devmem_size),
|
PAGE_ALIGN(devmem_size),
|
||||||
&jzfb->devmem_phys, GFP_KERNEL);
|
&jzfb->devmem_phys, GFP_KERNEL);
|
||||||
|
|
||||||
if (!jzfb->devmem) {
|
if (!jzfb->devmem) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (page = jzfb->vidmem;
|
for (page = jzfb->vidmem;
|
||||||
page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
|
page < jzfb->vidmem + PAGE_ALIGN(jzfb->vidmem_size);
|
||||||
page += PAGE_SIZE) {
|
page += PAGE_SIZE) {
|
||||||
SetPageReserved(virt_to_page(page));
|
SetPageReserved(virt_to_page(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +407,7 @@ static struct fb_ops jzfb_ops = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.fb_check_var = jzfb_check_var,
|
.fb_check_var = jzfb_check_var,
|
||||||
.fb_set_par = jzfb_set_par,
|
.fb_set_par = jzfb_set_par,
|
||||||
/* .fb_blank = jzfb_blank,*/
|
.fb_blank = jzfb_blank,
|
||||||
.fb_fillrect = sys_fillrect,
|
.fb_fillrect = sys_fillrect,
|
||||||
.fb_copyarea = sys_copyarea,
|
.fb_copyarea = sys_copyarea,
|
||||||
.fb_imageblit = sys_imageblit,
|
.fb_imageblit = sys_imageblit,
|
||||||
@ -390,6 +458,24 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
|
|||||||
jzfb->pdata = pdata;
|
jzfb->pdata = pdata;
|
||||||
jzfb->mem = mem;
|
jzfb->mem = mem;
|
||||||
|
|
||||||
|
jzfb->ldclk = clk_get(&pdev->dev, "lcd");
|
||||||
|
jzfb->lpclk = clk_get(&pdev->dev, "lcd_pclk");
|
||||||
|
|
||||||
|
jzfb->is_enabled = 1;
|
||||||
|
|
||||||
|
if (IS_ERR(jzfb->ldclk)) {
|
||||||
|
ret = PTR_ERR(jzfb->ldclk);
|
||||||
|
dev_err(&pdev->dev, "Faild to get device clock: %d\n", ret);
|
||||||
|
goto err_framebuffer_release;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ERR(jzfb->lpclk)) {
|
||||||
|
ret = PTR_ERR(jzfb->ldclk);
|
||||||
|
dev_err(&pdev->dev, "Faild to get pixel clock: %d\n", ret);
|
||||||
|
goto err_framebuffer_release;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
jzfb->base = ioremap(mem->start, resource_size(mem));
|
jzfb->base = ioremap(mem->start, resource_size(mem));
|
||||||
|
|
||||||
if (!jzfb->base) {
|
if (!jzfb->base) {
|
||||||
@ -428,6 +514,8 @@ static int __devinit jzfb_probe(struct platform_device *pdev)
|
|||||||
jzfb_set_par(fb);
|
jzfb_set_par(fb);
|
||||||
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
|
writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0);
|
||||||
|
|
||||||
|
jz_gpio_bulk_request(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
|
||||||
|
|
||||||
ret = register_framebuffer(fb);
|
ret = register_framebuffer(fb);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
|
dev_err(&pdev->dev, "Failed to register framebuffer: %d\n", ret);
|
||||||
@ -450,6 +538,7 @@ static int __devexit jzfb_remove(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct jzfb *jzfb = platform_get_drvdata(pdev);
|
struct jzfb *jzfb = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
jz_gpio_bulk_free(jz_lcd_pins, ARRAY_SIZE(jz_lcd_pins));
|
||||||
iounmap(jzfb->base);
|
iounmap(jzfb->base);
|
||||||
release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
|
release_mem_region(jzfb->mem->start, resource_size(jzfb->mem));
|
||||||
jzfb_free_devmem(jzfb);
|
jzfb_free_devmem(jzfb);
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
--- a/drivers/video/fbmem.c 2009-10-05 13:18:19.000000000 +0200
|
||||||
|
+++ b/drivers/video/fbmem.c 2009-12-03 05:08:15.000000000 +0100
|
||||||
|
@@ -997,12 +997,12 @@
|
||||||
|
int
|
||||||
|
fb_blank(struct fb_info *info, int blank)
|
||||||
|
{
|
||||||
|
- int ret = -EINVAL;
|
||||||
|
+ int ret = 0;
|
||||||
|
|
||||||
|
if (blank > FB_BLANK_POWERDOWN)
|
||||||
|
blank = FB_BLANK_POWERDOWN;
|
||||||
|
|
||||||
|
- if (info->fbops->fb_blank)
|
||||||
|
+ if (info->fbops->fb_blank && blank == FB_BLANK_UNBLANK)
|
||||||
|
ret = info->fbops->fb_blank(blank, info);
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
@@ -1013,6 +1013,10 @@
|
||||||
|
fb_notifier_call_chain(FB_EVENT_BLANK, &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (info->fbops->fb_blank && blank != FB_BLANK_UNBLANK)
|
||||||
|
+ ret = info->fbops->fb_blank(blank, info);
|
||||||
|
+
|
||||||
|
+
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user