XGI_main_26.c 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112
  1. /*
  2. * XG20, XG21, XG40, XG42 frame buffer device
  3. * for Linux kernels 2.5.x, 2.6.x
  4. * Base on TW's sis fbdev code.
  5. */
  6. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  7. #include <linux/sizes.h>
  8. #include <linux/module.h>
  9. #include <linux/pci.h>
  10. #include "XGI_main.h"
  11. #include "vb_init.h"
  12. #include "vb_util.h"
  13. #include "vb_setmode.h"
  14. #define Index_CR_GPIO_Reg1 0x48
  15. #define Index_CR_GPIO_Reg3 0x4a
  16. #define GPIOG_EN BIT(6)
  17. #define GPIOG_READ BIT(1)
  18. static char *forcecrt2type;
  19. static char *mode;
  20. static int vesa = -1;
  21. static unsigned int refresh_rate;
  22. /* -------------------- Macro definitions ---------------------------- */
  23. #ifdef DEBUG
  24. static void dumpVGAReg(struct xgifb_video_info *xgifb_info)
  25. {
  26. u8 i, reg;
  27. xgifb_reg_set(XGISR, 0x05, 0x86);
  28. for (i = 0; i < 0x4f; i++) {
  29. reg = xgifb_reg_get(XGISR, i);
  30. pr_debug("o 3c4 %x\n", i);
  31. pr_debug("i 3c5 => %x\n", reg);
  32. }
  33. for (i = 0; i < 0xF0; i++) {
  34. reg = xgifb_reg_get(XGICR, i);
  35. pr_debug("o 3d4 %x\n", i);
  36. pr_debug("i 3d5 => %x\n", reg);
  37. }
  38. }
  39. #else
  40. static inline void dumpVGAReg(struct xgifb_video_info *xgifb_info)
  41. {
  42. }
  43. #endif
  44. /* --------------- Hardware Access Routines -------------------------- */
  45. static int XGIfb_mode_rate_to_dclock(struct vb_device_info *XGI_Pr,
  46. struct xgi_hw_device_info *HwDeviceExtension,
  47. unsigned char modeno)
  48. {
  49. unsigned short ModeNo = modeno;
  50. unsigned short ModeIdIndex = 0, ClockIndex = 0;
  51. unsigned short RefreshRateTableIndex = 0;
  52. int Clock;
  53. InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
  54. XGI_SearchModeID(ModeNo, &ModeIdIndex);
  55. RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
  56. ModeIdIndex, XGI_Pr);
  57. ClockIndex = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
  58. Clock = XGI_VCLKData[ClockIndex].CLOCK * 1000;
  59. return Clock;
  60. }
  61. static int XGIfb_mode_rate_to_ddata(struct vb_device_info *XGI_Pr,
  62. struct xgi_hw_device_info *HwDeviceExtension,
  63. unsigned char modeno,
  64. u32 *left_margin, u32 *right_margin, u32 *upper_margin,
  65. u32 *lower_margin, u32 *hsync_len, u32 *vsync_len, u32 *sync,
  66. u32 *vmode)
  67. {
  68. unsigned short ModeNo = modeno;
  69. unsigned short ModeIdIndex, index = 0;
  70. unsigned short RefreshRateTableIndex = 0;
  71. unsigned short VRE, VBE, VRS, VDE;
  72. unsigned short HRE, HBE, HRS, HDE;
  73. unsigned char sr_data, cr_data, cr_data2;
  74. int B, C, D, F, temp, j;
  75. InitTo330Pointer(HwDeviceExtension->jChipType, XGI_Pr);
  76. if (!XGI_SearchModeID(ModeNo, &ModeIdIndex))
  77. return 0;
  78. RefreshRateTableIndex = XGI_GetRatePtrCRT2(HwDeviceExtension, ModeNo,
  79. ModeIdIndex, XGI_Pr);
  80. index = XGI330_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
  81. sr_data = XGI_CRT1Table[index].CR[5];
  82. HDE = XGI330_RefIndex[RefreshRateTableIndex].XRes >> 3;
  83. cr_data = XGI_CRT1Table[index].CR[3];
  84. /* Horizontal retrace (=sync) start */
  85. HRS = (cr_data & 0xff) | ((unsigned short) (sr_data & 0xC0) << 2);
  86. F = HRS - HDE - 3;
  87. sr_data = XGI_CRT1Table[index].CR[6];
  88. cr_data = XGI_CRT1Table[index].CR[2];
  89. cr_data2 = XGI_CRT1Table[index].CR[4];
  90. /* Horizontal blank end */
  91. HBE = (cr_data & 0x1f) | ((unsigned short) (cr_data2 & 0x80) >> 2)
  92. | ((unsigned short) (sr_data & 0x03) << 6);
  93. /* Horizontal retrace (=sync) end */
  94. HRE = (cr_data2 & 0x1f) | ((sr_data & 0x04) << 3);
  95. temp = HBE - ((HDE - 1) & 255);
  96. B = (temp > 0) ? temp : (temp + 256);
  97. temp = HRE - ((HDE + F + 3) & 63);
  98. C = (temp > 0) ? temp : (temp + 64);
  99. D = B - F - C;
  100. *left_margin = D * 8;
  101. *right_margin = F * 8;
  102. *hsync_len = C * 8;
  103. sr_data = XGI_CRT1Table[index].CR[14];
  104. cr_data2 = XGI_CRT1Table[index].CR[9];
  105. VDE = XGI330_RefIndex[RefreshRateTableIndex].YRes;
  106. cr_data = XGI_CRT1Table[index].CR[10];
  107. /* Vertical retrace (=sync) start */
  108. VRS = (cr_data & 0xff) | ((unsigned short) (cr_data2 & 0x04) << 6)
  109. | ((unsigned short) (cr_data2 & 0x80) << 2)
  110. | ((unsigned short) (sr_data & 0x08) << 7);
  111. F = VRS + 1 - VDE;
  112. cr_data = XGI_CRT1Table[index].CR[13];
  113. /* Vertical blank end */
  114. VBE = (cr_data & 0xff) | ((unsigned short) (sr_data & 0x10) << 4);
  115. temp = VBE - ((VDE - 1) & 511);
  116. B = (temp > 0) ? temp : (temp + 512);
  117. cr_data = XGI_CRT1Table[index].CR[11];
  118. /* Vertical retrace (=sync) end */
  119. VRE = (cr_data & 0x0f) | ((sr_data & 0x20) >> 1);
  120. temp = VRE - ((VDE + F - 1) & 31);
  121. C = (temp > 0) ? temp : (temp + 32);
  122. D = B - F - C;
  123. *upper_margin = D;
  124. *lower_margin = F;
  125. *vsync_len = C;
  126. if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x8000)
  127. *sync &= ~FB_SYNC_VERT_HIGH_ACT;
  128. else
  129. *sync |= FB_SYNC_VERT_HIGH_ACT;
  130. if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x4000)
  131. *sync &= ~FB_SYNC_HOR_HIGH_ACT;
  132. else
  133. *sync |= FB_SYNC_HOR_HIGH_ACT;
  134. *vmode = FB_VMODE_NONINTERLACED;
  135. if (XGI330_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & 0x0080)
  136. *vmode = FB_VMODE_INTERLACED;
  137. else {
  138. j = 0;
  139. while (XGI330_EModeIDTable[j].Ext_ModeID != 0xff) {
  140. if (XGI330_EModeIDTable[j].Ext_ModeID ==
  141. XGI330_RefIndex[RefreshRateTableIndex].ModeID) {
  142. if (XGI330_EModeIDTable[j].Ext_ModeFlag &
  143. DoubleScanMode) {
  144. *vmode = FB_VMODE_DOUBLE;
  145. }
  146. break;
  147. }
  148. j++;
  149. }
  150. }
  151. return 1;
  152. }
  153. void XGIRegInit(struct vb_device_info *XGI_Pr, unsigned long BaseAddr)
  154. {
  155. XGI_Pr->P3c4 = BaseAddr + 0x14;
  156. XGI_Pr->P3d4 = BaseAddr + 0x24;
  157. XGI_Pr->P3c0 = BaseAddr + 0x10;
  158. XGI_Pr->P3ce = BaseAddr + 0x1e;
  159. XGI_Pr->P3c2 = BaseAddr + 0x12;
  160. XGI_Pr->P3cc = BaseAddr + 0x1c;
  161. XGI_Pr->P3ca = BaseAddr + 0x1a;
  162. XGI_Pr->P3c6 = BaseAddr + 0x16;
  163. XGI_Pr->P3c7 = BaseAddr + 0x17;
  164. XGI_Pr->P3c8 = BaseAddr + 0x18;
  165. XGI_Pr->P3c9 = BaseAddr + 0x19;
  166. XGI_Pr->P3da = BaseAddr + 0x2A;
  167. XGI_Pr->Part0Port = BaseAddr + XGI_CRT2_PORT_00;
  168. /* Digital video interface registers (LCD) */
  169. XGI_Pr->Part1Port = BaseAddr + SIS_CRT2_PORT_04;
  170. /* 301 TV Encoder registers */
  171. XGI_Pr->Part2Port = BaseAddr + SIS_CRT2_PORT_10;
  172. /* 301 Macrovision registers */
  173. XGI_Pr->Part3Port = BaseAddr + SIS_CRT2_PORT_12;
  174. /* 301 VGA2 (and LCD) registers */
  175. XGI_Pr->Part4Port = BaseAddr + SIS_CRT2_PORT_14;
  176. /* 301 palette address port registers */
  177. XGI_Pr->Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2;
  178. }
  179. /* ------------------ Internal helper routines ----------------- */
  180. static int XGIfb_GetXG21DefaultLVDSModeIdx(struct xgifb_video_info *xgifb_info)
  181. {
  182. int i = 0;
  183. while ((XGIbios_mode[i].mode_no != 0)
  184. && (XGIbios_mode[i].xres <= xgifb_info->lvds_data.LVDSHDE)) {
  185. if ((XGIbios_mode[i].xres == xgifb_info->lvds_data.LVDSHDE)
  186. && (XGIbios_mode[i].yres == xgifb_info->lvds_data.LVDSVDE)
  187. && (XGIbios_mode[i].bpp == 8)) {
  188. return i;
  189. }
  190. i++;
  191. }
  192. return -1;
  193. }
  194. static void XGIfb_search_mode(struct xgifb_video_info *xgifb_info,
  195. const char *name)
  196. {
  197. unsigned int xres;
  198. unsigned int yres;
  199. unsigned int bpp;
  200. int i;
  201. if (sscanf(name, "%ux%ux%u", &xres, &yres, &bpp) != 3)
  202. goto invalid_mode;
  203. if (bpp == 24)
  204. bpp = 32; /* That's for people who mix up color and fb depth. */
  205. for (i = 0; XGIbios_mode[i].mode_no != 0; i++)
  206. if (XGIbios_mode[i].xres == xres &&
  207. XGIbios_mode[i].yres == yres &&
  208. XGIbios_mode[i].bpp == bpp) {
  209. xgifb_info->mode_idx = i;
  210. return;
  211. }
  212. invalid_mode:
  213. pr_info("Invalid mode '%s'\n", name);
  214. }
  215. static void XGIfb_search_vesamode(struct xgifb_video_info *xgifb_info,
  216. unsigned int vesamode)
  217. {
  218. int i = 0;
  219. if (vesamode == 0)
  220. goto invalid;
  221. vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
  222. while (XGIbios_mode[i].mode_no != 0) {
  223. if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
  224. (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
  225. xgifb_info->mode_idx = i;
  226. return;
  227. }
  228. i++;
  229. }
  230. invalid:
  231. pr_info("Invalid VESA mode 0x%x'\n", vesamode);
  232. }
  233. static int XGIfb_validate_mode(struct xgifb_video_info *xgifb_info, int myindex)
  234. {
  235. u16 xres, yres;
  236. struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
  237. unsigned long required_mem;
  238. if (xgifb_info->chip == XG21) {
  239. if (xgifb_info->display2 == XGIFB_DISP_LCD) {
  240. xres = xgifb_info->lvds_data.LVDSHDE;
  241. yres = xgifb_info->lvds_data.LVDSVDE;
  242. if (XGIbios_mode[myindex].xres > xres)
  243. return -1;
  244. if (XGIbios_mode[myindex].yres > yres)
  245. return -1;
  246. if ((XGIbios_mode[myindex].xres < xres) &&
  247. (XGIbios_mode[myindex].yres < yres)) {
  248. if (XGIbios_mode[myindex].bpp > 8)
  249. return -1;
  250. }
  251. }
  252. goto check_memory;
  253. }
  254. /* FIXME: for now, all is valid on XG27 */
  255. if (xgifb_info->chip == XG27)
  256. goto check_memory;
  257. if (!(XGIbios_mode[myindex].chipset & MD_XGI315))
  258. return -1;
  259. switch (xgifb_info->display2) {
  260. case XGIFB_DISP_LCD:
  261. switch (hw_info->ulCRT2LCDType) {
  262. case LCD_640x480:
  263. xres = 640;
  264. yres = 480;
  265. break;
  266. case LCD_800x600:
  267. xres = 800;
  268. yres = 600;
  269. break;
  270. case LCD_1024x600:
  271. xres = 1024;
  272. yres = 600;
  273. break;
  274. case LCD_1024x768:
  275. xres = 1024;
  276. yres = 768;
  277. break;
  278. case LCD_1152x768:
  279. xres = 1152;
  280. yres = 768;
  281. break;
  282. case LCD_1280x960:
  283. xres = 1280;
  284. yres = 960;
  285. break;
  286. case LCD_1280x768:
  287. xres = 1280;
  288. yres = 768;
  289. break;
  290. case LCD_1280x1024:
  291. xres = 1280;
  292. yres = 1024;
  293. break;
  294. case LCD_1400x1050:
  295. xres = 1400;
  296. yres = 1050;
  297. break;
  298. case LCD_1600x1200:
  299. xres = 1600;
  300. yres = 1200;
  301. break;
  302. default:
  303. xres = 0;
  304. yres = 0;
  305. break;
  306. }
  307. if (XGIbios_mode[myindex].xres > xres)
  308. return -1;
  309. if (XGIbios_mode[myindex].yres > yres)
  310. return -1;
  311. if ((hw_info->ulExternalChip == 0x01) || /* LVDS */
  312. (hw_info->ulExternalChip == 0x05)) { /* LVDS+Chrontel */
  313. switch (XGIbios_mode[myindex].xres) {
  314. case 512:
  315. if (XGIbios_mode[myindex].yres != 512)
  316. return -1;
  317. if (hw_info->ulCRT2LCDType == LCD_1024x600)
  318. return -1;
  319. break;
  320. case 640:
  321. if ((XGIbios_mode[myindex].yres != 400)
  322. && (XGIbios_mode[myindex].yres
  323. != 480))
  324. return -1;
  325. break;
  326. case 800:
  327. if (XGIbios_mode[myindex].yres != 600)
  328. return -1;
  329. break;
  330. case 1024:
  331. if ((XGIbios_mode[myindex].yres != 600) &&
  332. (XGIbios_mode[myindex].yres != 768))
  333. return -1;
  334. if ((XGIbios_mode[myindex].yres == 600) &&
  335. (hw_info->ulCRT2LCDType != LCD_1024x600))
  336. return -1;
  337. break;
  338. case 1152:
  339. if ((XGIbios_mode[myindex].yres) != 768)
  340. return -1;
  341. if (hw_info->ulCRT2LCDType != LCD_1152x768)
  342. return -1;
  343. break;
  344. case 1280:
  345. if ((XGIbios_mode[myindex].yres != 768) &&
  346. (XGIbios_mode[myindex].yres != 1024))
  347. return -1;
  348. if ((XGIbios_mode[myindex].yres == 768) &&
  349. (hw_info->ulCRT2LCDType != LCD_1280x768))
  350. return -1;
  351. break;
  352. case 1400:
  353. if (XGIbios_mode[myindex].yres != 1050)
  354. return -1;
  355. break;
  356. case 1600:
  357. if (XGIbios_mode[myindex].yres != 1200)
  358. return -1;
  359. break;
  360. default:
  361. return -1;
  362. }
  363. } else {
  364. switch (XGIbios_mode[myindex].xres) {
  365. case 512:
  366. if (XGIbios_mode[myindex].yres != 512)
  367. return -1;
  368. break;
  369. case 640:
  370. if ((XGIbios_mode[myindex].yres != 400) &&
  371. (XGIbios_mode[myindex].yres != 480))
  372. return -1;
  373. break;
  374. case 800:
  375. if (XGIbios_mode[myindex].yres != 600)
  376. return -1;
  377. break;
  378. case 1024:
  379. if (XGIbios_mode[myindex].yres != 768)
  380. return -1;
  381. break;
  382. case 1280:
  383. if ((XGIbios_mode[myindex].yres != 960) &&
  384. (XGIbios_mode[myindex].yres != 1024))
  385. return -1;
  386. if (XGIbios_mode[myindex].yres == 960) {
  387. if (hw_info->ulCRT2LCDType ==
  388. LCD_1400x1050)
  389. return -1;
  390. }
  391. break;
  392. case 1400:
  393. if (XGIbios_mode[myindex].yres != 1050)
  394. return -1;
  395. break;
  396. case 1600:
  397. if (XGIbios_mode[myindex].yres != 1200)
  398. return -1;
  399. break;
  400. default:
  401. return -1;
  402. }
  403. }
  404. break;
  405. case XGIFB_DISP_TV:
  406. switch (XGIbios_mode[myindex].xres) {
  407. case 512:
  408. case 640:
  409. case 800:
  410. break;
  411. case 720:
  412. if (xgifb_info->TV_type == TVMODE_NTSC) {
  413. if (XGIbios_mode[myindex].yres != 480)
  414. return -1;
  415. } else if (xgifb_info->TV_type == TVMODE_PAL) {
  416. if (XGIbios_mode[myindex].yres != 576)
  417. return -1;
  418. }
  419. /* LVDS/CHRONTEL does not support 720 */
  420. if (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL ||
  421. xgifb_info->hasVB == HASVB_CHRONTEL) {
  422. return -1;
  423. }
  424. break;
  425. case 1024:
  426. if (xgifb_info->TV_type == TVMODE_NTSC) {
  427. if (XGIbios_mode[myindex].bpp == 32)
  428. return -1;
  429. }
  430. break;
  431. default:
  432. return -1;
  433. }
  434. break;
  435. case XGIFB_DISP_CRT:
  436. if (XGIbios_mode[myindex].xres > 1280)
  437. return -1;
  438. break;
  439. case XGIFB_DISP_NONE:
  440. break;
  441. }
  442. check_memory:
  443. required_mem = XGIbios_mode[myindex].xres * XGIbios_mode[myindex].yres *
  444. XGIbios_mode[myindex].bpp / 8;
  445. if (required_mem > xgifb_info->video_size)
  446. return -1;
  447. return myindex;
  448. }
  449. static void XGIfb_search_crt2type(const char *name)
  450. {
  451. int i = 0;
  452. if (name == NULL)
  453. return;
  454. while (XGI_crt2type[i].type_no != -1) {
  455. if (!strcmp(name, XGI_crt2type[i].name)) {
  456. XGIfb_crt2type = XGI_crt2type[i].type_no;
  457. XGIfb_tvplug = XGI_crt2type[i].tvplug_no;
  458. break;
  459. }
  460. i++;
  461. }
  462. if (XGIfb_crt2type < 0)
  463. pr_info("Invalid CRT2 type: %s\n", name);
  464. }
  465. static u8 XGIfb_search_refresh_rate(struct xgifb_video_info *xgifb_info,
  466. unsigned int rate)
  467. {
  468. u16 xres, yres;
  469. int i = 0;
  470. xres = XGIbios_mode[xgifb_info->mode_idx].xres;
  471. yres = XGIbios_mode[xgifb_info->mode_idx].yres;
  472. xgifb_info->rate_idx = 0;
  473. while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
  474. if ((XGIfb_vrate[i].xres == xres) &&
  475. (XGIfb_vrate[i].yres == yres)) {
  476. if (XGIfb_vrate[i].refresh == rate) {
  477. xgifb_info->rate_idx = XGIfb_vrate[i].idx;
  478. break;
  479. } else if (XGIfb_vrate[i].refresh > rate) {
  480. if ((XGIfb_vrate[i].refresh - rate) <= 3) {
  481. pr_debug("Adjusting rate from %d up to %d\n",
  482. rate, XGIfb_vrate[i].refresh);
  483. xgifb_info->rate_idx =
  484. XGIfb_vrate[i].idx;
  485. xgifb_info->refresh_rate =
  486. XGIfb_vrate[i].refresh;
  487. } else if (((rate - XGIfb_vrate[i - 1].refresh)
  488. <= 2) && (XGIfb_vrate[i].idx
  489. != 1)) {
  490. pr_debug("Adjusting rate from %d down to %d\n",
  491. rate,
  492. XGIfb_vrate[i-1].refresh);
  493. xgifb_info->rate_idx =
  494. XGIfb_vrate[i - 1].idx;
  495. xgifb_info->refresh_rate =
  496. XGIfb_vrate[i - 1].refresh;
  497. }
  498. break;
  499. } else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
  500. pr_debug("Adjusting rate from %d down to %d\n",
  501. rate, XGIfb_vrate[i].refresh);
  502. xgifb_info->rate_idx = XGIfb_vrate[i].idx;
  503. break;
  504. }
  505. }
  506. i++;
  507. }
  508. if (xgifb_info->rate_idx > 0)
  509. return xgifb_info->rate_idx;
  510. pr_info("Unsupported rate %d for %dx%d\n",
  511. rate, xres, yres);
  512. return 0;
  513. }
  514. static void XGIfb_search_tvstd(const char *name)
  515. {
  516. int i = 0;
  517. if (name == NULL)
  518. return;
  519. while (XGI_tvtype[i].type_no != -1) {
  520. if (!strcmp(name, XGI_tvtype[i].name)) {
  521. XGIfb_tvmode = XGI_tvtype[i].type_no;
  522. break;
  523. }
  524. i++;
  525. }
  526. }
  527. /* ----------- FBDev related routines for all series ----------- */
  528. static void XGIfb_bpp_to_var(struct xgifb_video_info *xgifb_info,
  529. struct fb_var_screeninfo *var)
  530. {
  531. switch (var->bits_per_pixel) {
  532. case 8:
  533. var->red.offset = var->green.offset = var->blue.offset = 0;
  534. var->red.length = var->green.length = var->blue.length = 6;
  535. xgifb_info->video_cmap_len = 256;
  536. break;
  537. case 16:
  538. var->red.offset = 11;
  539. var->red.length = 5;
  540. var->green.offset = 5;
  541. var->green.length = 6;
  542. var->blue.offset = 0;
  543. var->blue.length = 5;
  544. var->transp.offset = 0;
  545. var->transp.length = 0;
  546. xgifb_info->video_cmap_len = 16;
  547. break;
  548. case 32:
  549. var->red.offset = 16;
  550. var->red.length = 8;
  551. var->green.offset = 8;
  552. var->green.length = 8;
  553. var->blue.offset = 0;
  554. var->blue.length = 8;
  555. var->transp.offset = 24;
  556. var->transp.length = 8;
  557. xgifb_info->video_cmap_len = 16;
  558. break;
  559. }
  560. }
  561. /* --------------------- SetMode routines ------------------------- */
  562. static void XGIfb_pre_setmode(struct xgifb_video_info *xgifb_info)
  563. {
  564. u8 cr30 = 0, cr31 = 0;
  565. cr31 = xgifb_reg_get(XGICR, 0x31);
  566. cr31 &= ~0x60;
  567. switch (xgifb_info->display2) {
  568. case XGIFB_DISP_CRT:
  569. cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
  570. cr31 |= SIS_DRIVER_MODE;
  571. break;
  572. case XGIFB_DISP_LCD:
  573. cr30 = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
  574. cr31 |= SIS_DRIVER_MODE;
  575. break;
  576. case XGIFB_DISP_TV:
  577. if (xgifb_info->TV_type == TVMODE_HIVISION)
  578. cr30 = (SIS_VB_OUTPUT_HIVISION
  579. | SIS_SIMULTANEOUS_VIEW_ENABLE);
  580. else if (xgifb_info->TV_plug == TVPLUG_SVIDEO)
  581. cr30 = (SIS_VB_OUTPUT_SVIDEO
  582. | SIS_SIMULTANEOUS_VIEW_ENABLE);
  583. else if (xgifb_info->TV_plug == TVPLUG_COMPOSITE)
  584. cr30 = (SIS_VB_OUTPUT_COMPOSITE
  585. | SIS_SIMULTANEOUS_VIEW_ENABLE);
  586. else if (xgifb_info->TV_plug == TVPLUG_SCART)
  587. cr30 = (SIS_VB_OUTPUT_SCART
  588. | SIS_SIMULTANEOUS_VIEW_ENABLE);
  589. cr31 |= SIS_DRIVER_MODE;
  590. if (XGIfb_tvmode == 1 || xgifb_info->TV_type == TVMODE_PAL)
  591. cr31 |= 0x01;
  592. else
  593. cr31 &= ~0x01;
  594. break;
  595. default: /* disable CRT2 */
  596. cr30 = 0x00;
  597. cr31 |= (SIS_DRIVER_MODE | SIS_VB_OUTPUT_DISABLE);
  598. }
  599. xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
  600. xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
  601. xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33,
  602. (xgifb_info->rate_idx & 0x0F));
  603. }
  604. static void XGIfb_post_setmode(struct xgifb_video_info *xgifb_info)
  605. {
  606. u8 reg;
  607. unsigned char doit = 1;
  608. if (xgifb_info->video_bpp == 8) {
  609. /*
  610. * We can't switch off CRT1 on LVDS/Chrontel
  611. * in 8bpp Modes
  612. */
  613. if ((xgifb_info->hasVB == HASVB_LVDS) ||
  614. (xgifb_info->hasVB == HASVB_LVDS_CHRONTEL)) {
  615. doit = 0;
  616. }
  617. /*
  618. * We can't switch off CRT1 on 301B-DH
  619. * in 8bpp Modes if using LCD
  620. */
  621. if (xgifb_info->display2 == XGIFB_DISP_LCD)
  622. doit = 0;
  623. }
  624. /* We can't switch off CRT1 if bridge is in slave mode */
  625. if (xgifb_info->hasVB != HASVB_NONE) {
  626. reg = xgifb_reg_get(XGIPART1, 0x00);
  627. if ((reg & 0x50) == 0x10)
  628. doit = 0;
  629. } else {
  630. XGIfb_crt1off = 0;
  631. }
  632. reg = xgifb_reg_get(XGICR, 0x17);
  633. if ((XGIfb_crt1off) && (doit))
  634. reg &= ~0x80;
  635. else
  636. reg |= 0x80;
  637. xgifb_reg_set(XGICR, 0x17, reg);
  638. xgifb_reg_and(XGISR, IND_SIS_RAMDAC_CONTROL, ~0x04);
  639. if (xgifb_info->display2 == XGIFB_DISP_TV &&
  640. xgifb_info->hasVB == HASVB_301) {
  641. reg = xgifb_reg_get(XGIPART4, 0x01);
  642. if (reg < 0xB0) { /* Set filter for XGI301 */
  643. int filter_tb;
  644. switch (xgifb_info->video_width) {
  645. case 320:
  646. filter_tb = (xgifb_info->TV_type ==
  647. TVMODE_NTSC) ? 4 : 12;
  648. break;
  649. case 640:
  650. filter_tb = (xgifb_info->TV_type ==
  651. TVMODE_NTSC) ? 5 : 13;
  652. break;
  653. case 720:
  654. filter_tb = (xgifb_info->TV_type ==
  655. TVMODE_NTSC) ? 6 : 14;
  656. break;
  657. case 800:
  658. filter_tb = (xgifb_info->TV_type ==
  659. TVMODE_NTSC) ? 7 : 15;
  660. break;
  661. default:
  662. filter_tb = 0;
  663. filter = -1;
  664. break;
  665. }
  666. xgifb_reg_or(XGIPART1,
  667. SIS_CRT2_WENABLE_315,
  668. 0x01);
  669. if (xgifb_info->TV_type == TVMODE_NTSC) {
  670. xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
  671. if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
  672. xgifb_reg_and(XGIPART2, 0x30, 0xdf);
  673. } else if (xgifb_info->TV_plug
  674. == TVPLUG_COMPOSITE) {
  675. xgifb_reg_or(XGIPART2, 0x30, 0x20);
  676. switch (xgifb_info->video_width) {
  677. case 640:
  678. xgifb_reg_set(XGIPART2,
  679. 0x35,
  680. 0xEB);
  681. xgifb_reg_set(XGIPART2,
  682. 0x36,
  683. 0x04);
  684. xgifb_reg_set(XGIPART2,
  685. 0x37,
  686. 0x25);
  687. xgifb_reg_set(XGIPART2,
  688. 0x38,
  689. 0x18);
  690. break;
  691. case 720:
  692. xgifb_reg_set(XGIPART2,
  693. 0x35,
  694. 0xEE);
  695. xgifb_reg_set(XGIPART2,
  696. 0x36,
  697. 0x0C);
  698. xgifb_reg_set(XGIPART2,
  699. 0x37,
  700. 0x22);
  701. xgifb_reg_set(XGIPART2,
  702. 0x38,
  703. 0x08);
  704. break;
  705. case 800:
  706. xgifb_reg_set(XGIPART2,
  707. 0x35,
  708. 0xEB);
  709. xgifb_reg_set(XGIPART2,
  710. 0x36,
  711. 0x15);
  712. xgifb_reg_set(XGIPART2,
  713. 0x37,
  714. 0x25);
  715. xgifb_reg_set(XGIPART2,
  716. 0x38,
  717. 0xF6);
  718. break;
  719. }
  720. }
  721. } else if (xgifb_info->TV_type == TVMODE_PAL) {
  722. xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
  723. if (xgifb_info->TV_plug == TVPLUG_SVIDEO) {
  724. xgifb_reg_and(XGIPART2, 0x30, 0xDF);
  725. } else if (xgifb_info->TV_plug
  726. == TVPLUG_COMPOSITE) {
  727. xgifb_reg_or(XGIPART2, 0x30, 0x20);
  728. switch (xgifb_info->video_width) {
  729. case 640:
  730. xgifb_reg_set(XGIPART2,
  731. 0x35,
  732. 0xF1);
  733. xgifb_reg_set(XGIPART2,
  734. 0x36,
  735. 0xF7);
  736. xgifb_reg_set(XGIPART2,
  737. 0x37,
  738. 0x1F);
  739. xgifb_reg_set(XGIPART2,
  740. 0x38,
  741. 0x32);
  742. break;
  743. case 720:
  744. xgifb_reg_set(XGIPART2,
  745. 0x35,
  746. 0xF3);
  747. xgifb_reg_set(XGIPART2,
  748. 0x36,
  749. 0x00);
  750. xgifb_reg_set(XGIPART2,
  751. 0x37,
  752. 0x1D);
  753. xgifb_reg_set(XGIPART2,
  754. 0x38,
  755. 0x20);
  756. break;
  757. case 800:
  758. xgifb_reg_set(XGIPART2,
  759. 0x35,
  760. 0xFC);
  761. xgifb_reg_set(XGIPART2,
  762. 0x36,
  763. 0xFB);
  764. xgifb_reg_set(XGIPART2,
  765. 0x37,
  766. 0x14);
  767. xgifb_reg_set(XGIPART2,
  768. 0x38,
  769. 0x2A);
  770. break;
  771. }
  772. }
  773. }
  774. if ((filter >= 0) && (filter <= 7)) {
  775. pr_debug("FilterTable[%d]-%d: %*ph\n",
  776. filter_tb, filter,
  777. 4, XGI_TV_filter[filter_tb].
  778. filter[filter]);
  779. xgifb_reg_set(
  780. XGIPART2,
  781. 0x35,
  782. (XGI_TV_filter[filter_tb].
  783. filter[filter][0]));
  784. xgifb_reg_set(
  785. XGIPART2,
  786. 0x36,
  787. (XGI_TV_filter[filter_tb].
  788. filter[filter][1]));
  789. xgifb_reg_set(
  790. XGIPART2,
  791. 0x37,
  792. (XGI_TV_filter[filter_tb].
  793. filter[filter][2]));
  794. xgifb_reg_set(
  795. XGIPART2,
  796. 0x38,
  797. (XGI_TV_filter[filter_tb].
  798. filter[filter][3]));
  799. }
  800. }
  801. }
  802. }
  803. static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
  804. struct fb_info *info)
  805. {
  806. struct xgifb_video_info *xgifb_info = info->par;
  807. struct xgi_hw_device_info *hw_info = &xgifb_info->hw_info;
  808. unsigned int htotal = var->left_margin + var->xres + var->right_margin
  809. + var->hsync_len;
  810. unsigned int vtotal = var->upper_margin + var->yres + var->lower_margin
  811. + var->vsync_len;
  812. #if defined(__BIG_ENDIAN)
  813. u8 cr_data;
  814. #endif
  815. unsigned int drate = 0, hrate = 0;
  816. int found_mode = 0;
  817. int old_mode;
  818. info->var.xres_virtual = var->xres_virtual;
  819. info->var.yres_virtual = var->yres_virtual;
  820. info->var.bits_per_pixel = var->bits_per_pixel;
  821. if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED)
  822. vtotal <<= 1;
  823. else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
  824. vtotal <<= 2;
  825. if (!htotal || !vtotal) {
  826. pr_debug("Invalid 'var' information\n");
  827. return -EINVAL;
  828. } pr_debug("var->pixclock=%d, htotal=%d, vtotal=%d\n",
  829. var->pixclock, htotal, vtotal);
  830. if (var->pixclock) {
  831. drate = 1000000000 / var->pixclock;
  832. hrate = (drate * 1000) / htotal;
  833. xgifb_info->refresh_rate = (unsigned int) (hrate * 2
  834. / vtotal);
  835. } else {
  836. xgifb_info->refresh_rate = 60;
  837. }
  838. pr_debug("Change mode to %dx%dx%d-%dHz\n",
  839. var->xres,
  840. var->yres,
  841. var->bits_per_pixel,
  842. xgifb_info->refresh_rate);
  843. old_mode = xgifb_info->mode_idx;
  844. xgifb_info->mode_idx = 0;
  845. while ((XGIbios_mode[xgifb_info->mode_idx].mode_no != 0) &&
  846. (XGIbios_mode[xgifb_info->mode_idx].xres <= var->xres)) {
  847. if ((XGIbios_mode[xgifb_info->mode_idx].xres == var->xres) &&
  848. (XGIbios_mode[xgifb_info->mode_idx].yres == var->yres) &&
  849. (XGIbios_mode[xgifb_info->mode_idx].bpp
  850. == var->bits_per_pixel)) {
  851. found_mode = 1;
  852. break;
  853. }
  854. xgifb_info->mode_idx++;
  855. }
  856. if (found_mode)
  857. xgifb_info->mode_idx = XGIfb_validate_mode(xgifb_info,
  858. xgifb_info->mode_idx);
  859. else
  860. xgifb_info->mode_idx = -1;
  861. if (xgifb_info->mode_idx < 0) {
  862. pr_err("Mode %dx%dx%d not supported\n",
  863. var->xres, var->yres, var->bits_per_pixel);
  864. xgifb_info->mode_idx = old_mode;
  865. return -EINVAL;
  866. }
  867. if (XGIfb_search_refresh_rate(xgifb_info,
  868. xgifb_info->refresh_rate) == 0) {
  869. xgifb_info->rate_idx = 1;
  870. xgifb_info->refresh_rate = 60;
  871. }
  872. if (isactive) {
  873. XGIfb_pre_setmode(xgifb_info);
  874. if (XGISetModeNew(xgifb_info, hw_info,
  875. XGIbios_mode[xgifb_info->mode_idx].mode_no)
  876. == 0) {
  877. pr_err("Setting mode[0x%x] failed\n",
  878. XGIbios_mode[xgifb_info->mode_idx].mode_no);
  879. return -EINVAL;
  880. }
  881. info->fix.line_length = (info->var.xres_virtual
  882. * info->var.bits_per_pixel) >> 6;
  883. xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
  884. xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
  885. xgifb_reg_set(XGISR,
  886. 0x0E,
  887. (info->fix.line_length & 0xff00) >> 8);
  888. XGIfb_post_setmode(xgifb_info);
  889. pr_debug("Set new mode: %dx%dx%d-%d\n",
  890. XGIbios_mode[xgifb_info->mode_idx].xres,
  891. XGIbios_mode[xgifb_info->mode_idx].yres,
  892. XGIbios_mode[xgifb_info->mode_idx].bpp,
  893. xgifb_info->refresh_rate);
  894. xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
  895. xgifb_info->video_vwidth = info->var.xres_virtual;
  896. xgifb_info->video_width =
  897. XGIbios_mode[xgifb_info->mode_idx].xres;
  898. xgifb_info->video_vheight = info->var.yres_virtual;
  899. xgifb_info->video_height =
  900. XGIbios_mode[xgifb_info->mode_idx].yres;
  901. xgifb_info->org_x = xgifb_info->org_y = 0;
  902. xgifb_info->video_linelength = info->var.xres_virtual
  903. * (xgifb_info->video_bpp >> 3);
  904. switch (xgifb_info->video_bpp) {
  905. case 8:
  906. xgifb_info->DstColor = 0x0000;
  907. xgifb_info->XGI310_AccelDepth = 0x00000000;
  908. xgifb_info->video_cmap_len = 256;
  909. #if defined(__BIG_ENDIAN)
  910. cr_data = xgifb_reg_get(XGICR, 0x4D);
  911. xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
  912. #endif
  913. break;
  914. case 16:
  915. xgifb_info->DstColor = 0x8000;
  916. xgifb_info->XGI310_AccelDepth = 0x00010000;
  917. #if defined(__BIG_ENDIAN)
  918. cr_data = xgifb_reg_get(XGICR, 0x4D);
  919. xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
  920. #endif
  921. xgifb_info->video_cmap_len = 16;
  922. break;
  923. case 32:
  924. xgifb_info->DstColor = 0xC000;
  925. xgifb_info->XGI310_AccelDepth = 0x00020000;
  926. xgifb_info->video_cmap_len = 16;
  927. #if defined(__BIG_ENDIAN)
  928. cr_data = xgifb_reg_get(XGICR, 0x4D);
  929. xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
  930. #endif
  931. break;
  932. default:
  933. xgifb_info->video_cmap_len = 16;
  934. pr_err("Unsupported depth %d\n",
  935. xgifb_info->video_bpp);
  936. break;
  937. }
  938. }
  939. XGIfb_bpp_to_var(xgifb_info, var); /*update ARGB info*/
  940. dumpVGAReg(xgifb_info);
  941. return 0;
  942. }
  943. static int XGIfb_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
  944. {
  945. struct xgifb_video_info *xgifb_info = info->par;
  946. unsigned int base;
  947. base = var->yoffset * info->var.xres_virtual + var->xoffset;
  948. /* calculate base bpp dep. */
  949. switch (info->var.bits_per_pixel) {
  950. case 16:
  951. base >>= 1;
  952. break;
  953. case 32:
  954. break;
  955. case 8:
  956. default:
  957. base >>= 2;
  958. break;
  959. }
  960. xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
  961. xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
  962. xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
  963. xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
  964. xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
  965. xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
  966. if (xgifb_info->display2 != XGIFB_DISP_NONE) {
  967. xgifb_reg_or(XGIPART1, SIS_CRT2_WENABLE_315, 0x01);
  968. xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
  969. xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
  970. xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
  971. xgifb_reg_and_or(XGIPART1,
  972. 0x02,
  973. 0x7F,
  974. ((base >> 24) & 0x01) << 7);
  975. }
  976. return 0;
  977. }
  978. static int XGIfb_open(struct fb_info *info, int user)
  979. {
  980. return 0;
  981. }
  982. static int XGIfb_release(struct fb_info *info, int user)
  983. {
  984. return 0;
  985. }
  986. /* similar to sisfb_get_cmap_len */
  987. static int XGIfb_get_cmap_len(const struct fb_var_screeninfo *var)
  988. {
  989. return (var->bits_per_pixel == 8) ? 256 : 16;
  990. }
  991. static int XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
  992. unsigned blue, unsigned transp, struct fb_info *info)
  993. {
  994. struct xgifb_video_info *xgifb_info = info->par;
  995. if (regno >= XGIfb_get_cmap_len(&info->var))
  996. return 1;
  997. switch (info->var.bits_per_pixel) {
  998. case 8:
  999. outb(regno, XGIDACA);
  1000. outb((red >> 10), XGIDACD);
  1001. outb((green >> 10), XGIDACD);
  1002. outb((blue >> 10), XGIDACD);
  1003. if (xgifb_info->display2 != XGIFB_DISP_NONE) {
  1004. outb(regno, XGIDAC2A);
  1005. outb((red >> 8), XGIDAC2D);
  1006. outb((green >> 8), XGIDAC2D);
  1007. outb((blue >> 8), XGIDAC2D);
  1008. }
  1009. break;
  1010. case 16:
  1011. ((u32 *) (info->pseudo_palette))[regno] = ((red & 0xf800))
  1012. | ((green & 0xfc00) >> 5) | ((blue & 0xf800)
  1013. >> 11);
  1014. break;
  1015. case 32:
  1016. red >>= 8;
  1017. green >>= 8;
  1018. blue >>= 8;
  1019. ((u32 *) (info->pseudo_palette))[regno] = (red << 16) | (green
  1020. << 8) | (blue);
  1021. break;
  1022. }
  1023. return 0;
  1024. }
  1025. /* ----------- FBDev related routines for all series ---------- */
  1026. static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
  1027. struct fb_info *info)
  1028. {
  1029. struct xgifb_video_info *xgifb_info = info->par;
  1030. memset(fix, 0, sizeof(struct fb_fix_screeninfo));
  1031. strncpy(fix->id, "XGI", sizeof(fix->id) - 1);
  1032. /* if register_framebuffer has been called, we must lock */
  1033. if (atomic_read(&info->count))
  1034. mutex_lock(&info->mm_lock);
  1035. fix->smem_start = xgifb_info->video_base;
  1036. fix->smem_len = xgifb_info->video_size;
  1037. /* if register_framebuffer has been called, we can unlock */
  1038. if (atomic_read(&info->count))
  1039. mutex_unlock(&info->mm_lock);
  1040. fix->type = FB_TYPE_PACKED_PIXELS;
  1041. fix->type_aux = 0;
  1042. if (xgifb_info->video_bpp == 8)
  1043. fix->visual = FB_VISUAL_PSEUDOCOLOR;
  1044. else
  1045. fix->visual = FB_VISUAL_DIRECTCOLOR;
  1046. fix->xpanstep = 0;
  1047. if (XGIfb_ypan)
  1048. fix->ypanstep = 1;
  1049. fix->ywrapstep = 0;
  1050. fix->line_length = xgifb_info->video_linelength;
  1051. fix->mmio_start = xgifb_info->mmio_base;
  1052. fix->mmio_len = xgifb_info->mmio_size;
  1053. fix->accel = FB_ACCEL_SIS_XABRE;
  1054. return 0;
  1055. }
  1056. static int XGIfb_set_par(struct fb_info *info)
  1057. {
  1058. int err;
  1059. err = XGIfb_do_set_var(&info->var, 1, info);
  1060. if (err)
  1061. return err;
  1062. XGIfb_get_fix(&info->fix, -1, info);
  1063. return 0;
  1064. }
  1065. static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
  1066. {
  1067. struct xgifb_video_info *xgifb_info = info->par;
  1068. unsigned int htotal = var->left_margin + var->xres + var->right_margin
  1069. + var->hsync_len;
  1070. unsigned int vtotal = 0;
  1071. unsigned int drate = 0, hrate = 0;
  1072. int found_mode = 0;
  1073. int refresh_rate, search_idx;
  1074. if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
  1075. vtotal = var->upper_margin + var->yres + var->lower_margin
  1076. + var->vsync_len;
  1077. vtotal <<= 1;
  1078. } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
  1079. vtotal = var->upper_margin + var->yres + var->lower_margin
  1080. + var->vsync_len;
  1081. vtotal <<= 2;
  1082. } else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
  1083. vtotal = var->upper_margin + (var->yres / 2)
  1084. + var->lower_margin + var->vsync_len;
  1085. } else
  1086. vtotal = var->upper_margin + var->yres + var->lower_margin
  1087. + var->vsync_len;
  1088. if (!(htotal) || !(vtotal)) {
  1089. pr_debug("No valid timing data\n");
  1090. return -EINVAL;
  1091. }
  1092. if (var->pixclock && htotal && vtotal) {
  1093. drate = 1000000000 / var->pixclock;
  1094. hrate = (drate * 1000) / htotal;
  1095. xgifb_info->refresh_rate =
  1096. (unsigned int) (hrate * 2 / vtotal);
  1097. pr_debug(
  1098. "%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
  1099. "%s: drate=%d, hrate=%d, refresh_rate=%d\n",
  1100. __func__, var->pixclock, htotal, vtotal,
  1101. __func__, drate, hrate, xgifb_info->refresh_rate);
  1102. } else {
  1103. xgifb_info->refresh_rate = 60;
  1104. }
  1105. /* Calculation wrong for 1024x600 - force it to 60Hz */
  1106. if ((var->xres == 1024) && (var->yres == 600))
  1107. refresh_rate = 60;
  1108. search_idx = 0;
  1109. while ((XGIbios_mode[search_idx].mode_no != 0) &&
  1110. (XGIbios_mode[search_idx].xres <= var->xres)) {
  1111. if ((XGIbios_mode[search_idx].xres == var->xres) &&
  1112. (XGIbios_mode[search_idx].yres == var->yres) &&
  1113. (XGIbios_mode[search_idx].bpp == var->bits_per_pixel)) {
  1114. if (XGIfb_validate_mode(xgifb_info, search_idx) > 0) {
  1115. found_mode = 1;
  1116. break;
  1117. }
  1118. }
  1119. search_idx++;
  1120. }
  1121. if (!found_mode) {
  1122. pr_err("%dx%dx%d is no valid mode\n",
  1123. var->xres, var->yres, var->bits_per_pixel);
  1124. search_idx = 0;
  1125. while (XGIbios_mode[search_idx].mode_no != 0) {
  1126. if ((var->xres <= XGIbios_mode[search_idx].xres) &&
  1127. (var->yres <= XGIbios_mode[search_idx].yres) &&
  1128. (var->bits_per_pixel ==
  1129. XGIbios_mode[search_idx].bpp)) {
  1130. if (XGIfb_validate_mode(xgifb_info,
  1131. search_idx) > 0) {
  1132. found_mode = 1;
  1133. break;
  1134. }
  1135. }
  1136. search_idx++;
  1137. }
  1138. if (found_mode) {
  1139. var->xres = XGIbios_mode[search_idx].xres;
  1140. var->yres = XGIbios_mode[search_idx].yres;
  1141. pr_debug("Adapted to mode %dx%dx%d\n",
  1142. var->xres, var->yres, var->bits_per_pixel);
  1143. } else {
  1144. pr_err("Failed to find similar mode to %dx%dx%d\n",
  1145. var->xres, var->yres, var->bits_per_pixel);
  1146. return -EINVAL;
  1147. }
  1148. }
  1149. /* Adapt RGB settings */
  1150. XGIfb_bpp_to_var(xgifb_info, var);
  1151. if (!XGIfb_ypan) {
  1152. if (var->xres != var->xres_virtual)
  1153. var->xres_virtual = var->xres;
  1154. if (var->yres != var->yres_virtual)
  1155. var->yres_virtual = var->yres;
  1156. }
  1157. /* Truncate offsets to maximum if too high */
  1158. if (var->xoffset > var->xres_virtual - var->xres)
  1159. var->xoffset = var->xres_virtual - var->xres - 1;
  1160. if (var->yoffset > var->yres_virtual - var->yres)
  1161. var->yoffset = var->yres_virtual - var->yres - 1;
  1162. /* Set everything else to 0 */
  1163. var->red.msb_right =
  1164. var->green.msb_right =
  1165. var->blue.msb_right =
  1166. var->transp.offset = var->transp.length = var->transp.msb_right = 0;
  1167. return 0;
  1168. }
  1169. static int XGIfb_pan_display(struct fb_var_screeninfo *var,
  1170. struct fb_info *info)
  1171. {
  1172. int err;
  1173. if (var->xoffset > (info->var.xres_virtual - info->var.xres))
  1174. return -EINVAL;
  1175. if (var->yoffset > (info->var.yres_virtual - info->var.yres))
  1176. return -EINVAL;
  1177. if (var->vmode & FB_VMODE_YWRAP) {
  1178. if (var->yoffset >= info->var.yres_virtual || var->xoffset)
  1179. return -EINVAL;
  1180. } else if (var->xoffset + info->var.xres > info->var.xres_virtual
  1181. || var->yoffset + info->var.yres
  1182. > info->var.yres_virtual) {
  1183. return -EINVAL;
  1184. }
  1185. err = XGIfb_pan_var(var, info);
  1186. if (err < 0)
  1187. return err;
  1188. info->var.xoffset = var->xoffset;
  1189. info->var.yoffset = var->yoffset;
  1190. if (var->vmode & FB_VMODE_YWRAP)
  1191. info->var.vmode |= FB_VMODE_YWRAP;
  1192. else
  1193. info->var.vmode &= ~FB_VMODE_YWRAP;
  1194. return 0;
  1195. }
  1196. static int XGIfb_blank(int blank, struct fb_info *info)
  1197. {
  1198. struct xgifb_video_info *xgifb_info = info->par;
  1199. u8 reg;
  1200. reg = xgifb_reg_get(XGICR, 0x17);
  1201. if (blank > 0)
  1202. reg &= 0x7f;
  1203. else
  1204. reg |= 0x80;
  1205. xgifb_reg_set(XGICR, 0x17, reg);
  1206. xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
  1207. xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
  1208. return 0;
  1209. }
  1210. static struct fb_ops XGIfb_ops = {
  1211. .owner = THIS_MODULE,
  1212. .fb_open = XGIfb_open,
  1213. .fb_release = XGIfb_release,
  1214. .fb_check_var = XGIfb_check_var,
  1215. .fb_set_par = XGIfb_set_par,
  1216. .fb_setcolreg = XGIfb_setcolreg,
  1217. .fb_pan_display = XGIfb_pan_display,
  1218. .fb_blank = XGIfb_blank,
  1219. .fb_fillrect = cfb_fillrect,
  1220. .fb_copyarea = cfb_copyarea,
  1221. .fb_imageblit = cfb_imageblit,
  1222. };
  1223. /* ---------------- Chip generation dependent routines ---------------- */
  1224. /* for XGI 315/550/650/740/330 */
  1225. static int XGIfb_get_dram_size(struct xgifb_video_info *xgifb_info)
  1226. {
  1227. u8 ChannelNum, tmp;
  1228. u8 reg = 0;
  1229. /* xorg driver sets 32MB * 1 channel */
  1230. if (xgifb_info->chip == XG27)
  1231. xgifb_reg_set(XGISR, IND_SIS_DRAM_SIZE, 0x51);
  1232. reg = xgifb_reg_get(XGISR, IND_SIS_DRAM_SIZE);
  1233. if (!reg)
  1234. return -1;
  1235. switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
  1236. case XGI_DRAM_SIZE_1MB:
  1237. xgifb_info->video_size = 0x100000;
  1238. break;
  1239. case XGI_DRAM_SIZE_2MB:
  1240. xgifb_info->video_size = 0x200000;
  1241. break;
  1242. case XGI_DRAM_SIZE_4MB:
  1243. xgifb_info->video_size = 0x400000;
  1244. break;
  1245. case XGI_DRAM_SIZE_8MB:
  1246. xgifb_info->video_size = 0x800000;
  1247. break;
  1248. case XGI_DRAM_SIZE_16MB:
  1249. xgifb_info->video_size = 0x1000000;
  1250. break;
  1251. case XGI_DRAM_SIZE_32MB:
  1252. xgifb_info->video_size = 0x2000000;
  1253. break;
  1254. case XGI_DRAM_SIZE_64MB:
  1255. xgifb_info->video_size = 0x4000000;
  1256. break;
  1257. case XGI_DRAM_SIZE_128MB:
  1258. xgifb_info->video_size = 0x8000000;
  1259. break;
  1260. case XGI_DRAM_SIZE_256MB:
  1261. xgifb_info->video_size = 0x10000000;
  1262. break;
  1263. default:
  1264. return -1;
  1265. }
  1266. tmp = (reg & 0x0c) >> 2;
  1267. switch (xgifb_info->chip) {
  1268. case XG20:
  1269. case XG21:
  1270. case XG27:
  1271. ChannelNum = 1;
  1272. break;
  1273. case XG42:
  1274. if (reg & 0x04)
  1275. ChannelNum = 2;
  1276. else
  1277. ChannelNum = 1;
  1278. break;
  1279. case XG40:
  1280. default:
  1281. if (tmp == 2)
  1282. ChannelNum = 2;
  1283. else if (tmp == 3)
  1284. ChannelNum = 3;
  1285. else
  1286. ChannelNum = 1;
  1287. break;
  1288. }
  1289. xgifb_info->video_size = xgifb_info->video_size * ChannelNum;
  1290. pr_info("SR14=%x DramSzie %x ChannelNum %x\n",
  1291. reg,
  1292. xgifb_info->video_size, ChannelNum);
  1293. return 0;
  1294. }
  1295. static void XGIfb_detect_VB(struct xgifb_video_info *xgifb_info)
  1296. {
  1297. u8 cr32, temp = 0;
  1298. xgifb_info->TV_plug = xgifb_info->TV_type = 0;
  1299. cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
  1300. if ((cr32 & SIS_CRT1) && !XGIfb_crt1off)
  1301. XGIfb_crt1off = 0;
  1302. else {
  1303. if (cr32 & 0x5F)
  1304. XGIfb_crt1off = 1;
  1305. else
  1306. XGIfb_crt1off = 0;
  1307. }
  1308. if (!xgifb_info->display2_force) {
  1309. if (cr32 & SIS_VB_TV)
  1310. xgifb_info->display2 = XGIFB_DISP_TV;
  1311. else if (cr32 & SIS_VB_LCD)
  1312. xgifb_info->display2 = XGIFB_DISP_LCD;
  1313. else if (cr32 & SIS_VB_CRT2)
  1314. xgifb_info->display2 = XGIFB_DISP_CRT;
  1315. else
  1316. xgifb_info->display2 = XGIFB_DISP_NONE;
  1317. }
  1318. if (XGIfb_tvplug != -1)
  1319. /* Override with option */
  1320. xgifb_info->TV_plug = XGIfb_tvplug;
  1321. else if (cr32 & SIS_VB_HIVISION) {
  1322. xgifb_info->TV_type = TVMODE_HIVISION;
  1323. xgifb_info->TV_plug = TVPLUG_SVIDEO;
  1324. } else if (cr32 & SIS_VB_SVIDEO)
  1325. xgifb_info->TV_plug = TVPLUG_SVIDEO;
  1326. else if (cr32 & SIS_VB_COMPOSITE)
  1327. xgifb_info->TV_plug = TVPLUG_COMPOSITE;
  1328. else if (cr32 & SIS_VB_SCART)
  1329. xgifb_info->TV_plug = TVPLUG_SCART;
  1330. if (xgifb_info->TV_type == 0) {
  1331. temp = xgifb_reg_get(XGICR, 0x38);
  1332. if (temp & 0x10)
  1333. xgifb_info->TV_type = TVMODE_PAL;
  1334. else
  1335. xgifb_info->TV_type = TVMODE_NTSC;
  1336. }
  1337. /* Copy forceCRT1 option to CRT1off if option is given */
  1338. if (XGIfb_forcecrt1 != -1) {
  1339. if (XGIfb_forcecrt1)
  1340. XGIfb_crt1off = 0;
  1341. else
  1342. XGIfb_crt1off = 1;
  1343. }
  1344. }
  1345. static bool XGIfb_has_VB(struct xgifb_video_info *xgifb_info)
  1346. {
  1347. u8 vb_chipid;
  1348. vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
  1349. switch (vb_chipid) {
  1350. case 0x01:
  1351. xgifb_info->hasVB = HASVB_301;
  1352. break;
  1353. case 0x02:
  1354. xgifb_info->hasVB = HASVB_302;
  1355. break;
  1356. default:
  1357. xgifb_info->hasVB = HASVB_NONE;
  1358. return false;
  1359. }
  1360. return true;
  1361. }
  1362. static void XGIfb_get_VB_type(struct xgifb_video_info *xgifb_info)
  1363. {
  1364. u8 reg;
  1365. if (!XGIfb_has_VB(xgifb_info)) {
  1366. reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
  1367. switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
  1368. case SIS_EXTERNAL_CHIP_LVDS:
  1369. xgifb_info->hasVB = HASVB_LVDS;
  1370. break;
  1371. case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
  1372. xgifb_info->hasVB = HASVB_LVDS_CHRONTEL;
  1373. break;
  1374. default:
  1375. break;
  1376. }
  1377. }
  1378. }
  1379. static int __init xgifb_optval(char *fullopt, int validx)
  1380. {
  1381. unsigned long lres;
  1382. if (kstrtoul(fullopt + validx, 0, &lres) < 0 || lres > INT_MAX) {
  1383. pr_err("Invalid value for option: %s\n", fullopt);
  1384. return 0;
  1385. }
  1386. return lres;
  1387. }
  1388. static int __init XGIfb_setup(char *options)
  1389. {
  1390. char *this_opt;
  1391. if (!options || !*options)
  1392. return 0;
  1393. pr_info("Options: %s\n", options);
  1394. while ((this_opt = strsep(&options, ",")) != NULL) {
  1395. if (!*this_opt)
  1396. continue;
  1397. if (!strncmp(this_opt, "mode:", 5)) {
  1398. mode = this_opt + 5;
  1399. } else if (!strncmp(this_opt, "vesa:", 5)) {
  1400. vesa = xgifb_optval(this_opt, 5);
  1401. } else if (!strncmp(this_opt, "vrate:", 6)) {
  1402. refresh_rate = xgifb_optval(this_opt, 6);
  1403. } else if (!strncmp(this_opt, "rate:", 5)) {
  1404. refresh_rate = xgifb_optval(this_opt, 5);
  1405. } else if (!strncmp(this_opt, "crt1off", 7)) {
  1406. XGIfb_crt1off = 1;
  1407. } else if (!strncmp(this_opt, "filter:", 7)) {
  1408. filter = xgifb_optval(this_opt, 7);
  1409. } else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
  1410. XGIfb_search_crt2type(this_opt + 14);
  1411. } else if (!strncmp(this_opt, "forcecrt1:", 10)) {
  1412. XGIfb_forcecrt1 = xgifb_optval(this_opt, 10);
  1413. } else if (!strncmp(this_opt, "tvmode:", 7)) {
  1414. XGIfb_search_tvstd(this_opt + 7);
  1415. } else if (!strncmp(this_opt, "tvstandard:", 11)) {
  1416. XGIfb_search_tvstd(this_opt + 7);
  1417. } else if (!strncmp(this_opt, "dstn", 4)) {
  1418. enable_dstn = 1;
  1419. /* DSTN overrules forcecrt2type */
  1420. XGIfb_crt2type = XGIFB_DISP_LCD;
  1421. } else if (!strncmp(this_opt, "noypan", 6)) {
  1422. XGIfb_ypan = 0;
  1423. } else {
  1424. mode = this_opt;
  1425. }
  1426. }
  1427. return 0;
  1428. }
  1429. static int xgifb_probe(struct pci_dev *pdev,
  1430. const struct pci_device_id *ent)
  1431. {
  1432. u8 reg, reg1;
  1433. u8 CR48, CR38;
  1434. int ret;
  1435. struct fb_info *fb_info;
  1436. struct xgifb_video_info *xgifb_info;
  1437. struct xgi_hw_device_info *hw_info;
  1438. unsigned long video_size_max;
  1439. fb_info = framebuffer_alloc(sizeof(*xgifb_info), &pdev->dev);
  1440. if (!fb_info)
  1441. return -ENOMEM;
  1442. xgifb_info = fb_info->par;
  1443. hw_info = &xgifb_info->hw_info;
  1444. xgifb_info->fb_info = fb_info;
  1445. xgifb_info->chip_id = pdev->device;
  1446. pci_read_config_byte(pdev,
  1447. PCI_REVISION_ID,
  1448. &xgifb_info->revision_id);
  1449. hw_info->jChipRevision = xgifb_info->revision_id;
  1450. xgifb_info->pcibus = pdev->bus->number;
  1451. xgifb_info->pcislot = PCI_SLOT(pdev->devfn);
  1452. xgifb_info->pcifunc = PCI_FUNC(pdev->devfn);
  1453. xgifb_info->subsysvendor = pdev->subsystem_vendor;
  1454. xgifb_info->subsysdevice = pdev->subsystem_device;
  1455. video_size_max = pci_resource_len(pdev, 0);
  1456. xgifb_info->video_base = pci_resource_start(pdev, 0);
  1457. xgifb_info->mmio_base = pci_resource_start(pdev, 1);
  1458. xgifb_info->mmio_size = pci_resource_len(pdev, 1);
  1459. xgifb_info->vga_base = pci_resource_start(pdev, 2) + 0x30;
  1460. dev_info(&pdev->dev, "Relocate IO address: %Lx [%08lx]\n",
  1461. (u64) pci_resource_start(pdev, 2),
  1462. xgifb_info->vga_base);
  1463. if (pci_enable_device(pdev)) {
  1464. ret = -EIO;
  1465. goto error;
  1466. }
  1467. if (XGIfb_crt2type != -1) {
  1468. xgifb_info->display2 = XGIfb_crt2type;
  1469. xgifb_info->display2_force = true;
  1470. }
  1471. XGIRegInit(&xgifb_info->dev_info, xgifb_info->vga_base);
  1472. xgifb_reg_set(XGISR, IND_SIS_PASSWORD, SIS_PASSWORD);
  1473. reg1 = xgifb_reg_get(XGISR, IND_SIS_PASSWORD);
  1474. if (reg1 != 0xa1) { /*I/O error */
  1475. dev_err(&pdev->dev, "I/O error\n");
  1476. ret = -EIO;
  1477. goto error_disable;
  1478. }
  1479. switch (xgifb_info->chip_id) {
  1480. case PCI_DEVICE_ID_XGI_20:
  1481. xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
  1482. CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
  1483. if (CR48&GPIOG_READ)
  1484. xgifb_info->chip = XG21;
  1485. else
  1486. xgifb_info->chip = XG20;
  1487. break;
  1488. case PCI_DEVICE_ID_XGI_40:
  1489. xgifb_info->chip = XG40;
  1490. break;
  1491. case PCI_DEVICE_ID_XGI_42:
  1492. xgifb_info->chip = XG42;
  1493. break;
  1494. case PCI_DEVICE_ID_XGI_27:
  1495. xgifb_info->chip = XG27;
  1496. break;
  1497. default:
  1498. ret = -ENODEV;
  1499. goto error_disable;
  1500. }
  1501. dev_info(&pdev->dev, "chipid = %x\n", xgifb_info->chip);
  1502. hw_info->jChipType = xgifb_info->chip;
  1503. if (XGIfb_get_dram_size(xgifb_info)) {
  1504. xgifb_info->video_size = min_t(unsigned long, video_size_max,
  1505. SZ_16M);
  1506. } else if (xgifb_info->video_size > video_size_max) {
  1507. xgifb_info->video_size = video_size_max;
  1508. }
  1509. /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */
  1510. xgifb_reg_or(XGISR,
  1511. IND_SIS_PCI_ADDRESS_SET,
  1512. (SIS_PCI_ADDR_ENABLE | SIS_MEM_MAP_IO_ENABLE));
  1513. /* Enable 2D accelerator engine */
  1514. xgifb_reg_or(XGISR, IND_SIS_MODULE_ENABLE, SIS_ENABLE_2D);
  1515. hw_info->ulVideoMemorySize = xgifb_info->video_size;
  1516. if (!request_mem_region(xgifb_info->video_base,
  1517. xgifb_info->video_size,
  1518. "XGIfb FB")) {
  1519. dev_err(&pdev->dev, "Unable request memory size %x\n",
  1520. xgifb_info->video_size);
  1521. dev_err(&pdev->dev,
  1522. "Fatal error: Unable to reserve frame buffer memory. Is there another framebuffer driver active?\n");
  1523. ret = -ENODEV;
  1524. goto error_disable;
  1525. }
  1526. if (!request_mem_region(xgifb_info->mmio_base,
  1527. xgifb_info->mmio_size,
  1528. "XGIfb MMIO")) {
  1529. dev_err(&pdev->dev,
  1530. "Fatal error: Unable to reserve MMIO region\n");
  1531. ret = -ENODEV;
  1532. goto error_0;
  1533. }
  1534. xgifb_info->video_vbase = hw_info->pjVideoMemoryAddress =
  1535. ioremap_wc(xgifb_info->video_base, xgifb_info->video_size);
  1536. xgifb_info->mmio_vbase = ioremap(xgifb_info->mmio_base,
  1537. xgifb_info->mmio_size);
  1538. dev_info(&pdev->dev,
  1539. "Framebuffer at 0x%Lx, mapped to 0x%p, size %dk\n",
  1540. (u64) xgifb_info->video_base,
  1541. xgifb_info->video_vbase,
  1542. xgifb_info->video_size / 1024);
  1543. dev_info(&pdev->dev,
  1544. "MMIO at 0x%Lx, mapped to 0x%p, size %ldk\n",
  1545. (u64) xgifb_info->mmio_base, xgifb_info->mmio_vbase,
  1546. xgifb_info->mmio_size / 1024);
  1547. pci_set_drvdata(pdev, xgifb_info);
  1548. if (!XGIInitNew(pdev))
  1549. dev_err(&pdev->dev, "XGIInitNew() failed!\n");
  1550. xgifb_info->mtrr = -1;
  1551. xgifb_info->hasVB = HASVB_NONE;
  1552. if ((xgifb_info->chip == XG20) ||
  1553. (xgifb_info->chip == XG27)) {
  1554. xgifb_info->hasVB = HASVB_NONE;
  1555. } else if (xgifb_info->chip == XG21) {
  1556. CR38 = xgifb_reg_get(XGICR, 0x38);
  1557. if ((CR38&0xE0) == 0xC0)
  1558. xgifb_info->display2 = XGIFB_DISP_LCD;
  1559. else if ((CR38&0xE0) == 0x60)
  1560. xgifb_info->hasVB = HASVB_CHRONTEL;
  1561. else
  1562. xgifb_info->hasVB = HASVB_NONE;
  1563. } else {
  1564. XGIfb_get_VB_type(xgifb_info);
  1565. }
  1566. hw_info->ujVBChipID = VB_CHIP_UNKNOWN;
  1567. hw_info->ulExternalChip = 0;
  1568. switch (xgifb_info->hasVB) {
  1569. case HASVB_301:
  1570. reg = xgifb_reg_get(XGIPART4, 0x01);
  1571. if (reg >= 0xE0) {
  1572. hw_info->ujVBChipID = VB_CHIP_302LV;
  1573. dev_info(&pdev->dev,
  1574. "XGI302LV bridge detected (revision 0x%02x)\n",
  1575. reg);
  1576. } else if (reg >= 0xD0) {
  1577. hw_info->ujVBChipID = VB_CHIP_301LV;
  1578. dev_info(&pdev->dev,
  1579. "XGI301LV bridge detected (revision 0x%02x)\n",
  1580. reg);
  1581. } else {
  1582. hw_info->ujVBChipID = VB_CHIP_301;
  1583. dev_info(&pdev->dev, "XGI301 bridge detected\n");
  1584. }
  1585. break;
  1586. case HASVB_302:
  1587. reg = xgifb_reg_get(XGIPART4, 0x01);
  1588. if (reg >= 0xE0) {
  1589. hw_info->ujVBChipID = VB_CHIP_302LV;
  1590. dev_info(&pdev->dev,
  1591. "XGI302LV bridge detected (revision 0x%02x)\n",
  1592. reg);
  1593. } else if (reg >= 0xD0) {
  1594. hw_info->ujVBChipID = VB_CHIP_301LV;
  1595. dev_info(&pdev->dev,
  1596. "XGI302LV bridge detected (revision 0x%02x)\n",
  1597. reg);
  1598. } else if (reg >= 0xB0) {
  1599. reg1 = xgifb_reg_get(XGIPART4, 0x23);
  1600. hw_info->ujVBChipID = VB_CHIP_302B;
  1601. } else {
  1602. hw_info->ujVBChipID = VB_CHIP_302;
  1603. dev_info(&pdev->dev, "XGI302 bridge detected\n");
  1604. }
  1605. break;
  1606. case HASVB_LVDS:
  1607. hw_info->ulExternalChip = 0x1;
  1608. dev_info(&pdev->dev, "LVDS transmitter detected\n");
  1609. break;
  1610. case HASVB_TRUMPION:
  1611. hw_info->ulExternalChip = 0x2;
  1612. dev_info(&pdev->dev, "Trumpion Zurac LVDS scaler detected\n");
  1613. break;
  1614. case HASVB_CHRONTEL:
  1615. hw_info->ulExternalChip = 0x4;
  1616. dev_info(&pdev->dev, "Chrontel TV encoder detected\n");
  1617. break;
  1618. case HASVB_LVDS_CHRONTEL:
  1619. hw_info->ulExternalChip = 0x5;
  1620. dev_info(&pdev->dev,
  1621. "LVDS transmitter and Chrontel TV encoder detected\n");
  1622. break;
  1623. default:
  1624. dev_info(&pdev->dev, "No or unknown bridge type detected\n");
  1625. break;
  1626. }
  1627. if (xgifb_info->hasVB != HASVB_NONE)
  1628. XGIfb_detect_VB(xgifb_info);
  1629. else if (xgifb_info->chip != XG21)
  1630. xgifb_info->display2 = XGIFB_DISP_NONE;
  1631. if (xgifb_info->display2 == XGIFB_DISP_LCD) {
  1632. if (!enable_dstn) {
  1633. reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
  1634. reg &= 0x0f;
  1635. hw_info->ulCRT2LCDType = XGI310paneltype[reg];
  1636. }
  1637. }
  1638. xgifb_info->mode_idx = -1;
  1639. if (mode)
  1640. XGIfb_search_mode(xgifb_info, mode);
  1641. else if (vesa != -1)
  1642. XGIfb_search_vesamode(xgifb_info, vesa);
  1643. if (xgifb_info->mode_idx >= 0)
  1644. xgifb_info->mode_idx =
  1645. XGIfb_validate_mode(xgifb_info, xgifb_info->mode_idx);
  1646. if (xgifb_info->mode_idx < 0) {
  1647. if (xgifb_info->display2 == XGIFB_DISP_LCD &&
  1648. xgifb_info->chip == XG21)
  1649. xgifb_info->mode_idx =
  1650. XGIfb_GetXG21DefaultLVDSModeIdx(xgifb_info);
  1651. else
  1652. xgifb_info->mode_idx = DEFAULT_MODE;
  1653. }
  1654. if (xgifb_info->mode_idx < 0) {
  1655. dev_err(&pdev->dev, "No supported video mode found\n");
  1656. ret = -EINVAL;
  1657. goto error_1;
  1658. }
  1659. /* set default refresh rate */
  1660. xgifb_info->refresh_rate = refresh_rate;
  1661. if (xgifb_info->refresh_rate == 0)
  1662. xgifb_info->refresh_rate = 60;
  1663. if (XGIfb_search_refresh_rate(xgifb_info,
  1664. xgifb_info->refresh_rate) == 0) {
  1665. xgifb_info->rate_idx = 1;
  1666. xgifb_info->refresh_rate = 60;
  1667. }
  1668. xgifb_info->video_bpp = XGIbios_mode[xgifb_info->mode_idx].bpp;
  1669. xgifb_info->video_vwidth =
  1670. xgifb_info->video_width =
  1671. XGIbios_mode[xgifb_info->mode_idx].xres;
  1672. xgifb_info->video_vheight =
  1673. xgifb_info->video_height =
  1674. XGIbios_mode[xgifb_info->mode_idx].yres;
  1675. xgifb_info->org_x = xgifb_info->org_y = 0;
  1676. xgifb_info->video_linelength =
  1677. xgifb_info->video_width *
  1678. (xgifb_info->video_bpp >> 3);
  1679. switch (xgifb_info->video_bpp) {
  1680. case 8:
  1681. xgifb_info->DstColor = 0x0000;
  1682. xgifb_info->XGI310_AccelDepth = 0x00000000;
  1683. xgifb_info->video_cmap_len = 256;
  1684. break;
  1685. case 16:
  1686. xgifb_info->DstColor = 0x8000;
  1687. xgifb_info->XGI310_AccelDepth = 0x00010000;
  1688. xgifb_info->video_cmap_len = 16;
  1689. break;
  1690. case 32:
  1691. xgifb_info->DstColor = 0xC000;
  1692. xgifb_info->XGI310_AccelDepth = 0x00020000;
  1693. xgifb_info->video_cmap_len = 16;
  1694. break;
  1695. default:
  1696. xgifb_info->video_cmap_len = 16;
  1697. pr_info("Unsupported depth %d\n",
  1698. xgifb_info->video_bpp);
  1699. break;
  1700. }
  1701. pr_info("Default mode is %dx%dx%d (%dHz)\n",
  1702. xgifb_info->video_width,
  1703. xgifb_info->video_height,
  1704. xgifb_info->video_bpp,
  1705. xgifb_info->refresh_rate);
  1706. fb_info->var.red.length = 8;
  1707. fb_info->var.green.length = 8;
  1708. fb_info->var.blue.length = 8;
  1709. fb_info->var.activate = FB_ACTIVATE_NOW;
  1710. fb_info->var.height = -1;
  1711. fb_info->var.width = -1;
  1712. fb_info->var.vmode = FB_VMODE_NONINTERLACED;
  1713. fb_info->var.xres = xgifb_info->video_width;
  1714. fb_info->var.xres_virtual = xgifb_info->video_width;
  1715. fb_info->var.yres = xgifb_info->video_height;
  1716. fb_info->var.yres_virtual = xgifb_info->video_height;
  1717. fb_info->var.bits_per_pixel = xgifb_info->video_bpp;
  1718. XGIfb_bpp_to_var(xgifb_info, &fb_info->var);
  1719. fb_info->var.pixclock = (u32) (1000000000 /
  1720. XGIfb_mode_rate_to_dclock(&xgifb_info->dev_info,
  1721. hw_info,
  1722. XGIbios_mode[xgifb_info->mode_idx].mode_no));
  1723. if (XGIfb_mode_rate_to_ddata(&xgifb_info->dev_info, hw_info,
  1724. XGIbios_mode[xgifb_info->mode_idx].mode_no,
  1725. &fb_info->var.left_margin,
  1726. &fb_info->var.right_margin,
  1727. &fb_info->var.upper_margin,
  1728. &fb_info->var.lower_margin,
  1729. &fb_info->var.hsync_len,
  1730. &fb_info->var.vsync_len,
  1731. &fb_info->var.sync,
  1732. &fb_info->var.vmode)) {
  1733. if ((fb_info->var.vmode & FB_VMODE_MASK) ==
  1734. FB_VMODE_INTERLACED) {
  1735. fb_info->var.yres <<= 1;
  1736. fb_info->var.yres_virtual <<= 1;
  1737. } else if ((fb_info->var.vmode & FB_VMODE_MASK) ==
  1738. FB_VMODE_DOUBLE) {
  1739. fb_info->var.pixclock >>= 1;
  1740. fb_info->var.yres >>= 1;
  1741. fb_info->var.yres_virtual >>= 1;
  1742. }
  1743. }
  1744. fb_info->flags = FBINFO_FLAG_DEFAULT;
  1745. fb_info->screen_base = xgifb_info->video_vbase;
  1746. fb_info->fbops = &XGIfb_ops;
  1747. XGIfb_get_fix(&fb_info->fix, -1, fb_info);
  1748. fb_info->pseudo_palette = xgifb_info->pseudo_palette;
  1749. fb_alloc_cmap(&fb_info->cmap, 256, 0);
  1750. xgifb_info->mtrr = arch_phys_wc_add(xgifb_info->video_base,
  1751. xgifb_info->video_size);
  1752. if (register_framebuffer(fb_info) < 0) {
  1753. ret = -EINVAL;
  1754. goto error_mtrr;
  1755. }
  1756. dumpVGAReg(xgifb_info);
  1757. return 0;
  1758. error_mtrr:
  1759. arch_phys_wc_del(xgifb_info->mtrr);
  1760. error_1:
  1761. iounmap(xgifb_info->mmio_vbase);
  1762. iounmap(xgifb_info->video_vbase);
  1763. release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
  1764. error_0:
  1765. release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
  1766. error_disable:
  1767. pci_disable_device(pdev);
  1768. error:
  1769. framebuffer_release(fb_info);
  1770. return ret;
  1771. }
  1772. /*****************************************************/
  1773. /* PCI DEVICE HANDLING */
  1774. /*****************************************************/
  1775. static void xgifb_remove(struct pci_dev *pdev)
  1776. {
  1777. struct xgifb_video_info *xgifb_info = pci_get_drvdata(pdev);
  1778. struct fb_info *fb_info = xgifb_info->fb_info;
  1779. unregister_framebuffer(fb_info);
  1780. arch_phys_wc_del(xgifb_info->mtrr);
  1781. iounmap(xgifb_info->mmio_vbase);
  1782. iounmap(xgifb_info->video_vbase);
  1783. release_mem_region(xgifb_info->mmio_base, xgifb_info->mmio_size);
  1784. release_mem_region(xgifb_info->video_base, xgifb_info->video_size);
  1785. pci_disable_device(pdev);
  1786. framebuffer_release(fb_info);
  1787. }
  1788. static struct pci_driver xgifb_driver = {
  1789. .name = "xgifb",
  1790. .id_table = xgifb_pci_table,
  1791. .probe = xgifb_probe,
  1792. .remove = xgifb_remove
  1793. };
  1794. /*****************************************************/
  1795. /* MODULE */
  1796. /*****************************************************/
  1797. module_param(mode, charp, 0);
  1798. MODULE_PARM_DESC(mode,
  1799. "Selects the desired default display mode in the format XxYxDepth (eg. 1024x768x16).");
  1800. module_param(forcecrt2type, charp, 0);
  1801. MODULE_PARM_DESC(forcecrt2type,
  1802. "Force the second display output type. Possible values are NONE, LCD, TV, VGA, SVIDEO or COMPOSITE.");
  1803. module_param(vesa, int, 0);
  1804. MODULE_PARM_DESC(vesa,
  1805. "Selects the desired default display mode by VESA mode number (eg. 0x117).");
  1806. module_param(filter, int, 0);
  1807. MODULE_PARM_DESC(filter,
  1808. "Selects TV flicker filter type (only for systems with a SiS301 video bridge). Possible values 0-7. Default: [no filter]).");
  1809. static int __init xgifb_init(void)
  1810. {
  1811. char *option = NULL;
  1812. if (forcecrt2type != NULL)
  1813. XGIfb_search_crt2type(forcecrt2type);
  1814. if (fb_get_options("xgifb", &option))
  1815. return -ENODEV;
  1816. XGIfb_setup(option);
  1817. return pci_register_driver(&xgifb_driver);
  1818. }
  1819. static void __exit xgifb_remove_module(void)
  1820. {
  1821. pci_unregister_driver(&xgifb_driver);
  1822. pr_debug("Module unloaded\n");
  1823. }
  1824. MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver");
  1825. MODULE_LICENSE("GPL");
  1826. MODULE_AUTHOR("XGITECH , Others");
  1827. module_init(xgifb_init);
  1828. module_exit(xgifb_remove_module);