aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/s3c2410fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/s3c2410fb.c')
-rw-r--r--drivers/video/s3c2410fb.c88
1 files changed, 71 insertions, 17 deletions
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index b3c31d9dc591..71fa6edb5c47 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;
@@ -663,7 +670,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info)
663 dma_addr_t map_dma; 670 dma_addr_t map_dma;
664 unsigned map_size = PAGE_ALIGN(info->fix.smem_len); 671 unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
665 672
666 dprintk("map_video_memory(fbi=%p)\n", fbi); 673 dprintk("map_video_memory(fbi=%p) map_size %u\n", fbi, map_size);
667 674
668 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, 675 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
669 &map_dma, GFP_KERNEL); 676 &map_dma, GFP_KERNEL);
@@ -672,7 +679,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info)
672 /* prevent initial garbage on screen */ 679 /* prevent initial garbage on screen */
673 dprintk("map_video_memory: clear %p:%08x\n", 680 dprintk("map_video_memory: clear %p:%08x\n",
674 info->screen_base, map_size); 681 info->screen_base, map_size);
675 memset(info->screen_base, 0xf0, map_size); 682 memset(info->screen_base, 0x00, map_size);
676 683
677 info->fix.smem_start = map_dma; 684 info->fix.smem_start = map_dma;
678 685
@@ -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;
@@ -799,6 +817,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
799 return -EINVAL; 817 return -EINVAL;
800 } 818 }
801 819
820 if (mach_info->default_display >= mach_info->num_displays) {
821 dev_err(&pdev->dev, "default is %d but only %d displays\n",
822 mach_info->default_display, mach_info->num_displays);
823 return -EINVAL;
824 }
825
802 display = mach_info->displays + mach_info->default_display; 826 display = mach_info->displays + mach_info->default_display;
803 827
804 irq = platform_get_irq(pdev, 0); 828 irq = platform_get_irq(pdev, 0);
@@ -815,6 +839,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
815 839
816 info = fbinfo->par; 840 info = fbinfo->par;
817 info->dev = &pdev->dev; 841 info->dev = &pdev->dev;
842 info->drv_type = drv_type;
818 843
819 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 844 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
820 if (res == NULL) { 845 if (res == NULL) {
@@ -838,6 +863,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
838 goto release_mem; 863 goto release_mem;
839 } 864 }
840 865
866 info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);
867
841 dprintk("devinit\n"); 868 dprintk("devinit\n");
842 869
843 strcpy(fbinfo->fix.id, driver_name); 870 strcpy(fbinfo->fix.id, driver_name);
@@ -946,6 +973,16 @@ dealloc_fb:
946 return ret; 973 return ret;
947} 974}
948 975
976static int __init s3c2410fb_probe(struct platform_device *pdev)
977{
978 return s3c24xxfb_probe(pdev, DRV_S3C2410);
979}
980
981static int __init s3c2412fb_probe(struct platform_device *pdev)
982{
983 return s3c24xxfb_probe(pdev, DRV_S3C2412);
984}
985
949/* s3c2410fb_stop_lcd 986/* s3c2410fb_stop_lcd
950 * 987 *
951 * shutdown the lcd controller 988 * shutdown the lcd controller
@@ -1047,14 +1084,31 @@ static struct platform_driver s3c2410fb_driver = {
1047 }, 1084 },
1048}; 1085};
1049 1086
1087static struct platform_driver s3c2412fb_driver = {
1088 .probe = s3c2412fb_probe,
1089 .remove = s3c2410fb_remove,
1090 .suspend = s3c2410fb_suspend,
1091 .resume = s3c2410fb_resume,
1092 .driver = {
1093 .name = "s3c2412-lcd",
1094 .owner = THIS_MODULE,
1095 },
1096};
1097
1050int __init s3c2410fb_init(void) 1098int __init s3c2410fb_init(void)
1051{ 1099{
1052 return platform_driver_register(&s3c2410fb_driver); 1100 int ret = platform_driver_register(&s3c2410fb_driver);
1101
1102 if (ret == 0)
1103 ret = platform_driver_register(&s3c2412fb_driver);;
1104
1105 return ret;
1053} 1106}
1054 1107
1055static void __exit s3c2410fb_cleanup(void) 1108static void __exit s3c2410fb_cleanup(void)
1056{ 1109{
1057 platform_driver_unregister(&s3c2410fb_driver); 1110 platform_driver_unregister(&s3c2410fb_driver);
1111 platform_driver_unregister(&s3c2412fb_driver);
1058} 1112}
1059 1113
1060module_init(s3c2410fb_init); 1114module_init(s3c2410fb_init);