36 #include <linux/module.h>
38 #include <linux/kernel.h>
40 #include <linux/errno.h>
41 #include <linux/string.h>
43 #include <linux/screen_info.h>
44 #include <linux/slab.h>
49 #include <linux/pci.h>
51 #include <linux/capability.h>
53 #include <linux/types.h>
63 #if !defined(CONFIG_FB_SIS_300) && !defined(CONFIG_FB_SIS_315)
64 #warning Neither CONFIG_FB_SIS_300 nor CONFIG_FB_SIS_315 is set
65 #warning sisfb will not work!
74 sisfb_setdefaultparms(
void)
98 sisfb_tvxposoffset = 0;
99 sisfb_tvyposoffset = 0;
101 #if !defined(__i386__) && !defined(__x86_64__)
110 sisfb_search_vesamode(
unsigned int vesamode,
bool quiet)
127 while(sisbios_mode[i++].
mode_no[0] != 0) {
128 if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
129 (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
131 if(sisbios_mode[i-1].
mode_no[1] == 0x50 ||
132 sisbios_mode[i-1].
mode_no[1] == 0x56 ||
133 sisbios_mode[i-1].
mode_no[1] == 0x53)
136 if(sisbios_mode[i-1].
mode_no[1] == 0x5a ||
137 sisbios_mode[i-1].
mode_no[1] == 0x5b)
150 sisfb_search_mode(
char *
name,
bool quiet)
152 unsigned int j = 0, xres = 0, yres = 0,
depth = 0,
rate = 0;
154 char strbuf[16], strbuf1[20];
155 char *nameptr =
name;
169 printk(
KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
177 for(i = 0; i <
strlen(strbuf1); i++) {
178 if(strbuf1[i] <
'0' || strbuf1[i] >
'9') strbuf1[
i] =
' ';
189 }
else if(
sscanf(strbuf1,
"%u %u %u", &xres, &yres, &
depth) == 3) {
194 if((
sscanf(strbuf1,
"%u %u", &xres, &yres) == 2) && (xres != 0)) {
195 sprintf(strbuf,
"%ux%ux8", xres, yres);
205 while(sisbios_mode[i].
mode_no[0] != 0) {
208 if(sisbios_mode[i-1].
mode_no[1] == 0x50 ||
209 sisbios_mode[i-1].
mode_no[1] == 0x56 ||
210 sisbios_mode[i-1].
mode_no[1] == 0x53)
213 if(sisbios_mode[i-1].
mode_no[1] == 0x5a ||
214 sisbios_mode[i-1].
mode_no[1] == 0x5b)
229 sisfb_get_vga_mode_from_kernel(
void)
239 (mydepth >= 8) && (mydepth <= 32) ) {
241 if(mydepth == 24) mydepth = 32;
248 "sisfb: Using vga mode %s pre-set by kernel as default\n",
251 sisfb_search_mode(mymode,
true);
259 sisfb_search_crt2type(
const char *name)
265 if(name ==
NULL)
return;
267 while(sis_crt2type[i].type_no != -1) {
268 if(!
strnicmp(name, sis_crt2type[i].name,
strlen(sis_crt2type[i].name))) {
285 sisfb_search_tvstd(
const char *name)
294 while(sis_tvtype[i].type_no != -1) {
295 if(!
strnicmp(name, sis_tvtype[i].name,
strlen(sis_tvtype[i].name))) {
304 sisfb_search_specialtiming(
const char *name)
318 while(mycustomttable[i].chipID != 0) {
319 if(!
strnicmp(name,mycustomttable[i].optionName,
320 strlen(mycustomttable[i].optionName))) {
321 sisfb_specialtiming = mycustomttable[
i].SpecialID;
324 mycustomttable[i].vendorName,
325 mycustomttable[i].cardName,
326 mycustomttable[i].optionName);
335 while(mycustomttable[i].chipID != 0) {
337 mycustomttable[i].optionName,
338 mycustomttable[i].vendorName,
339 mycustomttable[i].cardName);
351 unsigned char *biosver =
NULL;
352 unsigned char *biosdate =
NULL;
357 if(ivideo->
SiS_Pr.UseROM) {
358 biosver = ivideo->
SiS_Pr.VirtualRomBase + 0x06;
359 biosdate = ivideo->
SiS_Pr.VirtualRomBase + 0x2c;
360 for(i = 0; i < 32768; i++)
361 chksum += ivideo->
SiS_Pr.VirtualRomBase[i];
366 if( (mycustomttable[i].chipID == ivideo->
chip) &&
367 ((!
strlen(mycustomttable[i].biosversion)) ||
369 (!
strncmp(mycustomttable[i].biosversion, biosver,
370 strlen(mycustomttable[i].biosversion))))) &&
371 ((!
strlen(mycustomttable[i].biosdate)) ||
373 (!
strncmp(mycustomttable[i].biosdate, biosdate,
374 strlen(mycustomttable[i].biosdate))))) &&
375 ((!mycustomttable[i].bioschksum) ||
377 (mycustomttable[i].bioschksum == chksum))) &&
378 (mycustomttable[i].pcisubsysvendor == ivideo->
subsysvendor) &&
379 (mycustomttable[i].pcisubsyscard == ivideo->
subsysdevice) ) {
381 for(j = 0; j < 5; j++) {
382 if(mycustomttable[i].biosFootprintAddr[j]) {
383 if(ivideo->
SiS_Pr.UseROM) {
384 if(ivideo->
SiS_Pr.VirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
385 mycustomttable[i].biosFootprintData[j]) {
393 ivideo->
SiS_Pr.SiS_CustomT = mycustomttable[
i].SpecialID;
395 mycustomttable[i].vendorName,
396 mycustomttable[i].cardName);
398 mycustomttable[i].optionName);
403 }
while(mycustomttable[i].chipID);
407 sisfb_interpret_edid(
struct sisfb_monitor *monitor,
u8 *
buffer)
409 int i,
j, xres, yres, refresh,
index;
412 if(buffer[0] != 0x00 || buffer[1] != 0xff ||
413 buffer[2] != 0xff || buffer[3] != 0xff ||
414 buffer[4] != 0xff || buffer[5] != 0xff ||
415 buffer[6] != 0xff || buffer[7] != 0x00) {
420 if(buffer[0x12] != 0x01) {
426 monitor->feature = buffer[0x18];
428 if(!(buffer[0x14] & 0x80)) {
429 if(!(buffer[0x14] & 0x08)) {
431 "sisfb: WARNING: Monitor does not support separate syncs\n");
435 if(buffer[0x13] >= 0x01) {
441 if(buffer[j] == 0x00 && buffer[j + 1] == 0x00 &&
442 buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
443 buffer[j + 4] == 0x00) {
444 monitor->hmin = buffer[j + 7];
445 monitor->hmax = buffer[j + 8];
446 monitor->vmin = buffer[j + 5];
447 monitor->vmax = buffer[j + 6];
448 monitor->dclockmax = buffer[j + 9] * 10 * 1000;
449 monitor->datavalid =
true;
456 if(!monitor->datavalid) {
462 monitor->hmin = 65535; monitor->hmax = 0;
463 monitor->vmin = 65535; monitor->vmax = 0;
464 monitor->dclockmax = 0;
465 emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
466 for(i = 0; i < 13; i++) {
467 if(emodes & sisfb_ddcsmodes[i].
mask) {
468 if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[
i].h;
469 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[
i].h + 1;
470 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[
i].v;
471 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[
i].v;
472 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[
i].d;
476 for(i = 0; i < 8; i++) {
477 xres = (buffer[
index] + 31) * 8;
478 switch(buffer[index + 1] & 0xc0) {
479 case 0xc0: yres = (xres * 9) / 16;
break;
480 case 0x80: yres = (xres * 4) / 5;
break;
481 case 0x40: yres = (xres * 3) / 4;
break;
482 default: yres = xres;
break;
484 refresh = (buffer[index + 1] & 0x3f) + 60;
485 if((xres >= 640) && (yres >= 480)) {
486 for(j = 0; j < 8; j++) {
487 if((xres == sisfb_ddcfmodes[j].
x) &&
488 (yres == sisfb_ddcfmodes[
j].y) &&
489 (refresh == sisfb_ddcfmodes[j].
v)) {
490 if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[
j].h;
491 if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[
j].h + 1;
492 if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[
j].v;
493 if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[
j].v;
494 if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[
j].d;
500 if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
501 monitor->datavalid =
true;
505 return monitor->datavalid;
509 sisfb_handle_ddc(
struct sis_video_info *ivideo,
struct sisfb_monitor *monitor,
int crtno)
511 unsigned short temp,
i, realcrtno = crtno;
512 unsigned char buffer[256];
514 monitor->datavalid =
false;
526 realcrtno, 0, &buffer[0], ivideo->
vbflags2);
527 if((!temp) || (temp == 0xffff)) {
534 (temp & 0x1a) ?
"" :
"[none of the supported]",
535 (temp & 0x02) ?
"2 " :
"",
536 (temp & 0x08) ?
"D&P" :
"",
537 (temp & 0x10) ?
"FPDI-2" :
"");
542 realcrtno, 1, &buffer[0], ivideo->
vbflags2);
543 }
while((temp) && i--);
545 if(sisfb_interpret_edid(monitor, &buffer[0])) {
546 printk(
KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
547 monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
548 monitor->dclockmax / 1000);
564 sisfb_verify_rate(
struct sis_video_info *ivideo,
struct sisfb_monitor *monitor,
568 unsigned int dclock,
hsync;
570 if(!monitor->datavalid)
577 switch(sisbios_mode[mode_idx].
mode_no[ivideo->
mni]) {
588 #ifdef CONFIG_FB_SIS_315
595 if(rate < (monitor->vmin - 1))
597 if(rate > (monitor->vmax + 1))
601 sisbios_mode[mode_idx].mode_no[ivideo->
mni],
602 &htotal, &vtotal, rate_idx)) {
603 dclock = (htotal * vtotal *
rate) / 1000;
604 if(dclock > (monitor->dclockmax + 1000))
606 hsync = dclock / htotal;
607 if(hsync < (monitor->hmin - 1))
609 if(hsync > (monitor->hmax + 1))
620 u16 xres=0, yres, myres;
622 #ifdef CONFIG_FB_SIS_300
628 #ifdef CONFIG_FB_SIS_315
635 myres = sisbios_mode[myindex].yres;
644 if(sisbios_mode[myindex].xres > xres)
651 if(sisbios_mode[myindex].xres == 320) {
653 switch(sisbios_mode[myindex].mode_no[1]) {
656 case 0x53:
return -1;
663 sisbios_mode[myindex].yres, 0, ivideo->
sisfb_fstn,
664 ivideo->
SiS_Pr.SiS_CustomT, xres, yres, ivideo->
vbflags2) < 0x14) {
671 sisbios_mode[myindex].yres, 0, ivideo->
vbflags2) < 0x14) {
678 sisbios_mode[myindex].yres, 0, ivideo->
vbflags2) < 0x14) {
688 sisfb_search_refresh_rate(
struct sis_video_info *ivideo,
unsigned int rate,
int mode_idx)
691 u16 xres = sisbios_mode[mode_idx].xres;
692 u16 yres = sisbios_mode[mode_idx].yres;
695 while((sisfb_vrate[i].
idx != 0) && (sisfb_vrate[i].xres <= xres)) {
696 if((sisfb_vrate[i].xres == xres) && (sisfb_vrate[i].yres == yres)) {
697 if(sisfb_vrate[i].refresh == rate) {
700 }
else if(sisfb_vrate[i].refresh > rate) {
701 if((sisfb_vrate[i].refresh - rate) <= 3) {
702 DPRINTK(
"sisfb: Adjusting rate from %d up to %d\n",
703 rate, sisfb_vrate[i].refresh);
706 }
else if((sisfb_vrate[i].
idx != 1) &&
707 ((rate - sisfb_vrate[i-1].refresh) <= 2)) {
708 DPRINTK(
"sisfb: Adjusting rate from %d down to %d\n",
709 rate, sisfb_vrate[i-1].refresh);
710 ivideo->
rate_idx = sisfb_vrate[i-1].idx;
714 }
else if((rate - sisfb_vrate[i].refresh) <= 2) {
715 DPRINTK(
"sisfb: Adjusting rate from %d down to %d\n",
716 rate, sisfb_vrate[i].refresh);
741 if( ((ivideo->
sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
742 ((ivideo->
sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
768 if(!sisfballowretracecrt1(ivideo))
782 if(!sisfballowretracecrt1(ivideo))
797 case SIS_300_VGA: reg = 0x25;
break;
798 case SIS_315_VGA: reg = 0x30;
break;
799 default:
return false;
813 if(!sisfb_bridgeisslave(ivideo)) {
814 return sisfbcheckvretracecrt2(ivideo);
817 return sisfbcheckvretracecrt1(ivideo);
826 (*vcount) = (*hcount) = 0;
828 if((ivideo->
currentvbflags & VB_DISPTYPE_DISP2) && (!(sisfb_bridgeisslave(ivideo)))) {
836 case SIS_300_VGA: idx = 0x25;
break;
838 case SIS_315_VGA: idx = 0x30;
break;
847 (*vcount) = reg3 | ((reg4 & 0x70) << 4);
848 (*hcount) = reg2 | ((reg4 & 0x0f) << 8);
850 }
else if(sisfballowretracecrt1(ivideo)) {
863 (*vcount) = reg2 | ((reg3 & 0x07) << 8);
864 (*hcount) = (reg1 | ((reg3 & 0x10) << 4)) << 3;
873 u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
874 bool backlight =
true;
936 if(!(sisfb_bridgeisslave(ivideo))) {
953 #ifdef CONFIG_FB_SIS_315
956 SiS_Chrontel701xBLOn(&ivideo->
SiS_Pr);
958 SiS_Chrontel701xBLOff(&ivideo->
SiS_Pr);
996 #ifdef CONFIG_FB_SIS_300
1003 pci_read_config_dword(ivideo->
nbridge, reg, &
val);
1004 return (
unsigned int)
val;
1008 sisfb_write_nbridge_pci_dword(
struct SiS_Private *SiS_Pr,
int reg,
unsigned int val)
1016 sisfb_read_lpc_pci_dword(
struct SiS_Private *SiS_Pr,
int reg)
1021 if(!ivideo->
lpcdev)
return 0;
1023 pci_read_config_dword(ivideo->
lpcdev, reg, &val);
1024 return (
unsigned int)
val;
1028 #ifdef CONFIG_FB_SIS_315
1030 sisfb_write_nbridge_pci_byte(
struct SiS_Private *SiS_Pr,
int reg,
unsigned char val)
1038 sisfb_read_mio_pci_word(
struct SiS_Private *SiS_Pr,
int reg)
1043 if(!ivideo->
lpcdev)
return 0;
1045 pci_read_config_word(ivideo->
lpcdev, reg, &val);
1046 return (
unsigned int)
val;
1089 if(maxyres > 32767) maxyres = 32767;
1109 bool isslavemode =
false;
1113 if(sisfb_bridgeisslave(ivideo)) isslavemode =
true;
1122 if((ivideo->
currentvbflags & VB_DISPTYPE_DISP2) && (!isslavemode)) {
1136 var->
red.offset = var->
green.offset = var->
blue.offset = 0;
1137 var->
red.length = var->
green.length = var->
blue.length = 8;
1140 var->
red.offset = 11;
1141 var->
red.length = 5;
1142 var->
green.offset = 5;
1143 var->
green.length = 6;
1144 var->
blue.offset = 0;
1145 var->
blue.length = 5;
1150 var->
red.offset = 16;
1151 var->
red.length = 8;
1152 var->
green.offset = 8;
1153 var->
green.length = 8;
1154 var->
blue.offset = 0;
1155 var->
blue.length = 8;
1165 unsigned short modeno = ivideo->
mode_no;
1172 sisfb_pre_setmode(ivideo);
1181 sisfb_post_setmode(ivideo);
1191 unsigned int htotal = 0, vtotal = 0;
1192 unsigned int drate = 0, hrate = 0;
1193 int found_mode = 0, ret;
1204 vtotal += var->
yres;
1207 vtotal += var->
yres;
1210 vtotal += var->
yres;
1212 }
else vtotal += var->
yres;
1214 if(!(htotal) || !(vtotal)) {
1215 DPRINTK(
"sisfb: Invalid 'var' information\n");
1219 if(pixclock && htotal && vtotal) {
1220 drate = 1000000000 / pixclock;
1221 hrate = (
drate * 1000) / htotal;
1268 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
1269 #ifdef STUPID_ACCELF_TEXT_SHIT
1281 if((ret = sisfb_set_mode(ivideo, 1))) {
1289 sisfb_calc_pitch(ivideo, var);
1290 sisfb_set_pitch(ivideo);
1292 sisfb_set_vparms(ivideo);
1309 sisfb_set_base_CRT1(
struct sis_video_info *ivideo,
unsigned int base)
1322 sisfb_set_base_CRT2(
struct sis_video_info *ivideo,
unsigned int base)
1343 switch (info->
var.bits_per_pixel) {
1376 sisfb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
unsigned blue,
1381 if(regno >= sisfb_get_cmap_len(&info->
var))
1384 switch(info->
var.bits_per_pixel) {
1403 ((green & 0xfc00) >> 5) |
1404 ((blue & 0xf800) >> 11);
1414 (red << 16) | (green << 8) | (blue);
1421 sisfb_set_par(
struct fb_info *info)
1425 if((err = sisfb_do_set_var(&info->
var, 1, info)))
1428 sisfb_get_fix(&info->
fix, -1, info);
1437 unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
1438 unsigned int drate = 0, hrate = 0, maxyres;
1441 bool recalc_clock =
false;
1451 vtotal += var->
yres;
1454 vtotal += var->
yres;
1457 vtotal += var->
yres;
1460 vtotal += var->
yres;
1462 if(!(htotal) || !(vtotal)) {
1463 SISFAIL(
"sisfb: no valid timing data");
1467 while( (sisbios_mode[search_idx].mode_no[0] != 0) &&
1468 (sisbios_mode[search_idx].xres <= var->xres) ) {
1469 if( (sisbios_mode[search_idx].xres == var->
xres) &&
1470 (sisbios_mode[search_idx].yres == var->
yres) &&
1472 if((
tidx = sisfb_validate_mode(ivideo, search_idx,
1484 while(sisbios_mode[search_idx].mode_no[0] != 0) {
1485 if( (var->
xres <= sisbios_mode[search_idx].xres) &&
1486 (var->
yres <= sisbios_mode[search_idx].yres) &&
1488 if((
tidx = sisfb_validate_mode(ivideo,search_idx,
1499 "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
1501 sisbios_mode[search_idx].xres,
1502 sisbios_mode[search_idx].yres,
1504 var->
xres = sisbios_mode[search_idx].xres;
1505 var->
yres = sisbios_mode[search_idx].yres;
1508 "sisfb: Failed to find supported mode near %dx%dx%d\n",
1519 recalc_clock =
true;
1524 drate = 1000000000 / pixclock;
1525 hrate = (
drate * 1000) / htotal;
1526 refresh_rate = (
unsigned int) (hrate * 2 / vtotal);
1540 recalc_clock =
true;
1541 }
else if((pixclock) && (htotal) && (vtotal)) {
1542 drate = 1000000000 / pixclock;
1543 hrate = (
drate * 1000) / htotal;
1544 refresh_rate = (
unsigned int) (hrate * 2 / vtotal);
1547 recalc_clock =
true;
1550 recalc_clock =
true;
1553 myrateindex = sisfb_search_refresh_rate(ivideo, refresh_rate, search_idx);
1557 if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
1559 sisbios_mode[search_idx].mode_no[ivideo->
mni],
1562 sisbios_mode[search_idx].mode_no[ivideo->
mni],
1571 myrateindex, refresh_rate)) {
1573 "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
1578 sisfb_bpp_to_var(ivideo, var);
1588 maxyres = sisfb_calc_maxyres(ivideo, var);
1617 var->
red.msb_right =
1618 var->
green.msb_right =
1619 var->
blue.msb_right =
1622 var->
transp.msb_right = 0;
1636 if (var->
xoffset + info->
var.xres > info->
var.xres_virtual ||
1640 err = sisfb_pan_var(ivideo, info, var);
1651 sisfb_blank(
int blank,
struct fb_info *info)
1655 return sisfb_myblank(ivideo, blank);
1660 static int sisfb_ioctl(
struct fb_info *info,
unsigned int cmd,
1677 if(
copy_from_user(&sismemreq, (
void __user *)arg,
sizeof(sismemreq)))
1682 if(
copy_to_user((
void __user *)arg, &sismemreq,
sizeof(sismemreq))) {
1702 sisvbblank.count = 0;
1703 sisvbblank.flags = sisfb_setupvbblankflags(ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
1705 if(
copy_to_user((
void __user *)arg, &sisvbblank,
sizeof(sisvbblank)))
1716 "sisfb: Deprecated ioctl call received - update your application!\n");
1769 "sisfb: Deprecated ioctl call received - update your application!\n");
1771 if(sisfb_CheckVBRetrace(ivideo))
1779 "sisfb: Deprecated ioctl call received - update your application!\n");
1789 "sisfb: Deprecated ioctl call received - update your application!\n");
1801 sisfb_set_TVxposoffset(ivideo, ((
int)(gpu32 >> 16)) - 32);
1802 sisfb_set_TVyposoffset(ivideo, ((
int)(gpu32 & 0xffff)) - 32);
1830 #ifdef SIS_NEW_CONFIG_COMPAT
1880 static struct fb_ops sisfb_ops = {
1882 .fb_open = sisfb_open,
1883 .fb_release = sisfb_release,
1884 .fb_check_var = sisfb_check_var,
1885 .fb_set_par = sisfb_set_par,
1886 .fb_setcolreg = sisfb_setcolreg,
1887 .fb_pan_display = sisfb_pan_display,
1888 .fb_blank = sisfb_blank,
1893 #ifdef SIS_NEW_CONFIG_COMPAT
1894 .fb_compat_ioctl= sisfb_ioctl,
1896 .fb_ioctl = sisfb_ioctl
1902 sisfb_get_northbridge(
int basechipid)
1905 int nbridgenum, nbridgeidx,
i;
1906 static const unsigned short nbridgeids[] = {
1921 switch(basechipid) {
1922 #ifdef CONFIG_FB_SIS_300
1923 case SIS_540: nbridgeidx = 0; nbridgenum = 1;
break;
1924 case SIS_630: nbridgeidx = 1; nbridgenum = 2;
break;
1926 #ifdef CONFIG_FB_SIS_315
1927 case SIS_550: nbridgeidx = 3; nbridgenum = 1;
break;
1928 case SIS_650: nbridgeidx = 4; nbridgenum = 3;
break;
1929 case SIS_660: nbridgeidx = 7; nbridgenum = 5;
break;
1931 default:
return NULL;
1933 for(i = 0; i < nbridgenum; i++) {
1935 nbridgeids[nbridgeidx+i],
NULL)))
1944 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
1951 switch(ivideo->
chip) {
1952 #ifdef CONFIG_FB_SIS_300
1955 ivideo->
video_size = ((reg & 0x3F) + 1) << 20;
1962 pci_read_config_byte(ivideo->
nbridge, 0x63, ®);
1963 ivideo->
video_size = 1 << (((reg & 0x70) >> 4) + 21);
1966 #ifdef CONFIG_FB_SIS_315
1971 ivideo->
video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
1972 switch((reg >> 2) & 0x03) {
1983 ivideo->
video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
1990 ivideo->
video_size = (((reg & 0x3f) + 1) << 2) << 20;
1995 ivideo->
video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2001 reg = (reg & 0xf0) >> 4;
2021 ivideo->
video_size = (1 << ((reg & 0xf0) >> 4)) << 20;
2023 reg = (reg & 0x0c) >> 2;
2025 if(reg & 0x01) reg = 0x02;
2029 else if(reg == 0x03) ivideo->
video_size <<= 2;
2052 #ifdef CONFIG_FB_SIS_300
2177 return (count != -1);
2183 bool mustwait =
false;
2185 #ifdef CONFIG_FB_SIS_315
2194 if(sr1F & 0xc0) mustwait =
true;
2196 #ifdef CONFIG_FB_SIS_315
2214 for(i=0; i < 10; i++) sisfbwaitretracecrt1(ivideo);
2217 #ifdef CONFIG_FB_SIS_315
2234 if(temp == 0xffff) {
2239 }
while(((temp == 0) || (temp == 0xffff)) && i--);
2241 if((temp == 0) || (temp == 0xffff)) {
2242 if(sisfb_test_DDC1(ivideo)) temp = 1;
2246 if((temp) && (temp != 0xffff)) {
2250 #ifdef CONFIG_FB_SIS_315
2265 unsigned char buffer[256];
2266 unsigned short temp, realcrtno,
i;
2267 u8 reg, cr37 = 0, paneltype = 0;
2270 ivideo->
SiS_Pr.PanelSelfDetected =
false;
2284 if(ivideo->
SiS_Pr.DDCPortMixup)
2289 realcrtno, 0, &buffer[0], ivideo->
vbflags2);
2291 if((!temp) || (temp == 0xffff) || (!(temp & 0x02)))
2300 }
while((temp) && i--);
2306 if(!(buffer[0x14] & 0x80))
2310 if(!(buffer[0x18] & 0x02))
2313 xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
2314 yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
2337 if((buffer[0x47] & 0x18) == 0x18)
2338 cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
2347 ivideo->
SiS_Pr.PanelSelfDetected =
true;
2355 for(j = 0; j < 10; j++) {
2357 for(i = 0; i < 3; i++) {
2360 temp = (type >> 8) | (mytest & 0x00ff);
2368 if(temp == mytest) result++;
2375 if((result == 0) || (result >= 2))
break;
2383 u8 backupP4_0d,backupP2_00,backupP2_4d,backupSR_1e,biosflag=0;
2384 u16 svhs=0, svhs_c=0;
2385 u16 cvbs=0, cvbs_c=0;
2386 u16 vga2=0, vga2_c=0;
2388 char stdstr[] =
"sisfb: Detected";
2389 char tvstr[] =
"TV connected to";
2392 svhs = 0x00b9; cvbs = 0x00b3; vga2 = 0x00d1;
2395 svhs = 0x00dd; cvbs = 0x00ee; vga2 = 0x00fd;
2398 svhs = 0x016b; cvbs = 0x0174; vga2 = 0x0190;
2400 svhs = 0x0200; cvbs = 0x0100;
2402 svhs = 0x016b; cvbs = 0x0110; vga2 = 0x0190;
2406 vga2_c = 0x0e08; svhs_c = 0x0404; cvbs_c = 0x0804;
2408 svhs_c = 0x0408; cvbs_c = 0x0808;
2414 }
else if(ivideo->
newrom) {
2415 if(ivideo->
bios_abase[0x5d] & 0x04) biosflag |= 0x01;
2424 if(!(myflag & 0x01)) vga2 = vga2_c = 0;
2451 SISDoSense(ivideo, 0, 0);
2456 if(vga2_c || vga2) {
2457 if(SISDoSense(ivideo, vga2, vga2_c)) {
2458 if(biosflag & 0x01) {
2477 if((result = SISDoSense(ivideo, svhs, 0x0604))) {
2478 if((result = SISDoSense(ivideo, cvbs, 0x0804))) {
2489 if((result = SISDoSense(ivideo, svhs, svhs_c))) {
2493 if((biosflag & 0x02) || (!result)) {
2494 if(SISDoSense(ivideo, cvbs, cvbs_c)) {
2501 SISDoSense(ivideo, 0, 0);
2509 if(biosflag & 0x20) {
2510 for(myflag = 2; myflag > 0; myflag--) {
2524 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
2526 char stdstr[] =
"sisfb: Chrontel: Detected TV connected to";
2528 #ifdef CONFIG_FB_SIS_300
2529 unsigned char test[3];
2535 #ifdef CONFIG_FB_SIS_300
2536 ivideo->
SiS_Pr.SiS_IF_DEF_CH70xx = 1;
2542 if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
2547 if(temp2 != temp1) temp1 =
temp2;
2549 if((temp1 >= 0x22) && (temp1 <= 0x50)) {
2552 if((temp1 & 0x03) != 0x03) {
2558 for(i = 0; i < 3; i++) {
2564 if(!(temp1 & 0x08)) test[
i] = 0x02;
2565 else if(!(temp1 & 0x02)) test[
i] = 0x01;
2570 if(test[0] == test[1]) temp1 = test[0];
2571 else if(test[0] == test[2]) temp1 = test[0];
2572 else if(test[1] == test[2]) temp1 = test[1];
2575 "sisfb: TV detection unreliable - test results varied\n");
2583 }
else if (temp1 == 0x01) {
2592 }
else if(temp1 == 0) {
2602 #ifdef CONFIG_FB_SIS_315
2603 ivideo->
SiS_Pr.SiS_IF_DEF_CH70xx = 2;
2617 if(temp2 & 0x02) temp1 |= 0x01;
2618 if(temp2 & 0x10) temp1 |= 0x01;
2619 if(temp2 & 0x04) temp1 |= 0x02;
2620 if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
2649 char stdstr[] =
"sisfb: Detected";
2650 char bridgestr[] =
"video bridge";
2666 }
else if(reg < 0xc0) {
2677 }
else if(reg < 0xd0) {
2681 }
else if(reg < 0xe0) {
2685 }
else if(reg <= 0xe1) {
2715 #ifdef CONFIG_FB_SIS_300
2737 #ifdef CONFIG_FB_SIS_315
2751 #ifdef CONFIG_FB_SIS_315
2786 SiS_SenseLCD(ivideo);
2787 SiS_Sense30x(ivideo);
2789 SiS_SenseCh(ivideo);
2808 #ifdef CONFIG_FB_SIS_300
2818 tq_state |= (
u8)(tqueue_pos >> 8);
2827 #ifdef CONFIG_FB_SIS_315
2829 u32 tempq = 0, templ;
2843 case (4 * 1024 * 1024):
2846 case (2 * 1024 * 1024):
2849 case (1 * 1024 * 1024):
2936 printk(
KERN_DEBUG "sisfb: Invalid panel ID (%02x), assuming 1024x768, RGB18\n", reg);
2940 if(ivideo->
CRT2LCDType == sis_lcd_data[i].lcdtype) {
2941 ivideo->
lcdxres = sis_lcd_data[
i].xres;
2942 ivideo->
lcdyres = sis_lcd_data[
i].yres;
2948 #ifdef CONFIG_FB_SIS_300
2968 #ifdef CONFIG_FB_SIS_300
2978 if(ivideo->
SiS_Pr.PDC == -1) {
2985 if((ivideo->
SiS_Pr.PDC != -1) &&
2994 #ifdef CONFIG_FB_SIS_315
3002 ivideo->
SiS_Pr.SiS_UseLCDA =
true;
3029 if(ivideo->
SiS_Pr.PDC == -1) {
3034 if(ivideo->
SiS_Pr.PDCA == -1) {
3041 "sisfb: Detected LCD PDC 0x%02x (for LCD=CRT2)\n",
3046 "sisfb: Detected LCD PDC1 0x%02x (for LCD=CRT1)\n",
3057 ivideo->
SiS_Pr.HaveEMI =
true;
3059 ivideo->
SiS_Pr.HaveEMILCD =
true;
3066 if((ivideo->
SiS_Pr.PDC != -1) &&
3071 if((ivideo->
SiS_Pr.PDCA != -1) &&
3121 def = maxoffs - 0x8000;
3125 if((!ret) || (ret > maxoffs) || (ivideo->
cardnumber != 0))
3170 ivideo->
heapstart = sisfb_getheapstart(ivideo);
3184 poh = sisfb_poh_new_node(&ivideo->
sisfb_heap);
3213 sisfb_poh_new_node(
struct SIS_HEAP *memheap)
3230 poh = &poha->
aoh[0];
3231 for(i = cOhs - 1; i != 0; i--) {
3232 poh->poh_next = poh + 1;
3236 poh->poh_next =
NULL;
3254 DPRINTK(
"sisfb: Can't allocate %dk video memory\n",
3255 (
unsigned int) size / 1024);
3259 pohThis = memheap->
oh_free.poh_next;
3261 while(pohThis != &memheap->
oh_free) {
3262 if(size <= pohThis->size) {
3270 DPRINTK(
"sisfb: Can't allocate %dk video memory\n",
3271 (
unsigned int) size / 1024);
3275 if(size == pohThis->
size) {
3277 sisfb_delete_node(pohThis);
3279 pohRoot = sisfb_poh_new_node(memheap);
3293 sisfb_insert_node(pohThis, pohRoot);
3299 sisfb_delete_node(
struct SIS_OH *poh)
3306 sisfb_insert_node(
struct SIS_OH *pohList,
struct SIS_OH *poh)
3318 sisfb_poh_free(
struct SIS_HEAP *memheap,
u32 base)
3321 struct SIS_OH *poh_freed;
3328 poh_freed = memheap->
oh_used.poh_next;
3330 while(poh_freed != &memheap->
oh_used) {
3331 if(poh_freed->
offset == base) {
3344 poh_prev = poh_next =
NULL;
3345 ulUpper = poh_freed->
offset + poh_freed->
size;
3346 ulLower = poh_freed->
offset;
3348 pohThis = memheap->
oh_free.poh_next;
3350 while(pohThis != &memheap->
oh_free) {
3351 if(pohThis->
offset == ulUpper) {
3353 }
else if((pohThis->
offset + pohThis->
size) == ulLower) {
3359 sisfb_delete_node(poh_freed);
3361 if(poh_prev && poh_next) {
3363 sisfb_delete_node(poh_next);
3364 sisfb_free_node(memheap, poh_freed);
3365 sisfb_free_node(memheap, poh_next);
3371 sisfb_free_node(memheap, poh_freed);
3378 sisfb_free_node(memheap, poh_freed);
3382 sisfb_insert_node(&memheap->
oh_free, poh_freed);
3407 DPRINTK(
"sisfb: Video RAM allocation failed\n");
3411 DPRINTK(
"sisfb: Video RAM allocation succeeded: 0x%lx\n",
3422 sis_int_malloc(ivideo, req);
3432 sis_int_malloc(ivideo, req);
3445 poh = sisfb_poh_free(&ivideo->
sisfb_heap, base);
3448 DPRINTK(
"sisfb: sisfb_poh_free() failed at base 0x%x\n",
3449 (
unsigned int) base);
3458 sis_int_free(ivideo, base);
3466 sis_int_free(ivideo, base);
3485 #ifdef CONFIG_FB_SIS_300
3494 #ifdef CONFIG_FB_SIS_315
3501 if((cr30 & 0xe0) && (!(cr30 & 0x01))) {
3512 u8 cr30 = 0, cr31 = 0, cr33 = 0, cr35 = 0, cr38 = 0;
3525 #ifdef CONFIG_FB_SIS_315
3537 #ifdef CONFIG_FB_SIS_300
3553 #ifdef CONFIG_FB_SIS_315
3603 cr31 |= 0x01; cr35 |= 0x01;
3606 cr38 |= 0x40; cr35 |= 0x04;
3609 cr38 |= 0x80; cr35 |= 0x08;
3613 cr31 &= ~0x01; cr35 &= ~0x01;
3616 cr38 |= 0x40; cr35 |= 0x02;
3638 cr33 |= ((ivideo->
rate_idx & 0x0F) << 4);
3651 #ifdef CONFIG_FB_SIS_315
3664 sisfb_check_engine_and_sync(ivideo);
3668 #ifdef CONFIG_FB_SIS_315
3678 tmpreg = (tmpreg + 1) & 0xff;
3692 if(val > 32) val = 32;
3693 if(val < -32) val = -32;
3703 int x = ivideo->
tvx;
3721 unsigned short temp;
3723 p2_1f = ivideo->
p2_1f;
3724 p2_20 = ivideo->
p2_20;
3725 p2_2b = ivideo->
p2_2b;
3726 p2_42 = ivideo->
p2_42;
3727 p2_43 = ivideo->
p2_43;
3729 temp = p2_1f | ((p2_20 & 0xf0) << 4);
3731 p2_1f = temp & 0xff;
3732 p2_20 = (temp & 0xf00) >> 4;
3733 p2_2b = ((p2_2b & 0x0f) + (val * 2)) & 0x0f;
3734 temp = p2_43 | ((p2_42 & 0xf0) << 4);
3736 p2_43 = temp & 0xff;
3737 p2_42 = (temp & 0xf00) >> 4;
3750 if(val > 32) val = 32;
3751 if(val < -32) val = -32;
3761 int y = ivideo->
tvy;
3780 p2_01 = ivideo->
p2_01;
3781 p2_02 = ivideo->
p2_02;
3786 while((p2_01 <= 0) || (p2_02 <= 0)) {
3800 bool crt1isoff =
false;
3802 #if defined(CONFIG_FB_SIS_300) || defined(CONFIG_FB_SIS_315)
3805 #ifdef CONFIG_FB_SIS_315
3811 #ifdef CONFIG_FB_SIS_315
3812 sisfb_fixup_SR11(ivideo);
3820 if(sisfb_bridgeisslave(ivideo)) doit =
false;
3824 #ifdef CONFIG_FB_SIS_300
3836 #ifdef CONFIG_FB_SIS_315
3886 sisfb_set_TVxposoffset(ivideo, ivideo->
tvxpos);
3889 sisfb_set_TVyposoffset(ivideo, ivideo->
tvypos);
3893 sisfb_check_engine_and_sync(ivideo);
3897 sisfb_engine_init(ivideo);
3906 if(sisfb_set_mode(ivideo, 0))
3909 sisfb_set_pitch(ivideo);
3935 }
else if(sisfb_command->
sisfb_arg[0] == 99) {
3946 mycrt1off = sisfb_command->
sisfb_arg[0] ? 0 : 1;
3950 if(sisfb_reset_mode(ivideo)) {
3970 sisfb_setdefaultparms();
3972 if(!options || !(*options))
3975 while((this_opt =
strsep(&options,
",")) !=
NULL) {
3977 if(!(*this_opt))
continue;
3979 if(!
strnicmp(this_opt,
"off", 3)) {
3981 }
else if(!
strnicmp(this_opt,
"forcecrt2type:", 14)) {
3983 sisfb_search_crt2type(this_opt + 14);
3984 }
else if(!
strnicmp(this_opt,
"tvmode:",7)) {
3985 sisfb_search_tvstd(this_opt + 7);
3986 }
else if(!
strnicmp(this_opt,
"tvstandard:",11)) {
3987 sisfb_search_tvstd(this_opt + 11);
3988 }
else if(!
strnicmp(this_opt,
"mode:", 5)) {
3989 sisfb_search_mode(this_opt + 5,
false);
3990 }
else if(!
strnicmp(this_opt,
"vesa:", 5)) {
3992 }
else if(!
strnicmp(this_opt,
"rate:", 5)) {
3994 }
else if(!
strnicmp(this_opt,
"forcecrt1:", 10)) {
3996 }
else if(!
strnicmp(this_opt,
"mem:",4)) {
3998 }
else if(!
strnicmp(this_opt,
"pdc:", 4)) {
4000 }
else if(!
strnicmp(this_opt,
"pdc1:", 5)) {
4002 }
else if(!
strnicmp(this_opt,
"noaccel", 7)) {
4004 }
else if(!
strnicmp(this_opt,
"accel", 5)) {
4006 }
else if(!
strnicmp(this_opt,
"noypan", 6)) {
4008 }
else if(!
strnicmp(this_opt,
"ypan", 4)) {
4010 }
else if(!
strnicmp(this_opt,
"nomax", 5)) {
4012 }
else if(!
strnicmp(this_opt,
"max", 3)) {
4014 }
else if(!
strnicmp(this_opt,
"userom:", 7)) {
4016 }
else if(!
strnicmp(this_opt,
"useoem:", 7)) {
4018 }
else if(!
strnicmp(this_opt,
"nocrt2rate", 10)) {
4020 }
else if(!
strnicmp(this_opt,
"scalelcd:", 9)) {
4021 unsigned long temp = 2;
4023 if((temp == 0) || (temp == 1)) {
4024 sisfb_scalelcd = temp ^ 1;
4026 }
else if(!
strnicmp(this_opt,
"tvxposoffset:", 13)) {
4029 if((temp >= -32) && (temp <= 32)) {
4030 sisfb_tvxposoffset =
temp;
4032 }
else if(!
strnicmp(this_opt,
"tvyposoffset:", 13)) {
4035 if((temp >= -32) && (temp <= 32)) {
4036 sisfb_tvyposoffset =
temp;
4038 }
else if(!
strnicmp(this_opt,
"specialtiming:", 14)) {
4039 sisfb_search_specialtiming(this_opt + 14);
4040 }
else if(!
strnicmp(this_opt,
"lvdshl:", 7)) {
4043 if((temp >= 0) && (temp <= 3)) {
4044 sisfb_lvdshl =
temp;
4046 }
else if(this_opt[0] >=
'0' && this_opt[0] <=
'9') {
4047 sisfb_search_mode(this_opt,
true);
4048 #if !defined(__i386__) && !defined(__x86_64__)
4049 }
else if(!
strnicmp(this_opt,
"resetcard", 9)) {
4050 sisfb_resetcard = 1;
4051 }
else if(!
strnicmp(this_opt,
"videoram:", 9)) {
4070 if((
readb(rom_base) != 0x55) || (
readb(rom_base + 1) != 0xaa))
4073 romptr = (
readb(rom_base + 0x18) | (
readb(rom_base + 0x19) << 8));
4074 if(romptr > (0x10000 - 8))
4077 rom = rom_base + romptr;
4079 if((
readb(rom) !=
'P') || (
readb(rom + 1) !=
'C') ||
4080 (
readb(rom + 2) !=
'I') || (
readb(rom + 3) !=
'R'))
4093 sisfb_find_rom(
struct pci_dev *pdev)
4097 unsigned char *myrombase =
NULL;
4108 if(sisfb_check_rom(rom_base, ivideo)) {
4110 if((myrombase =
vmalloc(65536))) {
4112 (romsize > 65536) ? 65536 : romsize);
4119 if(myrombase)
return myrombase;
4123 #if defined(__i386__) || defined(__x86_64__)
4127 for (temp = 0x000c0000; temp < 0x000f0000; temp += 0x00001000) {
4129 rom_base =
ioremap(temp, 65536);
4133 if (!sisfb_check_rom(rom_base, ivideo)) {
4138 if ((myrombase =
vmalloc(65536)))
4153 sisfb_post_map_vram(
struct sis_video_info *ivideo,
unsigned int *mapsize,
4156 if (*mapsize < (min << 20))
4163 "sisfb: Unable to map maximum video RAM for size detection\n");
4167 if((*mapsize) < (min << 20))
4172 "sisfb: Video RAM size detection limited to %dMB\n",
4173 (
int)((*mapsize) >> 20));
4178 #ifdef CONFIG_FB_SIS_300
4183 unsigned short temp;
4192 for(i = 0; i < 2; i++) {
4194 for(j = 0; j < 4; j++) {
4196 if(
readw(FBAddress) == temp)
4208 writel(0x01234567L, FBAddress);
4209 writel(0x456789ABL, (FBAddress + 4));
4210 writel(0x89ABCDEFL, (FBAddress + 8));
4211 writel(0xCDEF0123L, (FBAddress + 12));
4215 if(
readl((FBAddress + 12)) == 0xCDEF0123L)
4219 if(
readl((FBAddress + 4)) == 0x456789ABL)
4225 static const unsigned short __devinitconst SiS_DRAMType[17][5] = {
4226 {0x0C,0x0A,0x02,0x40,0x39},
4227 {0x0D,0x0A,0x01,0x40,0x48},
4228 {0x0C,0x09,0x02,0x20,0x35},
4229 {0x0D,0x09,0x01,0x20,0x44},
4230 {0x0C,0x08,0x02,0x10,0x31},
4231 {0x0D,0x08,0x01,0x10,0x40},
4232 {0x0C,0x0A,0x01,0x20,0x34},
4233 {0x0C,0x09,0x01,0x08,0x32},
4234 {0x0B,0x08,0x02,0x08,0x21},
4235 {0x0C,0x08,0x01,0x08,0x30},
4236 {0x0A,0x08,0x02,0x04,0x11},
4237 {0x0B,0x0A,0x01,0x10,0x28},
4238 {0x09,0x08,0x02,0x02,0x01},
4239 {0x0B,0x09,0x01,0x08,0x24},
4240 {0x0B,0x08,0x01,0x04,0x20},
4241 {0x0A,0x08,0x01,0x02,0x10},
4242 {0x09,0x08,0x01,0x01,0x00}
4247 int PseudoRankCapacity,
int PseudoAdrPinCount,
4248 unsigned int mapsize)
4251 unsigned short sr14;
4252 unsigned int k, RankCapacity, PageCapacity, BankNumHigh, BankNumMid;
4253 unsigned int PhysicalAdrOtherPage, PhysicalAdrHigh, PhysicalAdrHalfPage;
4255 for(k = 0; k <
ARRAY_SIZE(SiS_DRAMType); k++) {
4257 RankCapacity = buswidth * SiS_DRAMType[
k][3];
4259 if(RankCapacity != PseudoRankCapacity)
4262 if((SiS_DRAMType[k][2] + SiS_DRAMType[k][0]) > PseudoAdrPinCount)
4265 BankNumHigh = RankCapacity * 16 * iteration - 1;
4266 if(iteration == 3) {
4267 BankNumMid = RankCapacity * 16 - 1;
4269 BankNumMid = RankCapacity * 16 * iteration / 2 - 1;
4272 PageCapacity = (1 << SiS_DRAMType[
k][1]) * buswidth * 4;
4273 PhysicalAdrHigh = BankNumHigh;
4274 PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
4275 PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[
k][2] + PhysicalAdrHigh;
4279 sr14 = (SiS_DRAMType[
k][3] *
buswidth) - 1;
4280 if(buswidth == 4) sr14 |= 0x80;
4281 else if(buswidth == 2) sr14 |= 0x40;
4288 if((BankNumHigh + PhysicalAdrHigh >= mapsize) ||
4289 (BankNumMid + PhysicalAdrHigh >= mapsize) ||
4290 (BankNumHigh + PhysicalAdrHalfPage >= mapsize) ||
4291 (BankNumHigh + PhysicalAdrOtherPage >= mapsize))
4295 writew(((
unsigned short)PhysicalAdrHigh),
4296 (FBAddr + BankNumHigh + PhysicalAdrHigh));
4297 writew(((
unsigned short)BankNumMid),
4298 (FBAddr + BankNumMid + PhysicalAdrHigh));
4299 writew(((
unsigned short)PhysicalAdrHalfPage),
4300 (FBAddr + BankNumHigh + PhysicalAdrHalfPage));
4301 writew(((
unsigned short)PhysicalAdrOtherPage),
4302 (FBAddr + BankNumHigh + PhysicalAdrOtherPage));
4305 if(
readw(FBAddr + BankNumHigh + PhysicalAdrHigh) == PhysicalAdrHigh)
4313 sisfb_post_300_ramsize(
struct pci_dev *pdev,
unsigned int mapsize)
4317 int PseudoRankCapacity, PseudoAdrPinCount;
4319 buswidth = sisfb_post_300_buswidth(ivideo);
4321 for(i = 6; i >= 0; i--) {
4322 PseudoRankCapacity = 1 <<
i;
4323 for(j = 4; j >= 1; j--) {
4324 PseudoAdrPinCount = 15 -
j;
4325 if((PseudoRankCapacity * j) <= 64) {
4326 if(sisfb_post_300_rwtest(ivideo,
4339 sisfb_post_sis300(
struct pci_dev *pdev)
4342 unsigned char *
bios = ivideo->
SiS_Pr.VirtualRomBase;
4345 unsigned int mapsize;
4347 if(!ivideo->
SiS_Pr.UseROM)
4353 if(bios[0x52] & 0x80) {
4354 memtype = bios[0x52];
4361 v3 = 0x80; v6 = 0x80;
4363 v1 = 0x44; v2 = 0x42;
4364 v4 = 0x44; v5 = 0x42;
4366 v1 = 0x68; v2 = 0x43;
4367 v4 = 0x68; v5 = 0x43;
4369 index = memtype * 5;
4370 rindex = index + 0x54;
4371 v1 = bios[rindex++];
4372 v2 = bios[rindex++];
4373 v3 = bios[rindex++];
4374 rindex = index + 0x7c;
4375 v4 = bios[rindex++];
4376 v5 = bios[rindex++];
4377 v6 = bios[rindex++];
4394 v1 = 0x01; v2 = 0x43; v3 = 0x1e; v4 = 0x2a;
4395 v5 = 0x06; v6 = 0x00; v7 = 0x00; v8 = 0x00;
4399 v2 = bios[memtype + 8];
4400 v3 = bios[memtype + 16];
4401 v4 = bios[memtype + 24];
4402 v5 = bios[memtype + 32];
4403 v6 = bios[memtype + 40];
4404 v7 = bios[memtype + 48];
4405 v8 = bios[memtype + 56];
4420 if(bios[0x53] & 0x02) {
4429 v1 = 0xf6; v2 = 0x0d; v3 = 0x00;
4443 v1 = 0x40; v2 = 0x11;
4454 if((reg == 1) || (reg == 2)) {
4457 v4 = 0x00; v5 = 0x00; v6 = 0x10;
4458 if(ivideo->
SiS_Pr.UseROM) {
4485 #if !defined(__i386__) && !defined(__x86_64__)
4486 if(sisfb_videoram) {
4488 reg = ((sisfb_videoram >> 10) - 1) | 0x40;
4494 sisfb_post_map_vram(ivideo, &mapsize, 4);
4497 sisfb_post_300_ramsize(pdev, mapsize);
4501 "sisfb: Failed to map memory for size detection, assuming 8MB\n");
4505 #if !defined(__i386__) && !defined(__x86_64__)
4513 if((reg & 0x30) == 0x30) {
4525 sisfb_sense_crt1(ivideo);
4528 ivideo->
SiS_Pr.SiS_UseOEM =
false;
4532 ivideo->
SiS_Pr.VideoMemorySize = 8 << 20;
4548 #ifdef CONFIG_FB_SIS_315
4551 sisfb_post_sis315330(
struct pci_dev *pdev)
4568 for(i = 0; i <= (delay * 10 * 36); i++) {
4579 unsigned short temp;
4584 if(temp == pcivendor) {
4596 unsigned int enda,
unsigned int mapsize)
4603 for(i = starta; i <= enda; i++) {
4609 sisfb_post_xgi_delay(ivideo, 150);
4614 for(i = starta; i <= enda; i++) {
4629 unsigned int buswidth, ranksize, channelab, mapsize;
4632 static const u8 dramsr13[12 * 5] = {
4633 0x02, 0x0e, 0x0b, 0x80, 0x5d,
4634 0x02, 0x0e, 0x0a, 0x40, 0x59,
4635 0x02, 0x0d, 0x0b, 0x40, 0x4d,
4636 0x02, 0x0e, 0x09, 0x20, 0x55,
4637 0x02, 0x0d, 0x0a, 0x20, 0x49,
4638 0x02, 0x0c, 0x0b, 0x20, 0x3d,
4639 0x02, 0x0e, 0x08, 0x10, 0x51,
4640 0x02, 0x0d, 0x09, 0x10, 0x45,
4641 0x02, 0x0c, 0x0a, 0x10, 0x39,
4642 0x02, 0x0d, 0x08, 0x08, 0x41,
4643 0x02, 0x0c, 0x09, 0x08, 0x35,
4644 0x02, 0x0c, 0x08, 0x04, 0x31
4646 static const u8 dramsr13_4[4 * 5] = {
4647 0x02, 0x0d, 0x09, 0x40, 0x45,
4648 0x02, 0x0c, 0x09, 0x20, 0x35,
4649 0x02, 0x0c, 0x08, 0x10, 0x31,
4650 0x02, 0x0b, 0x08, 0x08, 0x21
4665 sisfb_post_map_vram(ivideo, &mapsize, 32);
4668 printk(
KERN_ERR "sisfb: Unable to detect RAM size. Setting default.\n");
4688 sisfb_post_xgi_delay(ivideo, 1);
4690 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4695 sisfb_post_xgi_delay(ivideo, 1);
4696 if(sisfb_post_xgi_rwtest(ivideo, 23, 23, mapsize))
4702 sisfb_post_xgi_delay(ivideo, 1);
4704 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4712 sisfb_post_xgi_delay(ivideo, 1);
4714 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4719 sisfb_post_xgi_delay(ivideo, 1);
4720 if(sisfb_post_xgi_rwtest(ivideo, 22, 22, mapsize))
4726 sisfb_post_xgi_delay(ivideo, 1);
4728 if(sisfb_post_xgi_rwtest(ivideo, 21, 22, mapsize))
4749 sisfb_post_xgi_delay(ivideo, 1);
4750 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4755 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4762 if(sisfb_post_xgi_rwtest(ivideo, 22, 23, mapsize))
4772 sisfb_post_xgi_delay(ivideo, 1);
4773 if(sisfb_post_xgi_rwtest(ivideo, 23, 25, mapsize))
4778 sisfb_post_xgi_delay(ivideo, 1);
4780 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4787 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize)) {
4795 sisfb_post_xgi_delay(ivideo, 1);
4804 sisfb_post_xgi_delay(ivideo, 1);
4806 if(sisfb_post_xgi_rwtest(ivideo, 23, 24, mapsize))
4815 sisfb_post_xgi_delay(ivideo, 1);
4817 if(sisfb_post_xgi_rwtest(ivideo, 24, 25, mapsize))
4823 sisfb_post_xgi_delay(ivideo, 1);
4830 sisfb_post_xgi_delay(ivideo, 1);
4836 for(i = 0; i <
k; i++) {
4839 dramsr13[(i * 5) + 4] : dramsr13_4[(i * 5) + 4];
4841 sisfb_post_xgi_delay(ivideo, 50);
4844 dramsr13[(i * 5) + 3] : dramsr13_4[(i * 5) + 3];
4847 if(reg & 0x80) ranksize <<= 1;
4850 if(buswidth == 16) ranksize <<= 1;
4851 else if(buswidth == 32) ranksize <<= 2;
4853 if(buswidth == 64) ranksize <<= 1;
4859 if((ranksize * l) <= 256) {
4860 while((ranksize >>= 1)) reg += 0x10;
4866 sisfb_post_xgi_delay(ivideo, 1);
4868 if (sisfb_post_xgi_rwtest(ivideo, j, ((reg >> 4) + channelab - 2 + 20), mapsize)) {
4884 static const u8 cs90[8 * 3] = {
4894 static const u8 csb8[8 * 3] = {
4908 v1 = cs90[
index]; v2 = cs90[index + 1]; v3 = cs90[index + 2];
4917 sisfb_post_xgi_delay(ivideo, 0x43);
4918 sisfb_post_xgi_delay(ivideo, 0x43);
4919 sisfb_post_xgi_delay(ivideo, 0x43);
4921 v1 = csb8[
index]; v2 = csb8[index + 1]; v3 = csb8[index + 2];
4930 sisfb_post_xgi_delay(ivideo, 0x43);
4931 sisfb_post_xgi_delay(ivideo, 0x43);
4932 sisfb_post_xgi_delay(ivideo, 0x43);
4943 sisfb_post_xgi_delay(ivideo, 15);
4952 sisfb_post_xgi_delay(ivideo, 1);
4954 sisfb_post_xgi_setclocks(ivideo, regb);
4955 sisfb_post_xgi_delay(ivideo, 0x46);
4960 sisfb_post_xgi_delay(ivideo, 1);
4962 sisfb_post_xgi_delay(ivideo, 1);
4964 sisfb_post_xgi_delay(ivideo, 1);
4973 sisfb_post_xgi_delay(ivideo, 1);
4979 sisfb_post_xgi_setclocks(ivideo, 1);
4982 sisfb_post_xgi_delay(ivideo, 0x46);
5003 sisfb_post_xgi_delay(ivideo, 1);
5006 sisfb_post_xgi_delay(ivideo, 1);
5009 sisfb_post_xgi_delay(ivideo, 1);
5015 sisfb_post_xgi_delay(ivideo, 1);
5022 static const u8 cs158[8] = {
5023 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5025 static const u8 cs160[8] = {
5026 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5028 static const u8 cs168[8] = {
5029 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5042 v1 = cs168[regb]; v2 = cs160[regb]; v3 = cs158[regb];
5044 v1 = bios[regb + 0x168];
5045 v2 = bios[regb + 0x160];
5046 v3 = bios[regb + 0x158];
5058 if (sisfb_xgi_is21(ivideo))
5059 sisfb_post_xgi_ddr2_mrs_xg21(ivideo);
5061 sisfb_post_xgi_ddr2_mrs_default(ivideo, regb);
5072 ramtype = 0x00; v1 = 0x10;
5074 ramtype = bios[0x62];
5077 if (!(ramtype & 0x80)) {
5078 if (sisfb_xgi_is21(ivideo)) {
5083 ramtype = reg & 0x01;
5088 ramtype = (reg & 0x01) << 1;
5092 ramtype = reg & 0x02;
5095 ramtype = (reg >> 1) & 0x01;
5105 sisfb_post_xgi(
struct pci_dev *pdev)
5110 const u8 *
ptr, *ptr2;
5112 u32 rega, regb, regd;
5114 static const u8 cs78[3] = { 0xf6, 0x0d, 0x00 };
5115 static const u8 cs76[2] = { 0xa3, 0xfb };
5116 static const u8 cs7b[3] = { 0xc0, 0x11, 0x00 };
5117 static const u8 cs158[8] = {
5118 0x88, 0xaa, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00
5120 static const u8 cs160[8] = {
5121 0x44, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00
5123 static const u8 cs168[8] = {
5124 0x48, 0x78, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00
5126 static const u8 cs128[3 * 8] = {
5127 0x90, 0x28, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
5128 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5129 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00
5131 static const u8 cs148[2 * 8] = {
5132 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00,
5133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5135 static const u8 cs31a[8 * 4] = {
5136 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
5137 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00,
5138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5141 static const u8 cs33a[8 * 4] = {
5142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5147 static const u8 cs45a[8 * 2] = {
5148 0x00, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x00, 0x00,
5149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5151 static const u8 cs170[7 * 8] = {
5152 0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5153 0x54, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5154 0x0a, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
5155 0x44, 0x34, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00,
5156 0x10, 0x0a, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00,
5157 0x11, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
5158 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00
5160 static const u8 cs1a8[3 * 8] = {
5161 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
5162 0x05, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
5163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
5165 static const u8 cs100[2 * 8] = {
5166 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
5167 0xc4, 0x04, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00
5185 for(i = 0; i < 0x22; i++) {
5186 if(0x06 + i == 0x20)
continue;
5189 for(i = 0; i < 0x0b; i++) {
5192 for(i = 0; i < 0x10; i++) {
5198 ptr = (
const u8 *)&bios[0x78];
5200 for(i = 0; i < 3; i++) {
5206 ptr = (
const u8 *)&bios[0x76];
5208 for(i = 0; i < 2; i++) {
5212 v1 = 0x18; v2 = 0x00;
5226 ptr = (
const u8 *)&bios[0x7b];
5228 for(i = 0; i < 3; i++) {
5247 reg = (ivideo->
chip ==
XGI_40) ? 0x20 : 0x00;
5269 if(reg == 1 || reg == 2) {
5277 if((reg & 0xf0) >= 0xb0) {
5279 if(reg & 0x20) reg |= 0x40;
5281 reg = (reg & 0x20) ? 0x02 : 0x00;
5291 v2 = (reg & 0x30) >> 3;
5292 if(!(v2 & 0x04)) v2 ^= 0x02;
5294 if(reg & 0x80) v2 |= 0x80;
5299 if(((v2 & 0x06) == 2) || ((v2 & 0x06) == 4))
5310 pci_read_config_dword(mypdev, 0x94, ®d);
5312 pci_write_config_dword(mypdev, 0x94, regd);
5317 }
else if(sisfb_find_host_bridge(ivideo, pdev, 0x1106) ||
5318 sisfb_find_host_bridge(ivideo, pdev, 0x1022) ||
5319 sisfb_find_host_bridge(ivideo, pdev, 0x700e) ||
5320 sisfb_find_host_bridge(ivideo, pdev, 0x10de)) {
5321 if((v2 & 0x06) == 4)
5333 regd = bios[0x90 + 3] | (bios[0x90 + 4] << 8);
5334 if( (!(v1 & 0x02)) && (v2 & 0x30) && (regd < 0xcf) )
5350 if((!(reg & 0x02)) && (v2 & 0x0e))
5354 if(bios[0x64] & 0x01) {
5359 pci_read_config_dword(pdev, 0x50, ®d);
5360 regd = (regd >> 20) & 0x0f;
5394 ramtype = sisfb_post_xgi_ramtype(ivideo);
5395 if (!sisfb_xgi_is21(ivideo) && ramtype) {
5397 "RAM type something else than expected: %d\n",
5406 v1 = bios[0x140 + regb];
5412 ptr = (
const u8 *)&bios[0x128];
5414 for(i = 0, j = 0; i < 3; i++, j += 8) {
5421 index = (ivideo->
chip ==
XGI_20) ? 0x31a : 0x3a6;
5422 ptr = (
const u8 *)&bios[index];
5423 ptr2 = (
const u8 *)&bios[index + 0x20];
5425 for(i = 0; i < 2; i++) {
5434 for(j = 0; j < 16; j++) {
5436 if(regd & 0x01) reg |= 0x04;
5437 if(regd & 0x02) reg |= 0x08;
5450 index = (ivideo->
chip ==
XGI_20) ? 0x35a : 0x3e6;
5451 ptr = (
const u8 *)&bios[index];
5453 for(i = 0; i < 4; i++) {
5456 for(j = 0; j < 2; j++) {
5463 for(k = 0; k < 16; k++) {
5465 if(regd & 0x01) reg |= 0x01;
5466 if(regd & 0x02) reg |= 0x02;
5478 ptr = (
const u8 *)&bios[0x148];
5480 for(i = 0, j = 0; i < 2; i++, j += 8) {
5488 index = (ivideo->
chip ==
XGI_20) ? 0x45a : 0x4e6;
5489 ptr = (
const u8 *)&bios[index];
5493 for(i = 0; i < 5; i++) {
5495 if(regd & 0x01) reg |= 0x01;
5496 if(regd & 0x02) reg |= 0x02;
5504 v1 = 0xb5; v2 = 0x20; v3 = 0xf0; v4 = 0x13;
5506 v1 = bios[0x118 + regb];
5507 v2 = bios[0xf8 + regb];
5508 v3 = bios[0x120 + regb];
5518 ptr = (
const u8 *)&bios[0x170];
5520 for(i = 0, j = 0; i < 7; i++, j += 8) {
5528 ptr = (
const u8 *)&bios[0x1a8];
5530 for(i = 0, j = 0; i < 3; i++, j += 8) {
5536 ptr = (
const u8 *)&bios[0x100];
5538 for(i = 0, j = 0; i < 2; i++, j += 8) {
5567 sisfb_post_xgi_setclocks(ivideo, regb);
5571 v1 = cs158[regb]; v2 = cs160[regb]; v3 = cs168[regb];
5573 v1 = bios[regb + 0x158];
5574 v2 = bios[regb + 0x160];
5575 v3 = bios[regb + 0x168];
5610 if((ivideo->
chip ==
XGI_20) || (bios[0x1cb] != 0x0c)) {
5611 sisfb_post_xgi_delay(ivideo, 0x43);
5612 sisfb_post_xgi_delay(ivideo, 0x43);
5613 sisfb_post_xgi_delay(ivideo, 0x43);
5621 }
else if((ivideo->
chip ==
XGI_40) && (bios[0x1cb] == 0x0c)) {
5626 sisfb_post_xgi_delay(ivideo, 4);
5627 v1 = 0x31; v2 = 0x03; v3 = 0x83; v4 = 0x03; v5 = 0x83;
5630 index = (ivideo->
chip ==
XGI_20) ? 0x4b2 : 0x53e;
5632 v3 = bios[index + 1];
5633 v4 = bios[index + 2];
5634 v5 = bios[index + 3];
5640 sisfb_post_xgi_delay(ivideo, 0x43);
5642 sisfb_post_xgi_delay(ivideo, 0x22);
5650 sisfb_post_xgi_ddr2(ivideo, regb);
5653 sisfb_post_xgi_setclocks(ivideo, regb);
5670 v1 = cs160[regb]; v2 = cs158[regb];
5672 v1 = bios[regb + 0x160];
5673 v2 = bios[regb + 0x158];
5696 if((ivideo->
chip ==
XGI_40) && (bios[0x1cb] != 0x0c)) {
5697 sisfb_post_xgi_delay(ivideo, 0x43);
5698 sisfb_post_xgi_delay(ivideo, 0x43);
5699 sisfb_post_xgi_delay(ivideo, 0x43);
5705 sisfb_post_xgi_delay(ivideo, 4);
5719 sisfb_post_xgi_delay(ivideo, 0x43);
5725 sisfb_post_xgi_delay(ivideo, 0x22);
5741 v1 = bios[0x110 + regb];
5746 v1 = 0x00; v2 = 0x00;
5753 if((v1 & 0x40) && (v2 & regd) && ivideo->
haveXGIROM) {
5762 ivideo->
SiS_Pr.SiS_UseOEM =
false;
5766 ivideo->
SiS_Pr.VideoMemorySize = 8 << 20;
5773 err = sisfb_post_xgi_ramsize(ivideo);
5779 "%s: RAM size detection failed: %d\n",
5787 for(i = 0; i < 0xff; i++) {
5791 for(i = 0; i < 0x40; i++) {
5803 if((reg == 1) || (reg == 2)) {
5804 sisfb_sense_crt1(ivideo);
5811 ivideo->
SiS_Pr.SiS_UseOEM =
false;
5831 if((reg & 0x10) && (!(v1 & 0x04))) {
5833 "sisfb: Please connect power to the card.\n");
5845 struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->
driver_data];
5864 if(card_list ==
NULL) {
5869 while((countvideo = countvideo->
next) !=
NULL)
5890 sisfb_get_vga_mode_from_kernel();
5894 ivideo->
chip = chipinfo->chip;
5899 ivideo->
mni = chipinfo->mni;
5918 "but marked as boot video device ???\n");
5920 "as the primary VGA device\n");
5941 ivideo->
tvxpos = sisfb_tvxposoffset;
5942 ivideo->
tvypos = sisfb_tvyposoffset;
5949 ivideo->
SiS_Pr.UsePanelScaler = sisfb_scalelcd;
5950 ivideo->
SiS_Pr.CenterScreen = -1;
5951 ivideo->
SiS_Pr.SiS_CustomT = sisfb_specialtiming;
5952 ivideo->
SiS_Pr.LVDSHL = sisfb_lvdshl;
5954 ivideo->
SiS_Pr.SiS_Backup70xx = 0xff;
5955 ivideo->
SiS_Pr.SiS_CHOverScan = -1;
5956 ivideo->
SiS_Pr.SiS_ChSW =
false;
5957 ivideo->
SiS_Pr.SiS_UseLCDA =
false;
5958 ivideo->
SiS_Pr.HaveEMI =
false;
5959 ivideo->
SiS_Pr.HaveEMILCD =
false;
5960 ivideo->
SiS_Pr.OverruleEMI =
false;
5961 ivideo->
SiS_Pr.SiS_SensibleSR11 =
false;
5962 ivideo->
SiS_Pr.SiS_MyCR63 = 0x63;
5964 ivideo->
SiS_Pr.PDCA = -1;
5965 ivideo->
SiS_Pr.DDCPortMixup =
false;
5966 #ifdef CONFIG_FB_SIS_315
5968 ivideo->
SiS_Pr.SiS_MyCR63 = 0x53;
5970 ivideo->
SiS_Pr.SiS_SensibleSR11 =
true;
5977 pci_set_drvdata(pdev, ivideo);
5980 if((ivideo->
nbridge = sisfb_get_northbridge(ivideo->
chip))) {
5981 switch(ivideo->
nbridge->device) {
5982 #ifdef CONFIG_FB_SIS_300
5988 #ifdef CONFIG_FB_SIS_315
6021 ivideo->
SiS_Pr.ivideo = (
void *)ivideo;
6023 #ifdef CONFIG_FB_SIS_315
6033 pci_set_drvdata(pdev,
NULL);
6048 #ifdef CONFIG_FB_SIS_300
6053 if(mychswtable[i].subsysVendor == ivideo->
subsysvendor &&
6055 ivideo->
SiS_Pr.SiS_ChSW =
true;
6057 "requiring Chrontel/GPIO setup\n",
6058 mychswtable[i].vendorName,
6059 mychswtable[i].cardName);
6064 }
while(mychswtable[i].subsysVendor != 0);
6068 #ifdef CONFIG_FB_SIS_315
6077 #
if !defined(__i386__) && !defined(__x86_64__)
6078 || (sisfb_resetcard)
6081 for(i = 0x30; i <= 0x3f; i++) {
6092 #if defined(__i386__) || defined(__x86_64__)
6104 ivideo->
SiS_Pr.UseROM =
false;
6107 ivideo->
SiS_Pr.VirtualRomBase = sisfb_find_rom(pdev);
6111 ivideo->
SiS_Pr.UseROM ?
"" :
"not ");
6113 ivideo->
SiS_Pr.UseROM =
false;
6117 ivideo->
SiS_Pr.DDCPortMixup =
true;
6126 sisfb_detect_custom_timing(ivideo);
6129 #ifdef CONFIG_FB_SIS_315
6143 #
if !defined(__i386__) && !defined(__x86_64__)
6144 || (sisfb_resetcard)
6147 #ifdef CONFIG_FB_SIS_300
6150 sisfb_post_sis300(pdev);
6156 #ifdef CONFIG_FB_SIS_315
6165 result = sisfb_post_xgi(pdev);
6168 result = sisfb_post_xgi(pdev);
6172 "POSTed and sisfb can't do this either.\n");
6186 if(sisfb_get_dram_size(ivideo)) {
6187 printk(
KERN_INFO "sisfb: Fatal error: Unable to determine VRAM size.\n");
6202 if(sisfb_pdc != 0xff) {
6207 ivideo->
SiS_Pr.PDC = sisfb_pdc;
6209 #ifdef CONFIG_FB_SIS_315
6211 if(sisfb_pdca != 0xff)
6212 ivideo->
SiS_Pr.PDCA = sisfb_pdca & 0x1f;
6217 printk(
KERN_ERR "sisfb: Fatal error: Unable to reserve %dMB framebuffer memory\n",
6219 printk(
KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
6225 printk(
KERN_ERR "sisfb: Fatal error: Unable to reserve MMIO region\n");
6233 printk(
KERN_ERR "sisfb: Fatal error: Unable to map framebuffer memory\n");
6240 printk(
KERN_ERR "sisfb: Fatal error: Unable to map MMIO region\n");
6250 pci_set_drvdata(pdev,
NULL);
6257 printk(
KERN_INFO "sisfb: Video RAM at 0x%lx, mapped to 0x%lx, size %ldk\n",
6265 printk(
KERN_INFO "sisfb: MMIO at 0x%lx, mapped to 0x%lx, size %ldk\n",
6293 if((ivideo->
havenoheap = sisfb_heap_init(ivideo))) {
6318 sisfb_sense_crt1(ivideo);
6320 sisfb_get_VB_type(ivideo);
6323 sisfb_detect_VB_connect(ivideo);
6361 sisfb_detect_lcd_type(ivideo);
6364 sisfb_save_pdc_emi(ivideo);
6381 sisbios_mode[bu].xres,
6382 sisbios_mode[bu].yres,
6383 sisbios_mode[bu].
bpp);
6404 sisfb_search_refresh_rate(ivideo, ivideo->
refresh_rate,
6419 "exceeds monitor specs!\n");
6427 sisfb_set_vparms(ivideo);
6464 #ifdef STUPID_ACCELF_TEXT_SHIT
6470 #if defined(FBINFO_HWACCEL_DISABLED) && defined(FBINFO_HWACCEL_XPAN)
6483 sis_fb_info->
fbops = &sisfb_ops;
6493 if(ivideo->
mtrr < 0) {
6499 printk(
KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
6508 ivideo->
next = card_list;
6514 (ivideo->
sisfb_max ?
"enabled (auto-max)" :
6515 "enabled (no auto-max)") :
6522 printk(
KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n");
6558 if(ivideo->
mtrr >= 0)
6562 pci_set_drvdata(pdev,
NULL);
6585 if(registered && modechanged)
6587 "sisfb: Restoring of text mode not supported yet\n");
6592 .id_table = sisfb_pci_table,
6593 .probe = sisfb_probe,
6597 static int __init sisfb_init(
void)
6600 char *options =
NULL;
6605 sisfb_setup(options);
6607 return pci_register_driver(&sisfb_driver);
6621 static int vesa = -1;
6622 static unsigned int rate = 0;
6623 static unsigned int crt1off = 1;
6624 static unsigned int mem = 0;
6625 static char *forcecrt2type =
NULL;
6626 static int forcecrt1 = -1;
6627 static int pdc = -1;
6628 static int pdc1 = -1;
6629 static int noaccel = -1;
6630 static int noypan = -1;
6631 static int nomax = -1;
6632 static int userom = -1;
6633 static int useoem = -1;
6634 static char *tvstandard =
NULL;
6635 static int nocrt2rate = 0;
6636 static int scalelcd = -1;
6637 static char *specialtiming =
NULL;
6638 static int lvdshl = -1;
6639 static int tvxposoffset = 0, tvyposoffset = 0;
6640 #if !defined(__i386__) && !defined(__x86_64__)
6641 static int resetcard = 0;
6642 static int videoram = 0;
6645 static int __init sisfb_init_module(
void)
6647 sisfb_setdefaultparms();
6650 sisfb_parm_rate =
rate;
6652 if((scalelcd == 0) || (scalelcd == 1))
6653 sisfb_scalelcd = scalelcd ^ 1;
6658 sisfb_search_crt2type(forcecrt2type);
6661 sisfb_search_tvstd(tvstandard);
6664 sisfb_search_mode(mode,
false);
6666 sisfb_search_vesamode(vesa,
false);
6668 sisfb_crt1off = (crt1off == 0) ? 1 : 0;
6670 sisfb_forcecrt1 = forcecrt1;
6673 else if(forcecrt1 == 0)
6678 else if(noaccel == 0)
6683 else if(noypan == 0)
6692 sisfb_parm_mem =
mem;
6695 sisfb_userom = userom;
6698 sisfb_useoem = useoem;
6701 sisfb_pdc = (pdc & 0x7f);
6704 sisfb_pdca = (pdc1 & 0x1f);
6706 sisfb_nocrt2rate = nocrt2rate;
6709 sisfb_search_specialtiming(specialtiming);
6711 if((lvdshl >= 0) && (lvdshl <= 3))
6712 sisfb_lvdshl = lvdshl;
6714 sisfb_tvxposoffset = tvxposoffset;
6715 sisfb_tvyposoffset = tvyposoffset;
6717 #if !defined(__i386__) && !defined(__x86_64__)
6718 sisfb_resetcard = (resetcard) ? 1 : 0;
6720 sisfb_videoram = videoram;
6723 return sisfb_init();
6726 static void __exit sisfb_remove_module(
void)
6735 MODULE_DESCRIPTION(
"SiS 300/540/630/730/315/55x/65x/661/74x/330/76x/34x, XGI V3XT/V5/V8/Z7 framebuffer device driver");
6759 #if !defined(__i386__) && !defined(__x86_64__)
6765 "\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
6766 "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
6767 "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
6768 "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
6769 "otherwise at 12288KB. On 315/330/340 series, the heap size is 32KB by default.\n"
6770 "The value is to be specified without 'KB'.\n");
6773 "\nIf set to anything other than 0, 2D acceleration will be disabled.\n"
6777 "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
6778 "will be performed by redrawing the screen. (default: 0)\n");
6781 "\nIf y-panning is enabled, sisfb will by default use the entire available video\n"
6782 "memory for the virtual screen in order to optimize scrolling performance. If\n"
6783 "this is set to anything other than 0, sisfb will not do this and thereby \n"
6784 "enable the user to positively specify a virtual Y size of the screen using\n"
6785 "fbset. (default: 0)\n");
6788 "\nSelects the desired default display mode in the format XxYxDepth,\n"
6789 "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
6790 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
6791 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)\n");
6794 "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
6795 "0x117 (default: 0x0103)\n");
6798 "\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
6799 "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
6800 "will be ignored (default: 60)\n");
6803 "\nNormally, the driver autodetects whether or not CRT1 (external VGA) is \n"
6804 "connected. With this option, the detection can be overridden (1=CRT1 ON,\n"
6805 "0=CRT1 OFF) (default: [autodetected])\n");
6808 "\nIf this option is omitted, the driver autodetects CRT2 output devices, such as\n"
6809 "LCD, TV or secondary VGA. With this option, this autodetection can be\n"
6810 "overridden. Possible parameters are LCD, TV, VGA or NONE. NONE disables CRT2.\n"
6811 "On systems with a SiS video bridge, parameters SVIDEO, COMPOSITE or SCART can\n"
6812 "be used instead of TV to override the TV detection. Furthermore, on systems\n"
6813 "with a SiS video bridge, SVIDEO+COMPOSITE, HIVISION, YPBPR480I, YPBPR480P,\n"
6814 "YPBPR720P and YPBPR1080I are understood. However, whether or not these work\n"
6815 "depends on the very hardware in use. (default: [autodetected])\n");
6818 "\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
6819 "native resolution. Setting it to 0 will disable scaling; LVDS panels will\n"
6820 "show black bars around the image, TMDS panels will probably do the scaling\n"
6821 "themselves. Default: 1 on LVDS panels, 0 on TMDS panels\n");
6824 "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
6825 "should detect this correctly in most cases; however, sometimes this is not\n"
6826 "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
6827 "on a 300 series chipset; 6 on other chipsets. If the problem persists, try\n"
6828 "other values (on 300 series: between 4 and 60 in steps of 4; otherwise: any\n"
6829 "value from 0 to 31). (default: autodetected, if LCD is active during start)\n");
6831 #ifdef CONFIG_FB_SIS_315
6833 "\nThis is same as pdc, but for LCD-via CRT1. Hence, this is for the 315/330/340\n"
6834 "series only. (default: autodetected if LCD is in LCD-via-CRT1 mode during\n"
6835 "startup) - Note: currently, this has no effect because LCD-via-CRT1 is not\n"
6836 "implemented yet.\n");
6840 "\nPlease refer to documentation for more information on this option.\n");
6843 "\nPlease refer to documentation for more information on this option.\n");
6846 "\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
6847 "pal, ntsc, palm and paln. (default: [auto; pal or ntsc only])\n");
6850 "\nRelocate TV output horizontally. Possible parameters: -32 through 32.\n"
6854 "\nRelocate TV output vertically. Possible parameters: -32 through 32.\n"
6858 "\nSetting this to 1 will force the driver to use the default refresh rate for\n"
6859 "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)\n");
6861 #if !defined(__i386__) && !defined(__x86_64__)
6862 #ifdef CONFIG_FB_SIS_300
6864 "\nSet this to 1 in order to reset (POST) the card on non-x86 machines where\n"
6865 "the BIOS did not POST the card (only supported for SiS 300/305 and XGI cards\n"
6866 "currently). Default: 0\n");
6869 "\nSet this to the amount of video RAM (in kilobyte) the card has. Required on\n"
6870 "some non-x86 architectures where the memory auto detection fails. Only\n"
6871 "relevant if resetcard is set, too. SiS300/305 only. Default: [auto-detect]\n");