windows-nt/Source/XPSP1/NT/drivers/video/ms/ati/mini/eeprom.c

543 lines
16 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/************************************************************************/
/* */
/* EEPROM.C */
/* */
/* Copyright (c) 1992, ATI Technologies Incorporated. */
/************************************************************************/
/********************** PolyTron RCS Utilities
$Revision: 1.3 $
$Date: 23 Jan 1996 11:45:50 $
$Author: RWolff $
$Log: S:/source/wnt/ms11/miniport/archive/eeprom.c_v $
*
* Rev 1.3 23 Jan 1996 11:45:50 RWolff
* Eliminated level 3 warnings.
*
* Rev 1.2 23 Dec 1994 10:47:34 ASHANMUG
* ALPHA/Chrontel-DAC
*
* Rev 1.1 07 Feb 1994 14:07:06 RWOLFF
* Added alloc_text() pragmas to allow miniport to be swapped out when
* not needed.
*
* Rev 1.0 31 Jan 1994 11:08:14 RWOLFF
* Initial revision.
Rev 1.2 08 Oct 1993 15:17:42 RWOLFF
No longer includes VIDFIND.H.
Rev 1.1 03 Sep 1993 14:23:06 RWOLFF
Partway through CX isolation.
Rev 1.0 16 Aug 1993 13:23:00 Robert_Wolff
Initial revision.
Rev 1.10 21 Apr 1993 17:29:48 RWOLFF
Now uses AMACH.H instead of 68800.H/68801.H.
Rev 1.9 25 Mar 1993 11:14:42 RWOLFF
Added typecast to get rid of warnings.
Rev 1.8 08 Mar 1993 19:30:28 BRADES
submit to MS NT
Rev 1.5 06 Jan 1993 11:02:04 Robert_Wolff
Eliminated dead code.
Rev 1.4 24 Dec 1992 14:41:36 Chris_Brady
fixup warnings
Rev 1.3 27 Nov 1992 15:19:12 STEPHEN
No change.
Rev 1.2 13 Nov 1992 17:08:28 Robert_Wolff
Now includes 68801.H, which consists of the now-obsolete MACH8.H
and elements moved from VIDFIND.H.
Rev 1.1 12 Nov 1992 16:54:00 Robert_Wolff
Same source file can now be used with both Windows NT driver
and VIDEO.EXE test program.
Rev 1.0 05 Nov 1992 14:06:02 Robert_Wolff
Initial revision.
Rev 1.1 14 Sep 1992 09:44:40 Robert_Wolff
Moved EEPROM opcodes to VIDEO.H, made VGA routine names consistent
with same-purpose routines for 8514.
Rev 1.0 02 Sep 1992 12:12:54 Chris_Brady
Initial revision.
End of PolyTron RCS section *****************/
#ifdef DOC
EEPROM.C - EEPROM functions for 8514/Ultra, Graphics Ultra adapters
see EEVGA.ASM for the VGA class eeprom functions.
Since time marches on, and the names of accelerator products
changes often, these names are equivalent :
{ Mach32 or 68800 or Graphics Ultra Pro }
#endif
#include <conio.h>
#include "miniport.h"
#include "ntddvdeo.h"
#include "video.h"
#include "stdtyp.h"
#include "amach.h"
#include "amach1.h"
#include "atimp.h"
#include "eeprom.h"
#include "services.h"
//----------------IFNDEF DATA_ASM
extern WORD rom_segment;
extern WORD rom_offset;
//----------------IFNDEF INIT_ASM
extern WORD default_640_set;
extern WORD default_1024_set;
/*
* Global EEPROM data structures
*/
struct st_eeprom_data ee; // the location of I/O port bits
//-----------------------------------------
// function prototypes
void ee_wait (void);
void ee_clock_16 (WORD eedata);
void ee_sel_16 (void);
void ee_deselect_16 (void);
WORD ee_read (short index);
void ee_write (short index, WORD eedata);
//-----------------------------------------
/*
* Allow miniport to be swapped out when not needed.
*
* The following routines are called through function pointers
* rather than an explicit call to the routine, and may run into
* trouble if paged out. If problems develop, make them un-pageable:
* ee_cmd_16()
* ee_cmd_1K()
* ee_read_8514()
*/
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(PAGE_M, ee_wait)
#pragma alloc_text(PAGE_M, ee_cmd_16)
#pragma alloc_text(PAGE_M, ee_cmd_1K)
#pragma alloc_text(PAGE_M, ee_sel_16)
#pragma alloc_text(PAGE_M, ee_deselect_16)
#pragma alloc_text(PAGE_M, ee_clock_16)
#pragma alloc_text(PAGE_M, ee_read)
#pragma alloc_text(PAGE_M, ee_read_8514)
#pragma alloc_text(PAGE_M, ee_write)
#pragma alloc_text(PAGE_M, Mach32DescribeEEPROM)
#pragma alloc_text(PAGE_M, Mach8UltraDescribeEEPROM)
#pragma alloc_text(PAGE_M, Mach8ComboDescribeEEPROM)
#endif
// these commands do NOT use the index component bits 5-0 so there
// is not a problem addressing up to 8 bit indexes , 256 words.
#define EE_EWEN 0x04C0 // program enable
#define EE_EWDS 0x0400 // program disable
#define EE_ERAL 0x0480 // erase all
#define EE_WRAL 0x0440 // program all
//;----------------------------------------------------------------------
//; EE_WAIT
//; Waits for the requisite minimum setup time for the EEPROM
//;----------------------------------------------------------------------
void ee_wait ()
{
//EE_DELAY_TIME (256-1) * 0.8381 usec = 214.0 usec
delay (1); // delay in milliseconds
} /* ee_wait */
//----------------------------------------------------------------------
// EE_CMD_16
// Sends EEPROM opcode and address to a 1k, 2k eeprom
// instruct is an 5 bit command in the form of 0111 1100 0000
// with a 6 bit index in the form of 0000 0011 1111
// IF bit 10 is 1, then 8 bit address follows, else address not used.
// Write data Serially to the EE_DATA_OUT_M32 bit of the ee->out.
// Send out in high to low bit order
//
//----------------------------------------------------------------------
void ee_cmd_16 (WORD instruct)
{
int jj;
WORD bittest = 0x400; // 0100 0000 0000b bit 10
WORD eedata;
struct st_eeprom_data *ee = phwDeviceExtension->ee;
ee_clock_16((WORD) (ee->select | ee->chipselect)); // start bit
for (jj=0; jj < 11; jj++)
{
ee_wait();
if (instruct & bittest) // is a one bit
eedata = ee->select | ee->chipselect | ee->data_out;
else
eedata = ee->select | ee->chipselect;
OUTPW (ee->iop_out, eedata);
ee_clock_16 (eedata); // send cmd bit
bittest >>= 1; // next bit to the right
}
return;
} /* ee_cmd_16 */
//----------------------------------------------------------------------
// EE_CMD_1K
// Sends EEPROM opcode and address to a 1k, 2k eeprom
// instruct is an 5 bit command in the form of 0111 1100 0000
// with a 6 bit index in the form of 0000 0011 1111
// IF bit 10 is 1, then 8 bit address follows, else address not used.
// Write data Serially to the EE_DATA_OUT_M32 bit of the ee->iop_out.
// Send out in high to low bit order
//
//----------------------------------------------------------------------
void ee_cmd_1K (WORD instruct)
{
int jj;
WORD bittest = 0x400; // 0100 0000 0000b bit 10
WORD eedata;
struct st_eeprom_data *ee = phwDeviceExtension->ee;
ee_clock_16((WORD) (ee->select | ee->chipselect)); // start bit
for (jj=0; jj < 3; jj++)
{
ee_wait();
if (instruct & bittest) // is a one bit
eedata = ee->select | ee->chipselect | ee->data_out;
else
eedata = ee->select | ee->chipselect;
OUTPW (ee->iop_out, eedata);
ee_clock_16 (eedata); // send cmd bit
bittest >>= 1; // next bit to the right
}
bittest = 0x20; // 0010 0000b bit 5
for (jj=0; jj < 6; jj++)
{
ee_wait();
if (instruct & bittest) // is a one bit
eedata = ee->select | ee->chipselect | ee->data_out;
else
eedata = ee->select | ee->chipselect;
OUTPW (ee->iop_out, eedata);
ee_clock_16 (eedata); // send cmd bit
bittest >>= 1; // next bit to the right
}
return;
} /* ee_cmd_1K */
//;----------------------------------------------------------------------
//; EE_SEL_16
//; Pull EEPROM chip select high
//;
//;----------------------------------------------------------------------
void ee_sel_16 (void)
{
struct st_eeprom_data *ee = phwDeviceExtension->ee;
ee_wait();
OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect))); // EE_CS high
ee_wait();
return;
} /* ee_sel_16 */
//;----------------------------------------------------------------------
//; EE_DESELECT_16
//; Pull EEPROM chip select low
//;
//;----------------------------------------------------------------------
void ee_deselect_16 (void)
{
struct st_eeprom_data *ee = phwDeviceExtension->ee;
ee_wait();
OUTPW (ee->iop_out, ee->select); // EE_CS high
ee_clock_16 (ee->select); // send cmd bit
OUTPW (ee->iop_out, 0); // disable EEprom activity
ee_wait();
return;
} /* ee_deselect_16 */
//;----------------------------------------------------------------------
//; EE_CLOCK_16
//; Toggle EEPROM CLK line high then low
//;
//; INPUT: eedata = select status for EEPROM
//;----------------------------------------------------------------------
void ee_clock_16 (WORD eedata)
{
struct st_eeprom_data *ee = phwDeviceExtension->ee;
ee_wait();
OUTPW (ee->iop_out, (WORD)(eedata | (ee->clock))); // clock ON
ee_wait();
OUTPW (ee->iop_out, (WORD)(eedata & ~(ee->clock))); // clock OFF
ee_wait();
} /* ee_clock_16 */
//;----------------------------------------------------------------------
//; EE_READ - was a 68800 function
//; Read a word from EEPROM ONLY called from INIT.asm
//; INPUT: bl = index
//; OUTPUT: ax = data
//;----------------------------------------------------------------------
WORD ee_read (short index)
{
WORD indata=0;
if (INPW(CONFIG_STATUS_1) & 1) //is 8514 or VGA eeprom
{ // VGA disabled, use 8514 method
indata = ee_read_8514 (index);
}
else{
indata = ee_read_vga (index); // VGA method
}
return (indata);
} /* ee_read */
//;----------------------------------------------------------------------
//; EE_READ_8514
//; Read a word from using 8514 EEPROM registers
//; INPUT: bl = index
//; OUTPUT: ax = data
//;----------------------------------------------------------------------
WORD ee_read_8514 (short index)
{
struct st_eeprom_data *ee = phwDeviceExtension->ee;
int jj;
WORD save_misc, indata=0;
save_misc = INPW (R_MISC_CNTL); // Read only location
ee_sel_16();
(ee->EEcmd) ((WORD) (EE_READ | index)); // send read cmd and index to EEPROM
ee_clock_16 ((WORD) (ee->select | ee->chipselect));
for (jj=0; jj < 16; jj++)
{
indata <<= 1;
if (INPW(ee->iop_in) & ee->data_in) // get data bit
indata |= 1;
ee_clock_16 ((WORD) (ee->select | ee->chipselect));
}
ee_deselect_16();
OUTPW (MISC_CNTL, save_misc);
return (indata);
} /* ee_read_8514 */
//;----------------------------------------------------------------------
//; EE_WRITE
//; Writes a word to EEPROM
//; However, this will fail since 1K eeprom does NOT need
//; the EE_EWEN, EE_EWDS commands +++++++++++++++++
//; See EEVGA.C ee_write_vga().
//; INPUT: index = which word to write
//; data = data to write
//;----------------------------------------------------------------------
void ee_write (short index, WORD eedata)
{
struct st_eeprom_data *ee = phwDeviceExtension->ee;
int jj;
WORD save_misc, indata=0;
if (INPW(CONFIG_STATUS_1) & 1) //is 8514 or VGA eeprom
{ // VGA disabled, use 8514 method
save_misc = INPW (R_MISC_CNTL); // Read only location
OUTP (DISP_CNTL, 0x53); // disable CRT before writing EEPROM
ee_sel_16();
ee_cmd_16 (EE_EWEN); // enable EEPROM write
ee_deselect_16(); // EE_CS low
ee_sel_16();
ee_cmd_16 ((WORD) (EE_ERASE | index));
ee_deselect_16(); // EE_CS low
delay (50);
ee_sel_16();
ee_cmd_16 ((WORD) (EE_WRITE | index)); // EEPROM write data
for (jj=0; jj < 16; jj++)
{
ee_wait();
if (eedata & 0x8000) // get data bit
OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect) | (ee->data_out)));
else
OUTPW (ee->iop_out, (WORD)((ee->select) | (ee->chipselect)));
ee_clock_16 ((WORD) (ee->select | ee->chipselect));
eedata <<= 1;
}
ee_deselect_16(); // EE_CS low
delay (50); // in milliseconds
ee_sel_16();
ee_cmd_16 (EE_EWDS); // disable EEPROM write
ee_deselect_16(); // EE_CS low
OUTPW (ee->iop_out, save_misc);
}
else{
ee_write_vga (index, eedata); // VGA method
}
} /* ee_write */
/***************************************************************************
*
* New Functions
*
***************************************************************************/
/*
* void Mach32DescribeEEPROM(Style);
*
* int Style; Is data stored 8514-style or VGA-style?
*
* Fill in the EEPROM description structure for the Mach 32 card.
*/
void Mach32DescribeEEPROM(int Style)
{
ee.iop_out = MISC_CNTL;
ee.iop_in = EXT_GE_STATUS;
ee.clock = EE_CLK_M32;
ee.select = EE_SELECT_M32;
ee.chipselect = EE_CS_M32;
ee.data_out = EE_DATA_OUT_M32;
ee.data_in = EE_DATA_IN;
if (Style == STYLE_8514)
{
ee.EEread = ee_read_8514; // 8514 style
ee.EEcmd = ee_cmd_16;
}
else{
ee.EEread = ee_read_vga; // VGA style
ee.EEcmd = ee_cmd_vga;
ee.addr_size = 8;
}
return;
}
/*
* void Mach8UltraDescribeEEPROM(BusWidth);
*
* int BusWidth; Is 8514/ULTRA plugged into 8 or 16 bit slot?
*
* Fill in the EEPROM description structure for the 8514/ULTRA.
*/
void Mach8UltraDescribeEEPROM(int BusWidth)
{
ee.data_in = EE_DATA_IN;
ee.iop_out = EXT_GE_CONFIG;
ee.iop_in = EXT_GE_STATUS;
ee.EEread = ee_read_8514; // how read eeprom
ee.EEcmd = ee_cmd_1K; // send command to eeprom
/*
* Only the 8514/Ultra has a hardware bug that prevents it
* from writing to the EEPROM when it is in an 8 bit ISA bus.
*/
if (BusWidth == BUS_8BIT)
{
ee.clock = EE_CLK_M8_8;
ee.select = EE_SELECT_M8_8;
ee.chipselect = EE_CS_M8_8;
ee.data_out = EE_DATA_OUT_M8_8;
}
else{
ee.clock = EE_CLK_M8_16; // assume are in a 16 bit bus
ee.select = EE_SELECT_M8_16;
ee.chipselect = EE_CS_M8_16;
ee.data_out = EE_DATA_OUT_M8_16;
}
return;
}
/*
* void Mach8ComboDescribeEEPROM(void);
*
* Fill in the EEPROM description structure for the Graphics ULTRA
* and Graphics VANTAGE. These cards always have both the 8514 and
* the VGA enabled, so the EEPROM is ALWAYS read VGA style.
*/
extern void Mach8ComboDescribeEEPROM(void)
{
ee.addr_size = 6;
ee.iop_out = EXT_GE_CONFIG;
ee.iop_in = EXT_GE_STATUS;
ee.data_in = EE_DATA_IN;
ee.clock = EE_CLK_M8_16; // are in a 16 bit bus
ee.select = EE_SELECT_M8_16;
ee.chipselect = EE_CS_M8_16;
ee.data_out = EE_DATA_OUT_M8_16;
ee.EEread = ee_read_vga; // VGA style
ee.EEcmd = ee_cmd_vga;
return;
}
//******************* end of EEPROM.C ******************************