0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/module.h>
0015 #include <linux/kernel.h>
0016 #include <linux/errno.h>
0017 #include <linux/string.h>
0018 #include <linux/mm.h>
0019 #include <linux/tty.h>
0020 #include <linux/slab.h>
0021 #include <linux/delay.h>
0022 #include <linux/fb.h>
0023 #include <linux/svga.h>
0024 #include <linux/init.h>
0025 #include <linux/pci.h>
0026 #include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
0027 #include <video/vga.h>
0028
0029 struct arkfb_info {
0030 int mclk_freq;
0031 int wc_cookie;
0032
0033 struct dac_info *dac;
0034 struct vgastate state;
0035 struct mutex open_lock;
0036 unsigned int ref_count;
0037 u32 pseudo_palette[16];
0038 };
0039
0040
0041
0042
0043
0044 static const struct svga_fb_format arkfb_formats[] = {
0045 { 0, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
0046 FB_TYPE_TEXT, FB_AUX_TEXT_SVGA_STEP4, FB_VISUAL_PSEUDOCOLOR, 8, 8},
0047 { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
0048 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 16},
0049 { 4, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 1,
0050 FB_TYPE_INTERLEAVED_PLANES, 1, FB_VISUAL_PSEUDOCOLOR, 8, 16},
0051 { 8, {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0}, 0,
0052 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_PSEUDOCOLOR, 8, 8},
0053 {16, {10, 5, 0}, {5, 5, 0}, {0, 5, 0}, {0, 0, 0}, 0,
0054 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 4, 4},
0055 {16, {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0}, 0,
0056 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 4, 4},
0057 {24, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
0058 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 8, 8},
0059 {32, {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0}, 0,
0060 FB_TYPE_PACKED_PIXELS, 0, FB_VISUAL_TRUECOLOR, 2, 2},
0061 SVGA_FORMAT_END
0062 };
0063
0064
0065
0066
0067 static const struct vga_regset ark_h_total_regs[] = {{0x00, 0, 7}, {0x41, 7, 7}, VGA_REGSET_END};
0068 static const struct vga_regset ark_h_display_regs[] = {{0x01, 0, 7}, {0x41, 6, 6}, VGA_REGSET_END};
0069 static const struct vga_regset ark_h_blank_start_regs[] = {{0x02, 0, 7}, {0x41, 5, 5}, VGA_REGSET_END};
0070 static const struct vga_regset ark_h_blank_end_regs[] = {{0x03, 0, 4}, {0x05, 7, 7 }, VGA_REGSET_END};
0071 static const struct vga_regset ark_h_sync_start_regs[] = {{0x04, 0, 7}, {0x41, 4, 4}, VGA_REGSET_END};
0072 static const struct vga_regset ark_h_sync_end_regs[] = {{0x05, 0, 4}, VGA_REGSET_END};
0073
0074 static const struct vga_regset ark_v_total_regs[] = {{0x06, 0, 7}, {0x07, 0, 0}, {0x07, 5, 5}, {0x40, 7, 7}, VGA_REGSET_END};
0075 static const struct vga_regset ark_v_display_regs[] = {{0x12, 0, 7}, {0x07, 1, 1}, {0x07, 6, 6}, {0x40, 6, 6}, VGA_REGSET_END};
0076 static const struct vga_regset ark_v_blank_start_regs[] = {{0x15, 0, 7}, {0x07, 3, 3}, {0x09, 5, 5}, {0x40, 5, 5}, VGA_REGSET_END};
0077
0078 static const struct vga_regset ark_v_blank_end_regs[] = {{0x16, 0, 7}, VGA_REGSET_END};
0079 static const struct vga_regset ark_v_sync_start_regs[] = {{0x10, 0, 7}, {0x07, 2, 2}, {0x07, 7, 7}, {0x40, 4, 4}, VGA_REGSET_END};
0080 static const struct vga_regset ark_v_sync_end_regs[] = {{0x11, 0, 3}, VGA_REGSET_END};
0081
0082 static const struct vga_regset ark_line_compare_regs[] = {{0x18, 0, 7}, {0x07, 4, 4}, {0x09, 6, 6}, VGA_REGSET_END};
0083 static const struct vga_regset ark_start_address_regs[] = {{0x0d, 0, 7}, {0x0c, 0, 7}, {0x40, 0, 2}, VGA_REGSET_END};
0084 static const struct vga_regset ark_offset_regs[] = {{0x13, 0, 7}, {0x41, 3, 3}, VGA_REGSET_END};
0085
0086 static const struct svga_timing_regs ark_timing_regs = {
0087 ark_h_total_regs, ark_h_display_regs, ark_h_blank_start_regs,
0088 ark_h_blank_end_regs, ark_h_sync_start_regs, ark_h_sync_end_regs,
0089 ark_v_total_regs, ark_v_display_regs, ark_v_blank_start_regs,
0090 ark_v_blank_end_regs, ark_v_sync_start_regs, ark_v_sync_end_regs,
0091 };
0092
0093
0094
0095
0096
0097
0098
0099 static char *mode_option = "640x480-8@60";
0100
0101 MODULE_AUTHOR("(c) 2007 Ondrej Zajicek <santiago@crfreenet.org>");
0102 MODULE_LICENSE("GPL");
0103 MODULE_DESCRIPTION("fbdev driver for ARK 2000PV");
0104
0105 module_param(mode_option, charp, 0444);
0106 MODULE_PARM_DESC(mode_option, "Default video mode ('640x480-8@60', etc)");
0107 module_param_named(mode, mode_option, charp, 0444);
0108 MODULE_PARM_DESC(mode, "Default video mode ('640x480-8@60', etc) (deprecated)");
0109
0110 static int threshold = 4;
0111
0112 module_param(threshold, int, 0644);
0113 MODULE_PARM_DESC(threshold, "FIFO threshold");
0114
0115
0116
0117
0118
0119 static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)
0120 {
0121 const u8 *font = map->data;
0122 u8 __iomem *fb = (u8 __iomem *)info->screen_base;
0123 int i, c;
0124
0125 if ((map->width != 8) || (map->height != 16) ||
0126 (map->depth != 1) || (map->length != 256)) {
0127 fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n",
0128 map->width, map->height, map->depth, map->length);
0129 return;
0130 }
0131
0132 fb += 2;
0133 for (c = 0; c < map->length; c++) {
0134 for (i = 0; i < map->height; i++) {
0135 fb_writeb(font[i], &fb[i * 4]);
0136 fb_writeb(font[i], &fb[i * 4 + (128 * 8)]);
0137 }
0138 fb += 128;
0139
0140 if ((c % 8) == 7)
0141 fb += 128*8;
0142
0143 font += map->height;
0144 }
0145 }
0146
0147 static void arkfb_tilecursor(struct fb_info *info, struct fb_tilecursor *cursor)
0148 {
0149 struct arkfb_info *par = info->par;
0150
0151 svga_tilecursor(par->state.vgabase, info, cursor);
0152 }
0153
0154 static struct fb_tile_ops arkfb_tile_ops = {
0155 .fb_settile = arkfb_settile,
0156 .fb_tilecopy = svga_tilecopy,
0157 .fb_tilefill = svga_tilefill,
0158 .fb_tileblit = svga_tileblit,
0159 .fb_tilecursor = arkfb_tilecursor,
0160 .fb_get_tilemax = svga_get_tilemax,
0161 };
0162
0163
0164
0165
0166
0167
0168 static inline u32 expand_color(u32 c)
0169 {
0170 return ((c & 1) | ((c & 2) << 7) | ((c & 4) << 14) | ((c & 8) << 21)) * 0xFF;
0171 }
0172
0173
0174 static void arkfb_iplan_imageblit(struct fb_info *info, const struct fb_image *image)
0175 {
0176 u32 fg = expand_color(image->fg_color);
0177 u32 bg = expand_color(image->bg_color);
0178 const u8 *src1, *src;
0179 u8 __iomem *dst1;
0180 u32 __iomem *dst;
0181 u32 val;
0182 int x, y;
0183
0184 src1 = image->data;
0185 dst1 = info->screen_base + (image->dy * info->fix.line_length)
0186 + ((image->dx / 8) * 4);
0187
0188 for (y = 0; y < image->height; y++) {
0189 src = src1;
0190 dst = (u32 __iomem *) dst1;
0191 for (x = 0; x < image->width; x += 8) {
0192 val = *(src++) * 0x01010101;
0193 val = (val & fg) | (~val & bg);
0194 fb_writel(val, dst++);
0195 }
0196 src1 += image->width / 8;
0197 dst1 += info->fix.line_length;
0198 }
0199
0200 }
0201
0202
0203 static void arkfb_iplan_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
0204 {
0205 u32 fg = expand_color(rect->color);
0206 u8 __iomem *dst1;
0207 u32 __iomem *dst;
0208 int x, y;
0209
0210 dst1 = info->screen_base + (rect->dy * info->fix.line_length)
0211 + ((rect->dx / 8) * 4);
0212
0213 for (y = 0; y < rect->height; y++) {
0214 dst = (u32 __iomem *) dst1;
0215 for (x = 0; x < rect->width; x += 8) {
0216 fb_writel(fg, dst++);
0217 }
0218 dst1 += info->fix.line_length;
0219 }
0220
0221 }
0222
0223
0224
0225 static inline u32 expand_pixel(u32 c)
0226 {
0227 return (((c & 1) << 24) | ((c & 2) << 27) | ((c & 4) << 14) | ((c & 8) << 17) |
0228 ((c & 16) << 4) | ((c & 32) << 7) | ((c & 64) >> 6) | ((c & 128) >> 3)) * 0xF;
0229 }
0230
0231
0232 static void arkfb_cfb4_imageblit(struct fb_info *info, const struct fb_image *image)
0233 {
0234 u32 fg = image->fg_color * 0x11111111;
0235 u32 bg = image->bg_color * 0x11111111;
0236 const u8 *src1, *src;
0237 u8 __iomem *dst1;
0238 u32 __iomem *dst;
0239 u32 val;
0240 int x, y;
0241
0242 src1 = image->data;
0243 dst1 = info->screen_base + (image->dy * info->fix.line_length)
0244 + ((image->dx / 8) * 4);
0245
0246 for (y = 0; y < image->height; y++) {
0247 src = src1;
0248 dst = (u32 __iomem *) dst1;
0249 for (x = 0; x < image->width; x += 8) {
0250 val = expand_pixel(*(src++));
0251 val = (val & fg) | (~val & bg);
0252 fb_writel(val, dst++);
0253 }
0254 src1 += image->width / 8;
0255 dst1 += info->fix.line_length;
0256 }
0257
0258 }
0259
0260 static void arkfb_imageblit(struct fb_info *info, const struct fb_image *image)
0261 {
0262 if ((info->var.bits_per_pixel == 4) && (image->depth == 1)
0263 && ((image->width % 8) == 0) && ((image->dx % 8) == 0)) {
0264 if (info->fix.type == FB_TYPE_INTERLEAVED_PLANES)
0265 arkfb_iplan_imageblit(info, image);
0266 else
0267 arkfb_cfb4_imageblit(info, image);
0268 } else
0269 cfb_imageblit(info, image);
0270 }
0271
0272 static void arkfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
0273 {
0274 if ((info->var.bits_per_pixel == 4)
0275 && ((rect->width % 8) == 0) && ((rect->dx % 8) == 0)
0276 && (info->fix.type == FB_TYPE_INTERLEAVED_PLANES))
0277 arkfb_iplan_fillrect(info, rect);
0278 else
0279 cfb_fillrect(info, rect);
0280 }
0281
0282
0283
0284
0285
0286 enum
0287 {
0288 DAC_PSEUDO8_8,
0289 DAC_RGB1555_8,
0290 DAC_RGB0565_8,
0291 DAC_RGB0888_8,
0292 DAC_RGB8888_8,
0293 DAC_PSEUDO8_16,
0294 DAC_RGB1555_16,
0295 DAC_RGB0565_16,
0296 DAC_RGB0888_16,
0297 DAC_RGB8888_16,
0298 DAC_MAX
0299 };
0300
0301 struct dac_ops {
0302 int (*dac_get_mode)(struct dac_info *info);
0303 int (*dac_set_mode)(struct dac_info *info, int mode);
0304 int (*dac_get_freq)(struct dac_info *info, int channel);
0305 int (*dac_set_freq)(struct dac_info *info, int channel, u32 freq);
0306 void (*dac_release)(struct dac_info *info);
0307 };
0308
0309 typedef void (*dac_read_regs_t)(void *data, u8 *code, int count);
0310 typedef void (*dac_write_regs_t)(void *data, u8 *code, int count);
0311
0312 struct dac_info
0313 {
0314 struct dac_ops *dacops;
0315 dac_read_regs_t dac_read_regs;
0316 dac_write_regs_t dac_write_regs;
0317 void *data;
0318 };
0319
0320
0321 static inline u8 dac_read_reg(struct dac_info *info, u8 reg)
0322 {
0323 u8 code[2] = {reg, 0};
0324 info->dac_read_regs(info->data, code, 1);
0325 return code[1];
0326 }
0327
0328 static inline void dac_read_regs(struct dac_info *info, u8 *code, int count)
0329 {
0330 info->dac_read_regs(info->data, code, count);
0331 }
0332
0333 static inline void dac_write_reg(struct dac_info *info, u8 reg, u8 val)
0334 {
0335 u8 code[2] = {reg, val};
0336 info->dac_write_regs(info->data, code, 1);
0337 }
0338
0339 static inline void dac_write_regs(struct dac_info *info, u8 *code, int count)
0340 {
0341 info->dac_write_regs(info->data, code, count);
0342 }
0343
0344 static inline int dac_set_mode(struct dac_info *info, int mode)
0345 {
0346 return info->dacops->dac_set_mode(info, mode);
0347 }
0348
0349 static inline int dac_set_freq(struct dac_info *info, int channel, u32 freq)
0350 {
0351 return info->dacops->dac_set_freq(info, channel, freq);
0352 }
0353
0354 static inline void dac_release(struct dac_info *info)
0355 {
0356 info->dacops->dac_release(info);
0357 }
0358
0359
0360
0361
0362
0363
0364
0365 struct ics5342_info
0366 {
0367 struct dac_info dac;
0368 u8 mode;
0369 };
0370
0371 #define DAC_PAR(info) ((struct ics5342_info *) info)
0372
0373
0374 static const u8 ics5342_mode_table[DAC_MAX] = {
0375 [DAC_PSEUDO8_8] = 0x01, [DAC_RGB1555_8] = 0x21, [DAC_RGB0565_8] = 0x61,
0376 [DAC_RGB0888_8] = 0x41, [DAC_PSEUDO8_16] = 0x11, [DAC_RGB1555_16] = 0x31,
0377 [DAC_RGB0565_16] = 0x51, [DAC_RGB0888_16] = 0x91, [DAC_RGB8888_16] = 0x71
0378 };
0379
0380 static int ics5342_set_mode(struct dac_info *info, int mode)
0381 {
0382 u8 code;
0383
0384 if (mode >= DAC_MAX)
0385 return -EINVAL;
0386
0387 code = ics5342_mode_table[mode];
0388
0389 if (! code)
0390 return -EINVAL;
0391
0392 dac_write_reg(info, 6, code & 0xF0);
0393 DAC_PAR(info)->mode = mode;
0394
0395 return 0;
0396 }
0397
0398 static const struct svga_pll ics5342_pll = {3, 129, 3, 33, 0, 3,
0399 60000, 250000, 14318};
0400
0401
0402 static const struct svga_pll ics5342_pll_pd4 = {3, 129, 3, 33, 2, 2,
0403 60000, 335000, 14318};
0404
0405
0406
0407
0408 static int ics5342_set_freq(struct dac_info *info, int channel, u32 freq)
0409 {
0410 u16 m, n, r;
0411
0412
0413 int rv = svga_compute_pll((DAC_PAR(info)->mode == DAC_PSEUDO8_16)
0414 ? &ics5342_pll_pd4 : &ics5342_pll,
0415 freq, &m, &n, &r, 0);
0416
0417 if (rv < 0) {
0418 return -EINVAL;
0419 } else {
0420 u8 code[6] = {4, 3, 5, m-2, 5, (n-2) | (r << 5)};
0421 dac_write_regs(info, code, 3);
0422 return 0;
0423 }
0424 }
0425
0426 static void ics5342_release(struct dac_info *info)
0427 {
0428 ics5342_set_mode(info, DAC_PSEUDO8_8);
0429 kfree(info);
0430 }
0431
0432 static struct dac_ops ics5342_ops = {
0433 .dac_set_mode = ics5342_set_mode,
0434 .dac_set_freq = ics5342_set_freq,
0435 .dac_release = ics5342_release
0436 };
0437
0438
0439 static struct dac_info * ics5342_init(dac_read_regs_t drr, dac_write_regs_t dwr, void *data)
0440 {
0441 struct dac_info *info = kzalloc(sizeof(struct ics5342_info), GFP_KERNEL);
0442
0443 if (! info)
0444 return NULL;
0445
0446 info->dacops = &ics5342_ops;
0447 info->dac_read_regs = drr;
0448 info->dac_write_regs = dwr;
0449 info->data = data;
0450 DAC_PAR(info)->mode = DAC_PSEUDO8_8;
0451 return info;
0452 }
0453
0454
0455
0456
0457
0458 static unsigned short dac_regs[4] = {0x3c8, 0x3c9, 0x3c6, 0x3c7};
0459
0460 static void ark_dac_read_regs(void *data, u8 *code, int count)
0461 {
0462 struct fb_info *info = data;
0463 struct arkfb_info *par;
0464 u8 regval;
0465
0466 par = info->par;
0467 regval = vga_rseq(par->state.vgabase, 0x1C);
0468 while (count != 0)
0469 {
0470 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
0471 code[1] = vga_r(par->state.vgabase, dac_regs[code[0] & 3]);
0472 count--;
0473 code += 2;
0474 }
0475
0476 vga_wseq(par->state.vgabase, 0x1C, regval);
0477 }
0478
0479 static void ark_dac_write_regs(void *data, u8 *code, int count)
0480 {
0481 struct fb_info *info = data;
0482 struct arkfb_info *par;
0483 u8 regval;
0484
0485 par = info->par;
0486 regval = vga_rseq(par->state.vgabase, 0x1C);
0487 while (count != 0)
0488 {
0489 vga_wseq(par->state.vgabase, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
0490 vga_w(par->state.vgabase, dac_regs[code[0] & 3], code[1]);
0491 count--;
0492 code += 2;
0493 }
0494
0495 vga_wseq(par->state.vgabase, 0x1C, regval);
0496 }
0497
0498
0499 static void ark_set_pixclock(struct fb_info *info, u32 pixclock)
0500 {
0501 struct arkfb_info *par = info->par;
0502 u8 regval;
0503
0504 int rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);
0505 if (rv < 0) {
0506 fb_err(info, "cannot set requested pixclock, keeping old value\n");
0507 return;
0508 }
0509
0510
0511 regval = vga_r(par->state.vgabase, VGA_MIS_R);
0512 vga_w(par->state.vgabase, VGA_MIS_W, regval | VGA_MIS_ENB_PLL_LOAD);
0513 }
0514
0515
0516
0517
0518 static int arkfb_open(struct fb_info *info, int user)
0519 {
0520 struct arkfb_info *par = info->par;
0521
0522 mutex_lock(&(par->open_lock));
0523 if (par->ref_count == 0) {
0524 void __iomem *vgabase = par->state.vgabase;
0525
0526 memset(&(par->state), 0, sizeof(struct vgastate));
0527 par->state.vgabase = vgabase;
0528 par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS | VGA_SAVE_CMAP;
0529 par->state.num_crtc = 0x60;
0530 par->state.num_seq = 0x30;
0531 save_vga(&(par->state));
0532 }
0533
0534 par->ref_count++;
0535 mutex_unlock(&(par->open_lock));
0536
0537 return 0;
0538 }
0539
0540
0541
0542 static int arkfb_release(struct fb_info *info, int user)
0543 {
0544 struct arkfb_info *par = info->par;
0545
0546 mutex_lock(&(par->open_lock));
0547 if (par->ref_count == 0) {
0548 mutex_unlock(&(par->open_lock));
0549 return -EINVAL;
0550 }
0551
0552 if (par->ref_count == 1) {
0553 restore_vga(&(par->state));
0554 dac_set_mode(par->dac, DAC_PSEUDO8_8);
0555 }
0556
0557 par->ref_count--;
0558 mutex_unlock(&(par->open_lock));
0559
0560 return 0;
0561 }
0562
0563
0564
0565 static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
0566 {
0567 int rv, mem, step;
0568
0569 if (!var->pixclock)
0570 return -EINVAL;
0571
0572
0573 rv = svga_match_format (arkfb_formats, var, NULL);
0574 if (rv < 0)
0575 {
0576 fb_err(info, "unsupported mode requested\n");
0577 return rv;
0578 }
0579
0580
0581 if (var->xres > var->xres_virtual)
0582 var->xres_virtual = var->xres;
0583
0584 if (var->yres > var->yres_virtual)
0585 var->yres_virtual = var->yres;
0586
0587
0588 step = arkfb_formats[rv].xresstep - 1;
0589 var->xres_virtual = (var->xres_virtual+step) & ~step;
0590
0591
0592
0593 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
0594 if (mem > info->screen_size)
0595 {
0596 fb_err(info, "not enough framebuffer memory (%d kB requested, %d kB available)\n",
0597 mem >> 10, (unsigned int) (info->screen_size >> 10));
0598 return -EINVAL;
0599 }
0600
0601 rv = svga_check_timings (&ark_timing_regs, var, info->node);
0602 if (rv < 0)
0603 {
0604 fb_err(info, "invalid timings requested\n");
0605 return rv;
0606 }
0607
0608
0609 if (var->vmode & FB_VMODE_INTERLACED)
0610 return -EINVAL;
0611
0612 return 0;
0613 }
0614
0615
0616
0617 static int arkfb_set_par(struct fb_info *info)
0618 {
0619 struct arkfb_info *par = info->par;
0620 u32 value, mode, hmul, hdiv, offset_value, screen_size;
0621 u32 bpp = info->var.bits_per_pixel;
0622 u8 regval;
0623
0624 if (bpp != 0) {
0625 info->fix.ypanstep = 1;
0626 info->fix.line_length = (info->var.xres_virtual * bpp) / 8;
0627
0628 info->flags &= ~FBINFO_MISC_TILEBLITTING;
0629 info->tileops = NULL;
0630
0631
0632 info->pixmap.blit_x = (bpp == 4) ? (1 << (8 - 1)) : (~(u32)0);
0633 info->pixmap.blit_y = ~(u32)0;
0634
0635 offset_value = (info->var.xres_virtual * bpp) / 64;
0636 screen_size = info->var.yres_virtual * info->fix.line_length;
0637 } else {
0638 info->fix.ypanstep = 16;
0639 info->fix.line_length = 0;
0640
0641 info->flags |= FBINFO_MISC_TILEBLITTING;
0642 info->tileops = &arkfb_tile_ops;
0643
0644
0645 info->pixmap.blit_x = 1 << (8 - 1);
0646 info->pixmap.blit_y = 1 << (16 - 1);
0647
0648 offset_value = info->var.xres_virtual / 16;
0649 screen_size = (info->var.xres_virtual * info->var.yres_virtual) / 64;
0650 }
0651
0652 info->var.xoffset = 0;
0653 info->var.yoffset = 0;
0654 info->var.activate = FB_ACTIVATE_NOW;
0655
0656
0657 svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x80);
0658
0659
0660 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
0661 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
0662
0663
0664 svga_set_default_gfx_regs(par->state.vgabase);
0665 svga_set_default_atc_regs(par->state.vgabase);
0666 svga_set_default_seq_regs(par->state.vgabase);
0667 svga_set_default_crt_regs(par->state.vgabase);
0668 svga_wcrt_multi(par->state.vgabase, ark_line_compare_regs, 0xFFFFFFFF);
0669 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, 0);
0670
0671
0672 svga_wseq_mask(par->state.vgabase, 0x10, 0x1F, 0x1F);
0673 svga_wseq_mask(par->state.vgabase, 0x12, 0x03, 0x03);
0674
0675 vga_wseq(par->state.vgabase, 0x13, info->fix.smem_start >> 16);
0676 vga_wseq(par->state.vgabase, 0x14, info->fix.smem_start >> 24);
0677 vga_wseq(par->state.vgabase, 0x15, 0);
0678 vga_wseq(par->state.vgabase, 0x16, 0);
0679
0680
0681
0682 regval = 0x10 | ((threshold & 0x0E) >> 1) | (threshold & 0x01) << 7 | (threshold & 0x10) << 1;
0683 vga_wseq(par->state.vgabase, 0x18, regval);
0684
0685
0686 fb_dbg(info, "offset register : %d\n", offset_value);
0687 svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);
0688
0689
0690 svga_wcrt_mask(par->state.vgabase, 0x40, 0x08, 0x08);
0691
0692 if (info->var.vmode & FB_VMODE_DOUBLE)
0693 svga_wcrt_mask(par->state.vgabase, 0x09, 0x80, 0x80);
0694 else
0695 svga_wcrt_mask(par->state.vgabase, 0x09, 0x00, 0x80);
0696
0697 if (info->var.vmode & FB_VMODE_INTERLACED)
0698 svga_wcrt_mask(par->state.vgabase, 0x44, 0x04, 0x04);
0699 else
0700 svga_wcrt_mask(par->state.vgabase, 0x44, 0x00, 0x04);
0701
0702 hmul = 1;
0703 hdiv = 1;
0704 mode = svga_match_format(arkfb_formats, &(info->var), &(info->fix));
0705
0706
0707 switch (mode) {
0708 case 0:
0709 fb_dbg(info, "text mode\n");
0710 svga_set_textmode_vga_regs(par->state.vgabase);
0711
0712 vga_wseq(par->state.vgabase, 0x11, 0x10);
0713 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04);
0714 dac_set_mode(par->dac, DAC_PSEUDO8_8);
0715
0716 break;
0717 case 1:
0718 fb_dbg(info, "4 bit pseudocolor\n");
0719 vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);
0720
0721 vga_wseq(par->state.vgabase, 0x11, 0x10);
0722 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04);
0723 dac_set_mode(par->dac, DAC_PSEUDO8_8);
0724 break;
0725 case 2:
0726 fb_dbg(info, "4 bit pseudocolor, planar\n");
0727
0728 vga_wseq(par->state.vgabase, 0x11, 0x10);
0729 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04);
0730 dac_set_mode(par->dac, DAC_PSEUDO8_8);
0731 break;
0732 case 3:
0733 fb_dbg(info, "8 bit pseudocolor\n");
0734
0735 vga_wseq(par->state.vgabase, 0x11, 0x16);
0736
0737 if (info->var.pixclock > 20000) {
0738 fb_dbg(info, "not using multiplex\n");
0739 svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04);
0740 dac_set_mode(par->dac, DAC_PSEUDO8_8);
0741 } else {
0742 fb_dbg(info, "using multiplex\n");
0743 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04);
0744 dac_set_mode(par->dac, DAC_PSEUDO8_16);
0745 hdiv = 2;
0746 }
0747 break;
0748 case 4:
0749 fb_dbg(info, "5/5/5 truecolor\n");
0750
0751 vga_wseq(par->state.vgabase, 0x11, 0x1A);
0752 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04);
0753 dac_set_mode(par->dac, DAC_RGB1555_16);
0754 break;
0755 case 5:
0756 fb_dbg(info, "5/6/5 truecolor\n");
0757
0758 vga_wseq(par->state.vgabase, 0x11, 0x1A);
0759 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04);
0760 dac_set_mode(par->dac, DAC_RGB0565_16);
0761 break;
0762 case 6:
0763 fb_dbg(info, "8/8/8 truecolor\n");
0764
0765 vga_wseq(par->state.vgabase, 0x11, 0x16);
0766 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04);
0767 dac_set_mode(par->dac, DAC_RGB0888_16);
0768 hmul = 3;
0769 hdiv = 2;
0770 break;
0771 case 7:
0772 fb_dbg(info, "8/8/8/8 truecolor\n");
0773
0774 vga_wseq(par->state.vgabase, 0x11, 0x1E);
0775 svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04);
0776 dac_set_mode(par->dac, DAC_RGB8888_16);
0777 hmul = 2;
0778 break;
0779 default:
0780 fb_err(info, "unsupported mode - bug\n");
0781 return -EINVAL;
0782 }
0783
0784 value = (hdiv * info->var.pixclock) / hmul;
0785 if (!value) {
0786 fb_dbg(info, "invalid pixclock\n");
0787 value = 1;
0788 }
0789 ark_set_pixclock(info, value);
0790 svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv,
0791 (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1,
0792 (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1,
0793 hmul, info->node);
0794
0795
0796 value = info->var.xres + info->var.left_margin + info->var.right_margin + info->var.hsync_len;
0797 value = ((value * hmul / hdiv) / 8) - 5;
0798 vga_wcrt(par->state.vgabase, 0x42, (value + 1) / 2);
0799
0800 if (screen_size > info->screen_size)
0801 screen_size = info->screen_size;
0802 memset_io(info->screen_base, 0x00, screen_size);
0803
0804 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
0805 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
0806
0807 return 0;
0808 }
0809
0810
0811
0812 static int arkfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
0813 u_int transp, struct fb_info *fb)
0814 {
0815 switch (fb->var.bits_per_pixel) {
0816 case 0:
0817 case 4:
0818 if (regno >= 16)
0819 return -EINVAL;
0820
0821 if ((fb->var.bits_per_pixel == 4) &&
0822 (fb->var.nonstd == 0)) {
0823 outb(0xF0, VGA_PEL_MSK);
0824 outb(regno*16, VGA_PEL_IW);
0825 } else {
0826 outb(0x0F, VGA_PEL_MSK);
0827 outb(regno, VGA_PEL_IW);
0828 }
0829 outb(red >> 10, VGA_PEL_D);
0830 outb(green >> 10, VGA_PEL_D);
0831 outb(blue >> 10, VGA_PEL_D);
0832 break;
0833 case 8:
0834 if (regno >= 256)
0835 return -EINVAL;
0836
0837 outb(0xFF, VGA_PEL_MSK);
0838 outb(regno, VGA_PEL_IW);
0839 outb(red >> 10, VGA_PEL_D);
0840 outb(green >> 10, VGA_PEL_D);
0841 outb(blue >> 10, VGA_PEL_D);
0842 break;
0843 case 16:
0844 if (regno >= 16)
0845 return 0;
0846
0847 if (fb->var.green.length == 5)
0848 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xF800) >> 1) |
0849 ((green & 0xF800) >> 6) | ((blue & 0xF800) >> 11);
0850 else if (fb->var.green.length == 6)
0851 ((u32*)fb->pseudo_palette)[regno] = (red & 0xF800) |
0852 ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
0853 else
0854 return -EINVAL;
0855 break;
0856 case 24:
0857 case 32:
0858 if (regno >= 16)
0859 return 0;
0860
0861 ((u32*)fb->pseudo_palette)[regno] = ((red & 0xFF00) << 8) |
0862 (green & 0xFF00) | ((blue & 0xFF00) >> 8);
0863 break;
0864 default:
0865 return -EINVAL;
0866 }
0867
0868 return 0;
0869 }
0870
0871
0872
0873 static int arkfb_blank(int blank_mode, struct fb_info *info)
0874 {
0875 struct arkfb_info *par = info->par;
0876
0877 switch (blank_mode) {
0878 case FB_BLANK_UNBLANK:
0879 fb_dbg(info, "unblank\n");
0880 svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);
0881 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
0882 break;
0883 case FB_BLANK_NORMAL:
0884 fb_dbg(info, "blank\n");
0885 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
0886 svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);
0887 break;
0888 case FB_BLANK_POWERDOWN:
0889 case FB_BLANK_HSYNC_SUSPEND:
0890 case FB_BLANK_VSYNC_SUSPEND:
0891 fb_dbg(info, "sync down\n");
0892 svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);
0893 svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);
0894 break;
0895 }
0896 return 0;
0897 }
0898
0899
0900
0901
0902 static int arkfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
0903 {
0904 struct arkfb_info *par = info->par;
0905 unsigned int offset;
0906
0907
0908 if (info->var.bits_per_pixel == 0) {
0909 offset = (var->yoffset / 16) * (info->var.xres_virtual / 2)
0910 + (var->xoffset / 2);
0911 offset = offset >> 2;
0912 } else {
0913 offset = (var->yoffset * info->fix.line_length) +
0914 (var->xoffset * info->var.bits_per_pixel / 8);
0915 offset = offset >> ((info->var.bits_per_pixel == 4) ? 2 : 3);
0916 }
0917
0918
0919 svga_wcrt_multi(par->state.vgabase, ark_start_address_regs, offset);
0920
0921 return 0;
0922 }
0923
0924
0925
0926
0927
0928
0929
0930 static const struct fb_ops arkfb_ops = {
0931 .owner = THIS_MODULE,
0932 .fb_open = arkfb_open,
0933 .fb_release = arkfb_release,
0934 .fb_check_var = arkfb_check_var,
0935 .fb_set_par = arkfb_set_par,
0936 .fb_setcolreg = arkfb_setcolreg,
0937 .fb_blank = arkfb_blank,
0938 .fb_pan_display = arkfb_pan_display,
0939 .fb_fillrect = arkfb_fillrect,
0940 .fb_copyarea = cfb_copyarea,
0941 .fb_imageblit = arkfb_imageblit,
0942 .fb_get_caps = svga_get_caps,
0943 };
0944
0945
0946
0947
0948
0949
0950 static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
0951 {
0952 struct pci_bus_region bus_reg;
0953 struct resource vga_res;
0954 struct fb_info *info;
0955 struct arkfb_info *par;
0956 int rc;
0957 u8 regval;
0958
0959
0960 if (! svga_primary_device(dev)) {
0961 dev_info(&(dev->dev), "ignoring secondary device\n");
0962 return -ENODEV;
0963 }
0964
0965
0966 info = framebuffer_alloc(sizeof(struct arkfb_info), &(dev->dev));
0967 if (!info)
0968 return -ENOMEM;
0969
0970 par = info->par;
0971 mutex_init(&par->open_lock);
0972
0973 info->flags = FBINFO_PARTIAL_PAN_OK | FBINFO_HWACCEL_YPAN;
0974 info->fbops = &arkfb_ops;
0975
0976
0977 rc = pci_enable_device(dev);
0978 if (rc < 0) {
0979 dev_err(info->device, "cannot enable PCI device\n");
0980 goto err_enable_device;
0981 }
0982
0983 rc = pci_request_regions(dev, "arkfb");
0984 if (rc < 0) {
0985 dev_err(info->device, "cannot reserve framebuffer region\n");
0986 goto err_request_regions;
0987 }
0988
0989 par->dac = ics5342_init(ark_dac_read_regs, ark_dac_write_regs, info);
0990 if (! par->dac) {
0991 rc = -ENOMEM;
0992 dev_err(info->device, "RAMDAC initialization failed\n");
0993 goto err_dac;
0994 }
0995
0996 info->fix.smem_start = pci_resource_start(dev, 0);
0997 info->fix.smem_len = pci_resource_len(dev, 0);
0998
0999
1000 info->screen_base = pci_iomap_wc(dev, 0, 0);
1001 if (! info->screen_base) {
1002 rc = -ENOMEM;
1003 dev_err(info->device, "iomap for framebuffer failed\n");
1004 goto err_iomap;
1005 }
1006
1007 bus_reg.start = 0;
1008 bus_reg.end = 64 * 1024;
1009
1010 vga_res.flags = IORESOURCE_IO;
1011
1012 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
1013
1014 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
1015
1016
1017 regval = vga_rseq(par->state.vgabase, 0x10);
1018 info->screen_size = (1 << (regval >> 6)) << 20;
1019 info->fix.smem_len = info->screen_size;
1020
1021 strcpy(info->fix.id, "ARK 2000PV");
1022 info->fix.mmio_start = 0;
1023 info->fix.mmio_len = 0;
1024 info->fix.type = FB_TYPE_PACKED_PIXELS;
1025 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
1026 info->fix.ypanstep = 0;
1027 info->fix.accel = FB_ACCEL_NONE;
1028 info->pseudo_palette = (void*) (par->pseudo_palette);
1029
1030
1031 rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
1032 if (! ((rc == 1) || (rc == 2))) {
1033 rc = -EINVAL;
1034 dev_err(info->device, "mode %s not found\n", mode_option);
1035 goto err_find_mode;
1036 }
1037
1038 rc = fb_alloc_cmap(&info->cmap, 256, 0);
1039 if (rc < 0) {
1040 dev_err(info->device, "cannot allocate colormap\n");
1041 goto err_alloc_cmap;
1042 }
1043
1044 rc = register_framebuffer(info);
1045 if (rc < 0) {
1046 dev_err(info->device, "cannot register framebuffer\n");
1047 goto err_reg_fb;
1048 }
1049
1050 fb_info(info, "%s on %s, %d MB RAM\n",
1051 info->fix.id, pci_name(dev), info->fix.smem_len >> 20);
1052
1053
1054 pci_set_drvdata(dev, info);
1055 par->wc_cookie = arch_phys_wc_add(info->fix.smem_start,
1056 info->fix.smem_len);
1057 return 0;
1058
1059
1060 err_reg_fb:
1061 fb_dealloc_cmap(&info->cmap);
1062 err_alloc_cmap:
1063 err_find_mode:
1064 pci_iounmap(dev, info->screen_base);
1065 err_iomap:
1066 dac_release(par->dac);
1067 err_dac:
1068 pci_release_regions(dev);
1069 err_request_regions:
1070
1071 err_enable_device:
1072 framebuffer_release(info);
1073 return rc;
1074 }
1075
1076
1077
1078 static void ark_pci_remove(struct pci_dev *dev)
1079 {
1080 struct fb_info *info = pci_get_drvdata(dev);
1081
1082 if (info) {
1083 struct arkfb_info *par = info->par;
1084 arch_phys_wc_del(par->wc_cookie);
1085 dac_release(par->dac);
1086 unregister_framebuffer(info);
1087 fb_dealloc_cmap(&info->cmap);
1088
1089 pci_iounmap(dev, info->screen_base);
1090 pci_release_regions(dev);
1091
1092
1093 framebuffer_release(info);
1094 }
1095 }
1096
1097
1098
1099
1100 static int __maybe_unused ark_pci_suspend(struct device *dev)
1101 {
1102 struct fb_info *info = dev_get_drvdata(dev);
1103 struct arkfb_info *par = info->par;
1104
1105 dev_info(info->device, "suspend\n");
1106
1107 console_lock();
1108 mutex_lock(&(par->open_lock));
1109
1110 if (par->ref_count == 0) {
1111 mutex_unlock(&(par->open_lock));
1112 console_unlock();
1113 return 0;
1114 }
1115
1116 fb_set_suspend(info, 1);
1117
1118 mutex_unlock(&(par->open_lock));
1119 console_unlock();
1120
1121 return 0;
1122 }
1123
1124
1125
1126
1127 static int __maybe_unused ark_pci_resume(struct device *dev)
1128 {
1129 struct fb_info *info = dev_get_drvdata(dev);
1130 struct arkfb_info *par = info->par;
1131
1132 dev_info(info->device, "resume\n");
1133
1134 console_lock();
1135 mutex_lock(&(par->open_lock));
1136
1137 if (par->ref_count == 0)
1138 goto fail;
1139
1140 arkfb_set_par(info);
1141 fb_set_suspend(info, 0);
1142
1143 fail:
1144 mutex_unlock(&(par->open_lock));
1145 console_unlock();
1146 return 0;
1147 }
1148
1149 static const struct dev_pm_ops ark_pci_pm_ops = {
1150 #ifdef CONFIG_PM_SLEEP
1151 .suspend = ark_pci_suspend,
1152 .resume = ark_pci_resume,
1153 .freeze = NULL,
1154 .thaw = ark_pci_resume,
1155 .poweroff = ark_pci_suspend,
1156 .restore = ark_pci_resume,
1157 #endif
1158 };
1159
1160
1161
1162 static const struct pci_device_id ark_devices[] = {
1163 {PCI_DEVICE(0xEDD8, 0xA099)},
1164 {0, 0, 0, 0, 0, 0, 0}
1165 };
1166
1167
1168 MODULE_DEVICE_TABLE(pci, ark_devices);
1169
1170 static struct pci_driver arkfb_pci_driver = {
1171 .name = "arkfb",
1172 .id_table = ark_devices,
1173 .probe = ark_pci_probe,
1174 .remove = ark_pci_remove,
1175 .driver.pm = &ark_pci_pm_ops,
1176 };
1177
1178
1179
1180 static void __exit arkfb_cleanup(void)
1181 {
1182 pr_debug("arkfb: cleaning up\n");
1183 pci_unregister_driver(&arkfb_pci_driver);
1184 }
1185
1186
1187
1188 static int __init arkfb_init(void)
1189 {
1190
1191 #ifndef MODULE
1192 char *option = NULL;
1193
1194 if (fb_get_options("arkfb", &option))
1195 return -ENODEV;
1196
1197 if (option && *option)
1198 mode_option = option;
1199 #endif
1200
1201 pr_debug("arkfb: initializing\n");
1202 return pci_register_driver(&arkfb_pci_driver);
1203 }
1204
1205 module_init(arkfb_init);
1206 module_exit(arkfb_cleanup);