diff options
Diffstat (limited to 'drivers/video/s3c2410fb.c')
-rw-r--r-- | drivers/video/s3c2410fb.c | 88 |
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 | ||
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; |
@@ -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) | |||
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; |
@@ -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 | ||
976 | static int __init s3c2410fb_probe(struct platform_device *pdev) | ||
977 | { | ||
978 | return s3c24xxfb_probe(pdev, DRV_S3C2410); | ||
979 | } | ||
980 | |||
981 | static 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 | ||
1087 | static 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 | |||
1050 | int __init s3c2410fb_init(void) | 1098 | int __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 | ||
1055 | static void __exit s3c2410fb_cleanup(void) | 1108 | static 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 | ||
1060 | module_init(s3c2410fb_init); | 1114 | module_init(s3c2410fb_init); |