hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/video/fbdev/stifb.c
....@@ -922,6 +922,28 @@
922922 /* ------------------- driver specific functions --------------------------- */
923923
924924 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
925947 stifb_setcolreg(u_int regno, u_int red, u_int green,
926948 u_int blue, u_int transp, struct fb_info *info)
927949 {
....@@ -999,7 +1021,7 @@
9991021 case S9000_ID_HCRX:
10001022 HYPER_ENABLE_DISABLE_DISPLAY(fb, enable);
10011023 break;
1002
- case S9000_ID_A1659A: /* fall through */
1024
+ case S9000_ID_A1659A:
10031025 case S9000_ID_TIMBER:
10041026 case CRX24_OVERLAY_PLANES:
10051027 default:
....@@ -1037,6 +1059,48 @@
10371059 WRITE_WORD(((area->sx << 16) | area->sy), fb, REG_24);
10381060 WRITE_WORD(((area->width << 16) | area->height), fb, REG_7);
10391061 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));
10401104
10411105 SETUP_FB(fb);
10421106 }
....@@ -1101,11 +1165,12 @@
11011165
11021166 /* ------------ Interfaces to hardware functions ------------ */
11031167
1104
-static struct fb_ops stifb_ops = {
1168
+static const struct fb_ops stifb_ops = {
11051169 .owner = THIS_MODULE,
1170
+ .fb_check_var = stifb_check_var,
11061171 .fb_setcolreg = stifb_setcolreg,
11071172 .fb_blank = stifb_blank,
1108
- .fb_fillrect = cfb_fillrect,
1173
+ .fb_fillrect = stifb_fillrect,
11091174 .fb_copyarea = stifb_copyarea,
11101175 .fb_imageblit = cfb_imageblit,
11111176 };
....@@ -1122,6 +1187,7 @@
11221187 struct stifb_info *fb;
11231188 struct fb_info *info;
11241189 unsigned long sti_rom_address;
1190
+ char modestr[32];
11251191 char *dev_name;
11261192 int bpp, xres, yres;
11271193
....@@ -1157,7 +1223,7 @@
11571223 dev_name);
11581224 goto out_err0;
11591225 }
1160
- /* fall through */
1226
+ fallthrough;
11611227 case S9000_ID_ARTIST:
11621228 case S9000_ID_HCRX:
11631229 case S9000_ID_TIMBER:
....@@ -1198,7 +1264,7 @@
11981264 case S9000_ID_TOMCAT: /* Dual CRX, behaves else like a CRX */
11991265 /* FIXME: TomCat supports two heads:
12001266 * 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);
12021268 * for now we only support the left one ! */
12031269 xres = fb->ngle_rom.x_size_visible;
12041270 yres = fb->ngle_rom.y_size_visible;
....@@ -1257,7 +1323,7 @@
12571323
12581324 /* limit fbsize to max visible screen size */
12591325 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);
12611327
12621328 fix->accel = FB_ACCEL_NONE;
12631329
....@@ -1291,14 +1357,17 @@
12911357
12921358 strcpy(fix->id, "stifb");
12931359 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);
12951361 if (!info->screen_base) {
12961362 printk(KERN_ERR "stifb: failed to map memory\n");
12971363 goto out_err0;
12981364 }
12991365 info->screen_size = fix->smem_len;
1300
- info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA;
1366
+ info->flags = FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;
13011367 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);
13021371
13031372 /* This has to be done !!! */
13041373 if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
....@@ -1317,10 +1386,10 @@
13171386 goto out_err3;
13181387 }
13191388
1389
+ /* save for primary gfx device detection & unregister_framebuffer() */
1390
+ sti->info = info;
13201391 if (register_framebuffer(&fb->info) < 0)
13211392 goto out_err4;
1322
-
1323
- sti->info = info; /* save for unregister_framebuffer() */
13241393
13251394 fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",
13261395 fix->id,
....@@ -1344,6 +1413,7 @@
13441413 iounmap(info->screen_base);
13451414 out_err0:
13461415 kfree(fb);
1416
+ sti->info = NULL;
13471417 return -ENXIO;
13481418 }
13491419