~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/video/pxafb.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
627
627
 
628
628
static void overlay1fb_disable(struct pxafb_layer *ofb)
629
629
{
630
 
        uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
630
        uint32_t lccr5;
 
631
 
 
632
        if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
 
633
                return;
 
634
 
 
635
        lccr5 = lcd_readl(ofb->fbi, LCCR5);
631
636
 
632
637
        lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
633
638
 
685
690
 
686
691
static void overlay2fb_disable(struct pxafb_layer *ofb)
687
692
{
688
 
        uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
 
693
        uint32_t lccr5;
 
694
 
 
695
        if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
 
696
                return;
 
697
 
 
698
        lccr5 = lcd_readl(ofb->fbi, LCCR5);
689
699
 
690
700
        lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
691
701
 
720
730
        if (user == 0)
721
731
                return -ENODEV;
722
732
 
723
 
        /* allow only one user at a time */
724
 
        if (atomic_inc_and_test(&ofb->usage))
725
 
                return -EBUSY;
 
733
        if (ofb->usage++ == 0)
 
734
                /* unblank the base framebuffer */
 
735
                fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
726
736
 
727
 
        /* unblank the base framebuffer */
728
 
        fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
729
737
        return 0;
730
738
}
731
739
 
733
741
{
734
742
        struct pxafb_layer *ofb = (struct pxafb_layer*) info;
735
743
 
736
 
        atomic_dec(&ofb->usage);
737
 
        ofb->ops->disable(ofb);
 
744
        if (ofb->usage == 1) {
 
745
                ofb->ops->disable(ofb);
 
746
                ofb->fb.var.height      = -1;
 
747
                ofb->fb.var.width       = -1;
 
748
                ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
 
749
                ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
738
750
 
739
 
        free_pages_exact(ofb->video_mem, ofb->video_mem_size);
740
 
        ofb->video_mem = NULL;
741
 
        ofb->video_mem_size = 0;
 
751
                ofb->usage--;
 
752
        }
742
753
        return 0;
743
754
}
744
755
 
750
761
        int xpos, ypos, pfor, bpp;
751
762
 
752
763
        xpos = NONSTD_TO_XPOS(var->nonstd);
753
 
        ypos = NONSTD_TO_XPOS(var->nonstd);
 
764
        ypos = NONSTD_TO_YPOS(var->nonstd);
754
765
        pfor = NONSTD_TO_PFOR(var->nonstd);
755
766
 
756
767
        bpp = pxafb_var_to_bpp(var);
794
805
        return 0;
795
806
}
796
807
 
797
 
static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
 
808
static int overlayfb_check_video_memory(struct pxafb_layer *ofb)
798
809
{
799
810
        struct fb_var_screeninfo *var = &ofb->fb.var;
800
811
        int pfor = NONSTD_TO_PFOR(var->nonstd);
812
823
 
813
824
        size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
814
825
 
815
 
        /* don't re-allocate if the original video memory is enough */
816
826
        if (ofb->video_mem) {
817
827
                if (ofb->video_mem_size >= size)
818
828
                        return 0;
819
 
 
820
 
                free_pages_exact(ofb->video_mem, ofb->video_mem_size);
821
829
        }
822
 
 
823
 
        ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
824
 
        if (ofb->video_mem == NULL)
825
 
                return -ENOMEM;
826
 
 
827
 
        ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
828
 
        ofb->video_mem_size = size;
829
 
 
830
 
        mutex_lock(&ofb->fb.mm_lock);
831
 
        ofb->fb.fix.smem_start  = ofb->video_mem_phys;
832
 
        ofb->fb.fix.smem_len    = ofb->fb.fix.line_length * var->yres_virtual;
833
 
        mutex_unlock(&ofb->fb.mm_lock);
834
 
        ofb->fb.screen_base     = ofb->video_mem;
835
 
        return 0;
 
830
        return -EINVAL;
836
831
}
837
832
 
838
833
static int overlayfb_set_par(struct fb_info *info)
841
836
        struct fb_var_screeninfo *var = &info->var;
842
837
        int xpos, ypos, pfor, bpp, ret;
843
838
 
844
 
        ret = overlayfb_map_video_memory(ofb);
 
839
        ret = overlayfb_check_video_memory(ofb);
845
840
        if (ret)
846
841
                return ret;
847
842
 
848
843
        bpp  = pxafb_var_to_bpp(var);
849
844
        xpos = NONSTD_TO_XPOS(var->nonstd);
850
 
        ypos = NONSTD_TO_XPOS(var->nonstd);
 
845
        ypos = NONSTD_TO_YPOS(var->nonstd);
851
846
        pfor = NONSTD_TO_PFOR(var->nonstd);
852
847
 
853
848
        ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
891
886
 
892
887
        ofb->id = id;
893
888
        ofb->ops = &ofb_ops[id];
894
 
        atomic_set(&ofb->usage, 0);
 
889
        ofb->usage = 0;
895
890
        ofb->fbi = fbi;
896
891
        init_completion(&ofb->branch_done);
897
892
}
904
899
        return 0;
