Add comments, correct warnings, add a note by Marc Jones,
and change a name per Marc Jone's suggestion. Signed-off-by: Ronald G. Minnich <rminnich@gmail.com> Acked-by: Peter Stuge <peter@stuge.se> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@346 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
3311076a44
commit
faf5bc5f1b
2 changed files with 85 additions and 56 deletions
|
|
@ -16,47 +16,59 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <console.h>
|
||||
#include <io.h>
|
||||
#include <msr.h>
|
||||
#include <amd_geodelx.h>
|
||||
#include "cs5536.h"
|
||||
/*
|
||||
* cs5536_early_setup.c:Early chipset initialization for CS5536 companion device
|
||||
* This code is needed for setting up ram, since we need SMBUS working as
|
||||
* well as serial port.
|
||||
* This code is needed for setting up ram, since we need SMBUS working as
|
||||
* well as serial port.
|
||||
* This file implements the initialization sequence documented in section 4.2 of
|
||||
* AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set up GLINK routing for this part. The routing is controlled by an MSR.
|
||||
* @brief Set up GLINK routing for this part. The routing is controlled by an MSR.
|
||||
* This appears to be the
|
||||
* same on all boards.
|
||||
* If you don't know what GLINK routing is, there is no way to explain it here.
|
||||
*/
|
||||
static void cs5536_setup_extmsr(void)
|
||||
void cs5536_setup_extmsr(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
/* forward MSR access to CS5536_GLINK_PORT_NUM to CS5536_DEV_NUM */
|
||||
msr.hi = msr.lo = 0x00000000;
|
||||
if (CS5536_GLINK_PORT_NUM <= 4) {
|
||||
msr.lo = CS5536_DEV_NUM <<
|
||||
(unsigned char)((CS5536_GLINK_PORT_NUM - 1) * 8);
|
||||
} else {
|
||||
msr.hi = CS5536_DEV_NUM <<
|
||||
(unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
|
||||
}
|
||||
#if CS5536_GLINK_PORT_NUM <= 4
|
||||
msr.lo = CS5536_DEV_NUM <<
|
||||
(unsigned char)((CS5536_GLINK_PORT_NUM - 1) * 8);
|
||||
#else
|
||||
msr.hi = CS5536_DEV_NUM <<
|
||||
(unsigned char)((CS5536_GLINK_PORT_NUM - 5) * 8);
|
||||
#endif
|
||||
wrmsr(GLPCI_ExtMSR, msr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup PCI IDSEL for CS5536
|
||||
* @brief Setup PCI IDSEL for CS5536. There is a Magic Register that must be
|
||||
* written so that the chip appears at the expected place in the PCI tree.
|
||||
*/
|
||||
static void cs5536_setup_idsel(void)
|
||||
void cs5536_setup_idsel(void)
|
||||
{
|
||||
/* write IDSEL to the write once register at address 0x0000 */
|
||||
outl(0x1 << (CS5536_DEV_NUM + 10), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Need to get a good explanation of what this is.
|
||||
* @brief Magic Bits for undocumented register.
|
||||
* You don' t need to see those papers.
|
||||
* These are not the bits you're looking for.
|
||||
* You can go about your business.
|
||||
* Move along, move along.
|
||||
*/
|
||||
static void cs5536_usb_swapsif(void)
|
||||
void cs5536_usb_swapsif(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
|
|
@ -72,13 +84,13 @@ static void cs5536_usb_swapsif(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set up IO bases for SMBUS, GPIO, MFGPT, ACPI, and PM.
|
||||
* These can be changed by Linux later. We set some initial value so
|
||||
* that the resources are there as needed.
|
||||
* @brief Set up IO bases for SMBUS, GPIO, MFGPT, ACPI, and PM.
|
||||
* These can be changed by Linux later. We set some initial value so
|
||||
* that the resources are there as needed.
|
||||
* The values are hardcoded because, this early in the process, fancy
|
||||
* allocation can do more harm than good.
|
||||
* allocation can do more harm than good.
|
||||
*/
|
||||
static void cs5536_setup_iobase(void)
|
||||
void cs5536_setup_iobase(void)
|
||||
{
|
||||
msr_t msr;
|
||||
/* setup LBAR for SMBus controller */
|
||||
|
|
@ -108,30 +120,28 @@ static void cs5536_setup_iobase(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set up the power button for operation.
|
||||
* @brief Power Button Setup
|
||||
* setup GPIO24, it is the external signal for 5536 vsb_work_aux
|
||||
* which controls all voltage rails except Vstandby & Vmem.
|
||||
* We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
|
||||
* If GPIO24 is not enabled then soft-off will not work.
|
||||
*/
|
||||
static void cs5536_setup_power_button(void)
|
||||
void cs5536_setup_power_button(void)
|
||||
{
|
||||
/* Power Button Setup */
|
||||
outl(0x40020000, PMS_IO_BASE + 0x40);
|
||||
|
||||
/* setup GPIO24, it is the external signal for 5536 vsb_work_aux
|
||||
* which controls all voltage rails except Vstandby & Vmem.
|
||||
* We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
|
||||
* If GPIO24 is not enabled then soft-off will not work.
|
||||
*/
|
||||
outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUT_AUX1_SELECT);
|
||||
outl(GPIOH_24_SET, GPIO_IO_BASE + GPIOH_OUTPUT_ENABLE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the various GPIOs. An unknown question at this point is
|
||||
* how general this is to all mainboards.
|
||||
* @brief Set the various GPIOs. An unknown question at this point is
|
||||
* how general this is to all mainboards. At the same time, many
|
||||
* boards seem to follow this particular reference spec.
|
||||
*/
|
||||
static void cs5536_setup_gpio(void)
|
||||
void cs5536_setup_smbus_gpio(void)
|
||||
{
|
||||
uint32_t val;
|
||||
u32 val;
|
||||
|
||||
/* setup GPIO pins 14/15 for SDA/SCL */
|
||||
val = GPIOL_15_SET | GPIOL_14_SET;
|
||||
|
|
@ -146,14 +156,14 @@ static void cs5536_setup_gpio(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the internal UART.
|
||||
* Different boards have different UARTs for COM1.
|
||||
* @brief Disable the internal UART.
|
||||
* Different boards have different UARTs for COM1.
|
||||
*/
|
||||
static void cs5536_disable_internal_uart(void)
|
||||
void cs5536_disable_internal_uart(void)
|
||||
{
|
||||
msr_t msr;
|
||||
/* The UARTs default to enabled.
|
||||
* Disable and reset them and configure them later. (SIO init)
|
||||
* Disable and reset them and configure them later. (SIO init)
|
||||
*/
|
||||
msr = rdmsr(MDD_UART1_CONF);
|
||||
msr.lo = 1; // reset
|
||||
|
|
@ -169,9 +179,11 @@ static void cs5536_disable_internal_uart(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Set up the cs5536 CIS interface to CPU interface to match modes.
|
||||
* @brief Set up the cs5536 CIS interface to CPU interface to match modes.
|
||||
* The CIS is related to the interrupt system. It is important to match the
|
||||
* south and the cpu chips. At the same time, they always seem to use mode B.
|
||||
*/
|
||||
static void cs5536_setup_cis_mode(void)
|
||||
void cs5536_setup_cis_mode(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
|
|
@ -183,10 +195,9 @@ static void cs5536_setup_cis_mode(void)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the on chip UART.
|
||||
* @brief Enable the on chip UART.see page 412 of the cs5536 companion book
|
||||
*/
|
||||
/* see page 412 of the cs5536 companion book */
|
||||
static void cs5536_setup_onchipuart(void)
|
||||
void cs5536_setup_onchipuart(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
|
|
@ -227,12 +238,30 @@ static void cs5536_setup_onchipuart(void)
|
|||
|
||||
|
||||
/**
|
||||
* @brief Board setup. Known to work on norwich and digitial logic boards.
|
||||
* @brief Board setup. Known to work on norwich and digitial logic boards.
|
||||
* The extmsr and cis_mode are common for sure.
|
||||
* The RSTPLL check is mandatory.
|
||||
* IDSEl of course is required, so the chip appears in PCI config space,
|
||||
* and the swapsif covers a necessary chip fix.
|
||||
* Finally, the iobase is needed for DRAM, the GPIOs
|
||||
* are likely common to all boards, and the power button
|
||||
* seems to be the same on all. At the same time,
|
||||
* we may need to move gpio and power button
|
||||
* out as developments demand.
|
||||
* Note we do NOT do any UART
|
||||
* setup here -- this is done later by the mainboard setup,
|
||||
* since UART usage is not universal.
|
||||
* setup here -- this is done later by the mainboard setup,
|
||||
* since UART usage is not universal.
|
||||
* A comment from Marc Jones:
|
||||
"It
|
||||
would be difficult to move this to early mainboard (car_auto) because
|
||||
the IObase needs to be setup first and then SMBus setup would be
|
||||
optional etc. I think that any platform that uses the SMBus GPIOs for
|
||||
something other than SMBus will need a lot of customization anyway and
|
||||
they would have to override the generic file. I understand the desire to
|
||||
make everything generic but that really over complicates 99% of the
|
||||
designs."
|
||||
*/
|
||||
static void cs5536_early_setup(void)
|
||||
void cs5536_early_setup(void)
|
||||
{
|
||||
msr_t msr;
|
||||
|
||||
|
|
@ -251,7 +280,7 @@ static void cs5536_early_setup(void)
|
|||
cs5536_setup_idsel();
|
||||
cs5536_usb_swapsif();
|
||||
cs5536_setup_iobase();
|
||||
cs5536_setup_gpio();
|
||||
cs5536_enable_smbus();
|
||||
cs5536_setup_smbus_gpio();
|
||||
/* cs5536_enable_smbus(); -- leave this out for now */
|
||||
cs5536_setup_power_button();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,37 +259,37 @@ static u8 do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
|
|||
|
||||
if (smbus_check_stop_condition(smbus_io_base)) {
|
||||
error = "smbus_check_stop_condition timed out";
|
||||
goto err
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errno = smbus_start_condition(smbus_io_base)) {
|
||||
if ((errno = smbus_start_condition(smbus_io_base))) {
|
||||
error = "smbus_start_condition";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errno = smbus_send_slave_address(smbus_io_base, device)) {
|
||||
if ((errno = smbus_send_slave_address(smbus_io_base, device))) {
|
||||
error = "smbus_send_slave_address";
|
||||
goto err;
|
||||
}
|
||||
|
||||
smbus_ack(smbus_io_base);
|
||||
|
||||
if (errno = smbus_send_command(smbus_io_base, address)) {
|
||||
if ((errno = smbus_send_command(smbus_io_base, address))) {
|
||||
error = "smbus_send_command";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errno = smbus_start_condition(smbus_io_base)) {
|
||||
if ((errno = smbus_start_condition(smbus_io_base))) {
|
||||
error = "smbus_start_condition";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errno = smbus_send_slave_address(smbus_io_base, device | 0x01)) {
|
||||
if ((errno = smbus_send_slave_address(smbus_io_base, device | 0x01))) {
|
||||
error = "smbus_send_slave_address";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (errno = smbus_stop_condition(smbus_io_base)) {
|
||||
if ((errno = smbus_stop_condition(smbus_io_base))) {
|
||||
error = "second smbus_stop_condition";
|
||||
goto err;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue