aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via/viafbdev.c
diff options
context:
space:
mode:
authorFlorian Tobias Schandinat <FlorianSchandinat@gmx.de>2009-09-22 19:47:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-23 10:39:52 -0400
commitc3e25673843153ea75fda79a47cf12f10a25ca37 (patch)
treefdc15161f32ca26450614c08b82c293b788ffb40 /drivers/video/via/viafbdev.c
parentc4df5489e40e55f2962b9e8100ebc0d4d1374415 (diff)
viafb: 2D engine rewrite
This patch is a completly rewritten 2D engine. The engine is no longer in a default state but reinitialized every time to allow usage for both framebuffers regardless of their settings. The whole engine handling is concentrated in a big function which takes 16 parameters. Although the number of parameters is worryingly it is good to have a single funtion to deal with this stuff as it allows to easily support different engines and avoids some code duplication. On the way support for the new 2D engine in VX800 was added. As the with less code duplication but it is probably better to duplicate the code as this way is easier to walk if VIA ever decides to release a new engine which changes anything the driver touches. The engine support for VX800 gives a notable boost in speed. There are no known regressions but as this patch changes paths I do neither have the hardware nor documentation to check and has the possibility to put the system in a critical state heavy testing is appreciated. Signed-off-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: Scott Fang <ScottFang@viatech.com.cn> Cc: Joseph Chan <JosephChan@via.com.tw> Cc: Harald Welte <laforge@gnumonks.org> Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/via/viafbdev.c')
-rw-r--r--drivers/video/via/viafbdev.c226
1 files changed, 60 insertions, 166 deletions
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 4a8853a07602..66921de373fe 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -95,11 +95,8 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
95 struct fb_info *info) 95 struct fb_info *info)
96{ 96{
97 int vmode_index, htotal, vtotal; 97 int vmode_index, htotal, vtotal;
98 struct viafb_par *ppar; 98 struct viafb_par *ppar = info->par;
99 u32 long_refresh; 99 u32 long_refresh;
100 struct viafb_par *p_viafb_par;
101 ppar = info->par;
102
103 100
104 DEBUG_MSG(KERN_INFO "viafb_check_var!\n"); 101 DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
105 /* Sanity check */ 102 /* Sanity check */
@@ -144,22 +141,17 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
144 /* Adjust var according to our driver's own table */ 141 /* Adjust var according to our driver's own table */
145 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index); 142 viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
146 143
147 /* This is indeed a patch for VT3353 */
148 if (!info->par)
149 return -1;
150 p_viafb_par = (struct viafb_par *)info->par;
151 if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800)
152 var->accel_flags = 0;
153
154 return 0; 144 return 0;
155} 145}
156 146
157static int viafb_set_par(struct fb_info *info) 147static int viafb_set_par(struct fb_info *info)
158{ 148{
149 struct viafb_par *viapar = info->par;
159 int vmode_index; 150 int vmode_index;
160 int vmode_index1 = 0; 151 int vmode_index1 = 0;
161 DEBUG_MSG(KERN_INFO "viafb_set_par!\n"); 152 DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
162 153
154 viapar->depth = fb_get_color_depth(&info->var, &info->fix);
163 viafb_update_device_setting(info->var.xres, info->var.yres, 155 viafb_update_device_setting(info->var.xres, info->var.yres,
164 info->var.bits_per_pixel, viafb_refresh, 0); 156 info->var.bits_per_pixel, viafb_refresh, 0);
165 157
@@ -190,9 +182,6 @@ static int viafb_set_par(struct fb_info *info)
190 viafb_bpp = info->var.bits_per_pixel; 182 viafb_bpp = info->var.bits_per_pixel;
191 /* Update viafb_accel, it is necessary to our 2D accelerate */ 183 /* Update viafb_accel, it is necessary to our 2D accelerate */
192 viafb_accel = info->var.accel_flags; 184 viafb_accel = info->var.accel_flags;
193
194 if (viafb_accel)
195 viafb_set_2d_color_depth(info->var.bits_per_pixel);
196 } 185 }
197 186
198 return 0; 187 return 0;
@@ -777,10 +766,11 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
777static void viafb_fillrect(struct fb_info *info, 766static void viafb_fillrect(struct fb_info *info,
778 const struct fb_fillrect *rect) 767 const struct fb_fillrect *rect)
779{ 768{
780 u32 col = 0, rop = 0; 769 struct viafb_par *viapar = info->par;
781 int pitch; 770 u32 fg_color;
771 u8 rop;
782 772
783 if (!viafb_accel) { 773 if (!viapar->shared->hw_bitblt) {
784 cfb_fillrect(info, rect); 774 cfb_fillrect(info, rect);
785 return; 775 return;
786 } 776 }
@@ -788,67 +778,30 @@ static void viafb_fillrect(struct fb_info *info,
788 if (!rect->width || !rect->height) 778 if (!rect->width || !rect->height)
789 return; 779 return;
790 780
791 switch (rect->rop) { 781 if (info->fix.visual == FB_VISUAL_TRUECOLOR)
792 case ROP_XOR: 782 fg_color = ((u32 *)info->pseudo_palette)[rect->color];
783 else
784 fg_color = rect->color;
785
786 if (rect->rop == ROP_XOR)
793 rop = 0x5A; 787 rop = 0x5A;
794 break; 788 else
795 case ROP_COPY:
796 default:
797 rop = 0xF0; 789 rop = 0xF0;
798 break;
799 }
800
801 switch (info->var.bits_per_pixel) {
802 case 8:
803 col = rect->color;
804 break;
805 case 16:
806 col = ((u32 *) (info->pseudo_palette))[rect->color];
807 break;
808 case 32:
809 col = ((u32 *) (info->pseudo_palette))[rect->color];
810 break;
811 }
812
813 /* BitBlt Source Address */
814 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
815 /* Source Base Address */
816 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
817 /* Destination Base Address */
818 writel((info->fix.smem_start - viafbinfo->fix.smem_start) >> 3,
819 viaparinfo->io_virt + VIA_REG_DSTBASE);
820 /* Pitch */
821 pitch = (info->var.xres_virtual + 7) & ~7;
822 writel(VIA_PITCH_ENABLE |
823 (((pitch *
824 info->var.bits_per_pixel >> 3) >> 3) |
825 (((pitch * info->
826 var.bits_per_pixel >> 3) >> 3) << 16)),
827 viaparinfo->io_virt + VIA_REG_PITCH);
828 /* BitBlt Destination Address */
829 writel(((rect->dy << 16) | rect->dx),
830 viaparinfo->io_virt + VIA_REG_DSTPOS);
831 /* Dimension: width & height */
832 writel((((rect->height - 1) << 16) | (rect->width - 1)),
833 viaparinfo->io_virt + VIA_REG_DIMENSION);
834 /* Forground color or Destination color */
835 writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
836 /* GE Command */
837 writel((0x01 | 0x2000 | (rop << 24)),
838 viaparinfo->io_virt + VIA_REG_GECMD);
839 790
791 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
792 if (viapar->shared->hw_bitblt(viapar->io_virt, VIA_BITBLT_FILL,
793 rect->width, rect->height, info->var.bits_per_pixel,
794 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
795 NULL, 0, 0, 0, 0, fg_color, 0, rop))
796 cfb_fillrect(info, rect);
840} 797}
841 798
842static void viafb_copyarea(struct fb_info *info, 799static void viafb_copyarea(struct fb_info *info,
843 const struct fb_copyarea *area) 800 const struct fb_copyarea *area)
844{ 801{
845 u32 dy = area->dy, sy = area->sy, direction = 0x0; 802 struct viafb_par *viapar = info->par;
846 u32 sx = area->sx, dx = area->dx, width = area->width;
847 int pitch;
848 803
849 DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n"); 804 if (!viapar->shared->hw_bitblt) {
850
851 if (!viafb_accel) {
852 cfb_copyarea(info, area); 805 cfb_copyarea(info, area);
853 return; 806 return;
854 } 807 }
@@ -856,113 +809,48 @@ static void viafb_copyarea(struct fb_info *info,
856 if (!area->width || !area->height) 809 if (!area->width || !area->height)
857 return; 810 return;
858 811
859 if (sy < dy) { 812 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n");
860 dy += area->height - 1; 813 if (viapar->shared->hw_bitblt(viapar->io_virt, VIA_BITBLT_COLOR,
861 sy += area->height - 1; 814 area->width, area->height, info->var.bits_per_pixel,
862 direction |= 0x4000; 815 viapar->vram_addr, info->fix.line_length, area->dx, area->dy,
863 } 816 NULL, viapar->vram_addr, info->fix.line_length,
864 817 area->sx, area->sy, 0, 0, 0))
865 if (sx < dx) { 818 cfb_copyarea(info, area);
866 dx += width - 1;
867 sx += width - 1;
868 direction |= 0x8000;
869 }
870
871 /* Source Base Address */
872 writel((info->fix.smem_start - viafbinfo->fix.smem_start) >> 3,
873 viaparinfo->io_virt + VIA_REG_SRCBASE);
874 /* Destination Base Address */
875 writel((info->fix.smem_start - viafbinfo->fix.smem_start) >> 3,
876 viaparinfo->io_virt + VIA_REG_DSTBASE);
877 /* Pitch */
878 pitch = (info->var.xres_virtual + 7) & ~7;
879 /* VIA_PITCH_ENABLE can be omitted now. */
880 writel(VIA_PITCH_ENABLE |
881 (((pitch *
882 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
883 info->var.
884 bits_per_pixel
885 >> 3) >> 3)
886 << 16)),
887 viaparinfo->io_virt + VIA_REG_PITCH);
888 /* BitBlt Source Address */
889 writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS);
890 /* BitBlt Destination Address */
891 writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS);
892 /* Dimension: width & height */
893 writel((((area->height - 1) << 16) | (area->width - 1)),
894 viaparinfo->io_virt + VIA_REG_DIMENSION);
895 /* GE Command */
896 writel((0x01 | direction | (0xCC << 24)),
897 viaparinfo->io_virt + VIA_REG_GECMD);
898
899} 819}
900 820
901static void viafb_imageblit(struct fb_info *info, 821static void viafb_imageblit(struct fb_info *info,
902 const struct fb_image *image) 822 const struct fb_image *image)
903{ 823{
904 u32 size, bg_col = 0, fg_col = 0, *udata; 824 struct viafb_par *viapar = info->par;
905 int i; 825 u32 fg_color = 0, bg_color = 0;
906 int pitch; 826 u8 op;
907 827
908 if (!viafb_accel) { 828 if (!viapar->shared->hw_bitblt ||
829 (image->depth != 1 && image->depth != viapar->depth)) {
909 cfb_imageblit(info, image); 830 cfb_imageblit(info, image);
910 return; 831 return;
911 } 832 }
912 833
913 udata = (u32 *) image->data; 834 if (image->depth == 1) {
914 835 op = VIA_BITBLT_MONO;
915 switch (info->var.bits_per_pixel) { 836 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
916 case 8: 837 fg_color =
917 bg_col = image->bg_color; 838 ((u32 *)info->pseudo_palette)[image->fg_color];
918 fg_col = image->fg_color; 839 bg_color =
919 break; 840 ((u32 *)info->pseudo_palette)[image->bg_color];
920 case 16: 841 } else {
921 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; 842 fg_color = image->fg_color;
922 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color]; 843 bg_color = image->bg_color;
923 break; 844 }
924 case 32: 845 } else
925 bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color]; 846 op = VIA_BITBLT_COLOR;
926 fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
927 break;
928 }
929 size = image->width * image->height;
930
931 /* Source Base Address */
932 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
933 /* Destination Base Address */
934 writel((info->fix.smem_start - viafbinfo->fix.smem_start) >> 3,
935 viaparinfo->io_virt + VIA_REG_DSTBASE);
936 /* Pitch */
937 pitch = (info->var.xres_virtual + 7) & ~7;
938 writel(VIA_PITCH_ENABLE |
939 (((pitch *
940 info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
941 info->var.
942 bits_per_pixel
943 >> 3) >> 3)
944 << 16)),
945 viaparinfo->io_virt + VIA_REG_PITCH);
946 /* BitBlt Source Address */
947 writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
948 /* BitBlt Destination Address */
949 writel(((image->dy << 16) | image->dx),
950 viaparinfo->io_virt + VIA_REG_DSTPOS);
951 /* Dimension: width & height */
952 writel((((image->height - 1) << 16) | (image->width - 1)),
953 viaparinfo->io_virt + VIA_REG_DIMENSION);
954 /* fb color */
955 writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
956 /* bg color */
957 writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR);
958 /* GE Command */
959 writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD);
960
961 for (i = 0; i < size / 4; i++) {
962 writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE);
963 udata++;
964 }
965 847
848 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n");
849 if (viapar->shared->hw_bitblt(viapar->io_virt, op,
850 image->width, image->height, info->var.bits_per_pixel,
851 viapar->vram_addr, info->fix.line_length, image->dx, image->dy,
852 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0))
853 cfb_imageblit(info, image);
966} 854}
967 855
968static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 856static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
@@ -1961,6 +1849,7 @@ static int __devinit via_pci_probe(void)
1961 1849
1962 viaparinfo = (struct viafb_par *)viafbinfo->par; 1850 viaparinfo = (struct viafb_par *)viafbinfo->par;
1963 viaparinfo->shared = viafbinfo->par + viafb_par_length; 1851 viaparinfo->shared = viafbinfo->par + viafb_par_length;
1852 viaparinfo->vram_addr = 0;
1964 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; 1853 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info;
1965 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; 1854 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;
1966 viaparinfo->lvds_setting_info2 = 1855 viaparinfo->lvds_setting_info2 =
@@ -2007,7 +1896,7 @@ static int __devinit via_pci_probe(void)
2007 1896
2008 viafbinfo->pseudo_palette = pseudo_pal; 1897 viafbinfo->pseudo_palette = pseudo_pal;
2009 if (viafb_accel) { 1898 if (viafb_accel) {
2010 viafb_init_accel(); 1899 viafb_init_accel(viaparinfo->shared);
2011 viafb_init_2d_engine(); 1900 viafb_init_2d_engine();
2012 viafb_hw_cursor_init(); 1901 viafb_hw_cursor_init();
2013 } 1902 }
@@ -2110,6 +1999,7 @@ static int __devinit via_pci_probe(void)
2110 } 1999 }
2111 viaparinfo1 = viafbinfo1->par; 2000 viaparinfo1 = viafbinfo1->par;
2112 memcpy(viaparinfo1, viaparinfo, viafb_par_length); 2001 memcpy(viaparinfo1, viaparinfo, viafb_par_length);
2002 viaparinfo1->vram_addr = viafb_second_offset;
2113 viaparinfo1->memsize = viaparinfo->memsize - 2003 viaparinfo1->memsize = viaparinfo->memsize -
2114 viafb_second_offset; 2004 viafb_second_offset;
2115 viaparinfo->memsize = viafb_second_offset; 2005 viaparinfo->memsize = viafb_second_offset;
@@ -2157,12 +2047,16 @@ static int __devinit via_pci_probe(void)
2157 viafb_check_var(&default_var, viafbinfo1); 2047 viafb_check_var(&default_var, viafbinfo1);
2158 viafbinfo1->var = default_var; 2048 viafbinfo1->var = default_var;
2159 viafb_update_fix(viafbinfo1); 2049 viafb_update_fix(viafbinfo1);
2050 viaparinfo1->depth = fb_get_color_depth(&viafbinfo1->var,
2051 &viafbinfo1->fix);
2160 } 2052 }
2161 2053
2162 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo); 2054 viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
2163 viafb_check_var(&default_var, viafbinfo); 2055 viafb_check_var(&default_var, viafbinfo);
2164 viafbinfo->var = default_var; 2056 viafbinfo->var = default_var;
2165 viafb_update_fix(viafbinfo); 2057 viafb_update_fix(viafbinfo);
2058 viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
2059 &viafbinfo->fix);
2166 default_var.activate = FB_ACTIVATE_NOW; 2060 default_var.activate = FB_ACTIVATE_NOW;
2167 fb_alloc_cmap(&viafbinfo->cmap, 256, 0); 2061 fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
2168 2062