vgaHW.c 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078
  1. /*
  2. *
  3. * Copyright 1991-1999 by The XFree86 Project, Inc.
  4. *
  5. * Loosely based on code bearing the following copyright:
  6. *
  7. * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
  8. *
  9. */
  10. #define _NEED_SYSI86
  11. #ifdef HAVE_XORG_CONFIG_H
  12. #include <xorg-config.h>
  13. #endif
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <X11/X.h>
  18. #include "misc.h"
  19. #include "xf86.h"
  20. #include "xf86_OSproc.h"
  21. #include "vgaHW.h"
  22. #include "compiler.h"
  23. #include "xf86cmap.h"
  24. #include "Pci.h"
  25. #ifndef SAVE_FONT1
  26. #define SAVE_FONT1 1
  27. #endif
  28. /*
  29. * These used to be OS-specific, which made this module have an undesirable
  30. * OS dependency. Define them by default for all platforms.
  31. */
  32. #ifndef NEED_SAVED_CMAP
  33. #define NEED_SAVED_CMAP
  34. #endif
  35. #ifndef SAVE_TEXT
  36. #define SAVE_TEXT 1
  37. #endif
  38. #ifndef SAVE_FONT2
  39. #define SAVE_FONT2 1
  40. #endif
  41. /* bytes per plane to save for text */
  42. #define TEXT_AMOUNT 16384
  43. /* bytes per plane to save for font data */
  44. #define FONT_AMOUNT (8*8192)
  45. #if 0
  46. /* Override all of these for now */
  47. #undef SAVE_FONT1
  48. #define SAVE_FONT1 1
  49. #undef SAVE_FONT2
  50. #define SAVE_FONT2 1
  51. #undef SAVE_TEST
  52. #define SAVE_TEST 1
  53. #undef FONT_AMOUNT
  54. #define FONT_AMOUNT 65536
  55. #undef TEXT_AMOUNT
  56. #define TEXT_AMOUNT 65536
  57. #endif
  58. /* DAC indices for white and black */
  59. #define WHITE_VALUE 0x3F
  60. #define BLACK_VALUE 0x00
  61. #define OVERSCAN_VALUE 0x01
  62. /* Use a private definition of this here */
  63. #undef VGAHWPTR
  64. #define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
  65. #define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
  66. static int vgaHWPrivateIndex = -1;
  67. #define DAC_TEST_MASK 0x3F
  68. #ifdef NEED_SAVED_CMAP
  69. /* This default colourmap is used only when it can't be read from the VGA */
  70. static CARD8 defaultDAC[768] = {
  71. 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
  72. 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
  73. 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
  74. 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
  75. 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
  76. 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
  77. 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
  78. 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
  79. 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
  80. 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
  81. 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
  82. 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
  83. 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
  84. 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
  85. 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
  86. 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
  87. 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
  88. 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
  89. 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
  90. 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
  91. 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
  92. 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
  93. 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
  94. 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
  95. 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
  96. 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
  97. 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
  98. 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
  99. 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
  100. 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
  101. 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
  102. 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
  103. 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
  104. 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
  105. 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
  106. 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
  107. 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
  108. 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
  109. 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
  110. 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
  111. 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
  112. 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
  113. 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
  114. 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
  115. 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
  116. 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
  117. 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
  118. 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
  119. 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
  120. 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
  121. 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
  122. 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
  123. 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
  124. 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
  125. 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
  126. 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
  127. 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
  128. 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
  129. 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
  130. 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
  131. 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
  132. 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
  133. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  134. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  135. };
  136. #endif /* NEED_SAVED_CMAP */
  137. /*
  138. * Standard VGA versions of the register access functions.
  139. */
  140. static void
  141. stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
  142. {
  143. pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
  144. pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
  145. }
  146. static CARD8
  147. stdReadCrtc(vgaHWPtr hwp, CARD8 index)
  148. {
  149. pci_io_write8(hwp->io, hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
  150. return pci_io_read8(hwp->io, hwp->IOBase + VGA_CRTC_DATA_OFFSET);
  151. }
  152. static void
  153. stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
  154. {
  155. pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index);
  156. pci_io_write8(hwp->io, VGA_GRAPH_DATA, value);
  157. }
  158. static CARD8
  159. stdReadGr(vgaHWPtr hwp, CARD8 index)
  160. {
  161. pci_io_write8(hwp->io, VGA_GRAPH_INDEX, index);
  162. return pci_io_read8(hwp->io, VGA_GRAPH_DATA);
  163. }
  164. static void
  165. stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
  166. {
  167. pci_io_write8(hwp->io, VGA_SEQ_INDEX, index);
  168. pci_io_write8(hwp->io, VGA_SEQ_DATA, value);
  169. }
  170. static CARD8
  171. stdReadSeq(vgaHWPtr hwp, CARD8 index)
  172. {
  173. pci_io_write8(hwp->io, VGA_SEQ_INDEX, index);
  174. return pci_io_read8(hwp->io, VGA_SEQ_DATA);
  175. }
  176. static CARD8
  177. stdReadST00(vgaHWPtr hwp)
  178. {
  179. return pci_io_read8(hwp->io, VGA_IN_STAT_0);
  180. }
  181. static CARD8
  182. stdReadST01(vgaHWPtr hwp)
  183. {
  184. return pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  185. }
  186. static CARD8
  187. stdReadFCR(vgaHWPtr hwp)
  188. {
  189. return pci_io_read8(hwp->io, VGA_FEATURE_R);
  190. }
  191. static void
  192. stdWriteFCR(vgaHWPtr hwp, CARD8 value)
  193. {
  194. pci_io_write8(hwp->io, hwp->IOBase + VGA_FEATURE_W_OFFSET, value);
  195. }
  196. static void
  197. stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
  198. {
  199. if (hwp->paletteEnabled)
  200. index &= ~0x20;
  201. else
  202. index |= 0x20;
  203. (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  204. pci_io_write8(hwp->io, VGA_ATTR_INDEX, index);
  205. pci_io_write8(hwp->io, VGA_ATTR_DATA_W, value);
  206. }
  207. static CARD8
  208. stdReadAttr(vgaHWPtr hwp, CARD8 index)
  209. {
  210. if (hwp->paletteEnabled)
  211. index &= ~0x20;
  212. else
  213. index |= 0x20;
  214. (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  215. pci_io_write8(hwp->io, VGA_ATTR_INDEX, index);
  216. return pci_io_read8(hwp->io, VGA_ATTR_DATA_R);
  217. }
  218. static void
  219. stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
  220. {
  221. pci_io_write8(hwp->io, VGA_MISC_OUT_W, value);
  222. }
  223. static CARD8
  224. stdReadMiscOut(vgaHWPtr hwp)
  225. {
  226. return pci_io_read8(hwp->io, VGA_MISC_OUT_R);
  227. }
  228. static void
  229. stdEnablePalette(vgaHWPtr hwp)
  230. {
  231. (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  232. pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x00);
  233. hwp->paletteEnabled = TRUE;
  234. }
  235. static void
  236. stdDisablePalette(vgaHWPtr hwp)
  237. {
  238. (void) pci_io_read8(hwp->io, hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  239. pci_io_write8(hwp->io, VGA_ATTR_INDEX, 0x20);
  240. hwp->paletteEnabled = FALSE;
  241. }
  242. static void
  243. stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
  244. {
  245. pci_io_write8(hwp->io, VGA_DAC_MASK, value);
  246. }
  247. static CARD8
  248. stdReadDacMask(vgaHWPtr hwp)
  249. {
  250. return pci_io_read8(hwp->io, VGA_DAC_MASK);
  251. }
  252. static void
  253. stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
  254. {
  255. pci_io_write8(hwp->io, VGA_DAC_READ_ADDR, value);
  256. }
  257. static void
  258. stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
  259. {
  260. pci_io_write8(hwp->io, VGA_DAC_WRITE_ADDR, value);
  261. }
  262. static void
  263. stdWriteDacData(vgaHWPtr hwp, CARD8 value)
  264. {
  265. pci_io_write8(hwp->io, VGA_DAC_DATA, value);
  266. }
  267. static CARD8
  268. stdReadDacData(vgaHWPtr hwp)
  269. {
  270. return pci_io_read8(hwp->io, VGA_DAC_DATA);
  271. }
  272. static CARD8
  273. stdReadEnable(vgaHWPtr hwp)
  274. {
  275. return pci_io_read8(hwp->io, VGA_ENABLE);
  276. }
  277. static void
  278. stdWriteEnable(vgaHWPtr hwp, CARD8 value)
  279. {
  280. pci_io_write8(hwp->io, VGA_ENABLE, value);
  281. }
  282. void
  283. vgaHWSetStdFuncs(vgaHWPtr hwp)
  284. {
  285. hwp->writeCrtc = stdWriteCrtc;
  286. hwp->readCrtc = stdReadCrtc;
  287. hwp->writeGr = stdWriteGr;
  288. hwp->readGr = stdReadGr;
  289. hwp->readST00 = stdReadST00;
  290. hwp->readST01 = stdReadST01;
  291. hwp->readFCR = stdReadFCR;
  292. hwp->writeFCR = stdWriteFCR;
  293. hwp->writeAttr = stdWriteAttr;
  294. hwp->readAttr = stdReadAttr;
  295. hwp->writeSeq = stdWriteSeq;
  296. hwp->readSeq = stdReadSeq;
  297. hwp->writeMiscOut = stdWriteMiscOut;
  298. hwp->readMiscOut = stdReadMiscOut;
  299. hwp->enablePalette = stdEnablePalette;
  300. hwp->disablePalette = stdDisablePalette;
  301. hwp->writeDacMask = stdWriteDacMask;
  302. hwp->readDacMask = stdReadDacMask;
  303. hwp->writeDacWriteAddr = stdWriteDacWriteAddr;
  304. hwp->writeDacReadAddr = stdWriteDacReadAddr;
  305. hwp->writeDacData = stdWriteDacData;
  306. hwp->readDacData = stdReadDacData;
  307. hwp->readEnable = stdReadEnable;
  308. hwp->writeEnable = stdWriteEnable;
  309. hwp->io = pci_legacy_open_io(hwp->dev, 0, 64 * 1024);
  310. }
  311. /*
  312. * MMIO versions of the register access functions. These require
  313. * hwp->MemBase to be set in such a way that when the standard VGA port
  314. * adderss is added the correct memory address results.
  315. */
  316. #define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
  317. #define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
  318. static void
  319. mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
  320. {
  321. moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
  322. moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
  323. }
  324. static CARD8
  325. mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
  326. {
  327. moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
  328. return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
  329. }
  330. static void
  331. mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
  332. {
  333. moutb(VGA_GRAPH_INDEX, index);
  334. moutb(VGA_GRAPH_DATA, value);
  335. }
  336. static CARD8
  337. mmioReadGr(vgaHWPtr hwp, CARD8 index)
  338. {
  339. moutb(VGA_GRAPH_INDEX, index);
  340. return minb(VGA_GRAPH_DATA);
  341. }
  342. static void
  343. mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
  344. {
  345. moutb(VGA_SEQ_INDEX, index);
  346. moutb(VGA_SEQ_DATA, value);
  347. }
  348. static CARD8
  349. mmioReadSeq(vgaHWPtr hwp, CARD8 index)
  350. {
  351. moutb(VGA_SEQ_INDEX, index);
  352. return minb(VGA_SEQ_DATA);
  353. }
  354. static CARD8
  355. mmioReadST00(vgaHWPtr hwp)
  356. {
  357. return minb(VGA_IN_STAT_0);
  358. }
  359. static CARD8
  360. mmioReadST01(vgaHWPtr hwp)
  361. {
  362. return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  363. }
  364. static CARD8
  365. mmioReadFCR(vgaHWPtr hwp)
  366. {
  367. return minb(VGA_FEATURE_R);
  368. }
  369. static void
  370. mmioWriteFCR(vgaHWPtr hwp, CARD8 value)
  371. {
  372. moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET, value);
  373. }
  374. static void
  375. mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
  376. {
  377. if (hwp->paletteEnabled)
  378. index &= ~0x20;
  379. else
  380. index |= 0x20;
  381. (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  382. moutb(VGA_ATTR_INDEX, index);
  383. moutb(VGA_ATTR_DATA_W, value);
  384. }
  385. static CARD8
  386. mmioReadAttr(vgaHWPtr hwp, CARD8 index)
  387. {
  388. if (hwp->paletteEnabled)
  389. index &= ~0x20;
  390. else
  391. index |= 0x20;
  392. (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  393. moutb(VGA_ATTR_INDEX, index);
  394. return minb(VGA_ATTR_DATA_R);
  395. }
  396. static void
  397. mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
  398. {
  399. moutb(VGA_MISC_OUT_W, value);
  400. }
  401. static CARD8
  402. mmioReadMiscOut(vgaHWPtr hwp)
  403. {
  404. return minb(VGA_MISC_OUT_R);
  405. }
  406. static void
  407. mmioEnablePalette(vgaHWPtr hwp)
  408. {
  409. (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  410. moutb(VGA_ATTR_INDEX, 0x00);
  411. hwp->paletteEnabled = TRUE;
  412. }
  413. static void
  414. mmioDisablePalette(vgaHWPtr hwp)
  415. {
  416. (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
  417. moutb(VGA_ATTR_INDEX, 0x20);
  418. hwp->paletteEnabled = FALSE;
  419. }
  420. static void
  421. mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
  422. {
  423. moutb(VGA_DAC_MASK, value);
  424. }
  425. static CARD8
  426. mmioReadDacMask(vgaHWPtr hwp)
  427. {
  428. return minb(VGA_DAC_MASK);
  429. }
  430. static void
  431. mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
  432. {
  433. moutb(VGA_DAC_READ_ADDR, value);
  434. }
  435. static void
  436. mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
  437. {
  438. moutb(VGA_DAC_WRITE_ADDR, value);
  439. }
  440. static void
  441. mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
  442. {
  443. moutb(VGA_DAC_DATA, value);
  444. }
  445. static CARD8
  446. mmioReadDacData(vgaHWPtr hwp)
  447. {
  448. return minb(VGA_DAC_DATA);
  449. }
  450. static CARD8
  451. mmioReadEnable(vgaHWPtr hwp)
  452. {
  453. return minb(VGA_ENABLE);
  454. }
  455. static void
  456. mmioWriteEnable(vgaHWPtr hwp, CARD8 value)
  457. {
  458. moutb(VGA_ENABLE, value);
  459. }
  460. void
  461. vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
  462. {
  463. hwp->writeCrtc = mmioWriteCrtc;
  464. hwp->readCrtc = mmioReadCrtc;
  465. hwp->writeGr = mmioWriteGr;
  466. hwp->readGr = mmioReadGr;
  467. hwp->readST00 = mmioReadST00;
  468. hwp->readST01 = mmioReadST01;
  469. hwp->readFCR = mmioReadFCR;
  470. hwp->writeFCR = mmioWriteFCR;
  471. hwp->writeAttr = mmioWriteAttr;
  472. hwp->readAttr = mmioReadAttr;
  473. hwp->writeSeq = mmioWriteSeq;
  474. hwp->readSeq = mmioReadSeq;
  475. hwp->writeMiscOut = mmioWriteMiscOut;
  476. hwp->readMiscOut = mmioReadMiscOut;
  477. hwp->enablePalette = mmioEnablePalette;
  478. hwp->disablePalette = mmioDisablePalette;
  479. hwp->writeDacMask = mmioWriteDacMask;
  480. hwp->readDacMask = mmioReadDacMask;
  481. hwp->writeDacWriteAddr = mmioWriteDacWriteAddr;
  482. hwp->writeDacReadAddr = mmioWriteDacReadAddr;
  483. hwp->writeDacData = mmioWriteDacData;
  484. hwp->readDacData = mmioReadDacData;
  485. hwp->MMIOBase = base;
  486. hwp->MMIOOffset = offset;
  487. hwp->readEnable = mmioReadEnable;
  488. hwp->writeEnable = mmioWriteEnable;
  489. }
  490. /*
  491. * vgaHWProtect --
  492. * Protect VGA registers and memory from corruption during loads.
  493. */
  494. void
  495. vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
  496. {
  497. vgaHWPtr hwp = VGAHWPTR(pScrn);
  498. unsigned char tmp;
  499. if (pScrn->vtSema) {
  500. if (on) {
  501. /*
  502. * Turn off screen and disable sequencer.
  503. */
  504. tmp = hwp->readSeq(hwp, 0x01);
  505. vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
  506. hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
  507. hwp->enablePalette(hwp);
  508. }
  509. else {
  510. /*
  511. * Reenable sequencer, then turn on screen.
  512. */
  513. tmp = hwp->readSeq(hwp, 0x01);
  514. hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
  515. vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
  516. hwp->disablePalette(hwp);
  517. }
  518. }
  519. }
  520. vgaHWProtectProc *
  521. vgaHWProtectWeak(void)
  522. {
  523. return vgaHWProtect;
  524. }
  525. /*
  526. * vgaHWBlankScreen -- blank the screen.
  527. */
  528. void
  529. vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
  530. {
  531. vgaHWPtr hwp = VGAHWPTR(pScrn);
  532. unsigned char scrn;
  533. scrn = hwp->readSeq(hwp, 0x01);
  534. if (on) {
  535. scrn &= ~0x20; /* enable screen */
  536. }
  537. else {
  538. scrn |= 0x20; /* blank screen */
  539. }
  540. vgaHWSeqReset(hwp, TRUE);
  541. hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
  542. vgaHWSeqReset(hwp, FALSE);
  543. }
  544. vgaHWBlankScreenProc *
  545. vgaHWBlankScreenWeak(void)
  546. {
  547. return vgaHWBlankScreen;
  548. }
  549. /*
  550. * vgaHWSaveScreen -- blank the screen.
  551. */
  552. Bool
  553. vgaHWSaveScreen(ScreenPtr pScreen, int mode)
  554. {
  555. ScrnInfoPtr pScrn = NULL;
  556. Bool on;
  557. if (pScreen != NULL)
  558. pScrn = xf86ScreenToScrn(pScreen);
  559. on = xf86IsUnblank(mode);
  560. #if 0
  561. if (on)
  562. SetTimeSinceLastInputEvent();
  563. #endif
  564. if ((pScrn != NULL) && pScrn->vtSema) {
  565. vgaHWBlankScreen(pScrn, on);
  566. }
  567. return TRUE;
  568. }
  569. /*
  570. * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
  571. *
  572. * This generic VGA function can only set the Off and On modes. If the
  573. * Standby and Suspend modes are to be supported, a chip specific replacement
  574. * for this function must be written.
  575. */
  576. void
  577. vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
  578. {
  579. unsigned char seq1 = 0, crtc17 = 0;
  580. vgaHWPtr hwp = VGAHWPTR(pScrn);
  581. if (!pScrn->vtSema)
  582. return;
  583. switch (PowerManagementMode) {
  584. case DPMSModeOn:
  585. /* Screen: On; HSync: On, VSync: On */
  586. seq1 = 0x00;
  587. crtc17 = 0x80;
  588. break;
  589. case DPMSModeStandby:
  590. /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
  591. seq1 = 0x20;
  592. crtc17 = 0x80;
  593. break;
  594. case DPMSModeSuspend:
  595. /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
  596. seq1 = 0x20;
  597. crtc17 = 0x80;
  598. break;
  599. case DPMSModeOff:
  600. /* Screen: Off; HSync: Off, VSync: Off */
  601. seq1 = 0x20;
  602. crtc17 = 0x00;
  603. break;
  604. }
  605. hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
  606. seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20;
  607. hwp->writeSeq(hwp, 0x01, seq1);
  608. crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80;
  609. usleep(10000);
  610. hwp->writeCrtc(hwp, 0x17, crtc17);
  611. hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
  612. }
  613. /*
  614. * vgaHWSeqReset
  615. * perform a sequencer reset.
  616. */
  617. void
  618. vgaHWSeqReset(vgaHWPtr hwp, Bool start)
  619. {
  620. if (start)
  621. hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
  622. else
  623. hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
  624. }
  625. void
  626. vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
  627. {
  628. #if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
  629. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  630. int savedIOBase;
  631. unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
  632. Bool doMap = FALSE;
  633. /* If nothing to do, return now */
  634. if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
  635. return;
  636. if (hwp->Base == NULL) {
  637. doMap = TRUE;
  638. if (!vgaHWMapMem(scrninfp)) {
  639. xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
  640. "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
  641. return;
  642. }
  643. }
  644. /* save the registers that are needed here */
  645. miscOut = hwp->readMiscOut(hwp);
  646. attr10 = hwp->readAttr(hwp, 0x10);
  647. gr1 = hwp->readGr(hwp, 0x01);
  648. gr3 = hwp->readGr(hwp, 0x03);
  649. gr4 = hwp->readGr(hwp, 0x04);
  650. gr5 = hwp->readGr(hwp, 0x05);
  651. gr6 = hwp->readGr(hwp, 0x06);
  652. gr8 = hwp->readGr(hwp, 0x08);
  653. seq2 = hwp->readSeq(hwp, 0x02);
  654. seq4 = hwp->readSeq(hwp, 0x04);
  655. /* save hwp->IOBase and temporarily set it for colour mode */
  656. savedIOBase = hwp->IOBase;
  657. hwp->IOBase = VGA_IOBASE_COLOR;
  658. /* Force into colour mode */
  659. hwp->writeMiscOut(hwp, miscOut | 0x01);
  660. vgaHWBlankScreen(scrninfp, FALSE);
  661. /*
  662. * here we temporarily switch to 16 colour planar mode, to simply
  663. * copy the font-info and saved text.
  664. *
  665. * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
  666. */
  667. #if 0
  668. hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
  669. #endif
  670. hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
  671. hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
  672. hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
  673. if (scrninfp->depth == 4) {
  674. /* GJA */
  675. hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */
  676. hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */
  677. hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */
  678. }
  679. #if SAVE_FONT1
  680. if (hwp->FontInfo1) {
  681. hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
  682. hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
  683. slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
  684. }
  685. #endif
  686. #if SAVE_FONT2
  687. if (hwp->FontInfo2) {
  688. hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
  689. hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
  690. slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
  691. }
  692. #endif
  693. #if SAVE_TEXT
  694. if (hwp->TextInfo) {
  695. hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
  696. hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
  697. slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
  698. hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
  699. hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
  700. slowbcopy_tobus((unsigned char *) hwp->TextInfo + TEXT_AMOUNT,
  701. hwp->Base, TEXT_AMOUNT);
  702. }
  703. #endif
  704. vgaHWBlankScreen(scrninfp, TRUE);
  705. /* restore the registers that were changed */
  706. hwp->writeMiscOut(hwp, miscOut);
  707. hwp->writeAttr(hwp, 0x10, attr10);
  708. hwp->writeGr(hwp, 0x01, gr1);
  709. hwp->writeGr(hwp, 0x03, gr3);
  710. hwp->writeGr(hwp, 0x04, gr4);
  711. hwp->writeGr(hwp, 0x05, gr5);
  712. hwp->writeGr(hwp, 0x06, gr6);
  713. hwp->writeGr(hwp, 0x08, gr8);
  714. hwp->writeSeq(hwp, 0x02, seq2);
  715. hwp->writeSeq(hwp, 0x04, seq4);
  716. hwp->IOBase = savedIOBase;
  717. if (doMap)
  718. vgaHWUnmapMem(scrninfp);
  719. #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
  720. }
  721. void
  722. vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
  723. {
  724. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  725. int i;
  726. if (restore->MiscOutReg & 0x01)
  727. hwp->IOBase = VGA_IOBASE_COLOR;
  728. else
  729. hwp->IOBase = VGA_IOBASE_MONO;
  730. hwp->writeMiscOut(hwp, restore->MiscOutReg);
  731. for (i = 1; i < restore->numSequencer; i++)
  732. hwp->writeSeq(hwp, i, restore->Sequencer[i]);
  733. /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
  734. hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
  735. for (i = 0; i < restore->numCRTC; i++)
  736. hwp->writeCrtc(hwp, i, restore->CRTC[i]);
  737. for (i = 0; i < restore->numGraphics; i++)
  738. hwp->writeGr(hwp, i, restore->Graphics[i]);
  739. hwp->enablePalette(hwp);
  740. for (i = 0; i < restore->numAttribute; i++)
  741. hwp->writeAttr(hwp, i, restore->Attribute[i]);
  742. hwp->disablePalette(hwp);
  743. }
  744. void
  745. vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
  746. {
  747. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  748. int i;
  749. #if 0
  750. hwp->enablePalette(hwp);
  751. #endif
  752. hwp->writeDacMask(hwp, 0xFF);
  753. hwp->writeDacWriteAddr(hwp, 0x00);
  754. for (i = 0; i < 768; i++) {
  755. hwp->writeDacData(hwp, restore->DAC[i]);
  756. DACDelay(hwp);
  757. }
  758. hwp->disablePalette(hwp);
  759. }
  760. /*
  761. * vgaHWRestore --
  762. * restore the VGA state
  763. */
  764. void
  765. vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
  766. {
  767. if (flags & VGA_SR_MODE)
  768. vgaHWRestoreMode(scrninfp, restore);
  769. if (flags & VGA_SR_FONTS)
  770. vgaHWRestoreFonts(scrninfp, restore);
  771. if (flags & VGA_SR_CMAP)
  772. vgaHWRestoreColormap(scrninfp, restore);
  773. }
  774. void
  775. vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
  776. {
  777. #if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
  778. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  779. int savedIOBase;
  780. unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
  781. Bool doMap = FALSE;
  782. if (hwp->Base == NULL) {
  783. doMap = TRUE;
  784. if (!vgaHWMapMem(scrninfp)) {
  785. xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
  786. "vgaHWSaveFonts: vgaHWMapMem() failed\n");
  787. return;
  788. }
  789. }
  790. /* If in graphics mode, don't save anything */
  791. attr10 = hwp->readAttr(hwp, 0x10);
  792. if (attr10 & 0x01)
  793. return;
  794. /* save the registers that are needed here */
  795. miscOut = hwp->readMiscOut(hwp);
  796. gr4 = hwp->readGr(hwp, 0x04);
  797. gr5 = hwp->readGr(hwp, 0x05);
  798. gr6 = hwp->readGr(hwp, 0x06);
  799. seq2 = hwp->readSeq(hwp, 0x02);
  800. seq4 = hwp->readSeq(hwp, 0x04);
  801. /* save hwp->IOBase and temporarily set it for colour mode */
  802. savedIOBase = hwp->IOBase;
  803. hwp->IOBase = VGA_IOBASE_COLOR;
  804. /* Force into colour mode */
  805. hwp->writeMiscOut(hwp, miscOut | 0x01);
  806. vgaHWBlankScreen(scrninfp, FALSE);
  807. /*
  808. * get the character sets, and text screen if required
  809. */
  810. /*
  811. * Here we temporarily switch to 16 colour planar mode, to simply
  812. * copy the font-info
  813. *
  814. * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
  815. */
  816. #if 0
  817. hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
  818. #endif
  819. hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
  820. hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
  821. hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
  822. #if SAVE_FONT1
  823. if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) {
  824. hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
  825. hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
  826. slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
  827. }
  828. #endif /* SAVE_FONT1 */
  829. #if SAVE_FONT2
  830. if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) {
  831. hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
  832. hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
  833. slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
  834. }
  835. #endif /* SAVE_FONT2 */
  836. #if SAVE_TEXT
  837. if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) {
  838. hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
  839. hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
  840. slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
  841. hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
  842. hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
  843. slowbcopy_frombus(hwp->Base,
  844. (unsigned char *) hwp->TextInfo + TEXT_AMOUNT,
  845. TEXT_AMOUNT);
  846. }
  847. #endif /* SAVE_TEXT */
  848. /* Restore clobbered registers */
  849. hwp->writeAttr(hwp, 0x10, attr10);
  850. hwp->writeSeq(hwp, 0x02, seq2);
  851. hwp->writeSeq(hwp, 0x04, seq4);
  852. hwp->writeGr(hwp, 0x04, gr4);
  853. hwp->writeGr(hwp, 0x05, gr5);
  854. hwp->writeGr(hwp, 0x06, gr6);
  855. hwp->writeMiscOut(hwp, miscOut);
  856. hwp->IOBase = savedIOBase;
  857. vgaHWBlankScreen(scrninfp, TRUE);
  858. if (doMap)
  859. vgaHWUnmapMem(scrninfp);
  860. #endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
  861. }
  862. void
  863. vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
  864. {
  865. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  866. int i;
  867. save->MiscOutReg = hwp->readMiscOut(hwp);
  868. if (save->MiscOutReg & 0x01)
  869. hwp->IOBase = VGA_IOBASE_COLOR;
  870. else
  871. hwp->IOBase = VGA_IOBASE_MONO;
  872. for (i = 0; i < save->numCRTC; i++) {
  873. save->CRTC[i] = hwp->readCrtc(hwp, i);
  874. DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
  875. }
  876. hwp->enablePalette(hwp);
  877. for (i = 0; i < save->numAttribute; i++) {
  878. save->Attribute[i] = hwp->readAttr(hwp, i);
  879. DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
  880. }
  881. hwp->disablePalette(hwp);
  882. for (i = 0; i < save->numGraphics; i++) {
  883. save->Graphics[i] = hwp->readGr(hwp, i);
  884. DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
  885. }
  886. for (i = 1; i < save->numSequencer; i++) {
  887. save->Sequencer[i] = hwp->readSeq(hwp, i);
  888. DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
  889. }
  890. }
  891. void
  892. vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
  893. {
  894. vgaHWPtr hwp = VGAHWPTR(scrninfp);
  895. Bool readError = FALSE;
  896. int i;
  897. #ifdef NEED_SAVED_CMAP
  898. /*
  899. * Some ET4000 chips from 1991 have a HW bug that prevents the reading
  900. * of the color lookup table. Mask rev 9042EAI is known to have this bug.
  901. *
  902. * If the colourmap is not readable, we set the saved map to a default
  903. * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
  904. * Cards" 2nd ed).
  905. */
  906. /* Only save it once */
  907. if (hwp->cmapSaved)
  908. return;
  909. #if 0
  910. hwp->enablePalette(hwp);
  911. #endif
  912. hwp->writeDacMask(hwp, 0xFF);
  913. /*
  914. * check if we can read the lookup table
  915. */
  916. hwp->writeDacReadAddr(hwp, 0x00);
  917. for (i = 0; i < 6; i++) {
  918. save->DAC[i] = hwp->readDacData(hwp);
  919. switch (i % 3) {
  920. case 0:
  921. DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
  922. break;
  923. case 1:
  924. DebugF("0x%02x, ", save->DAC[i]);
  925. break;
  926. case 2:
  927. DebugF("0x%02x\n", save->DAC[i]);
  928. }
  929. }
  930. /*
  931. * Check if we can read the palette -
  932. * use foreground color to prevent flashing.
  933. */
  934. hwp->writeDacWriteAddr(hwp, 0x01);
  935. for (i = 3; i < 6; i++)
  936. hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK);
  937. hwp->writeDacReadAddr(hwp, 0x01);
  938. for (i = 3; i < 6; i++) {
  939. if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK))
  940. readError = TRUE;
  941. }
  942. hwp->writeDacWriteAddr(hwp, 0x01);
  943. for (i = 3; i < 6; i++)
  944. hwp->writeDacData(hwp, save->DAC[i]);
  945. if (readError) {
  946. /*
  947. * save the default lookup table
  948. */
  949. memmove(save->DAC, defaultDAC, 768);
  950. xf86DrvMsg(scrninfp->scrnIndex, X_WARNING,
  951. "Cannot read colourmap from VGA. Will restore with default\n");
  952. }
  953. else {
  954. /* save the colourmap */
  955. hwp->writeDacReadAddr(hwp, 0x02);
  956. for (i = 6; i < 768; i++) {
  957. save->DAC[i] = hwp->readDacData(hwp);
  958. DACDelay(hwp);
  959. switch (i % 3) {
  960. case 0:
  961. DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
  962. break;
  963. case 1:
  964. DebugF("0x%02x, ", save->DAC[i]);
  965. break;
  966. case 2:
  967. DebugF("0x%02x\n", save->DAC[i]);
  968. }
  969. }
  970. }
  971. hwp->disablePalette(hwp);
  972. hwp->cmapSaved = TRUE;
  973. #endif
  974. }
  975. /*
  976. * vgaHWSave --
  977. * save the current VGA state
  978. */
  979. void
  980. vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
  981. {
  982. if (save == NULL)
  983. return;
  984. if (flags & VGA_SR_CMAP)
  985. vgaHWSaveColormap(scrninfp, save);
  986. if (flags & VGA_SR_MODE)
  987. vgaHWSaveMode(scrninfp, save);
  988. if (flags & VGA_SR_FONTS)
  989. vgaHWSaveFonts(scrninfp, save);
  990. }
  991. /*
  992. * vgaHWInit --
  993. * Handle the initialization, etc. of a screen.
  994. * Return FALSE on failure.
  995. */
  996. Bool
  997. vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
  998. {
  999. unsigned int i;
  1000. vgaHWPtr hwp;
  1001. vgaRegPtr regp;
  1002. int depth = scrninfp->depth;
  1003. /*
  1004. * make sure the vgaHWRec is allocated
  1005. */
  1006. if (!vgaHWGetHWRec(scrninfp))
  1007. return FALSE;
  1008. hwp = VGAHWPTR(scrninfp);
  1009. regp = &hwp->ModeReg;
  1010. /*
  1011. * compute correct Hsync & Vsync polarity
  1012. */
  1013. if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
  1014. && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
  1015. regp->MiscOutReg = 0x23;
  1016. if (mode->Flags & V_NHSYNC)
  1017. regp->MiscOutReg |= 0x40;
  1018. if (mode->Flags & V_NVSYNC)
  1019. regp->MiscOutReg |= 0x80;
  1020. }
  1021. else {
  1022. int VDisplay = mode->VDisplay;
  1023. if (mode->Flags & V_DBLSCAN)
  1024. VDisplay *= 2;
  1025. if (mode->VScan > 1)
  1026. VDisplay *= mode->VScan;
  1027. if (VDisplay < 400)
  1028. regp->MiscOutReg = 0xA3; /* +hsync -vsync */
  1029. else if (VDisplay < 480)
  1030. regp->MiscOutReg = 0x63; /* -hsync +vsync */
  1031. else if (VDisplay < 768)
  1032. regp->MiscOutReg = 0xE3; /* -hsync -vsync */
  1033. else
  1034. regp->MiscOutReg = 0x23; /* +hsync +vsync */
  1035. }
  1036. regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
  1037. /*
  1038. * Time Sequencer
  1039. */
  1040. if (depth == 4)
  1041. regp->Sequencer[0] = 0x02;
  1042. else
  1043. regp->Sequencer[0] = 0x00;
  1044. if (mode->Flags & V_CLKDIV2)
  1045. regp->Sequencer[1] = 0x09;
  1046. else
  1047. regp->Sequencer[1] = 0x01;
  1048. if (depth == 1)
  1049. regp->Sequencer[2] = 1 << BIT_PLANE;
  1050. else
  1051. regp->Sequencer[2] = 0x0F;
  1052. regp->Sequencer[3] = 0x00; /* Font select */
  1053. if (depth < 8)
  1054. regp->Sequencer[4] = 0x06; /* Misc */
  1055. else
  1056. regp->Sequencer[4] = 0x0E; /* Misc */
  1057. /*
  1058. * CRTC Controller
  1059. */
  1060. regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5;
  1061. regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1;
  1062. regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1;
  1063. regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
  1064. i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
  1065. if (i < 0x80)
  1066. regp->CRTC[3] |= i;
  1067. regp->CRTC[4] = (mode->CrtcHSyncStart >> 3);
  1068. regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
  1069. | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
  1070. regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF;
  1071. regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
  1072. | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
  1073. | ((mode->CrtcVSyncStart & 0x100) >> 6)
  1074. | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
  1075. | 0x10 | (((mode->CrtcVTotal - 2) & 0x200) >> 4)
  1076. | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
  1077. | ((mode->CrtcVSyncStart & 0x200) >> 2);
  1078. regp->CRTC[8] = 0x00;
  1079. regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
  1080. if (mode->Flags & V_DBLSCAN)
  1081. regp->CRTC[9] |= 0x80;
  1082. if (mode->VScan >= 32)
  1083. regp->CRTC[9] |= 0x1F;
  1084. else if (mode->VScan > 1)
  1085. regp->CRTC[9] |= mode->VScan - 1;
  1086. regp->CRTC[10] = 0x00;
  1087. regp->CRTC[11] = 0x00;
  1088. regp->CRTC[12] = 0x00;
  1089. regp->CRTC[13] = 0x00;
  1090. regp->CRTC[14] = 0x00;
  1091. regp->CRTC[15] = 0x00;
  1092. regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
  1093. regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
  1094. regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
  1095. regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */
  1096. regp->CRTC[20] = 0x00;
  1097. regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF;
  1098. regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
  1099. if (depth < 8)
  1100. regp->CRTC[23] = 0xE3;
  1101. else
  1102. regp->CRTC[23] = 0xC3;
  1103. regp->CRTC[24] = 0xFF;
  1104. vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
  1105. vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
  1106. /*
  1107. * Theory resumes here....
  1108. */
  1109. /*
  1110. * Graphics Display Controller
  1111. */
  1112. regp->Graphics[0] = 0x00;
  1113. regp->Graphics[1] = 0x00;
  1114. regp->Graphics[2] = 0x00;
  1115. regp->Graphics[3] = 0x00;
  1116. if (depth == 1) {
  1117. regp->Graphics[4] = BIT_PLANE;
  1118. regp->Graphics[5] = 0x00;
  1119. }
  1120. else {
  1121. regp->Graphics[4] = 0x00;
  1122. if (depth == 4)
  1123. regp->Graphics[5] = 0x02;
  1124. else
  1125. regp->Graphics[5] = 0x40;
  1126. }
  1127. regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
  1128. regp->Graphics[7] = 0x0F;
  1129. regp->Graphics[8] = 0xFF;
  1130. if (depth == 1) {
  1131. /* Initialise the Mono map according to which bit-plane gets used */
  1132. Bool flipPixels = xf86GetFlipPixels();
  1133. for (i = 0; i < 16; i++)
  1134. if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
  1135. regp->Attribute[i] = WHITE_VALUE;
  1136. else
  1137. regp->Attribute[i] = BLACK_VALUE;
  1138. regp->Attribute[16] = 0x01; /* -VGA2- *//* wrong for the ET4000 */
  1139. if (!hwp->ShowOverscan)
  1140. regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */
  1141. }
  1142. else {
  1143. regp->Attribute[0] = 0x00; /* standard colormap translation */
  1144. regp->Attribute[1] = 0x01;
  1145. regp->Attribute[2] = 0x02;
  1146. regp->Attribute[3] = 0x03;
  1147. regp->Attribute[4] = 0x04;
  1148. regp->Attribute[5] = 0x05;
  1149. regp->Attribute[6] = 0x06;
  1150. regp->Attribute[7] = 0x07;
  1151. regp->Attribute[8] = 0x08;
  1152. regp->Attribute[9] = 0x09;
  1153. regp->Attribute[10] = 0x0A;
  1154. regp->Attribute[11] = 0x0B;
  1155. regp->Attribute[12] = 0x0C;
  1156. regp->Attribute[13] = 0x0D;
  1157. regp->Attribute[14] = 0x0E;
  1158. regp->Attribute[15] = 0x0F;
  1159. if (depth == 4)
  1160. regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
  1161. else
  1162. regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
  1163. /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
  1164. }
  1165. regp->Attribute[18] = 0x0F;
  1166. regp->Attribute[19] = 0x00;
  1167. regp->Attribute[20] = 0x00;
  1168. return TRUE;
  1169. }
  1170. /*
  1171. * OK, so much for theory. Now, let's deal with the >real< world...
  1172. *
  1173. * The above CRTC settings are precise in theory, except that many, if not
  1174. * most, VGA clones fail to reset the blanking signal when the character or
  1175. * line counter reaches [HV]Total. In this case, the signal is only
  1176. * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
  1177. * the case may be) at the start of the >next< scanline or frame, which
  1178. * means only part of the screen shows. This affects how null overscans
  1179. * are to be implemented on such adapters.
  1180. *
  1181. * Henceforth, VGA cores that implement this broken, but unfortunately
  1182. * common, behaviour are to be designated as KGA's, in honour of Koen
  1183. * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
  1184. * a series of events that led to the discovery of this problem.
  1185. *
  1186. * Some VGA's are KGA's only in the horizontal, or only in the vertical,
  1187. * some in both, others in neither. Don't let anyone tell you there is
  1188. * such a thing as a VGA "standard"... And, thank the Creator for the fact
  1189. * that Hilbert spaces are not yet implemented in this industry.
  1190. *
  1191. * The following implements a trick suggested by David Dawes. This sets
  1192. * [HV]BlankEnd to zero if the blanking interval does not already contain a
  1193. * 0-point, and decrements it by one otherwise. In the latter case, this
  1194. * will produce a left and/or top overscan which the colourmap code will
  1195. * (still) need to ensure is as close to black as possible. This will make
  1196. * the behaviour consistent across all chipsets, while allowing all
  1197. * chipsets to display the entire screen. Non-KGA drivers can ignore the
  1198. * following in their own copy of this code.
  1199. *
  1200. * -- TSI @ UQV, 1998.08.21
  1201. */
  1202. CARD32
  1203. vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
  1204. unsigned int Flags)
  1205. {
  1206. int nExtBits = (nBits < 6) ? 0 : nBits - 6;
  1207. CARD32 ExtBits;
  1208. CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
  1209. regp->CRTC[3] = (regp->CRTC[3] & ~0x1F)
  1210. | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
  1211. regp->CRTC[5] = (regp->CRTC[5] & ~0x80)
  1212. | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2);
  1213. ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask;
  1214. /* First the horizontal case */
  1215. if ((Flags & KGA_FIX_OVERSCAN)
  1216. && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3))) {
  1217. int i = (regp->CRTC[3] & 0x1F)
  1218. | ((regp->CRTC[5] & 0x80) >> 2)
  1219. | ExtBits;
  1220. if (Flags & KGA_ENABLE_ON_ZERO) {
  1221. if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1)
  1222. & (0x3F | ExtBitMask)))
  1223. && (mode->CrtcHBlankEnd == mode->CrtcHTotal))
  1224. i = 0;
  1225. }
  1226. else if (Flags & KGA_BE_TOT_DEC)
  1227. i--;
  1228. regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F);
  1229. regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80);
  1230. ExtBits = i & ExtBitMask;
  1231. }
  1232. return ExtBits >> 6;
  1233. }
  1234. /*
  1235. * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of
  1236. * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the
  1237. * very first scanline in a double- or multi-scanned mode. This last case
  1238. * needs further investigation.
  1239. */
  1240. CARD32
  1241. vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
  1242. unsigned int Flags)
  1243. {
  1244. CARD32 ExtBits;
  1245. CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8);
  1246. CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8;
  1247. /* If width is not known nBits should be 0. In this
  1248. * case BitMask is set to 0 so we can check for it. */
  1249. CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1);
  1250. int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF;
  1251. regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
  1252. ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask;
  1253. if ((Flags & KGA_FIX_OVERSCAN)
  1254. && (mode->CrtcVBlankEnd == mode->CrtcVTotal))
  1255. /* Null top overscan */
  1256. {
  1257. int i = regp->CRTC[22] | ExtBits;
  1258. if (Flags & KGA_ENABLE_ON_ZERO) {
  1259. if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
  1260. || ((i > VBlankStart) && /* 8-bit case */
  1261. ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
  1262. !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */
  1263. i = 0;
  1264. else
  1265. i = (i - 1);
  1266. }
  1267. else if (Flags & KGA_BE_TOT_DEC)
  1268. i = (i - 1);
  1269. regp->CRTC[22] = i & 0xFF;
  1270. ExtBits = i & 0xFF00;
  1271. }
  1272. return ExtBits >> 8;
  1273. }
  1274. /*
  1275. * these are some more hardware specific helpers, formerly in vga.c
  1276. */
  1277. static void
  1278. vgaHWGetHWRecPrivate(void)
  1279. {
  1280. if (vgaHWPrivateIndex < 0)
  1281. vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
  1282. return;
  1283. }
  1284. static void
  1285. vgaHWFreeRegs(vgaRegPtr regp)
  1286. {
  1287. free(regp->CRTC);
  1288. regp->CRTC = regp->Sequencer = regp->Graphics = regp->Attribute = NULL;
  1289. regp->numCRTC =
  1290. regp->numSequencer = regp->numGraphics = regp->numAttribute = 0;
  1291. }
  1292. static Bool
  1293. vgaHWAllocRegs(vgaRegPtr regp)
  1294. {
  1295. unsigned char *buf;
  1296. if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
  1297. regp->numAttribute) == 0)
  1298. return FALSE;
  1299. buf = calloc(regp->numCRTC +
  1300. regp->numSequencer +
  1301. regp->numGraphics + regp->numAttribute, 1);
  1302. if (!buf)
  1303. return FALSE;
  1304. regp->CRTC = buf;
  1305. regp->Sequencer = regp->CRTC + regp->numCRTC;
  1306. regp->Graphics = regp->Sequencer + regp->numSequencer;
  1307. regp->Attribute = regp->Graphics + regp->numGraphics;
  1308. return TRUE;
  1309. }
  1310. Bool
  1311. vgaHWAllocDefaultRegs(vgaRegPtr regp)
  1312. {
  1313. regp->numCRTC = VGA_NUM_CRTC;
  1314. regp->numSequencer = VGA_NUM_SEQ;
  1315. regp->numGraphics = VGA_NUM_GFX;
  1316. regp->numAttribute = VGA_NUM_ATTR;
  1317. return vgaHWAllocRegs(regp);
  1318. }
  1319. Bool
  1320. vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
  1321. int numGraphics, int numAttribute)
  1322. {
  1323. #define VGAHWMINNUM(regtype) \
  1324. ((newMode.num##regtype < regp->num##regtype) ? \
  1325. (newMode.num##regtype) : (regp->num##regtype))
  1326. #define VGAHWCOPYREGSET(regtype) \
  1327. memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
  1328. vgaRegRec newMode, newSaved;
  1329. vgaRegPtr regp;
  1330. regp = &VGAHWPTR(scrp)->ModeReg;
  1331. memcpy(&newMode, regp, sizeof(vgaRegRec));
  1332. /* allocate space for new registers */
  1333. regp = &newMode;
  1334. regp->numCRTC = numCRTC;
  1335. regp->numSequencer = numSequencer;
  1336. regp->numGraphics = numGraphics;
  1337. regp->numAttribute = numAttribute;
  1338. if (!vgaHWAllocRegs(regp))
  1339. return FALSE;
  1340. regp = &VGAHWPTR(scrp)->SavedReg;
  1341. memcpy(&newSaved, regp, sizeof(vgaRegRec));
  1342. regp = &newSaved;
  1343. regp->numCRTC = numCRTC;
  1344. regp->numSequencer = numSequencer;
  1345. regp->numGraphics = numGraphics;
  1346. regp->numAttribute = numAttribute;
  1347. if (!vgaHWAllocRegs(regp)) {
  1348. vgaHWFreeRegs(&newMode);
  1349. return FALSE;
  1350. }
  1351. /* allocations succeeded, copy register data into new space */
  1352. regp = &VGAHWPTR(scrp)->ModeReg;
  1353. VGAHWCOPYREGSET(CRTC);
  1354. VGAHWCOPYREGSET(Sequencer);
  1355. VGAHWCOPYREGSET(Graphics);
  1356. VGAHWCOPYREGSET(Attribute);
  1357. regp = &VGAHWPTR(scrp)->SavedReg;
  1358. VGAHWCOPYREGSET(CRTC);
  1359. VGAHWCOPYREGSET(Sequencer);
  1360. VGAHWCOPYREGSET(Graphics);
  1361. VGAHWCOPYREGSET(Attribute);
  1362. /* free old register arrays */
  1363. regp = &VGAHWPTR(scrp)->ModeReg;
  1364. vgaHWFreeRegs(regp);
  1365. memcpy(regp, &newMode, sizeof(vgaRegRec));
  1366. regp = &VGAHWPTR(scrp)->SavedReg;
  1367. vgaHWFreeRegs(regp);
  1368. memcpy(regp, &newSaved, sizeof(vgaRegRec));
  1369. return TRUE;
  1370. #undef VGAHWMINNUM
  1371. #undef VGAHWCOPYREGSET
  1372. }
  1373. Bool
  1374. vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
  1375. {
  1376. vgaHWFreeRegs(dst);
  1377. memcpy(dst, src, sizeof(vgaRegRec));
  1378. if (!vgaHWAllocRegs(dst))
  1379. return FALSE;
  1380. memcpy(dst->CRTC, src->CRTC, src->numCRTC);
  1381. memcpy(dst->Sequencer, src->Sequencer, src->numSequencer);
  1382. memcpy(dst->Graphics, src->Graphics, src->numGraphics);
  1383. memcpy(dst->Attribute, src->Attribute, src->numAttribute);
  1384. return TRUE;
  1385. }
  1386. Bool
  1387. vgaHWGetHWRec(ScrnInfoPtr scrp)
  1388. {
  1389. vgaRegPtr regp;
  1390. vgaHWPtr hwp;
  1391. int i;
  1392. /*
  1393. * Let's make sure that the private exists and allocate one.
  1394. */
  1395. vgaHWGetHWRecPrivate();
  1396. /*
  1397. * New privates are always set to NULL, so we can check if the allocation
  1398. * has already been done.
  1399. */
  1400. if (VGAHWPTR(scrp))
  1401. return TRUE;
  1402. hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
  1403. regp = &VGAHWPTR(scrp)->ModeReg;
  1404. if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
  1405. (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
  1406. free(hwp);
  1407. return FALSE;
  1408. }
  1409. if (scrp->bitsPerPixel == 1) {
  1410. rgb blackColour = scrp->display->blackColour,
  1411. whiteColour = scrp->display->whiteColour;
  1412. if (blackColour.red > 0x3F)
  1413. blackColour.red = 0x3F;
  1414. if (blackColour.green > 0x3F)
  1415. blackColour.green = 0x3F;
  1416. if (blackColour.blue > 0x3F)
  1417. blackColour.blue = 0x3F;
  1418. if (whiteColour.red > 0x3F)
  1419. whiteColour.red = 0x3F;
  1420. if (whiteColour.green > 0x3F)
  1421. whiteColour.green = 0x3F;
  1422. if (whiteColour.blue > 0x3F)
  1423. whiteColour.blue = 0x3F;
  1424. if ((blackColour.red == whiteColour.red) &&
  1425. (blackColour.green == whiteColour.green) &&
  1426. (blackColour.blue == whiteColour.blue)) {
  1427. blackColour.red ^= 0x3F;
  1428. blackColour.green ^= 0x3F;
  1429. blackColour.blue ^= 0x3F;
  1430. }
  1431. /*
  1432. * initialize default colormap for monochrome
  1433. */
  1434. for (i = 0; i < 3; i++)
  1435. regp->DAC[i] = 0x00;
  1436. for (i = 3; i < 768; i++)
  1437. regp->DAC[i] = 0x3F;
  1438. i = BLACK_VALUE * 3;
  1439. regp->DAC[i++] = blackColour.red;
  1440. regp->DAC[i++] = blackColour.green;
  1441. regp->DAC[i] = blackColour.blue;
  1442. i = WHITE_VALUE * 3;
  1443. regp->DAC[i++] = whiteColour.red;
  1444. regp->DAC[i++] = whiteColour.green;
  1445. regp->DAC[i] = whiteColour.blue;
  1446. i = OVERSCAN_VALUE * 3;
  1447. regp->DAC[i++] = 0x00;
  1448. regp->DAC[i++] = 0x00;
  1449. regp->DAC[i] = 0x00;
  1450. }
  1451. else {
  1452. /* Set all colours to black */
  1453. for (i = 0; i < 768; i++)
  1454. regp->DAC[i] = 0x00;
  1455. /* ... and the overscan */
  1456. if (scrp->depth >= 4)
  1457. regp->Attribute[OVERSCAN] = 0xFF;
  1458. }
  1459. if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) {
  1460. xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan");
  1461. xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n");
  1462. regp->DAC[765] = 0x3F;
  1463. regp->DAC[766] = 0x00;
  1464. regp->DAC[767] = 0x3F;
  1465. regp->Attribute[OVERSCAN] = 0xFF;
  1466. hwp->ShowOverscan = TRUE;
  1467. }
  1468. else
  1469. hwp->ShowOverscan = FALSE;
  1470. hwp->paletteEnabled = FALSE;
  1471. hwp->cmapSaved = FALSE;
  1472. hwp->MapSize = 0;
  1473. hwp->pScrn = scrp;
  1474. hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]);
  1475. return TRUE;
  1476. }
  1477. void
  1478. vgaHWFreeHWRec(ScrnInfoPtr scrp)
  1479. {
  1480. if (vgaHWPrivateIndex >= 0) {
  1481. vgaHWPtr hwp = VGAHWPTR(scrp);
  1482. if (!hwp)
  1483. return;
  1484. pci_device_close_io(hwp->dev, hwp->io);
  1485. free(hwp->FontInfo1);
  1486. free(hwp->FontInfo2);
  1487. free(hwp->TextInfo);
  1488. vgaHWFreeRegs(&hwp->ModeReg);
  1489. vgaHWFreeRegs(&hwp->SavedReg);
  1490. free(hwp);
  1491. VGAHWPTRLVAL(scrp) = NULL;
  1492. }
  1493. }
  1494. Bool
  1495. vgaHWMapMem(ScrnInfoPtr scrp)
  1496. {
  1497. vgaHWPtr hwp = VGAHWPTR(scrp);
  1498. if (hwp->Base)
  1499. return TRUE;
  1500. /* If not set, initialise with the defaults */
  1501. if (hwp->MapSize == 0)
  1502. hwp->MapSize = VGA_DEFAULT_MEM_SIZE;
  1503. if (hwp->MapPhys == 0)
  1504. hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR;
  1505. /*
  1506. * Map as VIDMEM_MMIO_32BIT because WC
  1507. * is bad when there is page flipping.
  1508. * XXX This is not correct but we do it
  1509. * for now.
  1510. */
  1511. DebugF("Mapping VGAMem\n");
  1512. pci_device_map_legacy(hwp->dev, hwp->MapPhys, hwp->MapSize,
  1513. PCI_DEV_MAP_FLAG_WRITABLE, &hwp->Base);
  1514. return hwp->Base != NULL;
  1515. }
  1516. void
  1517. vgaHWUnmapMem(ScrnInfoPtr scrp)
  1518. {
  1519. vgaHWPtr hwp = VGAHWPTR(scrp);
  1520. if (hwp->Base == NULL)
  1521. return;
  1522. DebugF("Unmapping VGAMem\n");
  1523. pci_device_unmap_legacy(hwp->dev, hwp->Base, hwp->MapSize);
  1524. hwp->Base = NULL;
  1525. }
  1526. int
  1527. vgaHWGetIndex(void)
  1528. {
  1529. return vgaHWPrivateIndex;
  1530. }
  1531. void
  1532. vgaHWGetIOBase(vgaHWPtr hwp)
  1533. {
  1534. hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ?
  1535. VGA_IOBASE_COLOR : VGA_IOBASE_MONO;
  1536. xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3,
  1537. "vgaHWGetIOBase: hwp->IOBase is 0x%04x\n", hwp->IOBase);
  1538. }
  1539. void
  1540. vgaHWLock(vgaHWPtr hwp)
  1541. {
  1542. /* Protect CRTC[0-7] */
  1543. hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
  1544. }
  1545. void
  1546. vgaHWUnlock(vgaHWPtr hwp)
  1547. {
  1548. /* Unprotect CRTC[0-7] */
  1549. hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
  1550. }
  1551. void
  1552. vgaHWEnable(vgaHWPtr hwp)
  1553. {
  1554. hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01);
  1555. }
  1556. void
  1557. vgaHWDisable(vgaHWPtr hwp)
  1558. {
  1559. hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01);
  1560. }
  1561. static void
  1562. vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO * colors,
  1563. VisualPtr pVisual)
  1564. {
  1565. vgaHWPtr hwp = VGAHWPTR(pScrn);
  1566. int i, index;
  1567. for (i = 0; i < numColors; i++) {
  1568. index = indices[i];
  1569. hwp->writeDacWriteAddr(hwp, index);
  1570. DACDelay(hwp);
  1571. hwp->writeDacData(hwp, colors[index].red);
  1572. DACDelay(hwp);
  1573. hwp->writeDacData(hwp, colors[index].green);
  1574. DACDelay(hwp);
  1575. hwp->writeDacData(hwp, colors[index].blue);
  1576. DACDelay(hwp);
  1577. }
  1578. /* This shouldn't be necessary, but we'll play safe. */
  1579. hwp->disablePalette(hwp);
  1580. }
  1581. static void
  1582. vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
  1583. {
  1584. vgaHWPtr hwp = VGAHWPTR(pScrn);
  1585. if (overscan < 0 || overscan > 255)
  1586. return;
  1587. hwp->enablePalette(hwp);
  1588. hwp->writeAttr(hwp, OVERSCAN, overscan);
  1589. #ifdef DEBUGOVERSCAN
  1590. {
  1591. int ov = hwp->readAttr(hwp, OVERSCAN);
  1592. int red, green, blue;
  1593. hwp->writeDacReadAddr(hwp, ov);
  1594. red = hwp->readDacData(hwp);
  1595. green = hwp->readDacData(hwp);
  1596. blue = hwp->readDacData(hwp);
  1597. ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
  1598. ov, red, green, blue);
  1599. }
  1600. #endif
  1601. hwp->disablePalette(hwp);
  1602. }
  1603. Bool
  1604. vgaHWHandleColormaps(ScreenPtr pScreen)
  1605. {
  1606. ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
  1607. if (pScrn->depth > 1 && pScrn->depth <= 8) {
  1608. return xf86HandleColormaps(pScreen, 1 << pScrn->depth,
  1609. pScrn->rgbBits, vgaHWLoadPalette,
  1610. pScrn->depth > 4 ? vgaHWSetOverscan : NULL,
  1611. CMAP_RELOAD_ON_MODE_SWITCH);
  1612. }
  1613. return TRUE;
  1614. }
  1615. /* ----------------------- DDC support ------------------------*/
  1616. /*
  1617. * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
  1618. * to read out EDID at a faster rate. Allowed maximum is 25kHz with
  1619. * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
  1620. * readback, enable access to cr00-cr07.
  1621. */
  1622. /* vertical timings */
  1623. #define DISPLAY_END 0x04
  1624. #define BLANK_START DISPLAY_END
  1625. #define SYNC_START BLANK_START
  1626. #define SYNC_END 0x09
  1627. #define BLANK_END SYNC_END
  1628. #define V_TOTAL BLANK_END
  1629. /* this function doesn't have to be reentrant for our purposes */
  1630. struct _vgaDdcSave {
  1631. unsigned char cr03;
  1632. unsigned char cr06;
  1633. unsigned char cr07;
  1634. unsigned char cr09;
  1635. unsigned char cr10;
  1636. unsigned char cr11;
  1637. unsigned char cr12;
  1638. unsigned char cr15;
  1639. unsigned char cr16;
  1640. unsigned char msr;
  1641. };
  1642. void
  1643. vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
  1644. {
  1645. vgaHWPtr hwp = VGAHWPTR(pScrn);
  1646. unsigned char tmp;
  1647. struct _vgaDdcSave *save;
  1648. switch (speed) {
  1649. case DDC_FAST:
  1650. if (hwp->ddc != NULL)
  1651. break;
  1652. hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave), 1);
  1653. save = (struct _vgaDdcSave *) hwp->ddc;
  1654. /* Lightpen register disable - allow access to cr10 & 11; just in case */
  1655. save->cr03 = hwp->readCrtc(hwp, 0x03);
  1656. hwp->writeCrtc(hwp, 0x03, (save->cr03 | 0x80));
  1657. save->cr12 = hwp->readCrtc(hwp, 0x12);
  1658. hwp->writeCrtc(hwp, 0x12, DISPLAY_END);
  1659. save->cr15 = hwp->readCrtc(hwp, 0x15);
  1660. hwp->writeCrtc(hwp, 0x15, BLANK_START);
  1661. save->cr10 = hwp->readCrtc(hwp, 0x10);
  1662. hwp->writeCrtc(hwp, 0x10, SYNC_START);
  1663. save->cr11 = hwp->readCrtc(hwp, 0x11);
  1664. /* unprotect group 1 registers; just in case ... */
  1665. hwp->writeCrtc(hwp, 0x11, ((save->cr11 & 0x70) | SYNC_END));
  1666. save->cr16 = hwp->readCrtc(hwp, 0x16);
  1667. hwp->writeCrtc(hwp, 0x16, BLANK_END);
  1668. save->cr06 = hwp->readCrtc(hwp, 0x06);
  1669. hwp->writeCrtc(hwp, 0x06, V_TOTAL);
  1670. /* all values have less than 8 bit - mask out 9th and 10th bits */
  1671. save->cr09 = hwp->readCrtc(hwp, 0x09);
  1672. hwp->writeCrtc(hwp, 0x09, (save->cr09 & 0xDF));
  1673. save->cr07 = hwp->readCrtc(hwp, 0x07);
  1674. hwp->writeCrtc(hwp, 0x07, (save->cr07 & 0x10));
  1675. /* vsync polarity negativ & ensure a 25MHz clock */
  1676. save->msr = hwp->readMiscOut(hwp);
  1677. hwp->writeMiscOut(hwp, ((save->msr & 0xF3) | 0x80));
  1678. break;
  1679. case DDC_SLOW:
  1680. if (hwp->ddc == NULL)
  1681. break;
  1682. save = (struct _vgaDdcSave *) hwp->ddc;
  1683. hwp->writeMiscOut(hwp, save->msr);
  1684. hwp->writeCrtc(hwp, 0x07, save->cr07);
  1685. tmp = hwp->readCrtc(hwp, 0x09);
  1686. hwp->writeCrtc(hwp, 0x09, ((save->cr09 & 0x20) | (tmp & 0xDF)));
  1687. hwp->writeCrtc(hwp, 0x06, save->cr06);
  1688. hwp->writeCrtc(hwp, 0x16, save->cr16);
  1689. hwp->writeCrtc(hwp, 0x11, save->cr11);
  1690. hwp->writeCrtc(hwp, 0x10, save->cr10);
  1691. hwp->writeCrtc(hwp, 0x15, save->cr15);
  1692. hwp->writeCrtc(hwp, 0x12, save->cr12);
  1693. hwp->writeCrtc(hwp, 0x03, save->cr03);
  1694. free(save);
  1695. hwp->ddc = NULL;
  1696. break;
  1697. default:
  1698. break;
  1699. }
  1700. }
  1701. DDC1SetSpeedProc
  1702. vgaHWddc1SetSpeedWeak(void)
  1703. {
  1704. return vgaHWddc1SetSpeed;
  1705. }
  1706. SaveScreenProcPtr
  1707. vgaHWSaveScreenWeak(void)
  1708. {
  1709. return vgaHWSaveScreen;
  1710. }
  1711. /*
  1712. * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
  1713. */
  1714. void
  1715. xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc) (ScrnInfoPtr, int),
  1716. void (*ProtectRegs) (ScrnInfoPtr, Bool),
  1717. void (*BlankScreen) (ScrnInfoPtr, Bool),
  1718. unsigned long vertsyncreg, int maskval, int knownclkindex,
  1719. int knownclkvalue)
  1720. {
  1721. register int status = vertsyncreg;
  1722. unsigned long i, cnt, rcnt, sync;
  1723. vgaHWPtr hwp = VGAHWPTR(pScrn);
  1724. /* First save registers that get written on */
  1725. (*ClockFunc) (pScrn, CLK_REG_SAVE);
  1726. if (num > MAXCLOCKS)
  1727. num = MAXCLOCKS;
  1728. for (i = 0; i < num; i++) {
  1729. if (ProtectRegs)
  1730. (*ProtectRegs) (pScrn, TRUE);
  1731. if (!(*ClockFunc) (pScrn, i)) {
  1732. pScrn->clock[i] = -1;
  1733. continue;
  1734. }
  1735. if (ProtectRegs)
  1736. (*ProtectRegs) (pScrn, FALSE);
  1737. if (BlankScreen)
  1738. (*BlankScreen) (pScrn, FALSE);
  1739. usleep(50000); /* let VCO stabilise */
  1740. cnt = 0;
  1741. sync = 200000;
  1742. while ((pci_io_read8(hwp->io, status) & maskval) == 0x00)
  1743. if (sync-- == 0)
  1744. goto finish;
  1745. /* Something appears to be happening, so reset sync count */
  1746. sync = 200000;
  1747. while ((pci_io_read8(hwp->io, status) & maskval) == maskval)
  1748. if (sync-- == 0)
  1749. goto finish;
  1750. /* Something appears to be happening, so reset sync count */
  1751. sync = 200000;
  1752. while ((pci_io_read8(hwp->io, status) & maskval) == 0x00)
  1753. if (sync-- == 0)
  1754. goto finish;
  1755. for (rcnt = 0; rcnt < 5; rcnt++) {
  1756. while (!(pci_io_read8(hwp->io, status) & maskval))
  1757. cnt++;
  1758. while ((pci_io_read8(hwp->io, status) & maskval))
  1759. cnt++;
  1760. }
  1761. finish:
  1762. pScrn->clock[i] = cnt ? cnt : -1;
  1763. if (BlankScreen)
  1764. (*BlankScreen) (pScrn, TRUE);
  1765. }
  1766. for (i = 0; i < num; i++) {
  1767. if (i != knownclkindex) {
  1768. if (pScrn->clock[i] == -1) {
  1769. pScrn->clock[i] = 0;
  1770. }
  1771. else {
  1772. pScrn->clock[i] = (int) (0.5 +
  1773. (((float) knownclkvalue) *
  1774. pScrn->clock[knownclkindex]) /
  1775. (pScrn->clock[i]));
  1776. /* Round to nearest 10KHz */
  1777. pScrn->clock[i] += 5;
  1778. pScrn->clock[i] /= 10;
  1779. pScrn->clock[i] *= 10;
  1780. }
  1781. }
  1782. }
  1783. pScrn->clock[knownclkindex] = knownclkvalue;
  1784. pScrn->numClocks = num;
  1785. /* Restore registers that were written on */
  1786. (*ClockFunc) (pScrn, CLK_REG_RESTORE);
  1787. }