Convert some comments to proper Doxygen syntax.
Also, make them all fit in 80chars/column, fix some whitespace issues and also some typos I noticed. Signed-off-by: Uwe Hermann <uwe@hermann-uwe.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@5993 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
parent
b907d321a5
commit
b69cb5a310
|
@ -17,39 +17,23 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
*----------------------------------------------------------------------------
|
|
||||||
* MODULES USED
|
|
||||||
*
|
|
||||||
*----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#undef FILECODE
|
#undef FILECODE
|
||||||
#define FILECODE 0xCCCC
|
#define FILECODE 0xCCCC
|
||||||
|
|
||||||
#include "comlib.h"
|
#include "comlib.h"
|
||||||
#include "AsPsDefs.h"
|
#include "AsPsDefs.h"
|
||||||
#include "AsPsNb.h"
|
#include "AsPsNb.h"
|
||||||
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
|
||||||
* PROTOTYPES OF LOCAL FUNCTIONS
|
|
||||||
*
|
|
||||||
*----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
u8 getNumOfNodeNb(void);
|
u8 getNumOfNodeNb(void);
|
||||||
u8 translateNodeIdToDeviceIdNb(u8 nodeId);
|
u8 translateNodeIdToDeviceIdNb(u8 nodeId);
|
||||||
|
|
||||||
|
/**
|
||||||
/*----------------------------------------------------------------------------
|
* Return the minimum possible NbCOF (in 100MHz) for the system.
|
||||||
* FUNCTION: getMinNbCOF
|
*
|
||||||
* INPUT: None
|
* This function can be run on any core and is used by the HT & Memory init
|
||||||
* OUTPUT: minNbCOF (in multiple of half of CLKIN, 100MHz)
|
* code in Phase 1.
|
||||||
* DESCRIPTION:
|
*
|
||||||
* This function returns the minimum possible NbCOF (in 100MHz)
|
* @return minNbCOF (in multiple of half of CLKIN, 100MHz).
|
||||||
* for the system .
|
|
||||||
* This function can be run on any core and is used by the HT & Memory init code
|
|
||||||
* in Phase 1.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
*/
|
||||||
u8 getMinNbCOF(void)
|
u8 getMinNbCOF(void)
|
||||||
{
|
{
|
||||||
|
@ -130,14 +114,13 @@ u8 getNumOfNodeNb(void)
|
||||||
return (u8)dtemp;
|
return (u8)dtemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------
|
/**
|
||||||
* FUNCTION: translateNodeIdToDeviceId
|
* Return the PCI device ID for PCI access using node ID.
|
||||||
* INPUT: u8 nodeId - node ID of the node
|
*
|
||||||
* OUTPUT: u8 - PCI device ID of the node
|
* This function may need to change node ID to device ID in big MP systems.
|
||||||
* DESCRIPTION:
|
*
|
||||||
* This function return the PCI device ID for PCI access using node ID.
|
* @param nodeId Node ID of the node.
|
||||||
* This function may need to chnage node ID to device ID in big MP systems.
|
* @return PCI device ID of the node.
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
*/
|
||||||
u8 translateNodeIdToDeviceIdNb(u8 nodeId)
|
u8 translateNodeIdToDeviceIdNb(u8 nodeId)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "e7501.h"
|
#include "e7501.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
Definitions:
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Uncomment this to enable run-time checking of DIMM parameters
|
// Uncomment this to enable run-time checking of DIMM parameters
|
||||||
// for dual-channel operation
|
// for dual-channel operation
|
||||||
// Unfortunately the code seems to chew up several K of space.
|
// Unfortunately the code seems to chew up several K of space.
|
||||||
|
@ -47,10 +51,6 @@ struct dimm_size {
|
||||||
unsigned long side2;
|
unsigned long side2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
/* DEFINITIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
static const uint32_t refresh_frequency[] = {
|
static const uint32_t refresh_frequency[] = {
|
||||||
/* Relative frequency (array value) of each E7501 Refresh Mode Select
|
/* Relative frequency (array value) of each E7501 Refresh Mode Select
|
||||||
* (RMS) value (array index)
|
* (RMS) value (array index)
|
||||||
|
@ -451,9 +451,10 @@ static const uint32_t maybe_pull_updown_offset_table[] = {
|
||||||
0x88888888, 0x88888888, 0x88888888, 0x88888888,
|
0x88888888, 0x88888888, 0x88888888, 0x88888888,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*-----------------------------------------------------------------------------
|
||||||
/* TABLES */
|
Delay functions:
|
||||||
/**********************************************************************************/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define SLOW_DOWN_IO inb(0x80)
|
#define SLOW_DOWN_IO inb(0x80)
|
||||||
//#define SLOW_DOWN_IO udelay(40);
|
//#define SLOW_DOWN_IO udelay(40);
|
||||||
|
|
||||||
|
@ -477,27 +478,26 @@ static void do_delay(void)
|
||||||
|
|
||||||
#define EXTRA_DELAY DO_DELAY
|
#define EXTRA_DELAY DO_DELAY
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
/* DELAY FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
static void die_on_spd_error(int spd_return_value)
|
static void die_on_spd_error(int spd_return_value)
|
||||||
{
|
{
|
||||||
if (spd_return_value < 0)
|
if (spd_return_value < 0)
|
||||||
die("Error reading SPD info\n");
|
die("Error reading SPD info\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
// Function: sdram_spd_get_page_size
|
Serial presence detect (SPD) functions:
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
-----------------------------------------------------------------------------*/
|
||||||
// Return Value: struct dimm_size - log2(page size) for each side of the DIMM.
|
|
||||||
// Description: Calculate the page size for each physical bank of the DIMM:
|
/**
|
||||||
// log2(page size) = (# columns) + log2(data width)
|
* Calculate the page size for each physical bank of the DIMM:
|
||||||
//
|
* log2(page size) = (# columns) + log2(data width)
|
||||||
// NOTE: page size is the total number of data bits in a row.
|
*
|
||||||
//
|
* NOTE: Page size is the total number of data bits in a row.
|
||||||
static struct dimm_size sdram_spd_get_page_size(uint16_t
|
*
|
||||||
dimm_socket_address)
|
* @param dimm_socket_address SMBus address of DIMM socket to interrogate.
|
||||||
|
* @return log2(page size) for each side of the DIMM.
|
||||||
|
*/
|
||||||
|
static struct dimm_size sdram_spd_get_page_size(uint16_t dimm_socket_address)
|
||||||
{
|
{
|
||||||
uint16_t module_data_width;
|
uint16_t module_data_width;
|
||||||
int value;
|
int value;
|
||||||
|
@ -554,13 +554,12 @@ static struct dimm_size sdram_spd_get_page_size(uint16_t
|
||||||
return pgsz; // Never reached
|
return pgsz; // Never reached
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_spd_get_width
|
* Read the width in bits of each DIMM side's DRAMs via SPD (i.e. 4, 8, 16).
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
*
|
||||||
// Return Value: dimm_size - width in bits of each DIMM side's DRAMs.
|
* @param dimm_socket_address SMBus address of DIMM socket to interrogate.
|
||||||
// Description: Read the width in bits of each DIMM side's DRAMs via SPD.
|
* @return Width in bits of each DIMM side's DRAMs.
|
||||||
// (i.e. 4, 8, 16)
|
*/
|
||||||
//
|
|
||||||
static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -601,18 +600,19 @@ static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: spd_get_dimm_size
|
* Calculate the log base 2 size in bits of both DIMM sides.
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
*
|
||||||
// Return Value: dimm_size - log2(number of bits) for each side of the DIMM
|
* log2(# bits) = (# columns) + log2(data width) +
|
||||||
// Description: Calculate the log base 2 size in bits of both DIMM sides.
|
* (# rows) + log2(banks per SDRAM)
|
||||||
// log2(# bits) = (# columns) + log2(data width) +
|
*
|
||||||
// (# rows) + log2(banks per SDRAM)
|
* Note that it might be easier to use SPD byte 31 here, it has the DIMM size
|
||||||
//
|
* as a multiple of 4MB. The way we do it now we can size both sides of an
|
||||||
// Note that it might be easier to use SPD byte 31 here, it has the
|
* asymmetric DIMM.
|
||||||
// DIMM size as a multiple of 4MB. The way we do it now we can size
|
*
|
||||||
// both sides of an asymmetric dimm.
|
* @param dimm_socket_address SMBus address of DIMM socket to interrogate.
|
||||||
//
|
* @return log2(number of bits) for each side of the DIMM.
|
||||||
|
*/
|
||||||
static struct dimm_size spd_get_dimm_size(unsigned dimm_socket_address)
|
static struct dimm_size spd_get_dimm_size(unsigned dimm_socket_address)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -651,20 +651,21 @@ static struct dimm_size spd_get_dimm_size(unsigned dimm_socket_address)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VALIDATE_DIMM_COMPATIBILITY
|
#ifdef VALIDATE_DIMM_COMPATIBILITY
|
||||||
//----------------------------------------------------------------------------------
|
|
||||||
// Function: are_spd_values_equal
|
/**
|
||||||
// Parameters: spd_byte_number -
|
* Determine whether two DIMMs have the same value for an SPD parameter.
|
||||||
// dimmN_address - SMBus addresses of DIMM sockets to interrogate
|
*
|
||||||
// Return Value: 1 if both DIMM sockets report the same value for the specified
|
* @param spd_byte_number The SPD byte number to compare in both DIMMs.
|
||||||
// SPD parameter; 0 if the values differed or an error occurred.
|
* @param dimm0_address SMBus address of the 1st DIMM socket to interrogate.
|
||||||
// Description: Determine whether two DIMMs have the same value for a SPD parameter.
|
* @param dimm1_address SMBus address of the 2nd DIMM socket to interrogate.
|
||||||
//
|
* @return 1 if both DIMM sockets report the same value for the specified
|
||||||
|
* SPD parameter, 0 if the values differed or an error occurred.
|
||||||
|
*/
|
||||||
static uint8_t are_spd_values_equal(uint8_t spd_byte_number,
|
static uint8_t are_spd_values_equal(uint8_t spd_byte_number,
|
||||||
uint16_t dimm0_address,
|
uint16_t dimm0_address,
|
||||||
uint16_t dimm1_address)
|
uint16_t dimm1_address)
|
||||||
{
|
{
|
||||||
uint8_t bEqual = 0;
|
uint8_t bEqual = 0;
|
||||||
|
|
||||||
int dimm0_value = spd_read_byte(dimm0_address, spd_byte_number);
|
int dimm0_value = spd_read_byte(dimm0_address, spd_byte_number);
|
||||||
int dimm1_value = spd_read_byte(dimm1_address, spd_byte_number);
|
int dimm1_value = spd_read_byte(dimm1_address, spd_byte_number);
|
||||||
|
|
||||||
|
@ -676,23 +677,24 @@ static uint8_t are_spd_values_equal(uint8_t spd_byte_number,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: spd_get_supported_dimms
|
* Scan for compatible DIMMs.
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
*
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* The code in this module only supports dual-channel operation, so we test
|
||||||
// Return Value: uint8_t - a bitmask indicating which of the possible sockets
|
* that compatible DIMMs are paired.
|
||||||
// for each channel was found to contain a compatible DIMM.
|
*
|
||||||
// Bit 0 corresponds to the closest socket for channel 0,
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Bit 1 to the next socket for channel 0,
|
* addresses of DIMM slots on the mainboard.
|
||||||
// ...
|
* @return A bitmask indicating which of the possible sockets for each channel
|
||||||
// Bit MAX_DIMM_SOCKETS_PER_CHANNEL-1 to the last socket for channel 0,
|
* was found to contain a compatible DIMM.
|
||||||
// Bit MAX_DIMM_SOCKETS_PER_CHANNEL is the closest socket for channel 1,
|
* Bit 0 corresponds to the closest socket for channel 0
|
||||||
// ...
|
* Bit 1 to the next socket for channel 0
|
||||||
// Bit 2*MAX_DIMM_SOCKETS_PER_CHANNEL-1 is the last socket for channel 1
|
* ...
|
||||||
// Description: Scan for compatible DIMMs.
|
* Bit MAX_DIMM_SOCKETS_PER_CHANNEL-1 to the last socket for channel 0
|
||||||
// The code in this module only supports dual-channel operation,
|
* Bit MAX_DIMM_SOCKETS_PER_CHANNEL is the closest socket for channel 1
|
||||||
// so we test that compatible DIMMs are paired.
|
* ...
|
||||||
//
|
* Bit 2*MAX_DIMM_SOCKETS_PER_CHANNEL-1 is the last socket for channel 1
|
||||||
|
*/
|
||||||
static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -828,25 +830,17 @@ static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
||||||
return dimm_mask;
|
return dimm_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*-----------------------------------------------------------------------------
|
||||||
/* SPD (SERIAL PRESENCE DETECT) FUNCTIONS */
|
SDRAM configuration functions:
|
||||||
/**********************************************************************************/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: do_ram_command
|
* Send the specified command to all DIMMs.
|
||||||
// Parameters:
|
*
|
||||||
// command - specifies the command to be sent to the DIMMs:
|
* @param command Specifies the command to be sent to the DIMMs.
|
||||||
// RAM_COMMAND_NOP - No Operation
|
* @param jedec_mode_bits For the MRS & EMRS commands, bits 0-12 contain the
|
||||||
// RAM_COMMAND_PRECHARGE - Precharge all banks
|
* register value in JEDEC format.
|
||||||
// RAM_COMMAND_MRS - Load Mode Register
|
*/
|
||||||
// RAM_COMMAND_EMRS - Load Extended Mode Register
|
|
||||||
// RAM_COMMAND_CBR - Auto Refresh ("CAS-before-RAS")
|
|
||||||
// RAM_COMMAND_NORMAL - Normal operation
|
|
||||||
// jedec_mode_bits - for mode register set & extended mode register set
|
|
||||||
// commands, bits 0-12 contain the register value in JEDEC format.
|
|
||||||
// Return Value: None
|
|
||||||
// Description: Send the specified command to all DIMMs.
|
|
||||||
//
|
|
||||||
static void do_ram_command(uint8_t command, uint16_t jedec_mode_bits)
|
static void do_ram_command(uint8_t command, uint16_t jedec_mode_bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -916,14 +910,15 @@ static void do_ram_command(uint8_t command, uint16_t jedec_mode_bits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: set_ram_mode
|
* Set the mode register of all DIMMs.
|
||||||
// Parameters: jedec_mode_bits - for mode register set & extended mode register set
|
*
|
||||||
// commands, bits 0-12 contain the register value in JEDEC format.
|
* The proper CAS# latency setting is added to the mode bits specified
|
||||||
// Return Value: None
|
* by the caller.
|
||||||
// Description: Set the mode register of all DIMMs. The proper CAS# latency
|
*
|
||||||
// setting is added to the mode bits specified by the caller.
|
* @param jedec_mode_bits For the MRS & EMRS commands, bits 0-12 contain the
|
||||||
//
|
* register value in JEDEC format.
|
||||||
|
*/
|
||||||
static void set_ram_mode(uint16_t jedec_mode_bits)
|
static void set_ram_mode(uint16_t jedec_mode_bits)
|
||||||
{
|
{
|
||||||
ASSERT(!(jedec_mode_bits & SDRAM_CAS_MASK));
|
ASSERT(!(jedec_mode_bits & SDRAM_CAS_MASK));
|
||||||
|
@ -948,22 +943,22 @@ static void set_ram_mode(uint16_t jedec_mode_bits)
|
||||||
do_ram_command(RAM_COMMAND_MRS, jedec_mode_bits);
|
do_ram_command(RAM_COMMAND_MRS, jedec_mode_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*-----------------------------------------------------------------------------
|
||||||
/* SDRAM CONFIGURATION FUNCTIONS */
|
DIMM-independant configuration functions:
|
||||||
/**********************************************************************************/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_dimm_row_boundaries
|
* Configure the E7501's DRAM Row Boundary (DRB) registers for the memory
|
||||||
// Parameters:
|
* present in the specified DIMM.
|
||||||
// dimm_log2_num_bits - log2(number of bits) for each side of the DIMM
|
*
|
||||||
// total_dram_64M_multiple - total DRAM in the system (as a
|
* @param dimm_log2_num_bits Specifies log2(number of bits) for each side of
|
||||||
// multiple of 64 MB) for DIMMs < dimm_index
|
* the DIMM.
|
||||||
// dimm_index - which DIMM pair is being processed
|
* @param total_dram_64M_multiple Total DRAM in the system (as a multiple of
|
||||||
// (0..MAX_DIMM_SOCKETS_PER_CHANNEL)
|
* 64 MB) for DIMMs < dimm_index.
|
||||||
// Return Value: New multiple of 64 MB total DRAM in the system
|
* @param dimm_index Which DIMM pair is being processed
|
||||||
// Description: Configure the E7501's DRAM Row Boundary registers for the memory
|
* (0..MAX_DIMM_SOCKETS_PER_CHANNEL).
|
||||||
// present in the specified DIMM.
|
* @return New multiple of 64 MB total DRAM in the system.
|
||||||
//
|
*/
|
||||||
static uint8_t configure_dimm_row_boundaries(struct dimm_size dimm_log2_num_bits, uint8_t total_dram_64M_multiple, unsigned dimm_index)
|
static uint8_t configure_dimm_row_boundaries(struct dimm_size dimm_log2_num_bits, uint8_t total_dram_64M_multiple, unsigned dimm_index)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1017,18 +1012,16 @@ static uint8_t configure_dimm_row_boundaries(struct dimm_size dimm_log2_num_bits
|
||||||
return total_dram_64M_multiple;
|
return total_dram_64M_multiple;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_e7501_ram_addresses
|
* Set the E7501's DRAM row boundary addresses & its Top Of Low Memory (TOLM).
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
*
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* If necessary, set up a remap window so we don't waste DRAM that ordinarily
|
||||||
// dimm_mask - bitmask of populated DIMMs on the board - see
|
* would lie behind addresses reserved for memory-mapped I/O.
|
||||||
// spd_get_supported_dimms()
|
*
|
||||||
// Return Value: None
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Description: Program the E7501's DRAM row boundary addresses and its Top Of
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Low Memory (TOLM). If necessary, set up a remap window so we
|
* @param dimm_mask Bitmask of populated DIMMs, see spd_get_supported_dimms().
|
||||||
// don't waste DRAM that ordinarily would lie behind addresses
|
*/
|
||||||
// reserved for memory-mapped I/O.
|
|
||||||
//
|
|
||||||
static void configure_e7501_ram_addresses(const struct mem_controller
|
static void configure_e7501_ram_addresses(const struct mem_controller
|
||||||
*ctrl, uint8_t dimm_mask)
|
*ctrl, uint8_t dimm_mask)
|
||||||
{
|
{
|
||||||
|
@ -1130,13 +1123,10 @@ static void configure_e7501_ram_addresses(const struct mem_controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: initialize_ecc
|
* If we're configured to use ECC, initialize the SDRAM and clear the E7501's
|
||||||
// Parameters: None
|
* ECC error flags.
|
||||||
// Return Value: None
|
*/
|
||||||
// Description: If we're configured to use ECC, initialize the SDRAM and
|
|
||||||
// clear the E7501's ECC error flags.
|
|
||||||
//
|
|
||||||
static void initialize_ecc(void)
|
static void initialize_ecc(void)
|
||||||
{
|
{
|
||||||
uint32_t dram_controller_mode;
|
uint32_t dram_controller_mode;
|
||||||
|
@ -1177,17 +1167,15 @@ static void initialize_ecc(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_e7501_dram_timing
|
* Program the DRAM Timing register (DRT) of the E7501 (except for CAS#
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* latency, which is assumed to have been programmed already), based on the
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* parameters of the various installed DIMMs.
|
||||||
// dimm_mask - bitmask of populated DIMMs on the board - see
|
*
|
||||||
// spd_get_supported_dimms()
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Return Value: None
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Description: Program the DRAM Timing register of the E7501 (except for CAS#
|
* @param dimm_mask Bitmask of populated DIMMs, see spd_get_supported_dimms().
|
||||||
// latency, which is assumed to have been programmed already), based
|
*/
|
||||||
// on the parameters of the various installed DIMMs.
|
|
||||||
//
|
|
||||||
static void configure_e7501_dram_timing(const struct mem_controller *ctrl,
|
static void configure_e7501_dram_timing(const struct mem_controller *ctrl,
|
||||||
uint8_t dimm_mask)
|
uint8_t dimm_mask)
|
||||||
{
|
{
|
||||||
|
@ -1314,16 +1302,14 @@ static void configure_e7501_dram_timing(const struct mem_controller *ctrl,
|
||||||
die(SPD_ERROR);
|
die(SPD_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_e7501_cas_latency
|
* Determine the shortest CAS# latency that the E7501 and all DIMMs have in
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* common, and program the E7501 to use it.
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
*
|
||||||
// dimm_mask - bitmask of populated DIMMs on the board - see
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// spd_get_supported_dimms()
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Return Value: None
|
* @param dimm_mask Bitmask of populated DIMMs, spd_get_supported_dimms().
|
||||||
// Description: Determine the shortest CAS# latency that the E7501 and all DIMMs
|
*/
|
||||||
// have in common, and program the E7501 to use it.
|
|
||||||
//
|
|
||||||
static void configure_e7501_cas_latency(const struct mem_controller *ctrl,
|
static void configure_e7501_cas_latency(const struct mem_controller *ctrl,
|
||||||
uint8_t dimm_mask)
|
uint8_t dimm_mask)
|
||||||
{
|
{
|
||||||
|
@ -1471,17 +1457,15 @@ static void configure_e7501_cas_latency(const struct mem_controller *ctrl,
|
||||||
die(SPD_ERROR);
|
die(SPD_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_e7501_dram_controller_mode
|
* Configure the refresh interval so that we refresh no more often than
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* required by the "most needy" DIMM. Also disable ECC if any of the DIMMs
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* don't support it.
|
||||||
// dimm_mask - bitmask of populated DIMMs on the board - see
|
*
|
||||||
// spd_get_supported_dimms()
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Return Value: None
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Description: Configure the refresh interval so that we refresh no more often
|
* @param dimm_mask Bitmask of populated DIMMs, spd_get_supported_dimms().
|
||||||
// than required by the "most needy" DIMM. Also disable ECC if any
|
*/
|
||||||
// of the DIMMs don't support it.
|
|
||||||
//
|
|
||||||
static void configure_e7501_dram_controller_mode(const struct
|
static void configure_e7501_dram_controller_mode(const struct
|
||||||
mem_controller *ctrl,
|
mem_controller *ctrl,
|
||||||
uint8_t dimm_mask)
|
uint8_t dimm_mask)
|
||||||
|
@ -1579,18 +1563,16 @@ static void configure_e7501_dram_controller_mode(const struct
|
||||||
pci_write_config32(PCI_DEV(0, 0, 0), DRC, controller_mode);
|
pci_write_config32(PCI_DEV(0, 0, 0), DRC, controller_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: configure_e7501_row_attributes
|
* Configure the E7501's DRAM Row Attributes (DRA) registers based on DIMM
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* parameters read via SPD. This tells the controller the width of the SDRAM
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* chips on each DIMM side (x4 or x8) and the page size of each DIMM side
|
||||||
// dimm_mask - bitmask of populated DIMMs on the board - see
|
* (4, 8, 16, or 32 KB).
|
||||||
// spd_get_supported_dimms()
|
*
|
||||||
// Return Value: None
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Description: Configure the E7501's DRAM Row Attributes (DRA) registers
|
* addresses of DIMM slots on the mainboard.
|
||||||
// based on DIMM parameters read via SPD. This tells the controller
|
* @param dimm_mask Bitmask of populated DIMMs, spd_get_supported_dimms().
|
||||||
// the width of the SDRAM chips on each DIMM side (x4 or x8) and
|
*/
|
||||||
// the page size of each DIMM side (4, 8, 16, or 32 KB).
|
|
||||||
//
|
|
||||||
static void configure_e7501_row_attributes(const struct mem_controller
|
static void configure_e7501_row_attributes(const struct mem_controller
|
||||||
*ctrl, uint8_t dimm_mask)
|
*ctrl, uint8_t dimm_mask)
|
||||||
{
|
{
|
||||||
|
@ -1634,14 +1616,12 @@ static void configure_e7501_row_attributes(const struct mem_controller
|
||||||
pci_write_config32(PCI_DEV(0, 0, 0), DRA, row_attributes);
|
pci_write_config32(PCI_DEV(0, 0, 0), DRA, row_attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/*
|
||||||
// Function: enable_e7501_clocks
|
* Enable clock signals for populated DIMM sockets and disable them for
|
||||||
// Parameters: dimm_mask - bitmask of populated DIMMs on the board - see
|
* unpopulated sockets (to reduce EMI).
|
||||||
// spd_get_supported_dimms()
|
*
|
||||||
// Return Value: None
|
* @param dimm_mask Bitmask of populated DIMMs, see spd_get_supported_dimms().
|
||||||
// Description: Enable clock signals for populated DIMM sockets and disable them
|
*/
|
||||||
// for unpopulated sockets (to reduce EMI).
|
|
||||||
//
|
|
||||||
static void enable_e7501_clocks(uint8_t dimm_mask)
|
static void enable_e7501_clocks(uint8_t dimm_mask)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1660,17 +1640,11 @@ static void enable_e7501_clocks(uint8_t dimm_mask)
|
||||||
pci_write_config8(PCI_DEV(0, 0, 0), CKDIS, clock_disable);
|
pci_write_config8(PCI_DEV(0, 0, 0), CKDIS, clock_disable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/* DIMM-dedependent configuration functions */
|
||||||
/* DIMM-DEDEPENDENT CONFIGURATION FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: RAM_RESET_DDR_PTR
|
* DDR Receive FIFO RE-Sync (?)
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
*/
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
|
||||||
// Return Value: None
|
|
||||||
// Description: DDR Receive FIFO RE-Sync (?)
|
|
||||||
//
|
|
||||||
static void RAM_RESET_DDR_PTR(void)
|
static void RAM_RESET_DDR_PTR(void)
|
||||||
{
|
{
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
|
@ -1683,17 +1657,15 @@ static void RAM_RESET_DDR_PTR(void)
|
||||||
pci_write_config8(PCI_DEV(0, 0, 0), 0x88, byte);
|
pci_write_config8(PCI_DEV(0, 0, 0), 0x88, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: ram_set_d0f0_regs
|
* Set E7501 registers that are either independent of DIMM specifics, or
|
||||||
// Parameters: None
|
* establish default settings that will be overridden when we learn the
|
||||||
// Return Value: None
|
* specifics.
|
||||||
// Description: Set E7501 registers that are either independent of DIMM specifics,
|
*
|
||||||
// or establish default settings that will be overridden when we
|
* This sets PCI configuration registers to known good values based on the
|
||||||
// learn the specifics.
|
* table 'constant_register_values', which are a triple of configuration
|
||||||
// This sets PCI configuration registers to known good values based
|
* register offset, mask, and bits to set.
|
||||||
// on the table 'constant_register_values', which are a triple of
|
*/
|
||||||
// configuration register offset, mask, and bits to set.
|
|
||||||
//
|
|
||||||
static void ram_set_d0f0_regs(void)
|
static void ram_set_d0f0_regs(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1726,14 +1698,13 @@ static void ram_set_d0f0_regs(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: write_8dwords
|
* Copy 64 bytes from one location to another.
|
||||||
// Parameters: src_addr
|
*
|
||||||
// dst_addr
|
* @param src_addr TODO
|
||||||
// Return Value: None
|
* @param dst_addr TODO
|
||||||
// Description: Copy 64 bytes from one location to another.
|
*/
|
||||||
//
|
static void write_8dwords(const uint32_t *src_addr, uint32_t dst_addr)
|
||||||
static void write_8dwords(const uint32_t * src_addr, uint32_t dst_addr)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
|
@ -1743,17 +1714,16 @@ static void write_8dwords(const uint32_t * src_addr, uint32_t dst_addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: ram_set_rcomp_regs
|
* Set the E7501's (undocumented) RCOMP registers.
|
||||||
// Parameters: None
|
*
|
||||||
// Return Value: None
|
* Per the 855PM datasheet and IXP2800 HW Initialization Reference Manual,
|
||||||
// Description: Set the E7501's (undocumented) RCOMP registers.
|
* RCOMP registers appear to affect drive strength, pullup/pulldown offset,
|
||||||
// Per the 855PM datasheet and IXP2800 HW Initialization Reference
|
* and slew rate of various signal groups.
|
||||||
// Manual, RCOMP registers appear to affect drive strength,
|
*
|
||||||
// pullup/pulldown offset, and slew rate of various signal groups.
|
* Comments below are conjecture based on apparent similarity between the
|
||||||
// Comments below are conjecture based on apparent similarity
|
* E7501 and these two chips.
|
||||||
// between the E7501 and these two chips.
|
*/
|
||||||
//
|
|
||||||
static void ram_set_rcomp_regs(void)
|
static void ram_set_rcomp_regs(void)
|
||||||
{
|
{
|
||||||
uint32_t dword;
|
uint32_t dword;
|
||||||
|
@ -1857,20 +1827,19 @@ static void ram_set_rcomp_regs(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
/*-----------------------------------------------------------------------------
|
||||||
/* DIMM-INDEPENDENT CONFIGURATION FUNCTIONS */
|
Public interface:
|
||||||
/**********************************************************************************/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_enable
|
* Go through the JEDEC initialization sequence for all DIMMs, then enable
|
||||||
// Parameters: controllers - not used
|
* refresh and initialize ECC and memory to zero. Upon exit, SDRAM is up
|
||||||
// ctrl - PCI addresses of memory controller functions, and
|
* and running.
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
*
|
||||||
// Return Value: None
|
* @param controllers Not used.
|
||||||
// Description: Go through the JEDEC initialization sequence for all DIMMs,
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// then enable refresh and initialize ECC and memory to zero.
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Upon exit, SDRAM is up and running.
|
*/
|
||||||
//
|
|
||||||
static void sdram_enable(int controllers,
|
static void sdram_enable(int controllers,
|
||||||
const struct mem_controller *ctrl)
|
const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
|
@ -1975,16 +1944,14 @@ static void sdram_enable(int controllers,
|
||||||
DUMPNORTH();
|
DUMPNORTH();
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_set_spd_registers
|
* Configure SDRAM controller parameters that depend on characteristics of the
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* DIMMs installed in the system. These characteristics are read from the
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* DIMMs via the standard Serial Presence Detect (SPD) interface.
|
||||||
// Return Value: None
|
*
|
||||||
// Description: Configure SDRAM controller parameters that depend on
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// characteristics of the DIMMs installed in the system. These
|
* addresses of DIMM slots on the mainboard.
|
||||||
// characteristics are read from the DIMMs via the standard Serial
|
*/
|
||||||
// Presence Detect (SPD) interface.
|
|
||||||
//
|
|
||||||
static void sdram_set_spd_registers(const struct mem_controller *ctrl)
|
static void sdram_set_spd_registers(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
uint8_t dimm_mask;
|
uint8_t dimm_mask;
|
||||||
|
@ -2023,14 +1990,13 @@ static void sdram_set_spd_registers(const struct mem_controller *ctrl)
|
||||||
pci_write_config16(PCI_DEV(0, 0, 0), SKPD, dimm_mask);
|
pci_write_config16(PCI_DEV(0, 0, 0), SKPD, dimm_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_set_registers
|
* Do basic RAM setup that does NOT depend on serial presence detect
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
* information (i.e. independent of DIMM specifics).
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
*
|
||||||
// Return Value: None
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Description: Do basic ram setup that does NOT depend on serial presence detect
|
* addresses of DIMM slots on the mainboard.
|
||||||
// information (i.e. independent of DIMM specifics).
|
*/
|
||||||
//
|
|
||||||
static void sdram_set_registers(const struct mem_controller *ctrl)
|
static void sdram_set_registers(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
RAM_DEBUG_MESSAGE("Northbridge prior to SDRAM init:\n");
|
RAM_DEBUG_MESSAGE("Northbridge prior to SDRAM init:\n");
|
||||||
|
@ -2039,7 +2005,3 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
|
||||||
ram_set_rcomp_regs();
|
ram_set_rcomp_regs();
|
||||||
ram_set_d0f0_regs();
|
ram_set_d0f0_regs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
/* PUBLIC INTERFACE */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cpu/x86/mtrr.h>
|
#include <cpu/x86/mtrr.h>
|
||||||
|
@ -81,8 +80,6 @@ static void sdram_set_registers(const struct mem_controller *ctrl)
|
||||||
print_spew("done.\n");
|
print_spew("done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct dimm_size {
|
struct dimm_size {
|
||||||
unsigned long side1;
|
unsigned long side1;
|
||||||
unsigned long side2;
|
unsigned long side2;
|
||||||
|
@ -209,7 +206,6 @@ static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
|
static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
unsigned dimm_mask;
|
unsigned dimm_mask;
|
||||||
|
@ -236,7 +232,6 @@ static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
|
||||||
return dimm_mask;
|
return dimm_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int spd_set_row_attributes(const struct mem_controller *ctrl,
|
static int spd_set_row_attributes(const struct mem_controller *ctrl,
|
||||||
long dimm_mask)
|
long dimm_mask)
|
||||||
{
|
{
|
||||||
|
@ -296,7 +291,6 @@ hw_err:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int spd_set_drt_attributes(const struct mem_controller *ctrl,
|
static int spd_set_drt_attributes(const struct mem_controller *ctrl,
|
||||||
long dimm_mask, uint32_t drc)
|
long dimm_mask, uint32_t drc)
|
||||||
{
|
{
|
||||||
|
@ -798,6 +792,7 @@ static void set_on_dimm_termination_enable(const struct mem_controller *ctrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_receive_enable(const struct mem_controller *ctrl)
|
static void set_receive_enable(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -1030,7 +1025,6 @@ static void set_receive_enable(const struct mem_controller *ctrl)
|
||||||
write32(BAR+0x154, recenb);
|
write32(BAR+0x154, recenb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
|
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cpu/x86/mtrr.h>
|
#include <cpu/x86/mtrr.h>
|
||||||
|
|
|
@ -25,6 +25,10 @@
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include "i855.h"
|
#include "i855.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------
|
||||||
|
Macros and definitions:
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define VALIDATE_DIMM_COMPATIBILITY
|
#define VALIDATE_DIMM_COMPATIBILITY
|
||||||
|
|
||||||
/* Debugging macros. */
|
/* Debugging macros. */
|
||||||
|
@ -65,10 +69,6 @@ struct dimm_size {
|
||||||
unsigned int side2;
|
unsigned int side2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
||||||
/* DEFINITIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
static const uint32_t refresh_frequency[] = {
|
static const uint32_t refresh_frequency[] = {
|
||||||
/* Relative frequency (array value) of each E7501 Refresh Mode Select
|
/* Relative frequency (array value) of each E7501 Refresh Mode Select
|
||||||
* (RMS) value (array index)
|
* (RMS) value (array index)
|
||||||
|
@ -104,7 +104,7 @@ static const uint32_t refresh_rate_map[] = {
|
||||||
#define MAX_SPD_REFRESH_RATE ((sizeof(refresh_rate_map) / sizeof(uint32_t)) - 1)
|
#define MAX_SPD_REFRESH_RATE ((sizeof(refresh_rate_map) / sizeof(uint32_t)) - 1)
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
SPD functions.
|
SPD functions:
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void die_on_spd_error(int spd_return_value)
|
static void die_on_spd_error(int spd_return_value)
|
||||||
|
@ -117,15 +117,16 @@ static void die_on_spd_error(int spd_return_value)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_spd_get_page_size
|
* Calculate the page size for each physical bank of the DIMM:
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
*
|
||||||
// Return Value: struct dimm_size - log2(page size) for each side of the DIMM.
|
* log2(page size) = (# columns) + log2(data width)
|
||||||
// Description: Calculate the page size for each physical bank of the DIMM:
|
*
|
||||||
// log2(page size) = (# columns) + log2(data width)
|
* NOTE: Page size is the total number of data bits in a row.
|
||||||
//
|
*
|
||||||
// NOTE: page size is the total number of data bits in a row.
|
* @param dimm_socket_address SMBus address of DIMM socket to interrogate.
|
||||||
//
|
* @return log2(page size) for each side of the DIMM.
|
||||||
|
*/
|
||||||
static struct dimm_size sdram_spd_get_page_size(uint16_t dimm_socket_address)
|
static struct dimm_size sdram_spd_get_page_size(uint16_t dimm_socket_address)
|
||||||
{
|
{
|
||||||
uint16_t module_data_width;
|
uint16_t module_data_width;
|
||||||
|
@ -180,13 +181,12 @@ static struct dimm_size sdram_spd_get_page_size(uint16_t dimm_socket_address)
|
||||||
return pgsz;
|
return pgsz;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: sdram_spd_get_width
|
* Read the width in bits of each DIMM side's DRAMs via SPD (i.e. 4, 8, 16).
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
*
|
||||||
// Return Value: dimm_size - width in bits of each DIMM side's DRAMs.
|
* @param dimm_socket_address SMBus address of DIMM socket to interrogate.
|
||||||
// Description: Read the width in bits of each DIMM side's DRAMs via SPD.
|
* @return Width in bits of each DIMM side's DRAMs.
|
||||||
// (i.e. 4, 8, 16)
|
*/
|
||||||
//
|
|
||||||
static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -225,18 +225,19 @@ static struct dimm_size sdram_spd_get_width(uint16_t dimm_socket_address)
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: spd_get_dimm_size
|
* Calculate the log base 2 size in bits of both DIMM sides.
|
||||||
// Parameters: dimm_socket_address - SMBus address of DIMM socket to interrogate
|
*
|
||||||
// Return Value: dimm_size - log2(number of bits) for each side of the DIMM
|
* log2(# bits) = (# columns) + log2(data width) +
|
||||||
// Description: Calculate the log base 2 size in bits of both DIMM sides.
|
* (# rows) + log2(banks per SDRAM)
|
||||||
// log2(# bits) = (# columns) + log2(data width) +
|
*
|
||||||
// (# rows) + log2(banks per SDRAM)
|
* Note that it might be easier to use SPD byte 31 here, it has the DIMM size
|
||||||
//
|
* as a multiple of 4MB. The way we do it now we can size both sides of an
|
||||||
// Note that it might be easier to use SPD byte 31 here, it has the
|
* asymmetric DIMM.
|
||||||
// DIMM size as a multiple of 4MB. The way we do it now we can size
|
*
|
||||||
// both sides of an asymmetric dimm.
|
* @param dimm SMBus address of DIMM socket to interrogate.
|
||||||
//
|
* @return log2(number of bits) for each side of the DIMM.
|
||||||
|
*/
|
||||||
static struct dimm_size spd_get_dimm_size(unsigned dimm)
|
static struct dimm_size spd_get_dimm_size(unsigned dimm)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
@ -270,13 +271,13 @@ static struct dimm_size spd_get_dimm_size(unsigned dimm)
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: spd_get_supported_dimms
|
* Scan for compatible DIMMs.
|
||||||
// Parameters: ctrl - PCI addresses of memory controller functions, and
|
*
|
||||||
// SMBus addresses of DIMM slots on the mainboard
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
// Return Value: uint8_t - a bitmask indicating which sockets contain a compatible DIMM.
|
* addresses of DIMM slots on the mainboard.
|
||||||
// Description: Scan for compatible DIMMs.
|
* @return A bitmask indicating which sockets contain a compatible DIMM.
|
||||||
//
|
*/
|
||||||
static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -356,8 +357,9 @@ static uint8_t spd_get_supported_dimms(const struct mem_controller *ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
DIMM-initialization functions.
|
SDRAM configuration functions:
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void do_ram_command(uint8_t command, uint16_t jedec_mode_bits)
|
static void do_ram_command(uint8_t command, uint16_t jedec_mode_bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -487,14 +489,16 @@ static void sdram_enable(int controllers, const struct mem_controller *ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------
|
/*-----------------------------------------------------------------------------
|
||||||
DIMM-independant configuration functions.
|
DIMM-independant configuration functions:
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set only what I need until it works, then make it figure things out on boot
|
* Set only what I need until it works, then make it figure things out on boot
|
||||||
* assumes only one dimm is populated
|
* assumes only one DIMM is populated.
|
||||||
*/
|
*
|
||||||
|
* @param ctrl PCI addresses of memory controller functions, and SMBus
|
||||||
|
* addresses of DIMM slots on the mainboard.
|
||||||
|
*/
|
||||||
static void sdram_set_registers(const struct mem_controller *ctrl)
|
static void sdram_set_registers(const struct mem_controller *ctrl)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -32,9 +32,7 @@ void i82801cx_hard_reset(void);
|
||||||
#define RTC_POWER_FAILED (1<<1)
|
#define RTC_POWER_FAILED (1<<1)
|
||||||
#define SLEEP_AFTER_POWER_FAIL (1<<0)
|
#define SLEEP_AFTER_POWER_FAIL (1<<0)
|
||||||
|
|
||||||
/********************************************************************/
|
/* IDE controller: */
|
||||||
/* IDE Controller */
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
// PCI Configuration Space (D31:F1)
|
// PCI Configuration Space (D31:F1)
|
||||||
#define IDE_TIM_PRI 0x40 // IDE timings, primary
|
#define IDE_TIM_PRI 0x40 // IDE timings, primary
|
||||||
|
@ -44,9 +42,7 @@ void i82801cx_hard_reset(void);
|
||||||
// IDE_TIM bits
|
// IDE_TIM bits
|
||||||
#define IDE_DECODE_ENABLE (1<<15)
|
#define IDE_DECODE_ENABLE (1<<15)
|
||||||
|
|
||||||
/********************************************************************/
|
/* SMBus: */
|
||||||
/* SMBus */
|
|
||||||
/********************************************************************/
|
|
||||||
|
|
||||||
// PCI Configuration Space (D31:F3)
|
// PCI Configuration Space (D31:F3)
|
||||||
#define SMB_BASE 0x20
|
#define SMB_BASE 0x20
|
||||||
|
|
|
@ -61,15 +61,14 @@ static void i82801cx_enable_serial_irqs( struct device *dev)
|
||||||
pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
|
pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: i82801cx_lpc_route_dma
|
* Route all DMA channels to either PCI or LPC.
|
||||||
// Parameters: dev
|
*
|
||||||
// mask - identifies whether each channel should be used for PCI DMA
|
* @param dev TODO
|
||||||
// (bit = 0) or LPC DMA (bit = 1). The LSb controls channel 0.
|
* @param mask Identifies whether each channel should be used for PCI DMA
|
||||||
// Channel 4 is not used (reserved).
|
* (bit = 0) or LPC DMA (bit = 1). The LSb controls channel 0.
|
||||||
// Return Value: None
|
* Channel 4 is not used (reserved).
|
||||||
// Description: Route all DMA channels to either PCI or LPC.
|
*/
|
||||||
//
|
|
||||||
static void i82801cx_lpc_route_dma( struct device *dev, uint8_t mask)
|
static void i82801cx_lpc_route_dma( struct device *dev, uint8_t mask)
|
||||||
{
|
{
|
||||||
uint16_t dmaConfig;
|
uint16_t dmaConfig;
|
||||||
|
|
|
@ -18,15 +18,15 @@ static void p64h2_ioapic_enable(device_t dev)
|
||||||
pci_write_config16(dev, PCI_COMMAND, command);
|
pci_write_config16(dev, PCI_COMMAND, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: p64h2_ioapic_init
|
* Configure one of the IOAPICs in a P64H2.
|
||||||
// Parameters: dev - PCI bus/device/function of P64H2 IOAPIC
|
*
|
||||||
// NOTE: There are two IOAPICs per P64H2, at D28:F0 and D30:F0
|
* Note that a PCI bus scan will detect both IOAPICs, so this function
|
||||||
// Return Value: None
|
* will be called twice for each P64H2 in the system.
|
||||||
// Description: Configure one of the IOAPICs in a P64H2.
|
*
|
||||||
// Note that a PCI bus scan will detect both IOAPICs, so this function
|
* @param dev PCI bus/device/function of P64H2 IOAPIC.
|
||||||
// will be called twice for each P64H2 in the system.
|
* NOTE: There are two IOAPICs per P64H2, at D28:F0 and D30:F0.
|
||||||
//
|
*/
|
||||||
static void p64h2_ioapic_init(device_t dev)
|
static void p64h2_ioapic_init(device_t dev)
|
||||||
{
|
{
|
||||||
uint32_t memoryBase;
|
uint32_t memoryBase;
|
||||||
|
|
|
@ -41,22 +41,6 @@
|
||||||
#include <cpu/amd/model_fxx_rev.h>
|
#include <cpu/amd/model_fxx_rev.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read resources for AGP aperture
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
*
|
|
||||||
* There is only one AGP aperture resource needed. The resoruce is added to
|
|
||||||
* the northbridge of BSP.
|
|
||||||
*
|
|
||||||
* The same trick can be used to augment legacy VGA resources which can
|
|
||||||
* be detect by generic pci reousrce allocator for VGA devices.
|
|
||||||
* BAD: it is more tricky than I think, the resource allocation code is
|
|
||||||
* implemented in a way to NOT DOING legacy VGA resource allcation on
|
|
||||||
* purpose :-(.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct msr_struct
|
typedef struct msr_struct
|
||||||
{
|
{
|
||||||
unsigned lo;
|
unsigned lo;
|
||||||
|
@ -71,6 +55,20 @@ static inline msr_t rdmsr(unsigned index)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read resources for AGP aperture.
|
||||||
|
*
|
||||||
|
* There is only one AGP aperture resource needed. The resoruce is added to
|
||||||
|
* the northbridge of BSP.
|
||||||
|
*
|
||||||
|
* The same trick can be used to augment legacy VGA resources which can
|
||||||
|
* be detect by generic PCI resource allocator for VGA devices.
|
||||||
|
* BAD: it is more tricky than I think, the resource allocation code is
|
||||||
|
* implemented in a way to NOT DOING legacy VGA resource allcation on
|
||||||
|
* purpose :-(.
|
||||||
|
*
|
||||||
|
* @param dev TODO
|
||||||
|
*/
|
||||||
static void sis761_read_resources(device_t dev)
|
static void sis761_read_resources(device_t dev)
|
||||||
{
|
{
|
||||||
/* Read the generic PCI resources */
|
/* Read the generic PCI resources */
|
||||||
|
|
|
@ -184,10 +184,9 @@ static void sis966_lpc_read_resources(device_t dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable resources for children devices
|
* Enable resources for children devices.
|
||||||
*
|
|
||||||
* @param dev the device whos children's resources are to be enabled
|
|
||||||
*
|
*
|
||||||
|
* @param dev The device whos children's resources are to be enabled.
|
||||||
*/
|
*/
|
||||||
static void sis966_lpc_enable_childrens_resources(device_t dev)
|
static void sis966_lpc_enable_childrens_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -124,17 +124,14 @@ static void set_apc(struct device *dev)
|
||||||
pci_write_config8(dev, 0x73, bTmp);
|
pci_write_config8(dev, 0x73, bTmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
/**
|
||||||
// Procedure: ReadEEprom
|
* Read one word out of the serial EEPROM.
|
||||||
//
|
*
|
||||||
// Description: This routine serially reads one word out of the EEPROM.
|
* @param dev TODO
|
||||||
//
|
* @param base TODO
|
||||||
// Arguments:
|
* @param Reg EEPROM word to read.
|
||||||
// Reg - EEPROM word to read.
|
* @return Contents of EEPROM word (Reg).
|
||||||
//
|
*/
|
||||||
// Returns:
|
|
||||||
// Contents of EEPROM word (Reg).
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
#define LoopNum 200
|
#define LoopNum 200
|
||||||
static unsigned long ReadEEprom( struct device *dev, u32 base, u32 Reg)
|
static unsigned long ReadEEprom( struct device *dev, u32 base, u32 Reg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,38 +23,26 @@
|
||||||
#include <arch/romcc_io.h>
|
#include <arch/romcc_io.h>
|
||||||
#include "lpc47b272.h"
|
#include "lpc47b272.h"
|
||||||
|
|
||||||
/*
|
/** Enable access to the LPC47B272's configuration registers. */
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47B272's configuration registers.
|
|
||||||
*/
|
|
||||||
static inline void pnp_enter_conf_state(device_t dev)
|
static inline void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0x55, port);
|
outb(0x55, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47B272's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47B272's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0xaa, port);
|
outb(0xaa, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47b272_enable_serial
|
* Configure the base I/O port of the specified serial device and enable the
|
||||||
* Parameters: dev - high 8 bits = Super I/O port,
|
* serial device.
|
||||||
* low 8 bits = logical device number (per lpc47b272.h)
|
*
|
||||||
* iobase - processor I/O port address to assign to this serial device
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
* Return Value: bool
|
* @param iobase Processor I/O port address to assign to this serial device.
|
||||||
* Description: Configure the base I/O port of the specified serial device
|
|
||||||
* and enable the serial device.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47b272_enable_serial(device_t dev, unsigned iobase)
|
static void lpc47b272_enable_serial(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -69,30 +69,23 @@ static struct pnp_info pnp_dev_info[] = {
|
||||||
{ &ops, LPC47B272_RT, PNP_IO0, { 0x780, 0 }, },
|
{ &ops, LPC47B272_RT, PNP_IO0, { 0x780, 0 }, },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**
|
||||||
/* PUBLIC INTERFACE */
|
* Create device structures and allocate resources to devices specified in the
|
||||||
/**********************************************************************************/
|
* pnp_dev_info array (above).
|
||||||
|
*
|
||||||
/*
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* Function: enable_dev
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Create device structures and allocate resources to devices
|
|
||||||
* specified in the pnp_dev_info array (above).
|
|
||||||
*/
|
*/
|
||||||
static void enable_dev(device_t dev)
|
static void enable_dev(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enable_devices(dev, &pnp_ops,
|
pnp_enable_devices(dev, &pnp_ops, ARRAY_SIZE(pnp_dev_info),
|
||||||
ARRAY_SIZE(pnp_dev_info),
|
|
||||||
pnp_dev_info);
|
pnp_dev_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47b272_pnp_set_resources
|
* Configure the specified Super I/O device with the resources (I/O space,
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
* etc.) that have been allocated for it.
|
||||||
* Return Value: None
|
*
|
||||||
* Description: Configure the specified Super I/O device with the resources
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* (I/O space, etc.) that have been allocated for it.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47b272_pnp_set_resources(device_t dev)
|
static void lpc47b272_pnp_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -122,13 +115,13 @@ static void lpc47b272_pnp_enable(device_t dev)
|
||||||
pnp_exit_conf_state(dev);
|
pnp_exit_conf_state(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47b272_init
|
* Initialize the specified Super I/O device.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* Devices other than COM ports and the keyboard controller are ignored.
|
||||||
* Description: Initialize the specified Super I/O device.
|
* For COM ports, we configure the baud rate.
|
||||||
* Devices other than COM ports and the keyboard controller are
|
*
|
||||||
* ignored. For COM ports, we configure the baud rate.
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
*/
|
*/
|
||||||
static void lpc47b272_init(device_t dev)
|
static void lpc47b272_init(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -157,40 +150,25 @@ static void lpc47b272_init(device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************/
|
/** Enable access to the LPC47B272's configuration registers. */
|
||||||
/* PRIVATE FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47B272's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_enter_conf_state(device_t dev)
|
static void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0x55, dev->path.pnp.port);
|
outb(0x55, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47B272's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47B272's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0xaa, dev->path.pnp.port);
|
outb(0xaa, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/**
|
||||||
* Function: dump_pnp_device
|
* Print the values of all of the LPC47B272's configuration registers.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* NOTE: The LPC47B272 must be in config mode when this function is called.
|
||||||
* Description: Print the values of all of the LPC47B272's configuration registers.
|
*
|
||||||
* NOTE: The LPC47B272 must be in configuration mode when this
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* function is called.
|
|
||||||
*/
|
*/
|
||||||
static void dump_pnp_device(device_t dev)
|
static void dump_pnp_device(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,38 +22,26 @@
|
||||||
#include <arch/romcc_io.h>
|
#include <arch/romcc_io.h>
|
||||||
#include "lpc47m10x.h"
|
#include "lpc47m10x.h"
|
||||||
|
|
||||||
/*
|
/** Enable access to the LPC47M10X2's configuration registers. */
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47M10X2's configuration registers.
|
|
||||||
*/
|
|
||||||
static inline void pnp_enter_conf_state(device_t dev)
|
static inline void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0x55, port);
|
outb(0x55, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47M10X2's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47M10X2's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0xaa, port);
|
outb(0xaa, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47m10x_enable_serial
|
* Configure the base I/O port of the specified serial device and enable the
|
||||||
* Parameters: dev - high 8 bits = Super I/O port,
|
* serial device.
|
||||||
* low 8 bits = logical device number (per lpc47m10x.h)
|
*
|
||||||
* iobase - processor I/O port address to assign to this serial device
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
* Return Value: bool
|
* @param iobase Processor I/O port address to assign to this serial device.
|
||||||
* Description: Configure the base I/O port of the specified serial device
|
|
||||||
* and enable the serial device.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47m10x_enable_serial(device_t dev, unsigned iobase)
|
static void lpc47m10x_enable_serial(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,30 +67,23 @@ static struct pnp_info pnp_dev_info[] = {
|
||||||
{ &ops, LPC47M10X2_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
|
{ &ops, LPC47M10X2_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1, { 0x7ff, 0 }, { 0x7ff, 0x4}, },
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**
|
||||||
/* PUBLIC INTERFACE */
|
* Create device structures and allocate resources to devices specified in the
|
||||||
/**********************************************************************************/
|
* pnp_dev_info array (above).
|
||||||
|
*
|
||||||
/*
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* Function: enable_dev
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Create device structures and allocate resources to devices
|
|
||||||
* specified in the pnp_dev_info array (above).
|
|
||||||
*/
|
*/
|
||||||
static void enable_dev(device_t dev)
|
static void enable_dev(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enable_devices(dev, &pnp_ops,
|
pnp_enable_devices(dev, &pnp_ops, ARRAY_SIZE(pnp_dev_info),
|
||||||
ARRAY_SIZE(pnp_dev_info),
|
|
||||||
pnp_dev_info);
|
pnp_dev_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47m10x_pnp_set_resources
|
* Configure the specified Super I/O device with the resources (I/O space,
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
* etc.) that have been allocated for it.
|
||||||
* Return Value: None
|
*
|
||||||
* Description: Configure the specified Super I/O device with the resources
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* (I/O space, etc.) that have been allocated for it.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47m10x_pnp_set_resources(device_t dev)
|
static void lpc47m10x_pnp_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -120,13 +113,13 @@ static void lpc47m10x_pnp_enable(device_t dev)
|
||||||
pnp_exit_conf_state(dev);
|
pnp_exit_conf_state(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47m10x_init
|
* Initialize the specified Super I/O device.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* Devices other than COM ports and the keyboard controller are ignored.
|
||||||
* Description: Initialize the specified Super I/O device.
|
* For COM ports, we configure the baud rate.
|
||||||
* Devices other than COM ports and the keyboard controller are
|
*
|
||||||
* ignored. For COM ports, we configure the baud rate.
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
*/
|
*/
|
||||||
static void lpc47m10x_init(device_t dev)
|
static void lpc47m10x_init(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -155,40 +148,25 @@ static void lpc47m10x_init(device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************/
|
/** Enable access to the LPC47M10X2's configuration registers. */
|
||||||
/* PRIVATE FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47M10X2's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_enter_conf_state(device_t dev)
|
static void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0x55, dev->path.pnp.port);
|
outb(0x55, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47M10X2's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47M10X2's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0xaa, dev->path.pnp.port);
|
outb(0xaa, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/**
|
||||||
* Function: dump_pnp_device
|
* Print the values of all of the LPC47M10X2's configuration registers.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* NOTE: The LPC47M10X2 must be in config mode when this function is called.
|
||||||
* Description: Print the values of all of the LPC47M10X2's configuration registers.
|
*
|
||||||
* NOTE: The LPC47M10X2 must be in configuration mode when this
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* function is called.
|
|
||||||
*/
|
*/
|
||||||
static void dump_pnp_device(device_t dev)
|
static void dump_pnp_device(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,38 +24,25 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "lpc47n217.h"
|
#include "lpc47n217.h"
|
||||||
|
|
||||||
/*
|
/** Enable access to the LPC47N217's configuration registers. */
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47N217's configuration registers.
|
|
||||||
*/
|
|
||||||
static inline void pnp_enter_conf_state(device_t dev)
|
static inline void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0x55, port);
|
outb(0x55, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47N217's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - high 8 bits = Super I/O port
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47N217's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev>>8;
|
unsigned port = dev>>8;
|
||||||
outb(0xaa, port);
|
outb(0xaa, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47n217_pnp_set_iobase
|
* Program the base I/O port for the specified logical device.
|
||||||
* Parameters: dev - high 8 bits = Super I/O port,
|
|
||||||
* low 8 bits = logical device number (per lpc47n217.h)
|
|
||||||
* iobase - base I/O port for the logical device
|
|
||||||
* Return Value:None
|
|
||||||
* Description: Program the base I/O port for the specified logical device.
|
|
||||||
*
|
*
|
||||||
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
|
* @param iobase Base I/O port for the logical device.
|
||||||
*/
|
*/
|
||||||
void lpc47n217_pnp_set_iobase(device_t dev, unsigned iobase)
|
void lpc47n217_pnp_set_iobase(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
|
@ -80,19 +67,17 @@ void lpc47n217_pnp_set_iobase(device_t dev, unsigned iobase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47n217_pnp_set_enable
|
* Enable or disable the specified logical device.
|
||||||
* Parameters: dev - high 8 bits = Super I/O port,
|
*
|
||||||
* low 8 bits = logical device number (per lpc47n217.h)
|
* Technically, a full disable requires setting the device's base I/O port
|
||||||
* enable - 0 to disable, anythig else to enable
|
* below 0x100. We don't do that here, because we don't have access to a data
|
||||||
* Return Value:None
|
* structure that specifies what the 'real' base port is (when asked to enable
|
||||||
* Description: Enable or disable the specified logical device.
|
* the device). Also the function is used only to disable the device while its
|
||||||
* Technically, a full disable requires setting the device's base
|
* true base port is programmed (see lpc47n217_enable_serial() below).
|
||||||
* I/O port below 0x100. We don't do that here, because we don't
|
*
|
||||||
* have access to a data structure that specifies what the 'real'
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
* base port is (when asked to enable the device). Also the function
|
* @param enable 0 to disable, anythig else to enable.
|
||||||
* is used only to disable the device while its true base port is
|
|
||||||
* programmed (see lpc47n217_enable_serial() below).
|
|
||||||
*/
|
*/
|
||||||
void lpc47n217_pnp_set_enable(device_t dev, int enable)
|
void lpc47n217_pnp_set_enable(device_t dev, int enable)
|
||||||
{
|
{
|
||||||
|
@ -130,20 +115,19 @@ void lpc47n217_pnp_set_enable(device_t dev, int enable)
|
||||||
pnp_write_config(dev, power_register, new_power);
|
pnp_write_config(dev, power_register, new_power);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47n217_enable_serial
|
* Configure the base I/O port of the specified serial device and enable the
|
||||||
* Parameters: dev - high 8 bits = Super I/O port,
|
* serial device.
|
||||||
* low 8 bits = logical device number (per lpc47n217.h)
|
*
|
||||||
* iobase - processor I/O port address to assign to this serial device
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
* Return Value:bool
|
* @param iobase Processor I/O port address to assign to this serial device.
|
||||||
* Description: Configure the base I/O port of the specified serial device
|
|
||||||
* and enable the serial device.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47n217_enable_serial(device_t dev, unsigned iobase)
|
static void lpc47n217_enable_serial(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
/* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
/*
|
||||||
* support for logical devices, which the LPC47N217 doesn't have*/
|
* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
||||||
|
* support for logical devices, which the LPC47N217 doesn't have.
|
||||||
|
*/
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
lpc47n217_pnp_set_enable(dev, 0);
|
lpc47n217_pnp_set_enable(dev, 0);
|
||||||
lpc47n217_pnp_set_iobase(dev, iobase);
|
lpc47n217_pnp_set_iobase(dev, iobase);
|
||||||
|
|
|
@ -72,30 +72,23 @@ static struct pnp_info pnp_dev_info[] = {
|
||||||
{ &ops, LPC47N217_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, }
|
{ &ops, LPC47N217_SP2, PNP_IO0 | PNP_IRQ0, { 0x7f8, 0 }, }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**
|
||||||
/* PUBLIC INTERFACE */
|
* Create device structures and allocate resources to devices specified in the
|
||||||
/**********************************************************************************/
|
* pnp_dev_info array (above).
|
||||||
|
*
|
||||||
/*
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* Function: enable_dev
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Create device structures and allocate resources to devices
|
|
||||||
* specified in the pnp_dev_info array (above).
|
|
||||||
*/
|
*/
|
||||||
static void enable_dev(device_t dev)
|
static void enable_dev(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enable_devices(dev, &pnp_ops,
|
pnp_enable_devices(dev, &pnp_ops, ARRAY_SIZE(pnp_dev_info),
|
||||||
ARRAY_SIZE(pnp_dev_info),
|
|
||||||
pnp_dev_info);
|
pnp_dev_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47n217_pnp_set_resources
|
* Configure the specified Super I/O device with the resources (I/O space,
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
* etc.) that have been allocate for it.
|
||||||
* Return Value: None
|
*
|
||||||
* Description: Configure the specified Super I/O device with the resources
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* (I/O space, etc.) that have been allocate for it.
|
|
||||||
*/
|
*/
|
||||||
static void lpc47n217_pnp_set_resources(device_t dev)
|
static void lpc47n217_pnp_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -118,8 +111,9 @@ static void lpc47n217_pnp_enable_resources(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
|
|
||||||
/* NOTE: Cannot use pnp_enable_resources() here because it assumes chip
|
/*
|
||||||
* support for logical devices, which the LPC47N217 doesn't have
|
* NOTE: Cannot use pnp_enable_resources() here because it assumes chip
|
||||||
|
* support for logical devices, which the LPC47N217 doesn't have.
|
||||||
*/
|
*/
|
||||||
lpc47n217_pnp_set_enable(dev, 1);
|
lpc47n217_pnp_set_enable(dev, 1);
|
||||||
|
|
||||||
|
@ -130,10 +124,10 @@ static void lpc47n217_pnp_enable(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
|
|
||||||
/* NOTE: Cannot use pnp_set_enable() here because it assumes chip
|
/*
|
||||||
* support for logical devices, which the LPC47N217 doesn't have
|
* NOTE: Cannot use pnp_set_enable() here because it assumes chip
|
||||||
|
* support for logical devices, which the LPC47N217 doesn't have.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(dev->enabled) {
|
if(dev->enabled) {
|
||||||
lpc47n217_pnp_set_enable(dev, 1);
|
lpc47n217_pnp_set_enable(dev, 1);
|
||||||
}
|
}
|
||||||
|
@ -144,13 +138,13 @@ static void lpc47n217_pnp_enable(device_t dev)
|
||||||
pnp_exit_conf_state(dev);
|
pnp_exit_conf_state(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Function: lpc47n217_init
|
* Initialize the specified Super I/O device.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* Devices other than COM ports are ignored. For COM ports, we configure the
|
||||||
* Description: Initialize the specified Super I/O device.
|
* baud rate.
|
||||||
* Devices other than COM ports are ignored.
|
*
|
||||||
* For COM ports, we configure the baud rate.
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
*/
|
*/
|
||||||
static void lpc47n217_init(device_t dev)
|
static void lpc47n217_init(device_t dev)
|
||||||
{
|
{
|
||||||
|
@ -173,10 +167,6 @@ static void lpc47n217_init(device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/* PRIVATE FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
static void lpc47n217_pnp_set_resource(device_t dev, struct resource *resource)
|
static void lpc47n217_pnp_set_resource(device_t dev, struct resource *resource)
|
||||||
{
|
{
|
||||||
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
||||||
|
@ -186,10 +176,10 @@ static void lpc47n217_pnp_set_resource(device_t dev, struct resource *resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now store the resource */
|
/* Now store the resource */
|
||||||
/* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
/*
|
||||||
* support for logical devices, which the LPC47N217 doesn't have
|
* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
||||||
|
* support for logical devices, which the LPC47N217 doesn't have.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (resource->flags & IORESOURCE_IO) {
|
if (resource->flags & IORESOURCE_IO) {
|
||||||
lpc47n217_pnp_set_iobase(dev, resource->base);
|
lpc47n217_pnp_set_iobase(dev, resource->base);
|
||||||
}
|
}
|
||||||
|
@ -327,36 +317,25 @@ static void lpc47n217_pnp_set_enable(device_t dev, int enable)
|
||||||
pnp_write_config(dev, power_register, new_power);
|
pnp_write_config(dev, power_register, new_power);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Enable access to the LPC47N217's configuration registers. */
|
||||||
* Function: pnp_enter_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Enable access to the LPC47N217's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_enter_conf_state(device_t dev)
|
static void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0x55, dev->path.pnp.port);
|
outb(0x55, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** Disable access to the LPC47N217's configuration registers. */
|
||||||
* Function: pnp_exit_conf_state
|
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
* Return Value: None
|
|
||||||
* Description: Disable access to the LPC47N217's configuration registers.
|
|
||||||
*/
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0xaa, dev->path.pnp.port);
|
outb(0xaa, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/**
|
||||||
* Function: dump_pnp_device
|
* Print the values of all of the LPC47N217's configuration registers.
|
||||||
* Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
* Return Value: None
|
* NOTE: The LPC47N217 must be in config mode when this function is called.
|
||||||
* Description: Print the values of all of the LPC47N217's configuration registers.
|
*
|
||||||
* NOTE: The LPC47N217 must be in configuration mode when this
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
* function is called.
|
|
||||||
*/
|
*/
|
||||||
static void dump_pnp_device(device_t dev)
|
static void dump_pnp_device(device_t dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,9 +17,10 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Since the LPC47N227 does not have logical devices but a flat configuration
|
/*
|
||||||
|
* Since the LPC47N227 does not have logical devices but a flat configuration
|
||||||
* space, these are arbitrary, but must match declarations in the mainboard
|
* space, these are arbitrary, but must match declarations in the mainboard
|
||||||
* devicetree.cb
|
* devicetree.cb.
|
||||||
*/
|
*/
|
||||||
#define LPC47N227_PP 1 /* Parallel Port */
|
#define LPC47N227_PP 1 /* Parallel Port */
|
||||||
#define LPC47N227_SP1 2 /* COM1 */
|
#define LPC47N227_SP1 2 /* COM1 */
|
||||||
|
|
|
@ -23,38 +23,34 @@
|
||||||
#include <arch/romcc_io.h>
|
#include <arch/romcc_io.h>
|
||||||
#include "lpc47n227.h"
|
#include "lpc47n227.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: pnp_enter_conf_state
|
* Enable access to the LPC47N227's configuration registers.
|
||||||
// Parameters: dev - high 8 bits = Super I/O port
|
*
|
||||||
// Return Value: None
|
* @param dev High 8 bits = Super I/O port.
|
||||||
// Description: Enable access to the LPC47N227's configuration registers.
|
*/
|
||||||
//
|
|
||||||
static inline void pnp_enter_conf_state(device_t dev)
|
static inline void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev >> 8;
|
unsigned port = dev >> 8;
|
||||||
outb(0x55, port);
|
outb(0x55, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: pnp_exit_conf_state
|
* Disable access to the LPC47N227's configuration registers.
|
||||||
// Parameters: dev - high 8 bits = Super I/O port
|
*
|
||||||
// Return Value: None
|
* @param dev High 8 bits = Super I/O port.
|
||||||
// Description: Disable access to the LPC47N227's configuration registers.
|
*/
|
||||||
//
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
unsigned port = dev >> 8;
|
unsigned port = dev >> 8;
|
||||||
outb(0xaa, port);
|
outb(0xaa, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: lpc47n227_pnp_set_iobase
|
* Program the base I/O port for the specified logical device.
|
||||||
// Parameters: dev - high 8 bits = Super I/O port,
|
*
|
||||||
// low 8 bits = logical device number (per lpc47n227.h)
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
// iobase - base I/O port for the logical device
|
* @param iobase Base I/O port for the logical device.
|
||||||
// Return Value: None
|
*/
|
||||||
// Description: Program the base I/O port for the specified logical device.
|
|
||||||
//
|
|
||||||
void lpc47n227_pnp_set_iobase(device_t dev, unsigned iobase)
|
void lpc47n227_pnp_set_iobase(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
// LPC47N227 requires base ports to be a multiple of 4
|
// LPC47N227 requires base ports to be a multiple of 4
|
||||||
|
@ -78,20 +74,18 @@ void lpc47n227_pnp_set_iobase(device_t dev, unsigned iobase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: lpc47n227_pnp_set_enable
|
* Enable or disable the specified logical device.
|
||||||
// Parameters: dev - high 8 bits = Super I/O port,
|
*
|
||||||
// low 8 bits = logical device number (per lpc47n227.h)
|
* Technically, a full disable requires setting the device's base I/O port
|
||||||
// enable - 0 to disable, anythig else to enable
|
* below 0x100. We don't do that here, because we don't have access to a data
|
||||||
// Return Value: None
|
* structure that specifies what the 'real' base port is (when asked to enable
|
||||||
// Description: Enable or disable the specified logical device.
|
* the device). Also the function is used only to disable the device while its
|
||||||
// Technically, a full disable requires setting the device's base
|
* true base port is programmed (see lpc47n227_enable_serial() below).
|
||||||
// I/O port below 0x100. We don't do that here, because we don't
|
*
|
||||||
// have access to a data structure that specifies what the 'real'
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
// base port is (when asked to enable the device). Also the function
|
* @param enable 0 to disable, anythig else to enable.
|
||||||
// is used only to disable the device while its true base port is
|
*/
|
||||||
// programmed (see lpc47n227_enable_serial() below).
|
|
||||||
//
|
|
||||||
void lpc47n227_pnp_set_enable(device_t dev, int enable)
|
void lpc47n227_pnp_set_enable(device_t dev, int enable)
|
||||||
{
|
{
|
||||||
uint8_t power_register = 0;
|
uint8_t power_register = 0;
|
||||||
|
@ -128,20 +122,19 @@ void lpc47n227_pnp_set_enable(device_t dev, int enable)
|
||||||
pnp_write_config(dev, power_register, new_power);
|
pnp_write_config(dev, power_register, new_power);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: lpc47n227_enable_serial
|
* Configure the base I/O port of the specified serial device and enable the
|
||||||
// Parameters: dev - high 8 bits = Super I/O port,
|
* serial device.
|
||||||
// low 8 bits = logical device number (per lpc47n227.h)
|
*
|
||||||
// iobase - processor I/O port address to assign to this serial device
|
* @param dev High 8 bits = Super I/O port, low 8 bits = logical device number.
|
||||||
// Return Value: bool
|
* @param iobase Processor I/O port address to assign to this serial device.
|
||||||
// Description: Configure the base I/O port of the specified serial device
|
*/
|
||||||
// and enable the serial device.
|
|
||||||
//
|
|
||||||
static void lpc47n227_enable_serial(device_t dev, unsigned iobase)
|
static void lpc47n227_enable_serial(device_t dev, unsigned iobase)
|
||||||
{
|
{
|
||||||
// NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
/*
|
||||||
// support for logical devices, which the LPC47N227 doesn't have
|
* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
||||||
|
* support for logical devices, which the LPC47N227 doesn't have.
|
||||||
|
*/
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
lpc47n227_pnp_set_enable(dev, 0);
|
lpc47n227_pnp_set_enable(dev, 0);
|
||||||
lpc47n227_pnp_set_iobase(dev, iobase);
|
lpc47n227_pnp_set_iobase(dev, iobase);
|
||||||
|
|
|
@ -70,38 +70,34 @@ static struct pnp_info pnp_dev_info[] = {
|
||||||
{0x7f8, 0x4},}
|
{0x7f8, 0x4},}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**********************************************************************************/
|
/**
|
||||||
/* PUBLIC INTERFACE */
|
* Create device structures and allocate resources to devices specified in the
|
||||||
/**********************************************************************************/
|
* pnp_dev_info array (above).
|
||||||
|
*
|
||||||
//----------------------------------------------------------------------------------
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
// Function: enable_dev
|
*/
|
||||||
// Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
// Return Value: None
|
|
||||||
// Description: Create device structures and allocate resources to devices
|
|
||||||
// specified in the pnp_dev_info array (above).
|
|
||||||
//
|
|
||||||
static void enable_dev(device_t dev)
|
static void enable_dev(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enable_devices(dev, &pnp_ops,
|
pnp_enable_devices(dev, &pnp_ops,
|
||||||
ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
|
ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: lpc47n227_pnp_set_resources
|
* Configure the specified Super I/O device with the resources (I/O space,
|
||||||
// Parameters: dev - pointer to structure describing a Super I/O device
|
* etc.) that have been allocate for it.
|
||||||
// Return Value: None
|
*
|
||||||
// Description: Configure the specified Super I/O device with the resources
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
// (I/O space, etc.) that have been allocate for it.
|
*/
|
||||||
//
|
|
||||||
void lpc47n227_pnp_set_resources(device_t dev)
|
void lpc47n227_pnp_set_resources(device_t dev)
|
||||||
{
|
{
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
|
|
||||||
// NOTE: Cannot use pnp_set_resources() here because it assumes chip
|
/*
|
||||||
// support for logical devices, which the LPC47N227 doesn't have
|
* NOTE: Cannot use pnp_set_resources() here because it assumes chip
|
||||||
|
* support for logical devices, which the LPC47N227 doesn't have.
|
||||||
|
*/
|
||||||
for (res = dev->resource_list; res; res = res->next)
|
for (res = dev->resource_list; res; res = res->next)
|
||||||
lpc47n227_pnp_set_resource(dev, res);
|
lpc47n227_pnp_set_resource(dev, res);
|
||||||
|
|
||||||
|
@ -112,8 +108,10 @@ void lpc47n227_pnp_enable_resources(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
|
|
||||||
// NOTE: Cannot use pnp_enable_resources() here because it assumes chip
|
/*
|
||||||
// support for logical devices, which the LPC47N227 doesn't have
|
* NOTE: Cannot use pnp_enable_resources() here because it assumes chip
|
||||||
|
* support for logical devices, which the LPC47N227 doesn't have.
|
||||||
|
*/
|
||||||
lpc47n227_pnp_set_enable(dev, 1);
|
lpc47n227_pnp_set_enable(dev, 1);
|
||||||
|
|
||||||
pnp_exit_conf_state(dev);
|
pnp_exit_conf_state(dev);
|
||||||
|
@ -123,9 +121,10 @@ void lpc47n227_pnp_enable(device_t dev)
|
||||||
{
|
{
|
||||||
pnp_enter_conf_state(dev);
|
pnp_enter_conf_state(dev);
|
||||||
|
|
||||||
// NOTE: Cannot use pnp_set_enable() here because it assumes chip
|
/*
|
||||||
// support for logical devices, which the LPC47N227 doesn't have
|
* NOTE: Cannot use pnp_set_enable() here because it assumes chip
|
||||||
|
* support for logical devices, which the LPC47N227 doesn't have.
|
||||||
|
*/
|
||||||
if (dev->enabled) {
|
if (dev->enabled) {
|
||||||
lpc47n227_pnp_set_enable(dev, 1);
|
lpc47n227_pnp_set_enable(dev, 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -135,14 +134,14 @@ void lpc47n227_pnp_enable(device_t dev)
|
||||||
pnp_exit_conf_state(dev);
|
pnp_exit_conf_state(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/**
|
||||||
// Function: lpc47n227_init
|
* Initialize the specified Super I/O device.
|
||||||
// Parameters: dev - pointer to structure describing a Super I/O device
|
*
|
||||||
// Return Value: None
|
* Devices other than COM ports and keyboard controller are ignored.
|
||||||
// Description: Initialize the specified Super I/O device.
|
* For COM ports, we configure the baud rate.
|
||||||
// Devices other than COM ports and keyboard controller are ignored.
|
*
|
||||||
// For COM ports, we configure the baud rate.
|
* @param dev Pointer to structure describing a Super I/O device.
|
||||||
//
|
*/
|
||||||
static void lpc47n227_init(device_t dev)
|
static void lpc47n227_init(device_t dev)
|
||||||
{
|
{
|
||||||
struct superio_smsc_lpc47n227_config *conf = dev->chip_info;
|
struct superio_smsc_lpc47n227_config *conf = dev->chip_info;
|
||||||
|
@ -169,10 +168,6 @@ static void lpc47n227_init(device_t dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************************/
|
|
||||||
/* PRIVATE FUNCTIONS */
|
|
||||||
/**********************************************************************************/
|
|
||||||
|
|
||||||
static void lpc47n227_pnp_set_resource(device_t dev, struct resource *resource)
|
static void lpc47n227_pnp_set_resource(device_t dev, struct resource *resource)
|
||||||
{
|
{
|
||||||
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
if (!(resource->flags & IORESOURCE_ASSIGNED)) {
|
||||||
|
@ -182,9 +177,10 @@ static void lpc47n227_pnp_set_resource(device_t dev, struct resource *resource)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now store the resource */
|
/* Now store the resource */
|
||||||
// NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
/*
|
||||||
// support for logical devices, which the LPC47N227 doesn't have
|
* NOTE: Cannot use pnp_set_XXX() here because they assume chip
|
||||||
|
* support for logical devices, which the LPC47N227 doesn't have.
|
||||||
|
*/
|
||||||
if (resource->flags & IORESOURCE_IO) {
|
if (resource->flags & IORESOURCE_IO) {
|
||||||
lpc47n227_pnp_set_iobase(dev, resource->base);
|
lpc47n227_pnp_set_iobase(dev, resource->base);
|
||||||
} else if (resource->flags & IORESOURCE_DRQ) {
|
} else if (resource->flags & IORESOURCE_DRQ) {
|
||||||
|
@ -328,25 +324,14 @@ void lpc47n227_pnp_set_enable(device_t dev, int enable)
|
||||||
pnp_write_config(dev, power_register, new_power);
|
pnp_write_config(dev, power_register, new_power);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/** Enable access to the LPC47N227's configuration registers. */
|
||||||
// Function: pnp_enter_conf_state
|
|
||||||
// Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
// Return Value: None
|
|
||||||
// Description: Enable access to the LPC47N227's configuration registers.
|
|
||||||
//
|
|
||||||
static void pnp_enter_conf_state(device_t dev)
|
static void pnp_enter_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0x55, dev->path.pnp.port);
|
outb(0x55, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
/** Disable access to the LPC47N227's configuration registers. */
|
||||||
// Function: pnp_exit_conf_state
|
|
||||||
// Parameters: dev - pointer to structure describing a Super I/O device
|
|
||||||
// Return Value: None
|
|
||||||
// Description: Disable access to the LPC47N227's configuration registers.
|
|
||||||
//
|
|
||||||
static void pnp_exit_conf_state(device_t dev)
|
static void pnp_exit_conf_state(device_t dev)
|
||||||
{
|
{
|
||||||
outb(0xaa, dev->path.pnp.port);
|
outb(0xaa, dev->path.pnp.port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue