.. | .. |
---|
922 | 922 | /* ------------------- driver specific functions --------------------------- */ |
---|
923 | 923 | |
---|
924 | 924 | static int |
---|
| 925 | +stifb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
---|
| 926 | +{ |
---|
| 927 | + struct stifb_info *fb = container_of(info, struct stifb_info, info); |
---|
| 928 | + |
---|
| 929 | + if (var->xres != fb->info.var.xres || |
---|
| 930 | + var->yres != fb->info.var.yres || |
---|
| 931 | + var->bits_per_pixel != fb->info.var.bits_per_pixel) |
---|
| 932 | + return -EINVAL; |
---|
| 933 | + |
---|
| 934 | + var->xres_virtual = var->xres; |
---|
| 935 | + var->yres_virtual = var->yres; |
---|
| 936 | + var->xoffset = 0; |
---|
| 937 | + var->yoffset = 0; |
---|
| 938 | + var->grayscale = fb->info.var.grayscale; |
---|
| 939 | + var->red.length = fb->info.var.red.length; |
---|
| 940 | + var->green.length = fb->info.var.green.length; |
---|
| 941 | + var->blue.length = fb->info.var.blue.length; |
---|
| 942 | + |
---|
| 943 | + return 0; |
---|
| 944 | +} |
---|
| 945 | + |
---|
| 946 | +static int |
---|
925 | 947 | stifb_setcolreg(u_int regno, u_int red, u_int green, |
---|
926 | 948 | u_int blue, u_int transp, struct fb_info *info) |
---|
927 | 949 | { |
---|
.. | .. |
---|
999 | 1021 | case S9000_ID_HCRX: |
---|
1000 | 1022 | HYPER_ENABLE_DISABLE_DISPLAY(fb, enable); |
---|
1001 | 1023 | break; |
---|
1002 | | - case S9000_ID_A1659A: /* fall through */ |
---|
| 1024 | + case S9000_ID_A1659A: |
---|
1003 | 1025 | case S9000_ID_TIMBER: |
---|
1004 | 1026 | case CRX24_OVERLAY_PLANES: |
---|
1005 | 1027 | default: |
---|
.. | .. |
---|
1037 | 1059 | WRITE_WORD(((area->sx << 16) | area->sy), fb, REG_24); |
---|
1038 | 1060 | WRITE_WORD(((area->width << 16) | area->height), fb, REG_7); |
---|
1039 | 1061 | WRITE_WORD(((area->dx << 16) | area->dy), fb, REG_25); |
---|
| 1062 | + |
---|
| 1063 | + SETUP_FB(fb); |
---|
| 1064 | +} |
---|
| 1065 | + |
---|
| 1066 | +#define ARTIST_VRAM_SIZE 0x000804 |
---|
| 1067 | +#define ARTIST_VRAM_SRC 0x000808 |
---|
| 1068 | +#define ARTIST_VRAM_SIZE_TRIGGER_WINFILL 0x000a04 |
---|
| 1069 | +#define ARTIST_VRAM_DEST_TRIGGER_BLOCKMOVE 0x000b00 |
---|
| 1070 | +#define ARTIST_SRC_BM_ACCESS 0x018008 |
---|
| 1071 | +#define ARTIST_FGCOLOR 0x018010 |
---|
| 1072 | +#define ARTIST_BGCOLOR 0x018014 |
---|
| 1073 | +#define ARTIST_BITMAP_OP 0x01801c |
---|
| 1074 | + |
---|
| 1075 | +static void |
---|
| 1076 | +stifb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) |
---|
| 1077 | +{ |
---|
| 1078 | + struct stifb_info *fb = container_of(info, struct stifb_info, info); |
---|
| 1079 | + |
---|
| 1080 | + if (rect->rop != ROP_COPY || |
---|
| 1081 | + (fb->id == S9000_ID_HCRX && fb->info.var.bits_per_pixel == 32)) |
---|
| 1082 | + return cfb_fillrect(info, rect); |
---|
| 1083 | + |
---|
| 1084 | + SETUP_HW(fb); |
---|
| 1085 | + |
---|
| 1086 | + if (fb->info.var.bits_per_pixel == 32) { |
---|
| 1087 | + WRITE_WORD(0xBBA0A000, fb, REG_10); |
---|
| 1088 | + |
---|
| 1089 | + NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xffffffff); |
---|
| 1090 | + } else { |
---|
| 1091 | + WRITE_WORD(fb->id == S9000_ID_HCRX ? 0x13a02000 : 0x13a01000, fb, REG_10); |
---|
| 1092 | + |
---|
| 1093 | + NGLE_REALLY_SET_IMAGE_PLANEMASK(fb, 0xff); |
---|
| 1094 | + } |
---|
| 1095 | + |
---|
| 1096 | + WRITE_WORD(0x03000300, fb, ARTIST_BITMAP_OP); |
---|
| 1097 | + WRITE_WORD(0x2ea01000, fb, ARTIST_SRC_BM_ACCESS); |
---|
| 1098 | + NGLE_QUICK_SET_DST_BM_ACCESS(fb, 0x2ea01000); |
---|
| 1099 | + NGLE_REALLY_SET_IMAGE_FG_COLOR(fb, rect->color); |
---|
| 1100 | + WRITE_WORD(0, fb, ARTIST_BGCOLOR); |
---|
| 1101 | + |
---|
| 1102 | + NGLE_SET_DSTXY(fb, (rect->dx << 16) | (rect->dy)); |
---|
| 1103 | + SET_LENXY_START_RECFILL(fb, (rect->width << 16) | (rect->height)); |
---|
1040 | 1104 | |
---|
1041 | 1105 | SETUP_FB(fb); |
---|
1042 | 1106 | } |
---|
.. | .. |
---|
1101 | 1165 | |
---|
1102 | 1166 | /* ------------ Interfaces to hardware functions ------------ */ |
---|
1103 | 1167 | |
---|
1104 | | -static struct fb_ops stifb_ops = { |
---|
| 1168 | +static const struct fb_ops stifb_ops = { |
---|
1105 | 1169 | .owner = THIS_MODULE, |
---|
| 1170 | + .fb_check_var = stifb_check_var, |
---|
1106 | 1171 | .fb_setcolreg = stifb_setcolreg, |
---|
1107 | 1172 | .fb_blank = stifb_blank, |
---|
1108 | | - .fb_fillrect = cfb_fillrect, |
---|
| 1173 | + .fb_fillrect = stifb_fillrect, |
---|
1109 | 1174 | .fb_copyarea = stifb_copyarea, |
---|
1110 | 1175 | .fb_imageblit = cfb_imageblit, |
---|
1111 | 1176 | }; |
---|
.. | .. |
---|
1122 | 1187 | struct stifb_info *fb; |
---|
1123 | 1188 | struct fb_info *info; |
---|
1124 | 1189 | unsigned long sti_rom_address; |
---|
| 1190 | + char modestr[32]; |
---|
1125 | 1191 | char *dev_name; |
---|
1126 | 1192 | int bpp, xres, yres; |
---|
1127 | 1193 | |
---|
.. | .. |
---|
1157 | 1223 | dev_name); |
---|
1158 | 1224 | goto out_err0; |
---|
1159 | 1225 | } |
---|
1160 | | - /* fall through */ |
---|
| 1226 | + fallthrough; |
---|
1161 | 1227 | case S9000_ID_ARTIST: |
---|
1162 | 1228 | case S9000_ID_HCRX: |
---|
1163 | 1229 | case S9000_ID_TIMBER: |
---|
.. | .. |
---|
1198 | 1264 | case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */ |
---|
1199 | 1265 | /* FIXME: TomCat supports two heads: |
---|
1200 | 1266 | * fb.iobase = REGION_BASE(fb_info,3); |
---|
1201 | | - * fb.screen_base = ioremap_nocache(REGION_BASE(fb_info,2),xxx); |
---|
| 1267 | + * fb.screen_base = ioremap(REGION_BASE(fb_info,2),xxx); |
---|
1202 | 1268 | * for now we only support the left one ! */ |
---|
1203 | 1269 | xres = fb->ngle_rom.x_size_visible; |
---|
1204 | 1270 | yres = fb->ngle_rom.y_size_visible; |
---|
.. | .. |
---|
1257 | 1323 | |
---|
1258 | 1324 | /* limit fbsize to max visible screen size */ |
---|
1259 | 1325 | if (fix->smem_len > yres*fix->line_length) |
---|
1260 | | - fix->smem_len = yres*fix->line_length; |
---|
| 1326 | + fix->smem_len = ALIGN(yres*fix->line_length, 4*1024*1024); |
---|
1261 | 1327 | |
---|
1262 | 1328 | fix->accel = FB_ACCEL_NONE; |
---|
1263 | 1329 | |
---|
.. | .. |
---|
1291 | 1357 | |
---|
1292 | 1358 | strcpy(fix->id, "stifb"); |
---|
1293 | 1359 | info->fbops = &stifb_ops; |
---|
1294 | | - info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len); |
---|
| 1360 | + info->screen_base = ioremap(REGION_BASE(fb,1), fix->smem_len); |
---|
1295 | 1361 | if (!info->screen_base) { |
---|
1296 | 1362 | printk(KERN_ERR "stifb: failed to map memory\n"); |
---|
1297 | 1363 | goto out_err0; |
---|
1298 | 1364 | } |
---|
1299 | 1365 | info->screen_size = fix->smem_len; |
---|
1300 | | - info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA; |
---|
| 1366 | + info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT; |
---|
1301 | 1367 | info->pseudo_palette = &fb->pseudo_palette; |
---|
| 1368 | + |
---|
| 1369 | + scnprintf(modestr, sizeof(modestr), "%dx%d-%d", xres, yres, bpp); |
---|
| 1370 | + fb_find_mode(&info->var, info, modestr, NULL, 0, NULL, bpp); |
---|
1302 | 1371 | |
---|
1303 | 1372 | /* This has to be done !!! */ |
---|
1304 | 1373 | if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0)) |
---|
.. | .. |
---|
1317 | 1386 | goto out_err3; |
---|
1318 | 1387 | } |
---|
1319 | 1388 | |
---|
| 1389 | + /* save for primary gfx device detection & unregister_framebuffer() */ |
---|
| 1390 | + sti->info = info; |
---|
1320 | 1391 | if (register_framebuffer(&fb->info) < 0) |
---|
1321 | 1392 | goto out_err4; |
---|
1322 | | - |
---|
1323 | | - sti->info = info; /* save for unregister_framebuffer() */ |
---|
1324 | 1393 | |
---|
1325 | 1394 | fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", |
---|
1326 | 1395 | fix->id, |
---|
.. | .. |
---|
1344 | 1413 | iounmap(info->screen_base); |
---|
1345 | 1414 | out_err0: |
---|
1346 | 1415 | kfree(fb); |
---|
| 1416 | + sti->info = NULL; |
---|
1347 | 1417 | return -ENXIO; |
---|
1348 | 1418 | } |
---|
1349 | 1419 | |
---|