diff options
author | Ben Dooks <ben-linux@fluff.org> | 2008-02-06 04:39:41 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:41:17 -0500 |
commit | f62e770b25bdc24e18c9191fe2ca3e159036bd79 (patch) | |
tree | 9180909af9cc5af60147b7232a0b897b56a2ac45 | |
parent | 40488db20e3f43e65f10747f9026fba7d59d29a3 (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.c | 78 | ||||
-rw-r--r-- | drivers/video/s3c2410fb.h | 7 | ||||
-rw-r--r-- | include/asm-arm/arch-s3c2410/regs-lcd.h | 11 |
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 | ||
113 | static 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, | |||
594 | static int s3c2410fb_blank(int blank_mode, struct fb_info *info) | 599 | static 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) | |||
763 | static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | 780 | static 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 | ||
780 | static char driver_name[] = "s3c2410fb"; | 797 | static char driver_name[] = "s3c2410fb"; |
781 | 798 | ||
782 | static int __init s3c2410fb_probe(struct platform_device *pdev) | 799 | static 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 | ||
970 | static int __init s3c2410fb_probe(struct platform_device *pdev) | ||
971 | { | ||
972 | return s3c24xxfb_probe(pdev, DRV_S3C2410); | ||
973 | } | ||
974 | |||
975 | static 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 | ||
1081 | static 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 | |||
1050 | int __init s3c2410fb_init(void) | 1092 | int __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 | ||
1055 | static void __exit s3c2410fb_cleanup(void) | 1102 | static 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 | ||
1060 | module_init(s3c2410fb_init); | 1108 | module_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 | ||
28 | enum s3c_drv_type { | ||
29 | DRV_S3C2410, | ||
30 | DRV_S3C2412, | ||
31 | }; | ||
32 | |||
28 | struct s3c2410fb_info { | 33 | struct 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 */ | ||