diff options
author | eric miao <eric.miao@marvell.com> | 2008-04-30 03:52:21 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:29:31 -0400 |
commit | ce4fb7b892a6d6c6a0f87366b26fd834d2923dd7 (patch) | |
tree | 1b30869071a065f24ab0976b23c9c47998022b24 /drivers/video/pxafb.c | |
parent | 92ac73c1e4b4e039162f5d3980c2da8192b28060 (diff) |
pxafb: convert fb driver to use ioremap() and __raw_{readl, writel}
This is part of the effort moving peripheral registers outside of pxa-regs.h,
and using ioremap() make it possible the same IP can be re-used on different
processors with different registers space
As a result, the fixed mapping in pxa_map_io() is removed.
The regs-lcd.h can actually moved to where closer to pxafb.c but some of its
bit definitions are directly used by various platform code, though this is not
a good style.
Signed-off-by: eric miao <eric.miao@marvell.com>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: Russell King <rmk@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r-- | drivers/video/pxafb.c | 94 |
1 files changed, 71 insertions, 23 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index f1846c0de934..d97dc9383d47 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -687,7 +687,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
687 | fbi->reg_lccr1 = new_regs.lccr1; | 687 | fbi->reg_lccr1 = new_regs.lccr1; |
688 | fbi->reg_lccr2 = new_regs.lccr2; | 688 | fbi->reg_lccr2 = new_regs.lccr2; |
689 | fbi->reg_lccr3 = new_regs.lccr3; | 689 | fbi->reg_lccr3 = new_regs.lccr3; |
690 | fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK); | 690 | fbi->reg_lccr4 = __raw_readl(fbi->mmio_base + LCCR4) & |
691 | (~LCCR4_PAL_FOR_MASK); | ||
691 | fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); | 692 | fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK); |
692 | set_hsync_time(fbi, pcd); | 693 | set_hsync_time(fbi, pcd); |
693 | local_irq_restore(flags); | 694 | local_irq_restore(flags); |
@@ -696,9 +697,12 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, | |||
696 | * Only update the registers if the controller is enabled | 697 | * Only update the registers if the controller is enabled |
697 | * and something has changed. | 698 | * and something has changed. |
698 | */ | 699 | */ |
699 | if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) || | 700 | if ((__raw_readl(fbi->mmio_base + LCCR0) != fbi->reg_lccr0) || |
700 | (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) || | 701 | (__raw_readl(fbi->mmio_base + LCCR1) != fbi->reg_lccr1) || |
701 | (FDADR0 != fbi->fdadr0) || (FDADR1 != fbi->fdadr1)) | 702 | (__raw_readl(fbi->mmio_base + LCCR2) != fbi->reg_lccr2) || |
703 | (__raw_readl(fbi->mmio_base + LCCR3) != fbi->reg_lccr3) || | ||
704 | (__raw_readl(fbi->mmio_base + FDADR0) != fbi->fdadr0) || | ||
705 | (__raw_readl(fbi->mmio_base + FDADR1) != fbi->fdadr1)) | ||
702 | pxafb_schedule_work(fbi, C_REENABLE); | 706 | pxafb_schedule_work(fbi, C_REENABLE); |
703 | 707 | ||
704 | return 0; | 708 | return 0; |
@@ -784,26 +788,31 @@ static void pxafb_enable_controller(struct pxafb_info *fbi) | |||
784 | clk_enable(fbi->clk); | 788 | clk_enable(fbi->clk); |
785 | 789 | ||
786 | /* Sequence from 11.7.10 */ | 790 | /* Sequence from 11.7.10 */ |
787 | LCCR3 = fbi->reg_lccr3; | 791 | __raw_writel(fbi->reg_lccr3, fbi->mmio_base + LCCR3); |
788 | LCCR2 = fbi->reg_lccr2; | 792 | __raw_writel(fbi->reg_lccr2, fbi->mmio_base + LCCR2); |
789 | LCCR1 = fbi->reg_lccr1; | 793 | __raw_writel(fbi->reg_lccr1, fbi->mmio_base + LCCR1); |
790 | LCCR0 = fbi->reg_lccr0 & ~LCCR0_ENB; | 794 | __raw_writel(fbi->reg_lccr0 & ~LCCR0_ENB, fbi->mmio_base + LCCR0); |
791 | 795 | ||
792 | FDADR0 = fbi->fdadr0; | 796 | __raw_writel(fbi->fdadr0, fbi->mmio_base + FDADR0); |
793 | FDADR1 = fbi->fdadr1; | 797 | __raw_writel(fbi->fdadr1, fbi->mmio_base + FDADR1); |
794 | LCCR0 |= LCCR0_ENB; | 798 | __raw_writel(fbi->reg_lccr0 | LCCR0_ENB, fbi->mmio_base + LCCR0); |
795 | } | 799 | } |
796 | 800 | ||
797 | static void pxafb_disable_controller(struct pxafb_info *fbi) | 801 | static void pxafb_disable_controller(struct pxafb_info *fbi) |
798 | { | 802 | { |
803 | uint32_t lccr0; | ||
804 | |||
799 | DECLARE_WAITQUEUE(wait, current); | 805 | DECLARE_WAITQUEUE(wait, current); |
800 | 806 | ||
801 | set_current_state(TASK_UNINTERRUPTIBLE); | 807 | set_current_state(TASK_UNINTERRUPTIBLE); |
802 | add_wait_queue(&fbi->ctrlr_wait, &wait); | 808 | add_wait_queue(&fbi->ctrlr_wait, &wait); |
803 | 809 | ||
804 | LCSR = 0xffffffff; /* Clear LCD Status Register */ | 810 | /* Clear LCD Status Register */ |
805 | LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */ | 811 | __raw_writel(0xffffffff, fbi->mmio_base + LCSR); |
806 | LCCR0 |= LCCR0_DIS; /* Disable LCD Controller */ | 812 | |
813 | lccr0 = __raw_readl(fbi->mmio_base + LCCR0) & ~LCCR0_LDM; | ||
814 | __raw_writel(lccr0, fbi->mmio_base + LCCR0); | ||
815 | __raw_writel(lccr0 | LCCR0_DIS, fbi->mmio_base + LCCR0); | ||
807 | 816 | ||
808 | schedule_timeout(200 * HZ / 1000); | 817 | schedule_timeout(200 * HZ / 1000); |
809 | remove_wait_queue(&fbi->ctrlr_wait, &wait); | 818 | remove_wait_queue(&fbi->ctrlr_wait, &wait); |
@@ -818,14 +827,15 @@ static void pxafb_disable_controller(struct pxafb_info *fbi) | |||
818 | static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) | 827 | static irqreturn_t pxafb_handle_irq(int irq, void *dev_id) |
819 | { | 828 | { |
820 | struct pxafb_info *fbi = dev_id; | 829 | struct pxafb_info *fbi = dev_id; |
821 | unsigned int lcsr = LCSR; | 830 | unsigned int lccr0, lcsr = __raw_readl(fbi->mmio_base + LCSR); |
822 | 831 | ||
823 | if (lcsr & LCSR_LDD) { | 832 | if (lcsr & LCSR_LDD) { |
824 | LCCR0 |= LCCR0_LDM; | 833 | lccr0 = __raw_readl(fbi->mmio_base + LCCR0) | LCCR0_LDM; |
834 | __raw_writel(lccr0, fbi->mmio_base + LCCR0); | ||
825 | wake_up(&fbi->ctrlr_wait); | 835 | wake_up(&fbi->ctrlr_wait); |
826 | } | 836 | } |
827 | 837 | ||
828 | LCSR = lcsr; | 838 | __raw_writel(lcsr, fbi->mmio_base + LCSR); |
829 | return IRQ_HANDLED; | 839 | return IRQ_HANDLED; |
830 | } | 840 | } |
831 | 841 | ||
@@ -1343,7 +1353,8 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1343 | { | 1353 | { |
1344 | struct pxafb_info *fbi; | 1354 | struct pxafb_info *fbi; |
1345 | struct pxafb_mach_info *inf; | 1355 | struct pxafb_mach_info *inf; |
1346 | int ret; | 1356 | struct resource *r; |
1357 | int irq, ret; | ||
1347 | 1358 | ||
1348 | dev_dbg(&dev->dev, "pxafb_probe\n"); | 1359 | dev_dbg(&dev->dev, "pxafb_probe\n"); |
1349 | 1360 | ||
@@ -1406,19 +1417,47 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1406 | goto failed; | 1417 | goto failed; |
1407 | } | 1418 | } |
1408 | 1419 | ||
1420 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
1421 | if (r == NULL) { | ||
1422 | dev_err(&dev->dev, "no I/O memory resource defined\n"); | ||
1423 | ret = -ENODEV; | ||
1424 | goto failed; | ||
1425 | } | ||
1426 | |||
1427 | r = request_mem_region(r->start, r->end - r->start + 1, dev->name); | ||
1428 | if (r == NULL) { | ||
1429 | dev_err(&dev->dev, "failed to request I/O memory\n"); | ||
1430 | ret = -EBUSY; | ||
1431 | goto failed; | ||
1432 | } | ||
1433 | |||
1434 | fbi->mmio_base = ioremap(r->start, r->end - r->start + 1); | ||
1435 | if (fbi->mmio_base == NULL) { | ||
1436 | dev_err(&dev->dev, "failed to map I/O memory\n"); | ||
1437 | ret = -EBUSY; | ||
1438 | goto failed_free_res; | ||
1439 | } | ||
1440 | |||
1409 | /* Initialize video memory */ | 1441 | /* Initialize video memory */ |
1410 | ret = pxafb_map_video_memory(fbi); | 1442 | ret = pxafb_map_video_memory(fbi); |
1411 | if (ret) { | 1443 | if (ret) { |
1412 | dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret); | 1444 | dev_err(&dev->dev, "Failed to allocate video RAM: %d\n", ret); |
1413 | ret = -ENOMEM; | 1445 | ret = -ENOMEM; |
1414 | goto failed; | 1446 | goto failed_free_io; |
1415 | } | 1447 | } |
1416 | 1448 | ||
1417 | ret = request_irq(IRQ_LCD, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi); | 1449 | irq = platform_get_irq(dev, 0); |
1450 | if (irq < 0) { | ||
1451 | dev_err(&dev->dev, "no IRQ defined\n"); | ||
1452 | ret = -ENODEV; | ||
1453 | goto failed_free_mem; | ||
1454 | } | ||
1455 | |||
1456 | ret = request_irq(irq, pxafb_handle_irq, IRQF_DISABLED, "LCD", fbi); | ||
1418 | if (ret) { | 1457 | if (ret) { |
1419 | dev_err(&dev->dev, "request_irq failed: %d\n", ret); | 1458 | dev_err(&dev->dev, "request_irq failed: %d\n", ret); |
1420 | ret = -EBUSY; | 1459 | ret = -EBUSY; |
1421 | goto failed; | 1460 | goto failed_free_mem; |
1422 | } | 1461 | } |
1423 | 1462 | ||
1424 | /* | 1463 | /* |
@@ -1434,7 +1473,7 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1434 | if (ret < 0) { | 1473 | if (ret < 0) { |
1435 | dev_err(&dev->dev, | 1474 | dev_err(&dev->dev, |
1436 | "Failed to register framebuffer device: %d\n", ret); | 1475 | "Failed to register framebuffer device: %d\n", ret); |
1437 | goto failed; | 1476 | goto failed_free_irq; |
1438 | } | 1477 | } |
1439 | 1478 | ||
1440 | #ifdef CONFIG_CPU_FREQ | 1479 | #ifdef CONFIG_CPU_FREQ |
@@ -1453,6 +1492,15 @@ static int __init pxafb_probe(struct platform_device *dev) | |||
1453 | 1492 | ||
1454 | return 0; | 1493 | return 0; |
1455 | 1494 | ||
1495 | failed_free_irq: | ||
1496 | free_irq(irq, fbi); | ||
1497 | failed_free_res: | ||
1498 | release_mem_region(r->start, r->end - r->start + 1); | ||
1499 | failed_free_io: | ||
1500 | iounmap(fbi->mmio_base); | ||
1501 | failed_free_mem: | ||
1502 | dma_free_writecombine(&dev->dev, fbi->map_size, | ||
1503 | fbi->map_cpu, fbi->map_dma); | ||
1456 | failed: | 1504 | failed: |
1457 | platform_set_drvdata(dev, NULL); | 1505 | platform_set_drvdata(dev, NULL); |
1458 | kfree(fbi); | 1506 | kfree(fbi); |