📄 sisusb.c
字号:
ret |= SETIREG(SISSR, 0x16, tmp8); tmp8 |= 0xd0; ret |= SETIREG(SISSR, 0x16, tmp8); tmp8 &= 0x0f; ret |= SETIREG(SISSR, 0x16, tmp8); tmp8 |= 0xa0; ret |= SETIREG(SISSR, 0x16, tmp8); } return ret;}static intsisusb_getbuswidth(struct sisusb_usb_data *sisusb, int *bw, int *chab){ int ret; u8 ramtype, done = 0; u32 t0, t1, t2, t3; u32 ramptr = SISUSB_PCI_MEMBASE; ret = GETIREG(SISSR, 0x3a, &ramtype); ramtype &= 3; ret |= SETIREG(SISSR, 0x13, 0x00); if (ramtype <= 1) { ret |= SETIREG(SISSR, 0x14, 0x12); ret |= SETIREGAND(SISSR, 0x15, 0xef); } else { ret |= SETIREG(SISSR, 0x14, 0x02); } ret |= sisusb_triggersr16(sisusb, ramtype); ret |= WRITEL(ramptr + 0, 0x01234567); ret |= WRITEL(ramptr + 4, 0x456789ab); ret |= WRITEL(ramptr + 8, 0x89abcdef); ret |= WRITEL(ramptr + 12, 0xcdef0123); ret |= WRITEL(ramptr + 16, 0x55555555); ret |= WRITEL(ramptr + 20, 0x55555555); ret |= WRITEL(ramptr + 24, 0xffffffff); ret |= WRITEL(ramptr + 28, 0xffffffff); ret |= READL(ramptr + 0, &t0); ret |= READL(ramptr + 4, &t1); ret |= READL(ramptr + 8, &t2); ret |= READL(ramptr + 12, &t3); if (ramtype <= 1) { *chab = 0; *bw = 64; if ((t3 != 0xcdef0123) || (t2 != 0x89abcdef)) { if ((t1 == 0x456789ab) && (t0 == 0x01234567)) { *chab = 0; *bw = 64; ret |= SETIREGAND(SISSR, 0x14, 0xfd); } } if ((t1 != 0x456789ab) || (t0 != 0x01234567)) { *chab = 1; *bw = 64; ret |= SETIREGANDOR(SISSR, 0x14, 0xfc,0x01); ret |= sisusb_triggersr16(sisusb, ramtype); ret |= WRITEL(ramptr + 0, 0x89abcdef); ret |= WRITEL(ramptr + 4, 0xcdef0123); ret |= WRITEL(ramptr + 8, 0x55555555); ret |= WRITEL(ramptr + 12, 0x55555555); ret |= WRITEL(ramptr + 16, 0xaaaaaaaa); ret |= WRITEL(ramptr + 20, 0xaaaaaaaa); ret |= READL(ramptr + 4, &t1); if (t1 != 0xcdef0123) { *bw = 32; ret |= SETIREGOR(SISSR, 0x15, 0x10); } } } else { *chab = 0; *bw = 64; /* default: cha, bw = 64 */ done = 0; if (t1 == 0x456789ab) { if (t0 == 0x01234567) { *chab = 0; *bw = 64; done = 1; } } else { if (t0 == 0x01234567) { *chab = 0; *bw = 32; ret |= SETIREG(SISSR, 0x14, 0x00); done = 1; } } if (!done) { ret |= SETIREG(SISSR, 0x14, 0x03); ret |= sisusb_triggersr16(sisusb, ramtype); ret |= WRITEL(ramptr + 0, 0x01234567); ret |= WRITEL(ramptr + 4, 0x456789ab); ret |= WRITEL(ramptr + 8, 0x89abcdef); ret |= WRITEL(ramptr + 12, 0xcdef0123); ret |= WRITEL(ramptr + 16, 0x55555555); ret |= WRITEL(ramptr + 20, 0x55555555); ret |= WRITEL(ramptr + 24, 0xffffffff); ret |= WRITEL(ramptr + 28, 0xffffffff); ret |= READL(ramptr + 0, &t0); ret |= READL(ramptr + 4, &t1); if (t1 == 0x456789ab) { if (t0 == 0x01234567) { *chab = 1; *bw = 64; return ret; } /* else error */ } else { if (t0 == 0x01234567) { *chab = 1; *bw = 32; ret |= SETIREG(SISSR, 0x14, 0x01); } /* else error */ } } } return ret;}static intsisusb_verify_mclk(struct sisusb_usb_data *sisusb){ int ret = 0; u32 ramptr = SISUSB_PCI_MEMBASE; u8 tmp1, tmp2, i, j; ret |= WRITEB(ramptr, 0xaa); ret |= WRITEB(ramptr + 16, 0x55); ret |= READB(ramptr, &tmp1); ret |= READB(ramptr + 16, &tmp2); if ((tmp1 != 0xaa) || (tmp2 != 0x55)) { for (i = 0, j = 16; i < 2; i++, j += 16) { ret |= GETIREG(SISSR, 0x21, &tmp1); ret |= SETIREGAND(SISSR, 0x21, (tmp1 & 0xfb)); ret |= SETIREGOR(SISSR, 0x3c, 0x01); /* not on 330 */ ret |= SETIREGAND(SISSR, 0x3c, 0xfe); /* not on 330 */ ret |= SETIREG(SISSR, 0x21, tmp1); ret |= WRITEB(ramptr + 16 + j, j); ret |= READB(ramptr + 16 + j, &tmp1); if (tmp1 == j) { ret |= WRITEB(ramptr + j, j); break; } } } return ret;}static intsisusb_set_rank(struct sisusb_usb_data *sisusb, int *iret, int index, u8 rankno, u8 chab, const u8 dramtype[][5], int bw){ int ret = 0, ranksize; u8 tmp; *iret = 0; if ((rankno == 2) && (dramtype[index][0] == 2)) return ret; ranksize = dramtype[index][3] / 2 * bw / 32; if ((ranksize * rankno) > 128) return ret; tmp = 0; while ((ranksize >>= 1) > 0) tmp += 0x10; tmp |= ((rankno - 1) << 2); tmp |= ((bw / 64) & 0x02); tmp |= (chab & 0x01); ret = SETIREG(SISSR, 0x14, tmp); ret |= sisusb_triggersr16(sisusb, 0); /* sic! */ *iret = 1; return ret;}static intsisusb_check_rbc(struct sisusb_usb_data *sisusb, int *iret, u32 inc, int testn){ int ret = 0, i; u32 j, tmp; *iret = 0; for (i = 0, j = 0; i < testn; i++) { ret |= WRITEL(sisusb->vrambase + j, j); j += inc; } for (i = 0, j = 0; i < testn; i++) { ret |= READL(sisusb->vrambase + j, &tmp); if (tmp != j) return ret; j += inc; } *iret = 1; return ret;}static intsisusb_check_ranks(struct sisusb_usb_data *sisusb, int *iret, int rankno, int idx, int bw, const u8 rtype[][5]){ int ret = 0, i, i2ret; u32 inc; *iret = 0; for (i = rankno; i >= 1; i--) { inc = 1 << (rtype[idx][2] + rtype[idx][1] + rtype[idx][0] + bw / 64 + i); ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2); if (!i2ret) return ret; } inc = 1 << (rtype[idx][2] + bw / 64 + 2); ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 4); if (!i2ret) return ret; inc = 1 << (10 + bw / 64); ret |= sisusb_check_rbc(sisusb, &i2ret, inc, 2); if (!i2ret) return ret; *iret = 1; return ret;}static intsisusb_get_sdram_size(struct sisusb_usb_data *sisusb, int *iret, int bw, int chab){ int ret = 0, i2ret = 0, i, j; static const u8 sdramtype[13][5] = { { 2, 12, 9, 64, 0x35 }, { 1, 13, 9, 64, 0x44 }, { 2, 12, 8, 32, 0x31 }, { 2, 11, 9, 32, 0x25 }, { 1, 12, 9, 32, 0x34 }, { 1, 13, 8, 32, 0x40 }, { 2, 11, 8, 16, 0x21 }, { 1, 12, 8, 16, 0x30 }, { 1, 11, 9, 16, 0x24 }, { 1, 11, 8, 8, 0x20 }, { 2, 9, 8, 4, 0x01 }, { 1, 10, 8, 4, 0x10 }, { 1, 9, 8, 2, 0x00 } }; *iret = 1; /* error */ for (i = 0; i < 13; i++) { ret |= SETIREGANDOR(SISSR, 0x13, 0x80, sdramtype[i][4]); for (j = 2; j > 0; j--) { ret |= sisusb_set_rank(sisusb, &i2ret, i, j, chab, sdramtype, bw); if (!i2ret) continue; ret |= sisusb_check_ranks(sisusb, &i2ret, j, i, bw, sdramtype); if (i2ret) { *iret = 0; /* ram size found */ return ret; } } } return ret;}static intsisusb_setup_screen(struct sisusb_usb_data *sisusb, int clrall, int drwfr){ int ret = 0; u32 address; int i, length, modex, modey, bpp; modex = 640; modey = 480; bpp = 2; address = sisusb->vrambase; /* Clear video ram */ if (clrall) length = sisusb->vramsize; else length = modex * bpp * modey; ret = sisusb_clear_vram(sisusb, address, length); if (!ret && drwfr) { for (i = 0; i < modex; i++) { address = sisusb->vrambase + (i * bpp); ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, address, 0xf100); address += (modex * (modey-1) * bpp); ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, address, 0xf100); } for (i = 0; i < modey; i++) { address = sisusb->vrambase + ((i * modex) * bpp); ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, address, 0xf100); address += ((modex - 1) * bpp); ret |= sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, address, 0xf100); } } return ret;}static intsisusb_set_default_mode(struct sisusb_usb_data *sisusb, int touchengines){ int ret = 0, i, j, modex, modey, bpp, du; u8 sr31, cr63, tmp8; static const char attrdata[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, 0x01,0x00,0x00,0x00 }; static const char crtcrdata[] = { 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, 0xff }; static const char grcdata[] = { 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, 0xff }; static const char crtcdata[] = { 0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, 0x00 }; modex = 640; modey = 480; bpp = 2; GETIREG(SISSR, 0x31, &sr31); GETIREG(SISCR, 0x63, &cr63); SETIREGOR(SISSR, 0x01, 0x20); SETIREG(SISCR, 0x63, cr63 & 0xbf); SETIREGOR(SISCR, 0x17, 0x80); SETIREGOR(SISSR, 0x1f, 0x04); SETIREGAND(SISSR, 0x07, 0xfb); SETIREG(SISSR, 0x00, 0x03); /* seq */ SETIREG(SISSR, 0x01, 0x21); SETIREG(SISSR, 0x02, 0x0f); SETIREG(SISSR, 0x03, 0x00); SETIREG(SISSR, 0x04, 0x0e); SETREG(SISMISCW, 0x23); /* misc */ for (i = 0; i <= 0x18; i++) { /* crtc */ SETIREG(SISCR, i, crtcrdata[i]); } for (i = 0; i <= 0x13; i++) { /* att */ GETREG(SISINPSTAT, &tmp8); SETREG(SISAR, i); SETREG(SISAR, attrdata[i]); } GETREG(SISINPSTAT, &tmp8); SETREG(SISAR, 0x14); SETREG(SISAR, 0x00); GETREG(SISINPSTAT, &tmp8); SETREG(SISAR, 0x20); GETREG(SISINPSTAT, &tmp8); for (i = 0; i <= 0x08; i++) { /* grc */ SETIREG(SISGR, i, grcdata[i]); } SETIREGAND(SISGR, 0x05, 0xbf); for (i = 0x0A; i <= 0x0E; i++) { /* clr ext */ SETIREG(SISSR, i, 0x00); } SETIREGAND(SISSR, 0x37, 0xfe); SETREG(SISMISCW, 0xef); /* sync */ SETIREG(SISCR, 0x11, 0x00); /* crtc */ for (j = 0x00, i = 0; i <= 7; i++, j++) { SETIREG(SISCR, j, crtcdata[i]); } for (j = 0x10; i <= 10; i++, j++) { SETIREG(SISCR, j, crtcdata[i]); } for (j = 0x15; i <= 12; i++, j++) { SETIREG(SISCR, j, crtcdata[i]); } for (j = 0x0A; i <= 15; i++, j++) { SETIREG(SISSR, j, crtcdata[i]); } SETIREG(SISSR, 0x0E, (crtcdata[16] & 0xE0)); SETIREGANDOR(SISCR, 0x09, 0x5f, ((crtcdata[16] & 0x01) << 5)); SETIREG(SISCR, 0x14, 0x4f); du = (modex / 16) * (bpp * 2); /* offset/pitch */ if (modex % 16) du += bpp; SETIREGANDOR(SISSR, 0x0e, 0xf0, ((du >> 8) & 0x0f)); SETIREG(SISCR, 0x13, (du & 0xff)); du <<= 5; tmp8 = du >> 8; if (du & 0xff) tmp8++; SETIREG(SISSR, 0x10, tmp8); SETIREG(SISSR, 0x31, 0x00); /* VCLK */ SETIREG(SISSR, 0x2b, 0x1b); SETIREG(SISSR, 0x2c, 0xe1); SETIREG(SISSR, 0x2d, 0x01); SETIREGAND(SISSR, 0x3d, 0xfe); /* FIFO */ SETIREG(SISSR, 0x08, 0xae); SETIREGAND(SISSR, 0x09, 0xf0); SETIREG(SISSR, 0x08, 0x34); SETIREGOR(SISSR, 0x3d, 0x01); SETIREGAND(SISSR, 0x1f, 0x3f); /* mode regs */ SETIREGANDOR(SISSR, 0x06, 0xc0, 0x0a); SETIREG(SISCR, 0x19, 0x00); SETIREGAND(SISCR, 0x1a, 0xfc); SETIREGAND(SISSR, 0x0f, 0xb7); SETIREGAND(SISSR, 0x31, 0xfb); SETIREGANDOR(SISSR, 0x21, 0x1f, 0xa0); SETIREGAND(SISSR, 0x32, 0xf3); SETIREGANDOR(SISSR, 0x07, 0xf8, 0x03); SETIREG(SISCR, 0x52, 0x6c); SETIREG(SISCR, 0x0d, 0x00); /* adjust frame */ SETIREG(SISCR, 0x0c, 0x00); SETIREG(SISSR, 0x0d, 0x00); SETIREGAND(SISSR, 0x37, 0xfe); SETIREG(SISCR, 0x32, 0x20); SETIREGAND(SISSR, 0x01, 0xdf); /* enable display */ SETIREG(SISCR, 0x63, (cr63 & 0xbf)); SETIREG(SISSR, 0x31, (sr31 & 0xfb)); if (touchengines) { SETIREG(SISSR, 0x20, 0xa1); /* enable engines */ SETIREGOR(SISSR, 0x1e, 0x5a); SETIREG(SISSR, 0x26, 0x01); /* disable cmdqueue */ SETIREG(SISSR, 0x27, 0x1f); SETIREG(SISSR, 0x26, 0x00); } SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ return ret;}static intsisusb_init_gfxcore(struct sisusb_usb_data *sisusb){ int ret = 0, i, j, bw, chab, iret, retry = 3; u8 tmp8, ramtype; u32 tmp32; static const char mclktable[] = { 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143 }; static const char eclktable[] = { 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143, 0x3b, 0x22, 0x01, 143 }; static const char ramtypetable1[] = { 0x00, 0x04, 0x60, 0x60, 0x0f, 0x0f, 0x1f, 0x1f, 0xba, 0xba, 0xba, 0xba, 0xa9, 0xa9, 0xac, 0xac, 0xa0, 0xa0, 0xa0, 0xa8, 0x00, 0x00, 0x02, 0x02, 0x30, 0x30, 0x40, 0x40 }; static const char ramtypetable2[] = { 0x77, 0x77, 0x44, 0x44, 0x77, 0x77, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x5b, 0xab, 0xab, 0x00, 0x00, 0xf0, 0xf8 }; while (retry--) { /* Enable VGA */ ret = GETREG(SISVGAEN, &tmp8); ret |= SETREG(SISVGAEN, (tmp8 | 0x01)); /* Enable GPU access to VRAM */ ret |= GETREG(SISMISCR, &tmp8); ret |= SETREG(SISMISCW, (tmp8 | 0x01)); if (ret) continue; /* Reset registers */ ret |= SETIREGAND(SISCR, 0x5b, 0xdf); ret |= SETIREG(SISSR, 0x05, 0x86); ret |= SETIREGOR(SISSR, 0x20, 0x01); ret |= SETREG(SISMISCW, 0x67); for (i = 0x06; i <= 0x1f; i++) { ret |= SETIREG(SISSR, i, 0x00); } for (i = 0x21; i <= 0x27; i++) { ret |= SETIREG(SISSR, i, 0x00); } for (i = 0x31; i <= 0x3d; i++) { ret |= SETIREG(SISSR, i, 0x00); } for (i = 0x12; i <= 0x1b; i++) { ret |= SETIREG(SISSR, i, 0x00); } for (i = 0x79; i <= 0x7c; i++) { ret |= SETIREG(SISCR, i, 0x00); } if (ret) continue; ret |= SETIREG(SISCR, 0x63, 0x80); ret |= GETIREG(SISSR, 0x3a, &ramtype); ramtype &= 0x03; ret |= SETIREG(SISSR, 0x28, mclktable[ramtype * 4]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -