diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-12-23 13:06:37 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-12-23 13:06:37 -0500 |
commit | 40321fd21c1eb1fb1886eea73b5f87c5e41ff2fb (patch) | |
tree | 0d949c487ba15c4c8198a69cd7b8c0cdb5773af4 /drivers/video/pxafb.c | |
parent | d83a12a40915774332cec625856c2e7ba9033e15 (diff) | |
parent | 3b24f30c4f678cfab5c6d090af9559fefa37cc41 (diff) |
Merge branch 'for-rmk' of git://git.kernel.org/pub/scm/linux/kernel/git/ycmiao/pxa-linux-2.6 into devel
Conflicts:
arch/arm/mach-pxa/am200epd.c
arch/arm/mach-pxa/ezx.c
Diffstat (limited to 'drivers/video/pxafb.c')
-rw-r--r-- | drivers/video/pxafb.c | 102 |
1 files changed, 29 insertions, 73 deletions
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index afe7a65c5603..d0fd22e06737 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
51 | #include <asm/div64.h> | 51 | #include <asm/div64.h> |
52 | #include <mach/pxa-regs.h> | 52 | #include <mach/pxa-regs.h> |
53 | #include <mach/pxa2xx-gpio.h> | ||
54 | #include <mach/bitfield.h> | 53 | #include <mach/bitfield.h> |
55 | #include <mach/pxafb.h> | 54 | #include <mach/pxafb.h> |
56 | 55 | ||
@@ -724,12 +723,19 @@ int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int n_cmds) | |||
724 | int i; | 723 | int i; |
725 | struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); | 724 | struct pxafb_info *fbi = container_of(info, struct pxafb_info, fb); |
726 | 725 | ||
727 | /* leave 2 commands for INTERRUPT and WAIT_FOR_SYNC */ | 726 | for (i = 0; i < n_cmds; i++, cmds++) { |
728 | for (i = 0; i < n_cmds; i++) { | 727 | /* if it is a software delay, flush and delay */ |
728 | if ((*cmds & 0xff00) == SMART_CMD_DELAY) { | ||
729 | pxafb_smart_flush(info); | ||
730 | mdelay(*cmds & 0xff); | ||
731 | continue; | ||
732 | } | ||
733 | |||
734 | /* leave 2 commands for INTERRUPT and WAIT_FOR_SYNC */ | ||
729 | if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8) | 735 | if (fbi->n_smart_cmds == CMD_BUFF_SIZE - 8) |
730 | pxafb_smart_flush(info); | 736 | pxafb_smart_flush(info); |
731 | 737 | ||
732 | fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds++; | 738 | fbi->smart_cmds[fbi->n_smart_cmds++] = *cmds; |
733 | } | 739 | } |
734 | 740 | ||
735 | return 0; | 741 | return 0; |
@@ -761,7 +767,9 @@ static void setup_smart_timing(struct pxafb_info *fbi, | |||
761 | LCCR1_HorSnchWdth(__smart_timing(t3, lclk)); | 767 | LCCR1_HorSnchWdth(__smart_timing(t3, lclk)); |
762 | 768 | ||
763 | fbi->reg_lccr2 = LCCR2_DisHght(var->yres); | 769 | fbi->reg_lccr2 = LCCR2_DisHght(var->yres); |
764 | fbi->reg_lccr3 = LCCR3_PixClkDiv(__smart_timing(t4, lclk)); | 770 | fbi->reg_lccr3 = fbi->lccr3 | LCCR3_PixClkDiv(__smart_timing(t4, lclk)); |
771 | fbi->reg_lccr3 |= (var->sync & FB_SYNC_HOR_HIGH_ACT) ? LCCR3_HSP : 0; | ||
772 | fbi->reg_lccr3 |= (var->sync & FB_SYNC_VERT_HIGH_ACT) ? LCCR3_VSP : 0; | ||
765 | 773 | ||
766 | /* FIXME: make this configurable */ | 774 | /* FIXME: make this configurable */ |
767 | fbi->reg_cmdcr = 1; | 775 | fbi->reg_cmdcr = 1; |
@@ -786,11 +794,15 @@ static int pxafb_smart_thread(void *arg) | |||
786 | if (try_to_freeze()) | 794 | if (try_to_freeze()) |
787 | continue; | 795 | continue; |
788 | 796 | ||
797 | mutex_lock(&fbi->ctrlr_lock); | ||
798 | |||
789 | if (fbi->state == C_ENABLE) { | 799 | if (fbi->state == C_ENABLE) { |
790 | inf->smart_update(&fbi->fb); | 800 | inf->smart_update(&fbi->fb); |
791 | complete(&fbi->refresh_done); | 801 | complete(&fbi->refresh_done); |
792 | } | 802 | } |
793 | 803 | ||
804 | mutex_unlock(&fbi->ctrlr_lock); | ||
805 | |||
794 | set_current_state(TASK_INTERRUPTIBLE); | 806 | set_current_state(TASK_INTERRUPTIBLE); |
795 | schedule_timeout(30 * HZ / 1000); | 807 | schedule_timeout(30 * HZ / 1000); |
796 | } | 808 | } |
@@ -801,14 +813,19 @@ static int pxafb_smart_thread(void *arg) | |||
801 | 813 | ||
802 | static int pxafb_smart_init(struct pxafb_info *fbi) | 814 | static int pxafb_smart_init(struct pxafb_info *fbi) |
803 | { | 815 | { |
804 | if (!(fbi->lccr0 | LCCR0_LCDT)) | 816 | if (!(fbi->lccr0 & LCCR0_LCDT)) |
805 | return 0; | 817 | return 0; |
806 | 818 | ||
819 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; | ||
820 | fbi->n_smart_cmds = 0; | ||
821 | |||
822 | init_completion(&fbi->command_done); | ||
823 | init_completion(&fbi->refresh_done); | ||
824 | |||
807 | fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, | 825 | fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi, |
808 | "lcd_refresh"); | 826 | "lcd_refresh"); |
809 | if (IS_ERR(fbi->smart_thread)) { | 827 | if (IS_ERR(fbi->smart_thread)) { |
810 | printk(KERN_ERR "%s: unable to create kernel thread\n", | 828 | pr_err("%s: unable to create kernel thread\n", __func__); |
811 | __func__); | ||
812 | return PTR_ERR(fbi->smart_thread); | 829 | return PTR_ERR(fbi->smart_thread); |
813 | } | 830 | } |
814 | 831 | ||
@@ -824,7 +841,9 @@ int pxafb_smart_flush(struct fb_info *info) | |||
824 | { | 841 | { |
825 | return 0; | 842 | return 0; |
826 | } | 843 | } |
827 | #endif /* CONFIG_FB_SMART_PANEL */ | 844 | |
845 | static inline int pxafb_smart_init(struct pxafb_info *fbi) { return 0; } | ||
846 | #endif /* CONFIG_FB_PXA_SMARTPANEL */ | ||
828 | 847 | ||
829 | static void setup_parallel_timing(struct pxafb_info *fbi, | 848 | static void setup_parallel_timing(struct pxafb_info *fbi, |
830 | struct fb_var_screeninfo *var) | 849 | struct fb_var_screeninfo *var) |
@@ -986,57 +1005,6 @@ static inline void __pxafb_lcd_power(struct pxafb_info *fbi, int on) | |||
986 | fbi->lcd_power(on, &fbi->fb.var); | 1005 | fbi->lcd_power(on, &fbi->fb.var); |
987 | } | 1006 | } |
988 | 1007 | ||
989 | static void pxafb_setup_gpio(struct pxafb_info *fbi) | ||
990 | { | ||
991 | int gpio, ldd_bits; | ||
992 | unsigned int lccr0 = fbi->lccr0; | ||
993 | |||
994 | /* | ||
995 | * setup is based on type of panel supported | ||
996 | */ | ||
997 | |||
998 | /* 4 bit interface */ | ||
999 | if ((lccr0 & LCCR0_CMS) == LCCR0_Mono && | ||
1000 | (lccr0 & LCCR0_SDS) == LCCR0_Sngl && | ||
1001 | (lccr0 & LCCR0_DPD) == LCCR0_4PixMono) | ||
1002 | ldd_bits = 4; | ||
1003 | |||
1004 | /* 8 bit interface */ | ||
1005 | else if (((lccr0 & LCCR0_CMS) == LCCR0_Mono && | ||
1006 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || | ||
1007 | (lccr0 & LCCR0_DPD) == LCCR0_8PixMono)) || | ||
1008 | ((lccr0 & LCCR0_CMS) == LCCR0_Color && | ||
1009 | (lccr0 & LCCR0_PAS) == LCCR0_Pas && | ||
1010 | (lccr0 & LCCR0_SDS) == LCCR0_Sngl)) | ||
1011 | ldd_bits = 8; | ||
1012 | |||
1013 | /* 16 bit interface */ | ||
1014 | else if ((lccr0 & LCCR0_CMS) == LCCR0_Color && | ||
1015 | ((lccr0 & LCCR0_SDS) == LCCR0_Dual || | ||
1016 | (lccr0 & LCCR0_PAS) == LCCR0_Act)) | ||
1017 | ldd_bits = 16; | ||
1018 | |||
1019 | else { | ||
1020 | printk(KERN_ERR "pxafb_setup_gpio: unable to determine " | ||
1021 | "bits per pixel\n"); | ||
1022 | return; | ||
1023 | } | ||
1024 | |||
1025 | for (gpio = 58; ldd_bits; gpio++, ldd_bits--) | ||
1026 | pxa_gpio_mode(gpio | GPIO_ALT_FN_2_OUT); | ||
1027 | /* 18 bit interface */ | ||
1028 | if (fbi->fb.var.bits_per_pixel > 16) { | ||
1029 | pxa_gpio_mode(86 | GPIO_ALT_FN_2_OUT); | ||
1030 | pxa_gpio_mode(87 | GPIO_ALT_FN_2_OUT); | ||
1031 | } | ||
1032 | pxa_gpio_mode(GPIO74_LCD_FCLK_MD); | ||
1033 | pxa_gpio_mode(GPIO75_LCD_LCLK_MD); | ||
1034 | pxa_gpio_mode(GPIO76_LCD_PCLK_MD); | ||
1035 | |||
1036 | if ((lccr0 & LCCR0_PAS) == 0) | ||
1037 | pxa_gpio_mode(GPIO77_LCD_ACBIAS_MD); | ||
1038 | } | ||
1039 | |||
1040 | static void pxafb_enable_controller(struct pxafb_info *fbi) | 1008 | static void pxafb_enable_controller(struct pxafb_info *fbi) |
1041 | { | 1009 | { |
1042 | pr_debug("pxafb: Enabling LCD controller\n"); | 1010 | pr_debug("pxafb: Enabling LCD controller\n"); |
@@ -1179,7 +1147,6 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) | |||
1179 | if (old_state == C_ENABLE) { | 1147 | if (old_state == C_ENABLE) { |
1180 | __pxafb_lcd_power(fbi, 0); | 1148 | __pxafb_lcd_power(fbi, 0); |
1181 | pxafb_disable_controller(fbi); | 1149 | pxafb_disable_controller(fbi); |
1182 | pxafb_setup_gpio(fbi); | ||
1183 | pxafb_enable_controller(fbi); | 1150 | pxafb_enable_controller(fbi); |
1184 | __pxafb_lcd_power(fbi, 1); | 1151 | __pxafb_lcd_power(fbi, 1); |
1185 | } | 1152 | } |
@@ -1202,7 +1169,6 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state) | |||
1202 | */ | 1169 | */ |
1203 | if (old_state != C_ENABLE) { | 1170 | if (old_state != C_ENABLE) { |
1204 | fbi->state = C_ENABLE; | 1171 | fbi->state = C_ENABLE; |
1205 | pxafb_setup_gpio(fbi); | ||
1206 | pxafb_enable_controller(fbi); | 1172 | pxafb_enable_controller(fbi); |
1207 | __pxafb_lcd_power(fbi, 1); | 1173 | __pxafb_lcd_power(fbi, 1); |
1208 | __pxafb_backlight_power(fbi, 1); | 1174 | __pxafb_backlight_power(fbi, 1); |
@@ -1340,11 +1306,6 @@ static int __devinit pxafb_map_video_memory(struct pxafb_info *fbi) | |||
1340 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; | 1306 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; |
1341 | 1307 | ||
1342 | pr_debug("pxafb: palette_mem_size = 0x%08x\n", fbi->palette_size*sizeof(u16)); | 1308 | pr_debug("pxafb: palette_mem_size = 0x%08x\n", fbi->palette_size*sizeof(u16)); |
1343 | |||
1344 | #ifdef CONFIG_FB_PXA_SMARTPANEL | ||
1345 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; | ||
1346 | fbi->n_smart_cmds = 0; | ||
1347 | #endif | ||
1348 | } | 1309 | } |
1349 | 1310 | ||
1350 | return fbi->map_cpu ? 0 : -ENOMEM; | 1311 | return fbi->map_cpu ? 0 : -ENOMEM; |
@@ -1466,10 +1427,6 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev) | |||
1466 | INIT_WORK(&fbi->task, pxafb_task); | 1427 | INIT_WORK(&fbi->task, pxafb_task); |
1467 | mutex_init(&fbi->ctrlr_lock); | 1428 | mutex_init(&fbi->ctrlr_lock); |
1468 | init_completion(&fbi->disable_done); | 1429 | init_completion(&fbi->disable_done); |
1469 | #ifdef CONFIG_FB_PXA_SMARTPANEL | ||
1470 | init_completion(&fbi->command_done); | ||
1471 | init_completion(&fbi->refresh_done); | ||
1472 | #endif | ||
1473 | 1430 | ||
1474 | return fbi; | 1431 | return fbi; |
1475 | } | 1432 | } |
@@ -1801,13 +1758,12 @@ static int __devinit pxafb_probe(struct platform_device *dev) | |||
1801 | goto failed_free_mem; | 1758 | goto failed_free_mem; |
1802 | } | 1759 | } |
1803 | 1760 | ||
1804 | #ifdef CONFIG_FB_PXA_SMARTPANEL | ||
1805 | ret = pxafb_smart_init(fbi); | 1761 | ret = pxafb_smart_init(fbi); |
1806 | if (ret) { | 1762 | if (ret) { |
1807 | dev_err(&dev->dev, "failed to initialize smartpanel\n"); | 1763 | dev_err(&dev->dev, "failed to initialize smartpanel\n"); |
1808 | goto failed_free_irq; | 1764 | goto failed_free_irq; |
1809 | } | 1765 | } |
1810 | #endif | 1766 | |
1811 | /* | 1767 | /* |
1812 | * This makes sure that our colour bitfield | 1768 | * This makes sure that our colour bitfield |
1813 | * descriptors are correctly initialised. | 1769 | * descriptors are correctly initialised. |