Skip to content

Commit

Permalink
FB/S3C2412: add S3C2412 support to S3C2410 fb driver
Browse files Browse the repository at this point in the history
Add support for the S3C2412 to the S3C2410 frame buffer driver
by ensuring that any moved registers can be dealt with.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Vincent Sanders <vince@simtec.co.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ben Dooks authored and Linus Torvalds committed Feb 6, 2008
1 parent 40488db commit f62e770
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 16 deletions.
78 changes: 63 additions & 15 deletions drivers/video/s3c2410fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,11 @@ static int debug = 0;

/* useful functions */

static int is_s3c2412(struct s3c2410fb_info *fbi)
{
return (fbi->drv_type == DRV_S3C2412);
}

/* s3c2410fb_set_lcdaddr
*
* initialise lcd controller address pointers
Expand Down Expand Up @@ -501,7 +506,7 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
{
unsigned long flags;
unsigned long irqen;
void __iomem *regs = fbi->io;
void __iomem *irq_base = fbi->irq_base;

local_irq_save(flags);

Expand All @@ -511,9 +516,9 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
fbi->palette_ready = 1;

/* enable IRQ */
irqen = readl(regs + S3C2410_LCDINTMSK);
irqen = readl(irq_base + S3C24XX_LCDINTMSK);
irqen &= ~S3C2410_LCDINT_FRSYNC;
writel(irqen, regs + S3C2410_LCDINTMSK);
writel(irqen, irq_base + S3C24XX_LCDINTMSK);
}

local_irq_restore(flags);
Expand Down Expand Up @@ -594,15 +599,17 @@ static int s3c2410fb_setcolreg(unsigned regno,
static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
{
struct s3c2410fb_info *fbi = info->par;
void __iomem *regs = fbi->io;
void __iomem *tpal_reg = fbi->io;

dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);

tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL;

if (blank_mode == FB_BLANK_UNBLANK)
writel(0x0, regs + S3C2410_TPAL);
writel(0x0, tpal_reg);
else {
dprintk("setting TPAL to output 0x000000\n");
writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL);
writel(S3C2410_TPAL_EN, tpal_reg);
}

return 0;
Expand Down Expand Up @@ -709,6 +716,16 @@ static int s3c2410fb_init_registers(struct fb_info *info)
struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
unsigned long flags;
void __iomem *regs = fbi->io;
void __iomem *tpal;
void __iomem *lpcsel;

if (is_s3c2412(fbi)) {
tpal = regs + S3C2412_TPAL;
lpcsel = regs + S3C2412_TCONSEL;
} else {
tpal = regs + S3C2410_TPAL;
lpcsel = regs + S3C2410_LPCSEL;
}

/* Initialise LCD with values from haret */

Expand All @@ -724,12 +741,12 @@ static int s3c2410fb_init_registers(struct fb_info *info)
local_irq_restore(flags);

dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
writel(mach_info->lpcsel, regs + S3C2410_LPCSEL);
writel(mach_info->lpcsel, lpcsel);

dprintk("replacing TPAL %08x\n", readl(regs + S3C2410_TPAL));
dprintk("replacing TPAL %08x\n", readl(tpal));

/* ensure temporary palette disabled */
writel(0x00, regs + S3C2410_TPAL);
writel(0x00, tpal);

return 0;
}
Expand Down Expand Up @@ -763,23 +780,24 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
{
struct s3c2410fb_info *fbi = dev_id;
void __iomem *regs = fbi->io;
unsigned long lcdirq = readl(regs + S3C2410_LCDINTPND);
void __iomem *irq_base = fbi->irq_base;
unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND);

if (lcdirq & S3C2410_LCDINT_FRSYNC) {
if (fbi->palette_ready)
s3c2410fb_write_palette(fbi);

writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDINTPND);
writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDSRCPND);
writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND);
writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND);
}

return IRQ_HANDLED;
}

static char driver_name[] = "s3c2410fb";

static int __init s3c2410fb_probe(struct platform_device *pdev)
static int __init s3c24xxfb_probe(struct platform_device *pdev,
enum s3c_drv_type drv_type)
{
struct s3c2410fb_info *info;
struct s3c2410fb_display *display;
Expand Down Expand Up @@ -815,6 +833,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)

info = fbinfo->par;
info->dev = &pdev->dev;
info->drv_type = drv_type;

res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
Expand All @@ -838,6 +857,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
goto release_mem;
}

info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);

dprintk("devinit\n");

strcpy(fbinfo->fix.id, driver_name);
Expand Down Expand Up @@ -946,6 +967,16 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
return ret;
}

static int __init s3c2410fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2410);
}

static int __init s3c2412fb_probe(struct platform_device *pdev)
{
return s3c24xxfb_probe(pdev, DRV_S3C2412);
}

/* s3c2410fb_stop_lcd
*
* shutdown the lcd controller
Expand Down Expand Up @@ -1047,14 +1078,31 @@ static struct platform_driver s3c2410fb_driver = {
},
};

static struct platform_driver s3c2412fb_driver = {
.probe = s3c2412fb_probe,
.remove = s3c2410fb_remove,
.suspend = s3c2410fb_suspend,
.resume = s3c2410fb_resume,
.driver = {
.name = "s3c2412-lcd",
.owner = THIS_MODULE,
},
};

int __init s3c2410fb_init(void)
{
return platform_driver_register(&s3c2410fb_driver);
int ret = platform_driver_register(&s3c2410fb_driver);

if (ret == 0)
ret = platform_driver_register(&s3c2412fb_driver);;

return ret;
}

static void __exit s3c2410fb_cleanup(void)
{
platform_driver_unregister(&s3c2410fb_driver);
platform_driver_unregister(&s3c2412fb_driver);
}

module_init(s3c2410fb_init);
Expand Down
7 changes: 7 additions & 0 deletions drivers/video/s3c2410fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,20 @@
#ifndef __S3C2410FB_H
#define __S3C2410FB_H

enum s3c_drv_type {
DRV_S3C2410,
DRV_S3C2412,
};

struct s3c2410fb_info {
struct device *dev;
struct clk *clk;

struct resource *mem;
void __iomem *io;
void __iomem *irq_base;

enum s3c_drv_type drv_type;
struct s3c2410fb_hw regs;

unsigned int palette_ready;
Expand Down
11 changes: 10 additions & 1 deletion include/asm-arm/arch-s3c2410/regs-lcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,16 @@

#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4))

#endif /* ___ASM_ARCH_REGS_LCD_H */
/* general registers */

/* base of the LCD registers, where INTPND, INTSRC and then INTMSK
* are available. */

#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54)
#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24)

#define S3C24XX_LCDINTPND (0x00)
#define S3C24XX_LCDSRCPND (0x04)
#define S3C24XX_LCDINTMSK (0x08)

#endif /* ___ASM_ARCH_REGS_LCD_H */

0 comments on commit f62e770

Please sign in to comment.