diff options
| -rw-r--r-- | drivers/video/s3c2410fb.c | 88 | ||||
| -rw-r--r-- | drivers/video/s3c2410fb.h | 3 |
2 files changed, 60 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, | |||
| 680 | static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi) | 681 | static 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) | |||
| 744 | static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | 747 | static 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); |
| 917 | release_irq: | 937 | release_irq: |
| 918 | free_irq(irq,info); | 938 | free_irq(irq,info); |
| 939 | release_regs: | ||
| 940 | iounmap(info->io); | ||
| 919 | release_mem: | 941 | release_mem: |
| 920 | release_mem_region((unsigned long)S3C24XX_VA_LCD, S3C24XX_SZ_LCD); | 942 | release_resource(info->mem); |
| 943 | kfree(info->mem); | ||
| 921 | dealloc_fb: | 944 | dealloc_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; |
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h index f3f8a8e15012..17c7915b7acd 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/s3c2410fb.h | |||
| @@ -30,6 +30,9 @@ struct s3c2410fb_info { | |||
| 30 | struct device *dev; | 30 | struct device *dev; |
| 31 | struct clk *clk; | 31 | struct clk *clk; |
| 32 | 32 | ||
| 33 | struct resource *mem; | ||
| 34 | void __iomem *io; | ||
| 35 | |||
| 33 | struct s3c2410fb_mach_info *mach_info; | 36 | struct s3c2410fb_mach_info *mach_info; |
| 34 | 37 | ||
| 35 | /* raw memory addresses */ | 38 | /* raw memory addresses */ |
