82 #include <linux/string.h>
83 #include <linux/kernel.h>
84 #include <linux/module.h>
86 #include <linux/pci.h>
98 static bool clipping = 1;
105 #define DEFAULT_VIDEO_MODE "640x480@60"
114 #define IS_VOODOO2(par) ((par)->type == ID_VOODOO2)
117 { .name =
"Voodoo Graphics", .default_gfx_clock = 50000, .max_gfxclk = 60 },
118 { .name =
"Voodoo2", .default_gfx_clock = 75000, .max_gfxclk = 85 },
126 #if (SST_DEBUG_REG > 0)
130 case FBIINIT0: regname =
"FbiInit0";
break;
131 case FBIINIT1: regname =
"FbiInit1";
break;
132 case FBIINIT2: regname =
"FbiInit2";
break;
133 case FBIINIT3: regname =
"FbiInit3";
break;
134 case FBIINIT4: regname =
"FbiInit4";
break;
135 case FBIINIT5: regname =
"FbiInit5";
break;
136 case FBIINIT6: regname =
"FbiInit6";
break;
137 default: regname =
NULL;
break;
142 r_dprintk(
" sst_read(%s): %#x\n", regname, val);
148 case FBIINIT0: regname =
"FbiInit0";
break;
149 case FBIINIT1: regname =
"FbiInit1";
break;
150 case FBIINIT2: regname =
"FbiInit2";
break;
151 case FBIINIT3: regname =
"FbiInit3";
break;
152 case FBIINIT4: regname =
"FbiInit4";
break;
153 case FBIINIT5: regname =
"FbiInit5";
break;
154 case FBIINIT6: regname =
"FbiInit6";
break;
155 default: regname =
NULL;
break;
158 r_ddprintk(
"sst_write(%#x, %#x)\n", reg, val);
160 r_dprintk(
" sst_write(%s, %#x)\n", regname, val);
163 # define sst_dbg_print_read_reg(reg, val) do {} while(0)
164 # define sst_dbg_print_write_reg(reg, val) do {} while(0)
172 #define sst_read(reg) __sst_read(par->mmio_vbase, reg)
173 #define sst_write(reg,val) __sst_write(par->mmio_vbase, reg, val)
174 #define sst_set_bits(reg,val) __sst_set_bits(par->mmio_vbase, reg, val)
175 #define sst_unset_bits(reg,val) __sst_unset_bits(par->mmio_vbase, reg, val)
176 #define sst_dac_read(reg) __sst_dac_read(par->mmio_vbase, reg)
177 #define sst_dac_write(reg,val) __sst_dac_write(par->mmio_vbase, reg, val)
178 #define dac_i_read(reg) __dac_i_read(par->mmio_vbase, reg)
179 #define dac_i_write(reg,val) __dac_i_write(par->mmio_vbase, reg, val)
196 r_dprintk(
"sst_set_bits(%#x, %#x)\n", reg, val);
197 __sst_write(vbase, reg, __sst_read(vbase, reg) | val);
200 static inline void __sst_unset_bits(
u8 __iomem *vbase,
u32 reg,
u32 val)
202 r_dprintk(
"sst_unset_bits(%#x, %#x)\n", reg, val);
203 __sst_write(vbase, reg, __sst_read(vbase, reg) & ~val);
213 #define sst_wait_idle() __sst_wait_idle(par->mmio_vbase)
215 static int __sst_wait_idle(
u8 __iomem *vbase)
232 if (count >= 5)
return 1;
246 __sst_wait_idle(vbase);
248 ret = __sst_read(vbase,
DAC_READ) & 0xff;
249 r_dprintk(
"sst_dac_read(%#x): %#x\n", reg, ret);
254 static void __sst_dac_write(
u8 __iomem *vbase,
u8 reg,
u8 val)
256 r_dprintk(
"sst_dac_write(%#x, %#x)\n", reg, val);
259 __sst_wait_idle(vbase);
269 r_dprintk(
"sst_dac_read_i(%#x): %#x\n", reg, ret);
274 r_dprintk(
"sst_dac_write_i(%#x, %#x)\n", reg, val);
290 static int sst_calc_pll(
const int freq,
int *freq_out,
struct pll_timing *
t)
292 int m, m2,
n,
p, best_err, fout;
299 while (((1 << p) * freq >
VCO_MAX) && (p >= 0))
303 for (n = 1; n < 32; n++) {
305 m2 = (2 * freq * (1 <<
p) * (n + 2) ) /
DAC_FREF - 4 ;
307 m = (m2 % 2 ) ? m2/2+1 : m2/2 ;
310 fout = (
DAC_FREF * (m + 2)) / ((1 <<
p) * (n + 2));
311 if ((
abs(fout - freq) < best_err) && (m > 0)) {
314 best_err =
abs(fout - freq);
316 if (200*best_err < freq)
break;
324 *freq_out = (
DAC_FREF * (t->
m + 2)) / ((1 << t->
p) * (t->
n + 2));
325 f_ddprintk (
"m: %d, n: %d, p: %d, F: %dKhz\n",
326 t->
m, t->
n, t->
p, *freq_out);
333 static void sstfb_clear_screen(
struct fb_info *
info)
368 vBackPorch += (vBackPorch % 2);
386 if (var->
xres <= 1 || yDim <= 0 || var->hsync_len <= 1 ||
387 hSyncOff <= 1 || var->left_margin <= 2 || vSyncOn <= 0 ||
388 vSyncOff <= 0 || vBackPorch <= 0) {
394 tiles_in_X = (var->
xres + 63 ) / 64 * 2;
404 vSyncOff >=
POW2(13) || vBackPorch >=
POW2(9) ||
405 tiles_in_X >=
POW2(6) || tiles_in_X <= 0) {
411 tiles_in_X = (var->
xres + 63 ) / 64;
414 printk(
KERN_ERR "sstfb: Interlace/doublescan not supported %#x\n",
425 vSyncOff >=
POW2(12) || vBackPorch >=
POW2(8) ||
426 tiles_in_X >=
POW2(4) || tiles_in_X <= 0) {
434 real_length = tiles_in_X * (
IS_VOODOO2(par) ? 32 : 64 )
437 if (real_length *
yDim > info->
fix.smem_len) {
457 var->
green.length = 6;
458 var->
blue.length = 5;
461 var->
red.offset = 11;
462 var->
green.offset = 5;
463 var->
blue.offset = 0;
476 static int sstfb_set_par(
struct fb_info *info)
479 u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit5, fbiinit6=0;
488 par->
vSyncOff = info->
var.yres + info->
var.lower_margin + info->
var.upper_margin;
512 f_ddprintk(
"hsync_len hSyncOff vsync_len vSyncOff\n");
516 f_ddprintk(
"left_margin upper_margin xres yres Freq\n");
518 info->
var.left_margin, info->
var.upper_margin,
543 par->
dac_sw.set_vidmod(info, info->
var.bits_per_pixel);
586 switch (info->
var.bits_per_pixel) {
616 switch (info->
var.bits_per_pixel) {
624 #if defined(__BIG_ENDIAN)
644 f_ddprintk(
"setting clipping dimensions 0..%d, 0..%d\n",
645 info->
var.xres - 1, par->
yDim - 1);
674 regno, red, green, blue, transp);
678 red >>= (16 - info->
var.red.length);
679 green >>= (16 - info->
var.green.length);
680 blue >>= (16 - info->
var.blue.length);
681 transp >>= (16 - info->
var.transp.length);
682 col = (red << info->
var.red.offset)
683 | (green << info->
var.green.offset)
684 | (blue << info->
var.blue.offset)
685 | (transp << info->
var.transp.offset);
692 static void sstfb_setvgapass(
struct fb_info *info,
int enable )
698 enable = enable ? 1:0;
725 sstfb_setvgapass(info, val);
742 static int sstfb_ioctl(
struct fb_info *info,
unsigned int cmd,
753 sstfb_setvgapass(info, val);
758 if (
copy_to_user((
void __user *)arg, &val,
sizeof(val)))
774 u32 stride = info->
fix.line_length;
800 u32 stride = info->
fix.line_length;
830 if (
mem >= 1 &&
mem <= 4) {
831 *memsize = (
mem * 0x100000);
836 writel(0xdeadbeef, fbbase_virt);
837 writel(0xdeadbeef, fbbase_virt+0x100000);
838 writel(0xdeadbeef, fbbase_virt+0x200000);
840 readl(fbbase_virt),
readl(fbbase_virt + 0x100000),
841 readl(fbbase_virt + 0x200000));
843 writel(0xabcdef01, fbbase_virt);
846 readl(fbbase_virt),
readl(fbbase_virt + 0x100000),
847 readl(fbbase_virt + 0x200000));
850 if (
readl(fbbase_virt + 0x200000) == 0xdeadbeef)
852 else if (
readl(fbbase_virt + 0x100000) == 0xdeadbeef)
856 f_ddprintk(
"detected memsize: %dMB\n", *memsize >> 20);
873 for (i = 0; i < 3; i++) {
898 for (i = 0; i<3; i++) {
932 int m_clk0_1, m_clk0_7, m_clk1_b;
933 int n_clk0_1, n_clk0_7, n_clk1_b;
936 for (i = 0; i<5; i++ ) {
946 f_ddprintk(
"m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#x\n",
947 m_clk0_1, m_clk0_7, m_clk1_b);
948 f_ddprintk(
"n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#x\n",
949 n_clk0_1, n_clk0_7, n_clk1_b);
965 static int sst_set_pll_att_ti(
struct fb_info *info,
1007 dprintk(
"%s: wrong clock code '%d'\n",
1019 static int sst_set_pll_ics(
struct fb_info *info,
1049 dprintk(
"%s: wrong clock code '%d'\n",
1057 static void sst_set_vidmod_att_ti(
struct fb_info *info,
const int bpp)
1081 dprintk(
"%s: bad depth '%u'\n", __func__, bpp);
1086 static void sst_set_vidmod_ics(
struct fb_info *info,
const int bpp)
1095 dprintk(
"%s: bad depth '%u'\n", __func__, bpp);
1108 static struct dac_switch dacs[] __devinitdata = {
1109 { .
name =
"TI TVP3409",
1110 .detect = sst_detect_ti,
1111 .set_pll = sst_set_pll_att_ti,
1112 .set_vidmod = sst_set_vidmod_att_ti },
1114 { .name =
"AT&T ATT20C409",
1115 .detect = sst_detect_att,
1116 .set_pll = sst_set_pll_att_ti,
1117 .set_vidmod = sst_set_vidmod_att_ti },
1118 { .name =
"ICS ICS5342",
1119 .detect = sst_detect_ics,
1120 .set_pll = sst_set_pll_ics,
1121 .set_vidmod = sst_set_vidmod_ics },
1129 ret = dacs[
i].detect(info);
1145 u32 fbiinit0, fbiinit1, fbiinit4;
1152 spec = &voodoo_spec[par->
type];
1153 f_ddprintk(
" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 "
1155 f_ddprintk(
"%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",
1184 if (!sst_detect_dactype(info, par)) {
1192 if ((gfxclk >10 ) && (gfxclk < spec->
max_gfxclk)) {
1193 printk(
KERN_INFO "sstfb: Using supplied graphic freq : %dMHz\n", gfxclk);
1194 gfx_clock = gfxclk *1000;
1195 }
else if (gfxclk) {
1199 sst_calc_pll(gfx_clock, &Fout, &gfx_timings);
1258 sst_calc_pll(20000, &Fout, &gfx_timings);
1278 if (!options || !*options)
1281 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
1282 if (!*this_opt)
continue;
1286 if (!
strcmp(this_opt,
"vganopass"))
1288 else if (!
strcmp(this_opt,
"vgapass"))
1290 else if (!
strcmp(this_opt,
"clipping"))
1292 else if (!
strcmp(this_opt,
"noclipping"))
1294 else if (!
strcmp(this_opt,
"fastpci"))
1296 else if (!
strcmp(this_opt,
"slowpci"))
1298 else if (!
strncmp(this_opt,
"mem:",4))
1300 else if (!
strncmp(this_opt,
"gfxclk:",7))
1303 mode_option = this_opt;
1309 static struct fb_ops sstfb_ops = {
1311 .fb_check_var = sstfb_check_var,
1312 .fb_set_par = sstfb_set_par,
1313 .fb_setcolreg = sstfb_setcolreg,
1317 .fb_ioctl = sstfb_ioctl,
1340 pci_set_drvdata(pdev, info);
1345 par->
type =
id->driver_data;
1346 spec = &voodoo_spec[par->
type];
1371 goto fail_mmio_remap;
1380 if (!sst_init(info, par)) {
1384 sst_get_memsize(info, &fix->
smem_len);
1398 info->
fbops = &sstfb_ops;
1413 if (sstfb_check_var(&info->
var, info)) {
1418 if (sstfb_set_par(info)) {
1435 sstfb_clear_screen(info);
1466 info = pci_get_drvdata(pdev);
1491 .id_table = sstfb_id_tbl,
1492 .probe = sstfb_probe,
1503 sstfb_setup(option);
1505 return pci_register_driver(&sstfb_driver);
1518 MODULE_DESCRIPTION(
"FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
1522 MODULE_PARM_DESC(
mem,
"Size of frame buffer memory in MB (1, 2, 4 MB, default=autodetect)");
1524 MODULE_PARM_DESC(vgapass,
"Enable VGA PassThrough mode (0 or 1) (default=0)");
1526 MODULE_PARM_DESC(clipping,
"Enable clipping (slower, safer) (0 or 1) (default=1)");
1528 MODULE_PARM_DESC(gfxclk,
"Force graphic chip frequency in MHz. DANGEROUS. (default=auto)");