aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-02-06 04:39:41 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-02-06 13:41:17 -0500
commitf62e770b25bdc24e18c9191fe2ca3e159036bd79 (patch)
tree9180909af9cc5af60147b7232a0b897b56a2ac45
parent40488db20e3f43e65f10747f9026fba7d59d29a3 (diff)
FB/S3C2412: add S3C2412 support to S3C2410 fb driver
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>
-rw-r--r--drivers/video/s3c2410fb.c78
-rw-r--r--drivers/video/s3c2410fb.h7
-rw-r--r--include/asm-arm/arch-s3c2410/regs-lcd.h11
3 files changed, 80 insertions, 16 deletions
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index b3c31d9dc591..628b9e67f0ca 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -110,6 +110,11 @@ static int debug = 0;
110 110
111/* useful functions */ 111/* useful functions */
112 112
113static int is_s3c2412(struct s3c2410fb_info *fbi)
114{
115 return (fbi->drv_type == DRV_S3C2412);
116}
117
113/* s3c2410fb_set_lcdaddr 118/* s3c2410fb_set_lcdaddr
114 * 119 *
115 * initialise lcd controller address pointers 120 * initialise lcd controller address pointers
@@ -501,7 +506,7 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
501{ 506{
502 unsigned long flags; 507 unsigned long flags;
503 unsigned long irqen; 508 unsigned long irqen;
504 void __iomem *regs = fbi->io; 509 void __iomem *irq_base = fbi->irq_base;
505 510
506 local_irq_save(flags); 511 local_irq_save(flags);
507 512
@@ -511,9 +516,9 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
511 fbi->palette_ready = 1; 516 fbi->palette_ready = 1;
512 517
513 /* enable IRQ */ 518 /* enable IRQ */
514 irqen = readl(regs + S3C2410_LCDINTMSK); 519 irqen = readl(irq_base + S3C24XX_LCDINTMSK);
515 irqen &= ~S3C2410_LCDINT_FRSYNC; 520 irqen &= ~S3C2410_LCDINT_FRSYNC;
516 writel(irqen, regs + S3C2410_LCDINTMSK); 521 writel(irqen, irq_base + S3C24XX_LCDINTMSK);
517 } 522 }
518 523
519 local_irq_restore(flags); 524 local_irq_restore(flags);
@@ -594,15 +599,17 @@ static int s3c2410fb_setcolreg(unsigned regno,
594static int s3c2410fb_blank(int blank_mode, struct fb_info *info) 599static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
595{ 600{
596 struct s3c2410fb_info *fbi = info->par; 601 struct s3c2410fb_info *fbi = info->par;
597 void __iomem *regs = fbi->io; 602 void __iomem *tpal_reg = fbi->io;
598 603
599 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); 604 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
600 605
606 tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL;
607
601 if (blank_mode == FB_BLANK_UNBLANK) 608 if (blank_mode == FB_BLANK_UNBLANK)
602 writel(0x0, regs + S3C2410_TPAL); 609 writel(0x0, tpal_reg);
603 else { 610 else {
604 dprintk("setting TPAL to output 0x000000\n"); 611 dprintk("setting TPAL to output 0x000000\n");
605 writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL); 612 writel(S3C2410_TPAL_EN, tpal_reg);
606 } 613 }
607 614
608 return 0; 615 return 0;
@@ -709,6 +716,16 @@ static int s3c2410fb_init_registers(struct fb_info *info)
709 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; 716 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
710 unsigned long flags; 717 unsigned long flags;
711 void __iomem *regs = fbi->io; 718 void __iomem *regs = fbi->io;
719 void __iomem *tpal;
720 void __iomem *lpcsel;
721
722 if (is_s3c2412(fbi)) {
723 tpal = regs + S3C2412_TPAL;
724 lpcsel = regs + S3C2412_TCONSEL;
725 } else {
726 tpal = regs + S3C2410_TPAL;
727 lpcsel = regs + S3C2410_LPCSEL;
728 }
712 729
713 /* Initialise LCD with values from haret */ 730 /* Initialise LCD with values from haret */
714 731
@@ -724,12 +741,12 @@ static int s3c2410fb_init_registers(struct fb_info *info)
724 local_irq_restore(flags); 741 local_irq_restore(flags);
725 742
726 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); 743 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
727 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); 744 writel(mach_info->lpcsel, lpcsel);
728 745
729 dprintk("replacing TPAL %08x\n", readl(regs + S3C2410_TPAL)); 746 dprintk("replacing TPAL %08x\n", readl(tpal));
730 747
731 /* ensure temporary palette disabled */ 748 /* ensure temporary palette disabled */
732 writel(0x00, regs + S3C2410_TPAL); 749 writel(0x00, tpal);
733 750
734 return 0; 751 return 0;
735} 752}
@@ -763,15 +780,15 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
763static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) 780static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
764{ 781{
765 struct s3c2410fb_info *fbi = dev_id; 782 struct s3c2410fb_info *fbi = dev_id;
766 void __iomem *regs = fbi->io; 783 void __iomem *irq_base = fbi->irq_base;
767 unsigned long lcdirq = readl(regs + S3C2410_LCDINTPND); 784 unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND);
768 785
769 if (lcdirq & S3C2410_LCDINT_FRSYNC) { 786 if (lcdirq & S3C2410_LCDINT_FRSYNC) {
770 if (fbi->palette_ready) 787 if (fbi->palette_ready)
771 s3c2410fb_write_palette(fbi); 788 s3c2410fb_write_palette(fbi);
772 789
773 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDINTPND); 790 writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND);
774 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDSRCPND); 791 writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND);
775 } 792 }
776 793
777 return IRQ_HANDLED; 794 return IRQ_HANDLED;
@@ -779,7 +796,8 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
779 796
780static char driver_name[] = "s3c2410fb"; 797static char driver_name[] = "s3c2410fb";
781 798
782static int __init s3c2410fb_probe(struct platform_device *pdev) 799static int __init s3c24xxfb_probe(struct platform_device *pdev,
800 enum s3c_drv_type drv_type)
783{ 801{
784 struct s3c2410fb_info *info; 802 struct s3c2410fb_info *info;
785 struct s3c2410fb_display *display; 803 struct s3c2410fb_display *display;
@@ -815,6 +833,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
815 833
816 info = fbinfo->par; 834 info = fbinfo->par;
817 info->dev = &pdev->dev; 835 info->dev = &pdev->dev;
836 info->drv_type = drv_type;
818 837
819 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 838 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
820 if (res == NULL) { 839 if (res == NULL) {
@@ -838,6 +857,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
838 goto release_mem; 857 goto release_mem;
839 } 858 }
840 859
860 info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);
861
841 dprintk("devinit\n"); 862 dprintk("devinit\n");
842 863
843 strcpy(fbinfo->fix.id, driver_name); 864 strcpy(fbinfo->fix.id, driver_name);
@@ -946,6 +967,16 @@ dealloc_fb:
946 return ret; 967 return ret;
947} 968}
948 969
970static int __init s3c2410fb_probe(struct platform_device *pdev)
971{
972 return s3c24xxfb_probe(pdev, DRV_S3C2410);
973}
974
975static int __init s3c2412fb_probe(struct platform_device *pdev)
976{
977 return s3c24xxfb_probe(pdev, DRV_S3C2412);
978}
979
949/* s3c2410fb_stop_lcd 980/* s3c2410fb_stop_lcd
950 * 981 *
951 * shutdown the lcd controller 982 * shutdown the lcd controller
@@ -1047,14 +1078,31 @@ static struct platform_driver s3c2410fb_driver = {
1047 }, 1078 },
1048}; 1079};
1049 1080
1081static struct platform_driver s3c2412fb_driver = {
1082 .probe = s3c2412fb_probe,
1083 .remove = s3c2410fb_remove,
1084 .suspend = s3c2410fb_suspend,
1085 .resume = s3c2410fb_resume,
1086 .driver = {
1087 .name = "s3c2412-lcd",
1088 .owner = THIS_MODULE,
1089 },
1090};
1091
1050int __init s3c2410fb_init(void) 1092int __init s3c2410fb_init(void)
1051{ 1093{
1052 return platform_driver_register(&s3c2410fb_driver); 1094 int ret = platform_driver_register(&s3c2410fb_driver);
1095
1096 if (ret == 0)
1097 ret = platform_driver_register(&s3c2412fb_driver);;
1098
1099 return ret;
1053} 1100}
1054 1101
1055static void __exit s3c2410fb_cleanup(void) 1102static void __exit s3c2410fb_cleanup(void)
1056{ 1103{
1057 platform_driver_unregister(&s3c2410fb_driver); 1104 platform_driver_unregister(&s3c2410fb_driver);
1105 platform_driver_unregister(&s3c2412fb_driver);
1058} 1106}
1059 1107
1060module_init(s3c2410fb_init); 1108module_init(s3c2410fb_init);
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 6ce5dc26c5f7..dbb73b95e2ef 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -25,13 +25,20 @@
25#ifndef __S3C2410FB_H 25#ifndef __S3C2410FB_H
26#define __S3C2410FB_H 26#define __S3C2410FB_H
27 27
28enum s3c_drv_type {
29 DRV_S3C2410,
30 DRV_S3C2412,
31};
32
28struct s3c2410fb_info { 33struct s3c2410fb_info {
29 struct device *dev; 34 struct device *dev;
30 struct clk *clk; 35 struct clk *clk;
31 36
32 struct resource *mem; 37 struct resource *mem;
33 void __iomem *io; 38 void __iomem *io;
39 void __iomem *irq_base;
34 40
41 enum s3c_drv_type drv_type;
35 struct s3c2410fb_hw regs; 42 struct s3c2410fb_hw regs;
36 43
37 unsigned int palette_ready; 44 unsigned int palette_ready;
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h
index 76fe5f693426..bd854845697f 100644
--- a/include/asm-arm/arch-s3c2410/regs-lcd.h
+++ b/include/asm-arm/arch-s3c2410/regs-lcd.h
@@ -147,7 +147,16 @@
147 147
148#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) 148#define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4))
149 149
150#endif /* ___ASM_ARCH_REGS_LCD_H */ 150/* general registers */
151
152/* base of the LCD registers, where INTPND, INTSRC and then INTMSK
153 * are available. */
151 154
155#define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54)
156#define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24)
152 157
158#define S3C24XX_LCDINTPND (0x00)
159#define S3C24XX_LCDSRCPND (0x04)
160#define S3C24XX_LCDINTMSK (0x08)
153 161
162#endif /* ___ASM_ARCH_REGS_LCD_H */