905
900
}
906
901
 
907
 
static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
 
902
static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
 
903
        struct pxafb_layer *ofb)
 
904
{
 
905
        /* We assume that user will use at most video_mem_size for overlay fb,
 
906
         * anyway, it's useless to use 16bpp main plane and 24bpp overlay
 
907
         */
 
908
        ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
 
909
                GFP_KERNEL | __GFP_ZERO);
 
910
        if (ofb->video_mem == NULL)
 
911
                return -ENOMEM;
 
912
 
 
913
        ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
 
914
        ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
 
915
 
 
916
        mutex_lock(&ofb->fb.mm_lock);
 
917
        ofb->fb.fix.smem_start  = ofb->video_mem_phys;
 
918
        ofb->fb.fix.smem_len    = pxafb->video_mem_size;
 
919
        mutex_unlock(&ofb->fb.mm_lock);
 
920
 
 
921
        ofb->fb.screen_base     = ofb->video_mem;
 
922
 
 
923
        return 0;
 
924
}
 
925
 
 
926
static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
908
927
{
909
928
        int i, ret;
910
929
 
911
930
        if (!pxafb_overlay_supported())
912
 
                return 0;
 
931
                return;
913
932
 
914
933
        for (i = 0; i < 2; i++) {
915
 
                init_pxafb_overlay(fbi, &fbi->overlay[i], i);
916
 
                ret = register_framebuffer(&fbi->overlay[i].fb);
 
934
                struct pxafb_layer *ofb = &fbi->overlay[i];
 
935
                init_pxafb_overlay(fbi, ofb, i);
 
936
                ret = register_framebuffer(&ofb->fb);
917
937
                if (ret) {
918
938
                        dev_err(fbi->dev, "failed to register overlay %d\n", i);
919
 
                        return ret;
920
 
                }
 
939
                        continue;
 
940
                }
 
941
                ret = pxafb_overlay_map_video_memory(fbi, ofb);
 
942
                if (ret) {
 
943
                        dev_err(fbi->dev,
 
944
                                "failed to map video memory for overlay %d\n",
 
945
                                i);
 
946
                        unregister_framebuffer(&ofb->fb);
 
947
                        continue;
 
948
                }
 
949
                ofb->registered = 1;
921
950
        }
922
951
 
923
952
        /* mask all IU/BS/EOF/SOF interrupts */
924
953
        lcd_writel(fbi, LCCR5, ~0);
925
954
 
926
 
        /* place overlay(s) on top of base */
927
 
        fbi->lccr0 |= LCCR0_OUC;
928
955
        pr_info("PXA Overlay driver loaded successfully!\n");
929
 
        return 0;
930
956
}
931
957
 
932
958
static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
936
962
        if (!pxafb_overlay_supported())
937
963
                return;
938
964
 
939
 
        for (i = 0; i < 2; i++)
940
 
                unregister_framebuffer(&fbi->overlay[i].fb);
 
965
        for (i = 0; i < 2; i++) {
 
966
                struct pxafb_layer *ofb = &fbi->overlay[i];
 
967
                if (ofb->registered) {
 
968
                        if (ofb->video_mem)
 
969
                                free_pages_exact(ofb->video_mem,
 
970
                                        ofb->video_mem_size);
 
971
                        unregister_framebuffer(&ofb->fb);
 
972
                }
 
973
        }
941
974
}
942
975
#else
943
976
static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
1368
1401
            (lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
1369
1402
            (lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
1370
1403
            (lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
1371
 
            (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
 
1404
            ((fbi->lccr0 & LCCR0_SDS) &&
 
1405
            (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
1372
1406
                pxafb_schedule_work(fbi, C_REENABLE);
1373
1407
 
1374
1408
        return 0;
1420
1454
        lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
1421
1455
 
1422
1456
        lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
1423
 
        lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
 
1457
        if (fbi->lccr0 & LCCR0_SDS)
 
1458
                lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
1424
1459
        lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
1425
1460
}
1426
1461
 
1613
1648
 
1614
1649
        switch (val) {
1615
1650
        case CPUFREQ_PRECHANGE:
1616
 
                set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
 
1651
#ifdef CONFIG_FB_PXA_OVERLAY
 
1652
                if (!(fbi->overlay[0].usage || fbi->overlay[1].usage))
 
1653
#endif
 
1654
                        set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
1617
1655
                break;
1618
1656
 
1619
1657
        case CPUFREQ_POSTCHANGE:
1806
1844
 
1807
1845
        pxafb_decode_mach_info(fbi, inf);
1808
1846
 
 
1847
#ifdef CONFIG_FB_PXA_OVERLAY
 
1848
        /* place overlay(s) on top of base */
 
1849
        if (pxafb_overlay_supported())
 
1850
                fbi->lccr0 |= LCCR0_OUC;
 
1851
#endif
 
1852
 
1809
1853
        init_waitqueue_head(&fbi->ctrlr_wait);
1810
1854
        INIT_WORK(&fbi->task, pxafb_task);
1811
1855
        mutex_init(&fbi->ctrlr_lock);