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, 57 insertions, 31 deletions
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index ed3426062a8b..8a4c6470d799 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -474,6 +474,7 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
474{ 474{
475 unsigned long flags; 475 unsigned long flags;
476 unsigned long irqen; 476 unsigned long irqen;
477 void __iomem *regs = fbi->io;
477 478
478 local_irq_save(flags); 479 local_irq_save(flags);
479 480
@@ -483,9 +484,9 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
483 fbi->palette_ready = 1; 484 fbi->palette_ready = 1;
484 485
485 /* enable IRQ */ 486 /* enable IRQ */
486 irqen = readl(S3C2410_LCDINTMSK); 487 irqen = readl(regs + S3C2410_LCDINTMSK);
487 irqen &= ~S3C2410_LCDINT_FRSYNC; 488 irqen &= ~S3C2410_LCDINT_FRSYNC;
488 writel(irqen, S3C2410_LCDINTMSK); 489 writel(irqen, regs + S3C2410_LCDINTMSK);
489 } 490 }
490 491
491 local_irq_restore(flags); 492 local_irq_restore(flags);
@@ -680,6 +681,7 @@ static inline void modify_gpio(void __iomem *reg,
680static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) 681static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
681{ 682{
682 unsigned long flags; 683 unsigned long flags;
684 void __iomem *regs = fbi->io;
683 685
684 /* Initialise LCD with values from haret */ 686 /* Initialise LCD with values from haret */
685 687
@@ -694,25 +696,25 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
694 696
695 local_irq_restore(flags); 697 local_irq_restore(flags);
696 698
697 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); 699 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
698 writel(fbi->regs.lcdcon2, S3C2410_LCDCON2); 700 writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
699 writel(fbi->regs.lcdcon3, S3C2410_LCDCON3); 701 writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
700 writel(fbi->regs.lcdcon4, S3C2410_LCDCON4); 702 writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
701 writel(fbi->regs.lcdcon5, S3C2410_LCDCON5); 703 writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
702 704
703 s3c2410fb_set_lcdaddr(fbi); 705 s3c2410fb_set_lcdaddr(fbi);
704 706
705 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); 707 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
706 writel(mach_info->lpcsel, S3C2410_LPCSEL); 708 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL);
707 709
708 dprintk("replacing TPAL %08x\n", readl(S3C2410_TPAL)); 710 dprintk("replacing TPAL %08x\n", readl(regs + S3C2410_TPAL));
709 711
710 /* ensure temporary palette disabled */ 712 /* ensure temporary palette disabled */
711 writel(0x00, S3C2410_TPAL); 713 writel(0x00, regs + S3C2410_TPAL);
712 714
713 /* Enable video by setting the ENVID bit to 1 */ 715 /* Enable video by setting the ENVID bit to 1 */
714 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID; 716 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
715 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); 717 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
716 return 0; 718 return 0;
717} 719}
718 720
@@ -720,6 +722,7 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
720{ 722{
721 unsigned int i; 723 unsigned int i;
722 unsigned long ent; 724 unsigned long ent;
725 void __iomem *regs = fbi->io;
723 726
724 fbi->palette_ready = 0; 727 fbi->palette_ready = 0;
725 728
@@ -727,14 +730,14 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
727 if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR) 730 if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR)
728 continue; 731 continue;
729 732
730 writel(ent, S3C2410_TFTPAL(i)); 733 writel(ent, regs + S3C2410_TFTPAL(i));
731 734
732 /* it seems the only way to know exactly 735 /* it seems the only way to know exactly
733 * if the palette wrote ok, is to check 736 * if the palette wrote ok, is to check
734 * to see if the value verifies ok 737 * to see if the value verifies ok
735 */ 738 */
736 739
737 if (readw(S3C2410_TFTPAL(i)) == ent) 740 if (readw(regs + S3C2410_TFTPAL(i)) == ent)
738 fbi->palette_buffer[i] = PALETTE_BUFF_CLEAR; 741 fbi->palette_buffer[i] = PALETTE_BUFF_CLEAR;
739 else 742 else
740 fbi->palette_ready = 1; /* retry */ 743 fbi->palette_ready = 1; /* retry */
@@ -744,14 +747,15 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
744static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) 747static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
745{ 748{
746 struct s3c2410fb_info *fbi = dev_id; 749 struct s3c2410fb_info *fbi = dev_id;
747 unsigned long lcdirq = readl(S3C2410_LCDINTPND); 750 void __iomem *regs = fbi->io;
751 unsigned long lcdirq = readl(regs + S3C2410_LCDINTPND);
748 752
749 if (lcdirq & S3C2410_LCDINT_FRSYNC) { 753 if (lcdirq & S3C2410_LCDINT_FRSYNC) {
750 if (fbi->palette_ready) 754 if (fbi->palette_ready)
751 s3c2410fb_write_palette(fbi); 755 s3c2410fb_write_palette(fbi);
752 756
753 writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDINTPND); 757 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDINTPND);
754 writel(S3C2410_LCDINT_FRSYNC, S3C2410_LCDSRCPND); 758 writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDSRCPND);
755 } 759 }
756 760
757 return IRQ_HANDLED; 761 return IRQ_HANDLED;
@@ -764,9 +768,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
764 struct s3c2410fb_info *info; 768 struct s3c2410fb_info *info;
765 struct fb_info *fbinfo; 769 struct fb_info *fbinfo;
766 struct s3c2410fb_hw *mregs; 770 struct s3c2410fb_hw *mregs;
771 struct resource *res;
767 int ret; 772 int ret;
768 int irq; 773 int irq;
769 int i; 774 int i;
775 int size;
770 u32 lcdcon1; 776 u32 lcdcon1;
771 777
772 mach_info = pdev->dev.platform_data; 778 mach_info = pdev->dev.platform_data;
@@ -788,11 +794,32 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
788 return -ENOMEM; 794 return -ENOMEM;
789 } 795 }
790 796
791
792 info = fbinfo->par; 797 info = fbinfo->par;
793 info->fb = fbinfo; 798 info->fb = fbinfo;
794 info->dev = &pdev->dev; 799 info->dev = &pdev->dev;
795 800
801 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
802 if (res == NULL) {
803 dev_err(&pdev->dev, "failed to get memory registersn");
804 ret = -ENXIO;
805 goto dealloc_fb;
806 }
807
808 size = (res->end - res->start)+1;
809 info->mem = request_mem_region(res->start, size, pdev->name);
810 if (info->mem == NULL) {
811 dev_err(&pdev->dev, "failed to get memory region\n");
812 ret = -ENOENT;
813 goto dealloc_fb;
814 }
815
816 info->io = ioremap(res->start, size);
817 if (info->io == NULL) {
818 dev_err(&pdev->dev, "ioremap() of registers failed\n");
819 ret = -ENXIO;
820 goto release_mem;
821 }
822
796 platform_set_drvdata(pdev, fbinfo); 823 platform_set_drvdata(pdev, fbinfo);
797 824
798 dprintk("devinit\n"); 825 dprintk("devinit\n");
@@ -803,8 +830,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
803 830
804 /* Stop the video and unset ENVID if set */ 831 /* Stop the video and unset ENVID if set */
805 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; 832 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
806 lcdcon1 = readl(S3C2410_LCDCON1); 833 lcdcon1 = readl(info->io + S3C2410_LCDCON1);
807 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); 834 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
808 835
809 info->mach_info = pdev->dev.platform_data; 836 info->mach_info = pdev->dev.platform_data;
810 837
@@ -855,19 +882,11 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
855 for (i = 0; i < 256; i++) 882 for (i = 0; i < 256; i++)
856 info->palette_buffer[i] = PALETTE_BUFF_CLEAR; 883 info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
857 884
858 if (!request_mem_region((unsigned long)S3C24XX_VA_LCD, SZ_1M, "s3c2410-lcd")) {
859 ret = -EBUSY;
860 goto dealloc_fb;
861 }
862
863
864 dprintk("got LCD region\n");
865
866 ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info); 885 ret = request_irq(irq, s3c2410fb_irq, IRQF_DISABLED, pdev->name, info);
867 if (ret) { 886 if (ret) {
868 dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret); 887 dev_err(&pdev->dev, "cannot get irq %d - err %d\n", irq, ret);
869 ret = -EBUSY; 888 ret = -EBUSY;
870 goto release_mem; 889 goto release_regs;
871 } 890 }
872 891
873 info->clk = clk_get(NULL, "lcd"); 892 info->clk = clk_get(NULL, "lcd");
@@ -889,6 +908,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
889 ret = -ENOMEM; 908 ret = -ENOMEM;
890 goto release_clock; 909 goto release_clock;
891 } 910 }
911
892 dprintk("got video memory\n"); 912 dprintk("got video memory\n");
893 913
894 ret = s3c2410fb_init_registers(info); 914 ret = s3c2410fb_init_registers(info);
@@ -916,8 +936,11 @@ release_clock:
916 clk_put(info->clk); 936 clk_put(info->clk);
917release_irq: 937release_irq:
918 free_irq(irq,info); 938 free_irq(irq,info);
939release_regs:
940 iounmap(info->io);
919release_mem: 941release_mem:
920 release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD); 942 release_resource(info->mem);
943 kfree(info->mem);
921dealloc_fb: 944dealloc_fb:
922 framebuffer_release(fbinfo); 945 framebuffer_release(fbinfo);
923 return ret; 946 return ret;
@@ -935,7 +958,7 @@ static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
935 local_irq_save(flags); 958 local_irq_save(flags);
936 959
937 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID; 960 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
938 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); 961 writel(fbi->regs.lcdcon1, fbi->io + S3C2410_LCDCON1);
939 962
940 local_irq_restore(flags); 963 local_irq_restore(flags);
941} 964}
@@ -962,7 +985,10 @@ static int s3c2410fb_remove(struct platform_device *pdev)
962 985
963 irq = platform_get_irq(pdev, 0); 986 irq = platform_get_irq(pdev, 0);
964 free_irq(irq,info); 987 free_irq(irq,info);
965 release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD); 988
989 release_resource(info->mem);
990 kfree(info->mem);
991 iounmap(info->io);
966 unregister_framebuffer(fbinfo); 992 unregister_framebuffer(fbinfo);
967 993
968 return 0; 994 return 0;