Author: rminnich Date: 2007-06-05 23:01:05 +0200 (Tue, 05 Jun 2007) New Revision: 346
Modified: LinuxBIOSv3/southbridge/amd/cs5536/cs5536_early_setup.c LinuxBIOSv3/southbridge/amd/cs5536/smbus_initram.c Log: 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
Modified: LinuxBIOSv3/southbridge/amd/cs5536/cs5536_early_setup.c =================================================================== --- LinuxBIOSv3/southbridge/amd/cs5536/cs5536_early_setup.c 2007-06-05 17:40:18 UTC (rev 345) +++ LinuxBIOSv3/southbridge/amd/cs5536/cs5536_early_setup.c 2007-06-05 21:01:05 UTC (rev 346) @@ -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 @@ }
/** - * @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 @@ }
/** - * @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 @@ }
/** - * @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 @@ }
/** - * @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 @@ }
/** - * @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 @@
/** - * @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 @@ 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(); }
Modified: LinuxBIOSv3/southbridge/amd/cs5536/smbus_initram.c =================================================================== --- LinuxBIOSv3/southbridge/amd/cs5536/smbus_initram.c 2007-06-05 17:40:18 UTC (rev 345) +++ LinuxBIOSv3/southbridge/amd/cs5536/smbus_initram.c 2007-06-05 21:01:05 UTC (rev 346) @@ -259,37 +259,37 @@
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; }