aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/pm3fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/pm3fb.c')
-rw-r--r--drivers/video/pm3fb.c152
1 files changed, 82 insertions, 70 deletions
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 195bcdbc66b5..1c41a4e5bc99 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -44,9 +44,10 @@
44 44
45#undef PM3FB_MASTER_DEBUG 45#undef PM3FB_MASTER_DEBUG
46#ifdef PM3FB_MASTER_DEBUG 46#ifdef PM3FB_MASTER_DEBUG
47#define DPRINTK(a,b...) printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b) 47#define DPRINTK(a, b...) \
48 printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
48#else 49#else
49#define DPRINTK(a,b...) 50#define DPRINTK(a, b...)
50#endif 51#endif
51 52
52#define PM3_PIXMAP_SIZE (2048 * 4) 53#define PM3_PIXMAP_SIZE (2048 * 4)
@@ -55,11 +56,11 @@
55 * Driver data 56 * Driver data
56 */ 57 */
57static char *mode_option __devinitdata; 58static char *mode_option __devinitdata;
58static int noaccel __devinitdata = 0; 59static int noaccel __devinitdata;
59 60
60/* mtrr option */ 61/* mtrr option */
61#ifdef CONFIG_MTRR 62#ifdef CONFIG_MTRR
62static int nomtrr __devinitdata = 0; 63static int nomtrr __devinitdata;
63#endif 64#endif
64 65
65/* 66/*
@@ -72,7 +73,7 @@ static int nomtrr __devinitdata = 0;
72struct pm3_par { 73struct pm3_par {
73 unsigned char __iomem *v_regs;/* virtual address of p_regs */ 74 unsigned char __iomem *v_regs;/* virtual address of p_regs */
74 u32 video; /* video flags before blanking */ 75 u32 video; /* video flags before blanking */
75 u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */ 76 u32 base; /* screen base in 128 bits unit */
76 u32 palette[16]; 77 u32 palette[16];
77 int mtrr_handle; 78 int mtrr_handle;
78}; 79};
@@ -376,7 +377,7 @@ static void pm3fb_init_engine(struct fb_info *info)
376 pm3fb_sync(info); 377 pm3fb_sync(info);
377} 378}
378 379
379static void pm3fb_fillrect (struct fb_info *info, 380static void pm3fb_fillrect(struct fb_info *info,
380 const struct fb_fillrect *region) 381 const struct fb_fillrect *region)
381{ 382{
382 struct pm3_par *par = info->par; 383 struct pm3_par *par = info->par;
@@ -384,7 +385,7 @@ static void pm3fb_fillrect (struct fb_info *info,
384 int vxres, vyres; 385 int vxres, vyres;
385 int rop; 386 int rop;
386 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 387 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
387 ((u32*)info->pseudo_palette)[region->color] : region->color; 388 ((u32 *)info->pseudo_palette)[region->color] : region->color;
388 389
389 if (info->state != FBINFO_STATE_RUNNING) 390 if (info->state != FBINFO_STATE_RUNNING)
390 return; 391 return;
@@ -403,18 +404,18 @@ static void pm3fb_fillrect (struct fb_info *info,
403 404
404 memcpy(&modded, region, sizeof(struct fb_fillrect)); 405 memcpy(&modded, region, sizeof(struct fb_fillrect));
405 406
406 if(!modded.width || !modded.height || 407 if (!modded.width || !modded.height ||
407 modded.dx >= vxres || modded.dy >= vyres) 408 modded.dx >= vxres || modded.dy >= vyres)
408 return; 409 return;
409 410
410 if(modded.dx + modded.width > vxres) 411 if (modded.dx + modded.width > vxres)
411 modded.width = vxres - modded.dx; 412 modded.width = vxres - modded.dx;
412 if(modded.dy + modded.height > vyres) 413 if (modded.dy + modded.height > vyres)
413 modded.height = vyres - modded.dy; 414 modded.height = vyres - modded.dy;
414 415
415 if(info->var.bits_per_pixel == 8) 416 if (info->var.bits_per_pixel == 8)
416 color |= color << 8; 417 color |= color << 8;
417 if(info->var.bits_per_pixel <= 16) 418 if (info->var.bits_per_pixel <= 16)
418 color |= color << 16; 419 color |= color << 16;
419 420
420 PM3_WAIT(par, 4); 421 PM3_WAIT(par, 4);
@@ -460,18 +461,18 @@ static void pm3fb_copyarea(struct fb_info *info,
460 vxres = info->var.xres_virtual; 461 vxres = info->var.xres_virtual;
461 vyres = info->var.yres_virtual; 462 vyres = info->var.yres_virtual;
462 463
463 if(!modded.width || !modded.height || 464 if (!modded.width || !modded.height ||
464 modded.sx >= vxres || modded.sy >= vyres || 465 modded.sx >= vxres || modded.sy >= vyres ||
465 modded.dx >= vxres || modded.dy >= vyres) 466 modded.dx >= vxres || modded.dy >= vyres)
466 return; 467 return;
467 468
468 if(modded.sx + modded.width > vxres) 469 if (modded.sx + modded.width > vxres)
469 modded.width = vxres - modded.sx; 470 modded.width = vxres - modded.sx;
470 if(modded.dx + modded.width > vxres) 471 if (modded.dx + modded.width > vxres)
471 modded.width = vxres - modded.dx; 472 modded.width = vxres - modded.dx;
472 if(modded.sy + modded.height > vyres) 473 if (modded.sy + modded.height > vyres)
473 modded.height = vyres - modded.sy; 474 modded.height = vyres - modded.sy;
474 if(modded.dy + modded.height > vyres) 475 if (modded.dy + modded.height > vyres)
475 modded.height = vyres - modded.dy; 476 modded.height = vyres - modded.dy;
476 477
477 o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */ 478 o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */
@@ -517,7 +518,7 @@ static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
517 struct pm3_par *par = info->par; 518 struct pm3_par *par = info->par;
518 u32 height = image->height; 519 u32 height = image->height;
519 u32 fgx, bgx; 520 u32 fgx, bgx;
520 const u32 *src = (const u32*)image->data; 521 const u32 *src = (const u32 *)image->data;
521 522
522 if (info->state != FBINFO_STATE_RUNNING) 523 if (info->state != FBINFO_STATE_RUNNING)
523 return; 524 return;
@@ -526,19 +527,19 @@ static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
526 return; 527 return;
527 } 528 }
528 switch (info->fix.visual) { 529 switch (info->fix.visual) {
529 case FB_VISUAL_PSEUDOCOLOR: 530 case FB_VISUAL_PSEUDOCOLOR:
530 fgx = image->fg_color; 531 fgx = image->fg_color;
531 bgx = image->bg_color; 532 bgx = image->bg_color;
532 break; 533 break;
533 case FB_VISUAL_TRUECOLOR: 534 case FB_VISUAL_TRUECOLOR:
534 default: 535 default:
535 fgx = par->palette[image->fg_color]; 536 fgx = par->palette[image->fg_color];
536 bgx = par->palette[image->bg_color]; 537 bgx = par->palette[image->bg_color];
537 break; 538 break;
538 } 539 }
539 if (image->depth != 1) { 540 if (image->depth != 1)
540 return cfb_imageblit(info, image); 541 return cfb_imageblit(info, image);
541 } 542
542 if (info->var.bits_per_pixel == 8) { 543 if (info->var.bits_per_pixel == 8) {
543 fgx |= fgx << 8; 544 fgx |= fgx << 8;
544 bgx |= bgx << 8; 545 bgx |= bgx << 8;
@@ -607,7 +608,8 @@ static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
607static void pm3fb_write_mode(struct fb_info *info) 608static void pm3fb_write_mode(struct fb_info *info)
608{ 609{
609 struct pm3_par *par = info->par; 610 struct pm3_par *par = info->par;
610 char tempsync = 0x00, tempmisc = 0x00; 611 char tempsync = 0x00;
612 char tempmisc = 0x00;
611 const u32 hsstart = info->var.right_margin; 613 const u32 hsstart = info->var.right_margin;
612 const u32 hsend = hsstart + info->var.hsync_len; 614 const u32 hsend = hsstart + info->var.hsync_len;
613 const u32 hbend = hsend + info->var.left_margin; 615 const u32 hbend = hsend + info->var.left_margin;
@@ -807,44 +809,54 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
807 if (bpp != var->bits_per_pixel) { 809 if (bpp != var->bits_per_pixel) {
808 /* set predefined mode for bits_per_pixel settings */ 810 /* set predefined mode for bits_per_pixel settings */
809 811
810 switch(var->bits_per_pixel) { 812 switch (var->bits_per_pixel) {
811 case 8: 813 case 8:
812 var->red.length = var->green.length = var->blue.length = 8; 814 var->red.length = 8;
813 var->red.offset = var->green.offset = var->blue.offset = 0; 815 var->green.length = 8;
816 var->blue.length = 8;
817 var->red.offset = 0;
818 var->green.offset = 0;
819 var->blue.offset = 0;
814 var->transp.offset = 0; 820 var->transp.offset = 0;
815 var->transp.length = 0; 821 var->transp.length = 0;
816 break; 822 break;
817 case 16: 823 case 16:
818 var->red.length = var->blue.length = 5; 824 var->red.length = 5;
825 var->blue.length = 5;
819 var->green.length = 6; 826 var->green.length = 6;
820 var->transp.length = 0; 827 var->transp.length = 0;
821 break; 828 break;
822 case 32: 829 case 32:
823 var->red.length = var->green.length = var->blue.length = 8; 830 var->red.length = 8;
831 var->green.length = 8;
832 var->blue.length = 8;
824 var->transp.length = 8; 833 var->transp.length = 8;
825 break; 834 break;
826 default: 835 default:
827 DPRINTK("depth not supported: %u\n", var->bits_per_pixel); 836 DPRINTK("depth not supported: %u\n",
837 var->bits_per_pixel);
828 return -EINVAL; 838 return -EINVAL;
829 } 839 }
830 } 840 }
831 /* it is assumed BGRA order */ 841 /* it is assumed BGRA order */
832 if (var->bits_per_pixel > 8 ) 842 if (var->bits_per_pixel > 8 ) {
833 {
834 var->blue.offset = 0; 843 var->blue.offset = 0;
835 var->green.offset = var->blue.length; 844 var->green.offset = var->blue.length;
836 var->red.offset = var->green.offset + var->green.length; 845 var->red.offset = var->green.offset + var->green.length;
837 var->transp.offset = var->red.offset + var->red.length; 846 var->transp.offset = var->red.offset + var->red.length;
838 } 847 }
839 var->height = var->width = -1; 848 var->height = -1;
849 var->width = -1;
840 850
841 if (var->xres != var->xres_virtual) { 851 if (var->xres != var->xres_virtual) {
842 DPRINTK("virtual x resolution != physical x resolution not supported\n"); 852 DPRINTK("virtual x resolution != "
853 "physical x resolution not supported\n");
843 return -EINVAL; 854 return -EINVAL;
844 } 855 }
845 856
846 if (var->yres > var->yres_virtual) { 857 if (var->yres > var->yres_virtual) {
847 DPRINTK("virtual y resolution < physical y resolution not possible\n"); 858 DPRINTK("virtual y resolution < "
859 "physical y resolution not possible\n");
848 return -EINVAL; 860 return -EINVAL;
849 } 861 }
850 862
@@ -878,7 +890,8 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
878 } 890 }
879 891
880 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) { 892 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) {
881 DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock)); 893 DPRINTK("pixclock too high (%ldKHz)\n",
894 PICOS2KHZ(var->pixclock));
882 return -EINVAL; 895 return -EINVAL;
883 } 896 }
884 897
@@ -895,7 +908,7 @@ static int pm3fb_set_par(struct fb_info *info)
895 const u32 xres = (info->var.xres + 31) & ~31; 908 const u32 xres = (info->var.xres + 31) & ~31;
896 const unsigned bpp = info->var.bits_per_pixel; 909 const unsigned bpp = info->var.bits_per_pixel;
897 910
898 par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres) 911 par->base = pm3fb_shift_bpp(bpp, (info->var.yoffset * xres)
899 + info->var.xoffset); 912 + info->var.xoffset);
900 par->video = 0; 913 par->video = 0;
901 914
@@ -954,10 +967,9 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
954 return -EINVAL; 967 return -EINVAL;
955 968
956 /* grayscale works only partially under directcolor */ 969 /* grayscale works only partially under directcolor */
957 if (info->var.grayscale) { 970 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
958 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 971 if (info->var.grayscale)
959 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 972 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
960 }
961 973
962 /* Directcolor: 974 /* Directcolor:
963 * var->{color}.offset contains start of bitfield 975 * var->{color}.offset contains start of bitfield
@@ -971,8 +983,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
971 * 983 *
972 * Pseudocolor: 984 * Pseudocolor:
973 * var->{color}.offset is 0 985 * var->{color}.offset is 0
974 * var->{color}.length contains width of DAC or the number of unique 986 * var->{color}.length contains width of DAC or the number
975 * colors available (color depth) 987 * of unique colors available (color depth)
976 * pseudo_palette is not used 988 * pseudo_palette is not used
977 * RAMDAC[X] is programmed to (red, green, blue) 989 * RAMDAC[X] is programmed to (red, green, blue)
978 * color depth = var->{color}.length 990 * color depth = var->{color}.length
@@ -982,7 +994,7 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
982 * This is the point where the color is converted to something that 994 * This is the point where the color is converted to something that
983 * is acceptable by the hardware. 995 * is acceptable by the hardware.
984 */ 996 */
985#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 997#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
986 red = CNVT_TOHW(red, info->var.red.length); 998 red = CNVT_TOHW(red, info->var.red.length);
987 green = CNVT_TOHW(green, info->var.green.length); 999 green = CNVT_TOHW(green, info->var.green.length);
988 blue = CNVT_TOHW(blue, info->var.blue.length); 1000 blue = CNVT_TOHW(blue, info->var.blue.length);
@@ -1006,12 +1018,11 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
1006 break; 1018 break;
1007 case 16: 1019 case 16:
1008 case 32: 1020 case 32:
1009 ((u32*)(info->pseudo_palette))[regno] = v; 1021 ((u32 *)(info->pseudo_palette))[regno] = v;
1010 break; 1022 break;
1011 } 1023 }
1012 return 0; 1024 return 0;
1013 } 1025 } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
1014 else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
1015 pm3fb_set_color(par, regno, red, green, blue); 1026 pm3fb_set_color(par, regno, red, green, blue);
1016 1027
1017 return 0; 1028 return 0;
@@ -1073,7 +1084,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
1073 } 1084 }
1074 1085
1075 PM3_WAIT(par, 1); 1086 PM3_WAIT(par, 1);
1076 PM3_WRITE_REG(par,PM3VideoControl, video); 1087 PM3_WRITE_REG(par, PM3VideoControl, video);
1077 return 0; 1088 return 0;
1078} 1089}
1079 1090
@@ -1104,7 +1115,8 @@ static struct fb_ops pm3fb_ops = {
1104/* the pm3fb_fix.smem_start is also set */ 1115/* the pm3fb_fix.smem_start is also set */
1105static unsigned long pm3fb_size_memory(struct pm3_par *par) 1116static unsigned long pm3fb_size_memory(struct pm3_par *par)
1106{ 1117{
1107 unsigned long memsize = 0, tempBypass, i, temp1, temp2; 1118 unsigned long memsize = 0;
1119 unsigned long tempBypass, i, temp1, temp2;
1108 unsigned char __iomem *screen_mem; 1120 unsigned char __iomem *screen_mem;
1109 1121
1110 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */ 1122 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
@@ -1132,7 +1144,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
1132 PM3_WAIT(par, 1); 1144 PM3_WAIT(par, 1);
1133 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); 1145 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
1134 1146
1135 /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ 1147 /* pm3 split up memory, replicates, and do a lot of
1148 * nasty stuff IMHO ;-)
1149 */
1136 for (i = 0; i < 32; i++) { 1150 for (i = 0; i < 32; i++) {
1137 fb_writel(i * 0x00345678, 1151 fb_writel(i * 0x00345678,
1138 (screen_mem + (i * 1048576))); 1152 (screen_mem + (i * 1048576)));
@@ -1189,8 +1203,9 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1189{ 1203{
1190 struct fb_info *info; 1204 struct fb_info *info;
1191 struct pm3_par *par; 1205 struct pm3_par *par;
1192 struct device* device = &dev->dev; /* for pci drivers */ 1206 struct device *device = &dev->dev; /* for pci drivers */
1193 int err, retval = -ENXIO; 1207 int err;
1208 int retval = -ENXIO;
1194 1209
1195 err = pci_enable_device(dev); 1210 err = pci_enable_device(dev);
1196 if (err) { 1211 if (err) {
@@ -1235,8 +1250,7 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1235 /* Linear frame buffer - request region and map it. */ 1250 /* Linear frame buffer - request region and map it. */
1236 pm3fb_fix.smem_start = pci_resource_start(dev, 1); 1251 pm3fb_fix.smem_start = pci_resource_start(dev, 1);
1237 pm3fb_fix.smem_len = pm3fb_size_memory(par); 1252 pm3fb_fix.smem_len = pm3fb_size_memory(par);
1238 if (!pm3fb_fix.smem_len) 1253 if (!pm3fb_fix.smem_len) {
1239 {
1240 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n"); 1254 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n");
1241 goto err_exit_mmio; 1255 goto err_exit_mmio;
1242 } 1256 }
@@ -1255,11 +1269,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1255 info->screen_size = pm3fb_fix.smem_len; 1269 info->screen_size = pm3fb_fix.smem_len;
1256 1270
1257#ifdef CONFIG_MTRR 1271#ifdef CONFIG_MTRR
1258 if (!nomtrr) { 1272 if (!nomtrr)
1259 par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start, 1273 par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start,
1260 pm3fb_fix.smem_len, 1274 pm3fb_fix.smem_len,
1261 MTRR_TYPE_WRCOMB, 1); 1275 MTRR_TYPE_WRCOMB, 1);
1262 }
1263#endif 1276#endif
1264 info->fbops = &pm3fb_ops; 1277 info->fbops = &pm3fb_ops;
1265 1278
@@ -1275,8 +1288,8 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1275 FBINFO_HWACCEL_FILLRECT; 1288 FBINFO_HWACCEL_FILLRECT;
1276 1289
1277 if (noaccel) { 1290 if (noaccel) {
1278 printk(KERN_DEBUG "disabling acceleration\n"); 1291 printk(KERN_DEBUG "disabling acceleration\n");
1279 info->flags |= FBINFO_HWACCEL_DISABLED; 1292 info->flags |= FBINFO_HWACCEL_DISABLED;
1280 } 1293 }
1281 info->pixmap.addr = kmalloc(PM3_PIXMAP_SIZE, GFP_KERNEL); 1294 info->pixmap.addr = kmalloc(PM3_PIXMAP_SIZE, GFP_KERNEL);
1282 if (!info->pixmap.addr) { 1295 if (!info->pixmap.addr) {
@@ -1403,15 +1416,14 @@ static int __init pm3fb_setup(char *options)
1403 while ((this_opt = strsep(&options, ",")) != NULL) { 1416 while ((this_opt = strsep(&options, ",")) != NULL) {
1404 if (!*this_opt) 1417 if (!*this_opt)
1405 continue; 1418 continue;
1406 else if (!strncmp(this_opt, "noaccel", 7)) { 1419 else if (!strncmp(this_opt, "noaccel", 7))
1407 noaccel = 1; 1420 noaccel = 1;
1408#ifdef CONFIG_MTRR 1421#ifdef CONFIG_MTRR
1409 } else if (!strncmp(this_opt, "nomtrr", 6)) { 1422 else if (!strncmp(this_opt, "nomtrr", 6))
1410 nomtrr = 1; 1423 nomtrr = 1;
1411#endif 1424#endif
1412 } else { 1425 else
1413 mode_option = this_opt; 1426 mode_option = this_opt;
1414 }
1415 } 1427 }
1416 return 0; 1428 return 0;
1417} 1429}