Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

542 lines
16 KiB

  1. /************************************************************************/
  2. /* */
  3. /* EEPROM.C */
  4. /* */
  5. /* Copyright (c) 1992, ATI Technologies Incorporated. */
  6. /************************************************************************/
  7. /********************** PolyTron RCS Utilities
  8. $Revision: 1.3 $
  9. $Date: 23 Jan 1996 11:45:50 $
  10. $Author: RWolff $
  11. $Log: S:/source/wnt/ms11/miniport/archive/eeprom.c_v $
  12. *
  13. * Rev 1.3 23 Jan 1996 11:45:50 RWolff
  14. * Eliminated level 3 warnings.
  15. *
  16. * Rev 1.2 23 Dec 1994 10:47:34 ASHANMUG
  17. * ALPHA/Chrontel-DAC
  18. *
  19. * Rev 1.1 07 Feb 1994 14:07:06 RWOLFF
  20. * Added alloc_text() pragmas to allow miniport to be swapped out when
  21. * not needed.
  22. *
  23. * Rev 1.0 31 Jan 1994 11:08:14 RWOLFF
  24. * Initial revision.
  25. Rev 1.2 08 Oct 1993 15:17:42 RWOLFF
  26. No longer includes VIDFIND.H.
  27. Rev 1.1 03 Sep 1993 14:23:06 RWOLFF
  28. Partway through CX isolation.
  29. Rev 1.0 16 Aug 1993 13:23:00 Robert_Wolff
  30. Initial revision.
  31. Rev 1.10 21 Apr 1993 17:29:48 RWOLFF
  32. Now uses AMACH.H instead of 68800.H/68801.H.
  33. Rev 1.9 25 Mar 1993 11:14:42 RWOLFF
  34. Added typecast to get rid of warnings.
  35. Rev 1.8 08 Mar 1993 19:30:28 BRADES
  36. submit to MS NT
  37. Rev 1.5 06 Jan 1993 11:02:04 Robert_Wolff
  38. Eliminated dead code.
  39. Rev 1.4 24 Dec 1992 14:41:36 Chris_Brady
  40. fixup warnings
  41. Rev 1.3 27 Nov 1992 15:19:12 STEPHEN
  42. No change.
  43. Rev 1.2 13 Nov 1992 17:08:28 Robert_Wolff
  44. Now includes 68801.H, which consists of the now-obsolete MACH8.H
  45. and elements moved from VIDFIND.H.
  46. Rev 1.1 12 Nov 1992 16:54:00 Robert_Wolff
  47. Same source file can now be used with both Windows NT driver
  48. and VIDEO.EXE test program.
  49. Rev 1.0 05 Nov 1992 14:06:02 Robert_Wolff
  50. Initial revision.
  51. Rev 1.1 14 Sep 1992 09:44:40 Robert_Wolff
  52. Moved EEPROM opcodes to VIDEO.H, made VGA routine names consistent
  53. with same-purpose routines for 8514.
  54. Rev 1.0 02 Sep 1992 12:12:54 Chris_Brady
  55. Initial revision.
  56. End of PolyTron RCS section *****************/
  57. #ifdef DOC
  58. EEPROM.C - EEPROM functions for 8514/Ultra, Graphics Ultra adapters
  59. see EEVGA.ASM for the VGA class eeprom functions.
  60. Since time marches on, and the names of accelerator products
  61. changes often, these names are equivalent :
  62. { Mach32 or 68800 or Graphics Ultra Pro }
  63. #endif
  64. #include <conio.h>
  65. #include "miniport.h"
  66. #include "ntddvdeo.h"
  67. #include "video.h"
  68. #include "stdtyp.h"
  69. #include "amach.h"
  70. #include "amach1.h"
  71. #include "atimp.h"
  72. #include "eeprom.h"
  73. #include "services.h"
  74. //----------------IFNDEF DATA_ASM
  75. extern WORD rom_segment;
  76. extern WORD rom_offset;
  77. //----------------IFNDEF INIT_ASM
  78. extern WORD default_640_set;
  79. extern WORD default_1024_set;
  80. /*
  81. * Global EEPROM data structures
  82. */
  83. struct st_eeprom_data ee; // the location of I/O port bits
  84. //-----------------------------------------
  85. // function prototypes
  86. void ee_wait (void);
  87. void ee_clock_16 (WORD eedata);
  88. void ee_sel_16 (void);
  89. void ee_deselect_16 (void);
  90. WORD ee_read (short index);
  91. void ee_write (short index, WORD eedata);
  92. //-----------------------------------------
  93. /*
  94. * Allow miniport to be swapped out when not needed.
  95. *
  96. * The following routines are called through function pointers
  97. * rather than an explicit call to the routine, and may run into
  98. * trouble if paged out. If problems develop, make them un-pageable:
  99. * ee_cmd_16()
  100. * ee_cmd_1K()
  101. * ee_read_8514()
  102. */
  103. #if defined (ALLOC_PRAGMA)
  104. #pragma alloc_text(PAGE_M, ee_wait)
  105. #pragma alloc_text(PAGE_M, ee_cmd_16)
  106. #pragma alloc_text(PAGE_M, ee_cmd_1K)
  107. #pragma alloc_text(PAGE_M, ee_sel_16)
  108. #pragma alloc_text(PAGE_M, ee_deselect_16)
  109. #pragma alloc_text(PAGE_M, ee_clock_16)
  110. #pragma alloc_text(PAGE_M, ee_read)
  111. #pragma alloc_text(PAGE_M, ee_read_8514)
  112. #pragma alloc_text(PAGE_M, ee_write)
  113. #pragma alloc_text(PAGE_M, Mach32DescribeEEPROM)
  114. #pragma alloc_text(PAGE_M, Mach8UltraDescribeEEPROM)
  115. #pragma alloc_text(PAGE_M, Mach8ComboDescribeEEPROM)
  116. #endif
  117. // these commands do NOT use the index component bits 5-0 so there
  118. // is not a problem addressing up to 8 bit indexes , 256 words.
  119. #define EE_EWEN 0x04C0 // program enable
  120. #define EE_EWDS 0x0400 // program disable
  121. #define EE_ERAL 0x0480 // erase all
  122. #define EE_WRAL 0x0440 // program all
  123. //;----------------------------------------------------------------------
  124. //; EE_WAIT
  125. //; Waits for the requisite minimum setup time for the EEPROM
  126. //;----------------------------------------------------------------------
  127. void ee_wait ()
  128. {
  129. //EE_DELAY_TIME (256-1) * 0.8381 usec = 214.0 usec
  130. delay (1); // delay in milliseconds
  131. } /* ee_wait */
  132. //----------------------------------------------------------------------
  133. // EE_CMD_16
  134. // Sends EEPROM opcode and address to a 1k, 2k eeprom
  135. // instruct is an 5 bit command in the form of 0111 1100 0000
  136. // with a 6 bit index in the form of 0000 0011 1111
  137. // IF bit 10 is 1, then 8 bit address follows, else address not used.
  138. // Write data Serially to the EE_DATA_OUT_M32 bit of the ee->out.
  139. // Send out in high to low bit order
  140. //
  141. //----------------------------------------------------------------------
  142. void ee_cmd_16 (WORD instruct)
  143. {
  144. int jj;
  145. WORD bittest = 0x400; // 0100 0000 0000b bit 10
  146. WORD eedata;
  147. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  148. ee_clock_16((WORD) (ee->select | ee->chipselect)); // start bit
  149. for (jj=0; jj < 11; jj++)
  150. {
  151. ee_wait();
  152. if (instruct & bittest) // is a one bit
  153. eedata = ee->select | ee->chipselect | ee->data_out;
  154. else
  155. eedata = ee->select | ee->chipselect;
  156. OUTPW (ee->iop_out, eedata);
  157. ee_clock_16 (eedata); // send cmd bit
  158. bittest >>= 1; // next bit to the right
  159. }
  160. return;
  161. } /* ee_cmd_16 */
  162. //----------------------------------------------------------------------
  163. // EE_CMD_1K
  164. // Sends EEPROM opcode and address to a 1k, 2k eeprom
  165. // instruct is an 5 bit command in the form of 0111 1100 0000
  166. // with a 6 bit index in the form of 0000 0011 1111
  167. // IF bit 10 is 1, then 8 bit address follows, else address not used.
  168. // Write data Serially to the EE_DATA_OUT_M32 bit of the ee->iop_out.
  169. // Send out in high to low bit order
  170. //
  171. //----------------------------------------------------------------------
  172. void ee_cmd_1K (WORD instruct)
  173. {
  174. int jj;
  175. WORD bittest = 0x400; // 0100 0000 0000b bit 10
  176. WORD eedata;
  177. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  178. ee_clock_16((WORD) (ee->select | ee->chipselect)); // start bit
  179. for (jj=0; jj < 3; jj++)
  180. {
  181. ee_wait();
  182. if (instruct & bittest) // is a one bit
  183. eedata = ee->select | ee->chipselect | ee->data_out;
  184. else
  185. eedata = ee->select | ee->chipselect;
  186. OUTPW (ee->iop_out, eedata);
  187. ee_clock_16 (eedata); // send cmd bit
  188. bittest >>= 1; // next bit to the right
  189. }
  190. bittest = 0x20; // 0010 0000b bit 5
  191. for (jj=0; jj < 6; jj++)
  192. {
  193. ee_wait();
  194. if (instruct & bittest) // is a one bit
  195. eedata = ee->select | ee->chipselect | ee->data_out;
  196. else
  197. eedata = ee->select | ee->chipselect;
  198. OUTPW (ee->iop_out, eedata);
  199. ee_clock_16 (eedata); // send cmd bit
  200. bittest >>= 1; // next bit to the right
  201. }
  202. return;
  203. } /* ee_cmd_1K */
  204. //;----------------------------------------------------------------------
  205. //; EE_SEL_16
  206. //; Pull EEPROM chip select high
  207. //;
  208. //;----------------------------------------------------------------------
  209. void ee_sel_16 (void)
  210. {
  211. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  212. ee_wait();
  213. OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect))); // EE_CS high
  214. ee_wait();
  215. return;
  216. } /* ee_sel_16 */
  217. //;----------------------------------------------------------------------
  218. //; EE_DESELECT_16
  219. //; Pull EEPROM chip select low
  220. //;
  221. //;----------------------------------------------------------------------
  222. void ee_deselect_16 (void)
  223. {
  224. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  225. ee_wait();
  226. OUTPW (ee->iop_out, ee->select); // EE_CS high
  227. ee_clock_16 (ee->select); // send cmd bit
  228. OUTPW (ee->iop_out, 0); // disable EEprom activity
  229. ee_wait();
  230. return;
  231. } /* ee_deselect_16 */
  232. //;----------------------------------------------------------------------
  233. //; EE_CLOCK_16
  234. //; Toggle EEPROM CLK line high then low
  235. //;
  236. //; INPUT: eedata = select status for EEPROM
  237. //;----------------------------------------------------------------------
  238. void ee_clock_16 (WORD eedata)
  239. {
  240. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  241. ee_wait();
  242. OUTPW (ee->iop_out, (WORD)(eedata | (ee->clock))); // clock ON
  243. ee_wait();
  244. OUTPW (ee->iop_out, (WORD)(eedata & ~(ee->clock))); // clock OFF
  245. ee_wait();
  246. } /* ee_clock_16 */
  247. //;----------------------------------------------------------------------
  248. //; EE_READ - was a 68800 function
  249. //; Read a word from EEPROM ONLY called from INIT.asm
  250. //; INPUT: bl = index
  251. //; OUTPUT: ax = data
  252. //;----------------------------------------------------------------------
  253. WORD ee_read (short index)
  254. {
  255. WORD indata=0;
  256. if (INPW(CONFIG_STATUS_1) & 1) //is 8514 or VGA eeprom
  257. { // VGA disabled, use 8514 method
  258. indata = ee_read_8514 (index);
  259. }
  260. else{
  261. indata = ee_read_vga (index); // VGA method
  262. }
  263. return (indata);
  264. } /* ee_read */
  265. //;----------------------------------------------------------------------
  266. //; EE_READ_8514
  267. //; Read a word from using 8514 EEPROM registers
  268. //; INPUT: bl = index
  269. //; OUTPUT: ax = data
  270. //;----------------------------------------------------------------------
  271. WORD ee_read_8514 (short index)
  272. {
  273. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  274. int jj;
  275. WORD save_misc, indata=0;
  276. save_misc = INPW (R_MISC_CNTL); // Read only location
  277. ee_sel_16();
  278. (ee->EEcmd) ((WORD) (EE_READ | index)); // send read cmd and index to EEPROM
  279. ee_clock_16 ((WORD) (ee->select | ee->chipselect));
  280. for (jj=0; jj < 16; jj++)
  281. {
  282. indata <<= 1;
  283. if (INPW(ee->iop_in) & ee->data_in) // get data bit
  284. indata |= 1;
  285. ee_clock_16 ((WORD) (ee->select | ee->chipselect));
  286. }
  287. ee_deselect_16();
  288. OUTPW (MISC_CNTL, save_misc);
  289. return (indata);
  290. } /* ee_read_8514 */
  291. //;----------------------------------------------------------------------
  292. //; EE_WRITE
  293. //; Writes a word to EEPROM
  294. //; However, this will fail since 1K eeprom does NOT need
  295. //; the EE_EWEN, EE_EWDS commands +++++++++++++++++
  296. //; See EEVGA.C ee_write_vga().
  297. //; INPUT: index = which word to write
  298. //; data = data to write
  299. //;----------------------------------------------------------------------
  300. void ee_write (short index, WORD eedata)
  301. {
  302. struct st_eeprom_data *ee = phwDeviceExtension->ee;
  303. int jj;
  304. WORD save_misc, indata=0;
  305. if (INPW(CONFIG_STATUS_1) & 1) //is 8514 or VGA eeprom
  306. { // VGA disabled, use 8514 method
  307. save_misc = INPW (R_MISC_CNTL); // Read only location
  308. OUTP (DISP_CNTL, 0x53); // disable CRT before writing EEPROM
  309. ee_sel_16();
  310. ee_cmd_16 (EE_EWEN); // enable EEPROM write
  311. ee_deselect_16(); // EE_CS low
  312. ee_sel_16();
  313. ee_cmd_16 ((WORD) (EE_ERASE | index));
  314. ee_deselect_16(); // EE_CS low
  315. delay (50);
  316. ee_sel_16();
  317. ee_cmd_16 ((WORD) (EE_WRITE | index)); // EEPROM write data
  318. for (jj=0; jj < 16; jj++)
  319. {
  320. ee_wait();
  321. if (eedata & 0x8000) // get data bit
  322. OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect) | (ee->data_out)));
  323. else
  324. OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect)));
  325. ee_clock_16 ((WORD) (ee->select | ee->chipselect));
  326. eedata <<= 1;
  327. }
  328. ee_deselect_16(); // EE_CS low
  329. delay (50); // in milliseconds
  330. ee_sel_16();
  331. ee_cmd_16 (EE_EWDS); // disable EEPROM write
  332. ee_deselect_16(); // EE_CS low
  333. OUTPW (ee->iop_out, save_misc);
  334. }
  335. else{
  336. ee_write_vga (index, eedata); // VGA method
  337. }
  338. } /* ee_write */
  339. /***************************************************************************
  340. *
  341. * New Functions
  342. *
  343. ***************************************************************************/
  344. /*
  345. * void Mach32DescribeEEPROM(Style);
  346. *
  347. * int Style; Is data stored 8514-style or VGA-style?
  348. *
  349. * Fill in the EEPROM description structure for the Mach 32 card.
  350. */
  351. void Mach32DescribeEEPROM(int Style)
  352. {
  353. ee.iop_out = MISC_CNTL;
  354. ee.iop_in = EXT_GE_STATUS;
  355. ee.clock = EE_CLK_M32;
  356. ee.select = EE_SELECT_M32;
  357. ee.chipselect = EE_CS_M32;
  358. ee.data_out = EE_DATA_OUT_M32;
  359. ee.data_in = EE_DATA_IN;
  360. if (Style == STYLE_8514)
  361. {
  362. ee.EEread = ee_read_8514; // 8514 style
  363. ee.EEcmd = ee_cmd_16;
  364. }
  365. else{
  366. ee.EEread = ee_read_vga; // VGA style
  367. ee.EEcmd = ee_cmd_vga;
  368. ee.addr_size = 8;
  369. }
  370. return;
  371. }
  372. /*
  373. * void Mach8UltraDescribeEEPROM(BusWidth);
  374. *
  375. * int BusWidth; Is 8514/ULTRA plugged into 8 or 16 bit slot?
  376. *
  377. * Fill in the EEPROM description structure for the 8514/ULTRA.
  378. */
  379. void Mach8UltraDescribeEEPROM(int BusWidth)
  380. {
  381. ee.data_in = EE_DATA_IN;
  382. ee.iop_out = EXT_GE_CONFIG;
  383. ee.iop_in = EXT_GE_STATUS;
  384. ee.EEread = ee_read_8514; // how read eeprom
  385. ee.EEcmd = ee_cmd_1K; // send command to eeprom
  386. /*
  387. * Only the 8514/Ultra has a hardware bug that prevents it
  388. * from writing to the EEPROM when it is in an 8 bit ISA bus.
  389. */
  390. if (BusWidth == BUS_8BIT)
  391. {
  392. ee.clock = EE_CLK_M8_8;
  393. ee.select = EE_SELECT_M8_8;
  394. ee.chipselect = EE_CS_M8_8;
  395. ee.data_out = EE_DATA_OUT_M8_8;
  396. }
  397. else{
  398. ee.clock = EE_CLK_M8_16; // assume are in a 16 bit bus
  399. ee.select = EE_SELECT_M8_16;
  400. ee.chipselect = EE_CS_M8_16;
  401. ee.data_out = EE_DATA_OUT_M8_16;
  402. }
  403. return;
  404. }
  405. /*
  406. * void Mach8ComboDescribeEEPROM(void);
  407. *
  408. * Fill in the EEPROM description structure for the Graphics ULTRA
  409. * and Graphics VANTAGE. These cards always have both the 8514 and
  410. * the VGA enabled, so the EEPROM is ALWAYS read VGA style.
  411. */
  412. extern void Mach8ComboDescribeEEPROM(void)
  413. {
  414. ee.addr_size = 6;
  415. ee.iop_out = EXT_GE_CONFIG;
  416. ee.iop_in = EXT_GE_STATUS;
  417. ee.data_in = EE_DATA_IN;
  418. ee.clock = EE_CLK_M8_16; // are in a 16 bit bus
  419. ee.select = EE_SELECT_M8_16;
  420. ee.chipselect = EE_CS_M8_16;
  421. ee.data_out = EE_DATA_OUT_M8_16;
  422. ee.EEread = ee_read_vga; // VGA style
  423. ee.EEcmd = ee_cmd_vga;
  424. return;
  425. }
  426. //******************* end of EEPROM.C ******************************