#include "northbridge/amd/gx1/raminit.c"
#include "cpu/x86/bist.h"
#include "superio/winbond/w83977f/w83977f_early_serial.c"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x3f0, W83977F_SP1)
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs690/rs690_early_setup.c"
-#include "southbridge/amd/sb600/sb600_early_setup.c"
+#include "southbridge/amd/rs690/early_setup.c"
+#include "southbridge/amd/sb600/early_setup.c"
#include "northbridge/amd/amdk8/debug.c" /* After sb600_early_setup.c! */
static void memreset(int controllers, const struct mem_controller *ctrl) { }
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
-#include "northbridge/amd/amdk8/debug.c" /* After sb700_early_setup.c! */
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
+#include "northbridge/amd/amdk8/debug.c" /* After sb700/early_setup.c! */
static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
#include <spd.h>
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
static inline int spd_read_byte(unsigned int device, unsigned int address)
{
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs690/rs690_early_setup.c"
-#include "southbridge/amd/sb600/sb600_early_setup.c"
-#include "northbridge/amd/amdk8/debug.c" /* After sb600_early_setup.c! */
+#include "southbridge/amd/rs690/early_setup.c"
+#include "southbridge/amd/sb600/early_setup.c"
+#include "northbridge/amd/amdk8/debug.c" /* After sb600/early_setup.c! */
static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include <cpu/amd/gx2def.h>
#include <cpu/amd/geode_post_code.h>
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include <reset.h>
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include <cpu/amd/mtrr.h>
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <cpu/x86/lapic.h>
#include <console/console.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include <lib.h>
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
#include <spd.h>
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87360_SP1)
#include "southbridge/amd/cs5536/cs5536.h"
#include "spd_table.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
static int spd_read_byte(unsigned device, unsigned address)
{
#include "northbridge/amd/gx1/raminit.c"
#include "cpu/x86/bist.h"
#include "superio/nsc/pc87351/pc87351_early_serial.c"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87351_SP1)
#include "northbridge/amd/gx1/raminit.c"
#include "superio/nsc/pc87351/pc87351_early_serial.c"
#include "cpu/x86/bist.h"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87351_SP1)
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
-#include "northbridge/amd/amdk8/debug.c" /* After sb700_early_setup.c! */
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
+#include "northbridge/amd/amdk8/debug.c" /* After sb700/early_setup.c! */
#define SERIAL_DEV PNP_DEV(0x2e, W83627DHG_SP1)
#define GPIO2345_DEV PNP_DEV(0x2e, W83627DHG_GPIO2345_V)
#include <cpu/amd/model_fxx_rev.h>
#include <console/console.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/raminit.c"
#include "lib/generic_sdram.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
-#include "southbridge/nvidia/ck804/ck804_early_setup.c"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include "superio/winbond/w83627ehg/w83627ehg_early_serial.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
-#include "northbridge/amd/amdk8/debug.c" /* After vt8237r_early_smbus.c! */
+#include "southbridge/via/vt8237r/early_smbus.c"
+#include "northbridge/amd/amdk8/debug.c" /* After vt8237r/early_smbus.c! */
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
}
}
-#include "southbridge/via/k8t890/k8t890_early_car.c"
+#include "southbridge/via/k8t890/early_car.c"
#include "northbridge/amd/amdk8/amdk8.h"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include "superio/winbond/w83627ehg/w83627ehg_early_serial.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
-#include "northbridge/amd/amdk8/debug.c" /* After vt8237r_early_smbus.c! */
+#include "southbridge/via/vt8237r/early_smbus.c"
+#include "northbridge/amd/amdk8/debug.c" /* After vt8237r/early_smbus.c! */
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
}
}
-#include "southbridge/via/k8t890/k8t890_early_car.c"
+#include "southbridge/via/k8t890/early_car.c"
#include "northbridge/amd/amdk8/amdk8.h"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/debug.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
return smbus_read_byte(device, address);
}
-#include "southbridge/via/k8t890/k8t890_early_car.c"
+#include "southbridge/via/k8t890/early_car.c"
#include "northbridge/amd/amdk8/amdk8.h"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/debug.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
return smbus_read_byte(device, address);
}
-#include "southbridge/via/k8t890/k8t890_early_car.c"
+#include "southbridge/via/k8t890/early_car.c"
#include "northbridge/amd/amdk8/amdk8.h"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include "northbridge/amd/gx1/raminit.c"
#include "superio/nsc/pc97317/pc97317_early_serial.c"
#include "cpu/x86/bist.h"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC97317_SP1)
#include "northbridge/amd/gx1/raminit.c"
#include "superio/nsc/pc97317/pc97317_early_serial.c"
#include "cpu/x86/bist.h"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC97317_SP1)
#include "lib/delay.c"
#include <lib.h>
#include <spd.h>
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "superio/winbond/w83697hf/w83697hf_early_serial.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83697HF_SP1)
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/broadcom/bcm5785/bcm5785_early_smbus.c"
+#include "southbridge/broadcom/bcm5785/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/broadcom/bcm5785/bcm5785_early_setup.c"
+#include "southbridge/broadcom/bcm5785/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87417_SP1)
#define RTC_DEV PNP_DEV(0x2e, PC87417_RTC)
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#include <console/console.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/nsc/pc8374/pc8374_early_init.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include "southbridge/intel/i82801dx/i82801dx.h"
-#include "southbridge/intel/i82801dx/i82801dx_early_smbus.c"
+#include "southbridge/intel/i82801dx/early_smbus.c"
#include "northbridge/intel/i855/raminit.h"
#include "northbridge/intel/i855/debug.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <console/console.h>
#include "superio/nsc/pc97317/pc97317_early_serial.c"
#include "cpu/x86/bist.h"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#include "northbridge/amd/gx1/raminit.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC97317_SP1)
extern unsigned char AmlCode[];
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
#include <console/console.h>
#include <cpu/x86/smm.h>
#include "southbridge/intel/i82801gx/i82801gx.h"
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
#include "northbridge/intel/i945/udelay.c"
#include "ec.c"
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "southbridge/sis/sis966/sis966.h"
-#include "southbridge/sis/sis966/sis966_early_smbus.c"
-#include "southbridge/sis/sis966/sis966_enable_rom.c"
+#include "southbridge/sis/sis966/early_smbus.c"
+#include "southbridge/sis/sis966/enable_rom.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/sis/sis966/sis966_early_ctrl.c"
+#include "southbridge/sis/sis966/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, IT8716F_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/sis/sis966/sis966_early_setup_ss.h"
+#include "southbridge/sis/sis966/early_setup_ss.h"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include <usbdebug.h>
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, IT8716F_SP1)
#define GPIO_DEV PNP_DEV(0x2e, IT8716F_GPIO)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "northbridge/amd/amdk8/amdk8_f.h"
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/broadcom/bcm5785/bcm5785_early_smbus.c"
+#include "southbridge/broadcom/bcm5785/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/broadcom/bcm5785/bcm5785_early_setup.c"
+#include "southbridge/broadcom/bcm5785/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, PILOT_SP1)
#define RTC_DEV PNP_DEV(0x4e, PC87417_RTC)
#include "option_table.h"
#include <console/console.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/broadcom/bcm5785/bcm5785_early_smbus.c"
+#include "southbridge/broadcom/bcm5785/early_smbus.c"
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include <lib.h>
#include "northbridge/amd/amdfam10/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
//#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/broadcom/bcm5785/bcm5785_early_setup.c"
+#include "southbridge/broadcom/bcm5785/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, PILOT_SP1)
#define RTC_DEV PNP_DEV(0x4e, PC87417_RTC)
unsigned long acpi_create_slic(unsigned long current);
#endif
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
memset((void *)gnvs, 0, sizeof(*gnvs));
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
/* The southbridge SMI handler checks whether gnvs has a
* valid pointer before calling the trap handler
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
#include <spd.h>
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87366_SP1)
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#include <spd.h>
#define SERIAL_DEV PNP_DEV(0x2e, PC87366_SP1)
#include <arch/hlt.h>
#include <console/console.h>
#include "superio/winbond/w83977f/w83977f_early_serial.c"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#include "cpu/x86/bist.h"
#include "pc80/udelay_io.c"
#include "northbridge/amd/gx1/raminit.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
#define SERIAL_DEV PNP_DEV(0x2e, F71859_SP1)
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
#include <arch/hlt.h>
#include <console/console.h>
#include "superio/winbond/w83977tf/w83977tf_early_serial.c"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#include "cpu/x86/bist.h"
#define SERIAL_DEV PNP_DEV(0x3f0, W83977TF_SP1)
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
} __attribute__((packed)) acpi_oemb_t;
#endif
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
#if OLD_ACPI
static void acpi_create_oemb(acpi_oemb_t *oemb)
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
/* The southbridge SMI handler checks whether gnvs has a
* valid pointer before calling the trap handler
#include <console/console.h>
#include <cpu/x86/bist.h>
#include <cpu/intel/acpi.h>
-#include "southbridge/intel/i3100/i3100_early_smbus.c"
-#include "southbridge/intel/i3100/i3100_early_lpc.c"
+#include "southbridge/intel/i3100/early_smbus.c"
+#include "southbridge/intel/i3100/early_lpc.c"
#include "reset.c"
#include "superio/intel/i3100/i3100_early_serial.c"
#include "superio/smsc/smscsuperio/smscsuperio_early_serial.c"
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#include <console/console.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/nsc/pc87427/pc87427.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <cpu/x86/lapic.h>
#include <pc80/mc146818rtc.h>
#include <console/console.h>
-#include "southbridge/intel/i3100/i3100_early_smbus.c"
-#include "southbridge/intel/i3100/i3100_early_lpc.c"
+#include "southbridge/intel/i3100/early_smbus.c"
+#include "southbridge/intel/i3100/early_lpc.c"
#include "northbridge/intel/i3100/raminit.h"
#include "superio/intel/i3100/i3100.h"
#include "cpu/x86/mtrr/earlymtrr.c"
#include <pc80/mc146818rtc.h>
#include "pc80/udelay_io.c"
#include <console/console.h>
-#include "southbridge/intel/i3100/i3100_early_smbus.c"
-#include "southbridge/intel/i3100/i3100_early_lpc.c"
+#include "southbridge/intel/i3100/early_smbus.c"
+#include "southbridge/intel/i3100/early_lpc.c"
#include "northbridge/intel/i3100/raminit_ep80579.h"
#include "superio/intel/i3100/i3100.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <stdlib.h>
#include <pc80/mc146818rtc.h>
#include <console/console.h>
-#include "southbridge/intel/i82801cx/i82801cx_early_smbus.c"
+#include "southbridge/intel/i82801cx/early_smbus.c"
#include "northbridge/intel/e7501/raminit.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/intel/e7501/debug.c"
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include "cpu/x86/bist.h"
#include "pc80/udelay_io.c"
#include "lib/delay.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "superio/fintek/f71805f/f71805f_early_serial.c"
#include <lib.h>
#include <spd.h>
#include "cpu/x86/mtrr/earlymtrr.c"
#include <cpu/amd/mtrr.h>
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/amd/rs780/rs780_early_setup.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
+#include "southbridge/amd/rs780/early_setup.c"
+#include "southbridge/amd/sb700/early_setup.c"
#include "northbridge/amd/amdfam10/debug.c"
#if CONFIG_TTYS0_BASE == 0x2f8
#include "cpu/amd/model_10xxx/update_microcode.c"
#include "cpu/amd/model_10xxx/init_cpus.c"
#include "northbridge/amd/amdfam10/early_ht.c"
-#include "southbridge/amd/sb700/sb700_early_setup.c"
#include <spd.h>
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
unsigned long acpi_create_slic(unsigned long current);
#endif
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
memset((void *)gnvs, 0, sizeof(*gnvs));
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
/* The southbridge SMI handler checks whether gnvs has a
* valid pointer before calling the trap handler
#include <cpu/amd/mtrr.h>
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs690/rs690_early_setup.c"
-#include "southbridge/amd/sb600/sb600_early_setup.c"
+#include "southbridge/amd/rs690/early_setup.c"
+#include "southbridge/amd/sb600/early_setup.c"
static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include "southbridge/intel/i82801dx/i82801dx.h"
-#include "southbridge/intel/i82801dx/i82801dx_early_smbus.c"
+#include "southbridge/intel/i82801dx/early_smbus.c"
#include "northbridge/intel/i855/raminit.h"
#include "northbridge/intel/i855/debug.c"
#include "superio/winbond/w83627thg/w83627thg_early_serial.c"
#include <cpu/amd/gx2def.h>
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5535/cs5535.h"
-#include "southbridge/amd/cs5535/cs5535_early_smbus.c"
-#include "southbridge/amd/cs5535/cs5535_early_setup.c"
+#include "southbridge/amd/cs5535/early_smbus.c"
+#include "southbridge/amd/cs5535/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
/* Bit0 enables Spread Spectrum. */
#include <cpu/amd/lxdef.h>
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
/* Bit0 enables Spread Spectrum, bit1 makes on-board CF slot act as IDE slave. */
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
#define ManualConf 1 /* No automatic strapped PLL config */
#include <cpu/amd/lxdef.h>
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/ite/it8712f/it8712f_early_serial.c"
/* Bit0 enables Spread Spectrum, bit1 makes on-board SSD act as IDE slave. */
#include <cpu/amd/model_fxx_rev.h>
#include <console/console.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/raminit.c"
#include "lib/generic_sdram.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
-#include "southbridge/nvidia/ck804/ck804_early_setup_car.c"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <console/console.h>
#include <usbdebug.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x4e, W83627EHG_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/broadcom/bcm5785/bcm5785_early_smbus.c"
+#include "southbridge/broadcom/bcm5785/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/broadcom/bcm5785/bcm5785_early_setup.c"
+#include "southbridge/broadcom/bcm5785/early_setup.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC87417_SP1)
#define RTC_DEV PNP_DEV(0x2e, PC87417_RTC)
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include <spd.h>
#include "northbridge/amd/amdk8/setup_resource_map.c"
#include <device/pci_ids.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627EHG_SP1)
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
//set GPIO to input mode
#define MCP55_MB_SETUP \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff), ((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/ \
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
// Disabled until it's actually used:
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "northbridge/amd/amdfam10/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627EHG_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/microcode/microcode.c"
#include "cpu/amd/model_10xxx/update_microcode.c"
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627EHG_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
/* The ALIX1.C has no SMBus; the setup is hard-wired. */
static void cs5536_enable_smbus(void) { }
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
/* The part is a Hynix hy5du121622ctp-d43.
/* The ALIX.2D has no SMBus; the setup is hard-wired. */
static void cs5536_enable_smbus(void) { }
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_setup.c"
/* The part is a Hynix hy5du121622ctp-d43.
*
#include "northbridge/intel/i82830/raminit.h"
#include "northbridge/intel/i82830/memory_initialized.c"
#include "southbridge/intel/i82801dx/i82801dx.h"
-#include "southbridge/intel/i82801dx/i82801dx_reset.c"
+#include "southbridge/intel/i82801dx/reset.c"
#include "cpu/x86/bist.h"
#include "spd_table.h"
#include "gpio.c"
-#include "southbridge/intel/i82801dx/i82801dx_early_smbus.c"
-#include "southbridge/intel/i82801dx/i82801dx_tco_timer.c"
+#include "southbridge/intel/i82801dx/early_smbus.c"
+#include "southbridge/intel/i82801dx/tco_timer.c"
#define SERIAL_DEV PNP_DEV(0x2e, SMSCSUPERIO_SP1)
}
#endif
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
static void acpi_create_gnvs(global_nvs_t *gnvs)
{
memset((void *)gnvs, 0, sizeof(*gnvs));
#include <arch/romcc_io.h>
#include <console/console.h>
#include <cpu/x86/smm.h>
-#include "southbridge/intel/i82801gx/i82801gx_nvs.h"
+#include "southbridge/intel/i82801gx/nvs.h"
/* The southbridge SMI handler checks whether gnvs has a
* valid pointer before calling the trap handler
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
//set GPIO to input mode
#define CK804_MB_SETUP \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/
-#include "southbridge/nvidia/ck804/ck804_early_setup_car.c"
+#include "southbridge/nvidia/ck804/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c" // for enable the FAN
+#include "southbridge/nvidia/mcp55/early_smbus.c" // for enable the FAN
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#define DUMMY_DEV PNP_DEV(0x2e, 0)
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c" // for enable the FAN
+#include "southbridge/nvidia/mcp55/early_smbus.c" // for enable the FAN
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#define DUMMY_DEV PNP_DEV(0x2e, 0)
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c" // for enable the FAN
+#include "southbridge/nvidia/mcp55/early_smbus.c" // for enable the FAN
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include "cpu/amd/model_10xxx/apic_timer.c"
#include "northbridge/amd/amdfam10/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#define DUMMY_DEV PNP_DEV(0x2e, 0)
#include "northbridge/amd/amdfam10/amdfam10_pci.c"
#include "resourcemap.c"
#include "cpu/amd/quadcore/quadcore.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/microcode/microcode.c"
#include "cpu/amd/model_10xxx/update_microcode.c"
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c" // for enable the FAN
+#include "southbridge/nvidia/mcp55/early_smbus.c" // for enable the FAN
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include "cpu/amd/model_10xxx/apic_timer.c"
#include "northbridge/amd/amdfam10/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#define DUMMY_DEV PNP_DEV(0x2e, 0)
#include "northbridge/amd/amdfam10/amdfam10_pci.c"
#include "resourcemap.c"
#include "cpu/amd/quadcore/quadcore.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/microcode/microcode.c"
#include "cpu/amd/model_10xxx/update_microcode.c"
#include <console/console.h>
#include "pc80/udelay_io.c"
#include "lib/delay.c"
-#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
+#include "southbridge/intel/esb6300/early_smbus.c"
#include "northbridge/intel/e7525/raminit.h"
#include "superio/winbond/w83627hf/w83627hf.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <console/console.h>
#include "pc80/udelay_io.c"
#include "lib/delay.c"
-#include "southbridge/intel/esb6300/esb6300_early_smbus.c"
+#include "southbridge/intel/esb6300/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/winbond/w83627hf/w83627hf.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#include <console/console.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/nsc/pc87427/pc87427.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#include <console/console.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/winbond/w83627hf/w83627hf.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#include <console/console.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7520/raminit.h"
#include "superio/winbond/w83627hf/w83627hf.h"
#include "cpu/x86/lapic/boot_cpu.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs690/rs690_early_setup.c"
-#include "southbridge/amd/sb600/sb600_early_setup.c"
+#include "southbridge/amd/rs690/early_setup.c"
+#include "southbridge/amd/sb600/early_setup.c"
static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/rs690/rs690_early_setup.c"
-#include "southbridge/amd/sb600/sb600_early_setup.c"
+#include "southbridge/amd/rs690/early_setup.c"
+#include "southbridge/amd/sb600/early_setup.c"
static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }
#include "northbridge/amd/gx1/raminit.c"
#include "superio/nsc/pc97317/pc97317_early_serial.c"
#include "cpu/x86/bist.h"
-#include "southbridge/amd/cs5530/cs5530_enable_rom.c"
+#include "southbridge/amd/cs5530/enable_rom.c"
#define SERIAL_DEV PNP_DEV(0x2e, PC97317_SP1)
#include "northbridge/intel/i82830/raminit.h"
#include "northbridge/intel/i82830/memory_initialized.c"
#include "southbridge/intel/i82801dx/i82801dx.h"
-#include "southbridge/intel/i82801dx/i82801dx_reset.c"
+#include "southbridge/intel/i82801dx/reset.c"
#include "cpu/x86/bist.h"
#include "spd_table.h"
#include "gpio.c"
-#include "southbridge/intel/i82801dx/i82801dx_early_smbus.c"
-#include "southbridge/intel/i82801dx/i82801dx_tco_timer.c"
+#include "southbridge/intel/i82801dx/early_smbus.c"
+#include "southbridge/intel/i82801dx/tco_timer.c"
#define SERIAL_DEV PNP_DEV(0x2e, SMSCSUPERIO_SP1)
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
static inline int spd_read_byte(unsigned int device, unsigned int address)
{
#include <console/console.h>
#include <lib.h>
#include <spd.h>
-#include "southbridge/intel/i82801ex/i82801ex_early_smbus.c"
+#include "southbridge/intel/i82801ex/early_smbus.c"
#include "northbridge/intel/e7501/raminit.h"
#include "northbridge/intel/e7501/debug.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
-#include "southbridge/nvidia/ck804/ck804_early_setup.c"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
//set GPIO to input mode
#define CK804_MB_SETUP \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/ \
-#include "southbridge/nvidia/ck804/ck804_early_setup_car.c"
+#include "southbridge/nvidia/ck804/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <spd.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/nvidia/ck804/ck804_early_smbus.h"
+#include "southbridge/nvidia/ck804/early_smbus.h"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "lib/generic_sdram.c"
#include "resourcemap.c"
#include "cpu/amd/dualcore/dualcore.c"
-#include "southbridge/nvidia/ck804/ck804_early_setup_ss.h"
+#include "southbridge/nvidia/ck804/early_setup_ss.h"
//set GPIO to input mode
#define CK804_MB_SETUP \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+16, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* K4,GPIO17, PCIXB_PRSNT1_L*/ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+45, ~(0xff),((0<<4)|(0<<2)|(0<<0)),/* P7,GPIO46, PCIXB_PRSNT2_L*/
-#include "southbridge/nvidia/ck804/ck804_early_setup_car.c"
+#include "southbridge/nvidia/ck804/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <spd.h>
#include <usbdebug.h>
#include <cpu/amd/model_fxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "northbridge/amd/amdk8/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include <lib.h>
#include <spd.h>
#include <cpu/amd/model_10xxx_rev.h>
-#include "southbridge/nvidia/mcp55/mcp55_early_smbus.c"
+#include "southbridge/nvidia/mcp55/early_smbus.c"
#include "northbridge/amd/amdfam10/raminit.h"
#include "northbridge/amd/amdfam10/amdfam10.h"
#include "cpu/amd/model_10xxx/apic_timer.c"
#include "northbridge/amd/amdfam10/debug.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "northbridge/amd/amdfam10/setup_resource_map.c"
-#include "southbridge/nvidia/mcp55/mcp55_early_ctrl.c"
+#include "southbridge/nvidia/mcp55/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+59, 0x00, 0x60,/* GPIP60 FANCTL0 */ \
RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+60, 0x00, 0x60,/* GPIO61 FANCTL1 */
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_ss.h"
-#include "southbridge/nvidia/mcp55/mcp55_early_setup_car.c"
+#include "southbridge/nvidia/mcp55/early_setup_ss.h"
+#include "southbridge/nvidia/mcp55/early_setup_car.c"
#include "cpu/amd/car/post_cache_as_ram.c"
#include "cpu/amd/microcode/microcode.c"
#include "cpu/amd/model_10xxx/update_microcode.c"
#include <lib.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <lib.h>
#include <cpu/amd/model_fxx_rev.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
-#include "southbridge/amd/amd8111/amd8111_early_smbus.c"
+#include "southbridge/amd/amd8111/early_smbus.c"
#include "northbridge/amd/amdk8/raminit.h"
#include "cpu/amd/model_fxx/apic_timer.c"
#include "lib/delay.c"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "northbridge/amd/amdk8/setup_resource_map.c"
-#include "southbridge/amd/amd8111/amd8111_early_ctrl.c"
+#include "southbridge/amd/amd8111/early_ctrl.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include "cpu/x86/bist.h"
#include "pc80/udelay_io.c"
#include "lib/delay.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
-#include "southbridge/via/vt8235/vt8235_early_serial.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
+#include "southbridge/via/vt8235/early_serial.c"
#include <spd.h>
static inline int spd_read_byte(unsigned device, unsigned address)
#include "lib/delay.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "lib/debug.c"
-#include "southbridge/via/vt8235/vt8235_early_smbus.c"
-#include "southbridge/via/vt8235/vt8235_early_serial.c"
+#include "southbridge/via/vt8235/early_smbus.c"
+#include "southbridge/via/vt8235/early_serial.c"
static inline int spd_read_byte(unsigned device, unsigned address)
{
#include "pc80/udelay_io.c"
#include "lib/delay.c"
#include "cpu/x86/lapic/boot_cpu.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "superio/winbond/w83697hf/w83697hf_early_serial.c"
#include <spd.h>
#include "pc80/udelay_io.c"
#include "lib/delay.c"
#include "lib/debug.c"
-#include "southbridge/via/vt8231/vt8231_early_smbus.c"
-#include "southbridge/via/vt8231/vt8231_early_serial.c"
-#include "southbridge/via/vt8231/vt8231_enable_rom.c"
+#include "southbridge/via/vt8231/early_smbus.c"
+#include "southbridge/via/vt8231/early_serial.c"
+#include "southbridge/via/vt8231/enable_rom.c"
static inline int spd_read_byte(unsigned device, unsigned address)
{
#include "cpu/x86/bist.h"
#include "pc80/udelay_io.c"
#include "lib/delay.c"
-#include "southbridge/via/vt8237r/vt8237r_early_smbus.c"
+#include "southbridge/via/vt8237r/early_smbus.c"
#include "superio/ite/it8716f/it8716f_early_serial.c"
#include <spd.h>
#include <cpu/amd/geode_post_code.h>
#include "southbridge/amd/cs5536/cs5536.h"
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
#include "superio/winbond/w83627hf/w83627hf_early_serial.c"
#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
#include <cpu/amd/gx2def.h>
#include <cpu/amd/geode_post_code.h>
#include <spd.h>
-#include "southbridge/amd/cs5536/cs5536_early_smbus.c"
-#include "southbridge/amd/cs5536/cs5536_early_setup.c"
+#include "southbridge/amd/cs5536/early_smbus.c"
+#include "southbridge/amd/cs5536/early_setup.c"
static inline int spd_read_byte(unsigned int device, unsigned int address)
{
driver-y += amd8111.c
-driver-y += amd8111_usb.c
-driver-y += amd8111_lpc.c
-driver-y += amd8111_ide.c
-driver-y += amd8111_acpi.c
-driver-y += amd8111_usb2.c
-driver-y += amd8111_ac97.c
-driver-y += amd8111_nic.c
-driver-y += amd8111_pci.c
-driver-y += amd8111_smbus.c
-ramstage-y += amd8111_reset.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += ide.c
+driver-y += acpi.c
+driver-y += usb2.c
+driver-y += ac97.c
+driver-y += nic.c
+driver-y += pci.c
+driver-y += smbus.c
+ramstage-y += reset.c
--- /dev/null
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x2c,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ac97audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = amd8111_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x746D,
+};
+
+
+static struct device_operations ac97modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = amd8111_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x746E,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <pc80/mc146818rtc.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include "amd8111.h"
+#include "amd8111_smbus.h"
+
+#define PREVIOUS_POWER_STATE 0x43
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define SLOW_CPU_OFF 0
+#define SLOW_CPU__ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ unsigned device;
+ struct resource *res;
+
+ device = dev->path.i2c.device;
+ res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+
+ device = dev->path.i2c.device;
+ res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+
+ device = dev->path.i2c.device;
+ res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+
+ device = dev->path.i2c.device;
+ res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+
+#if CONFIG_GENERATE_ACPI_TABLES == 1
+unsigned pm_base;
+#endif
+
+static void acpi_init(struct device *dev)
+{
+ uint8_t byte;
+ uint16_t pm10_bar;
+ uint32_t dword;
+ int on;
+
+#if 0
+ uint16_t word;
+ printk(BIOS_DEBUG, "ACPI: disabling NMI watchdog.. ");
+ byte = pci_read_config8(dev, 0x49);
+ pci_write_config8(dev, 0x49, byte | (1<<2));
+
+
+ byte = pci_read_config8(dev, 0x41);
+ pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<2));
+
+ /* added from sourceforge */
+ byte = pci_read_config8(dev, 0x48);
+ pci_write_config8(dev, 0x48, byte | (1<<3));
+
+ printk(BIOS_DEBUG, "done.\n");
+
+
+ printk(BIOS_DEBUG, "ACPI: Routing IRQ 12 to PS2 port.. ");
+ word = pci_read_config16(dev, 0x46);
+ pci_write_config16(dev, 0x46, word | (1<<9));
+ printk(BIOS_DEBUG, "done.\n");
+#endif
+
+ /* To enable the register 0xcf9 in the IO space
+ * bit [D5] is set in the amd8111 configuration register.
+ * The config. reg. is devBx41. Register 0xcf9 allows
+ * hard reset capability to the system. For the ACPI
+ * reset.reg values in fadt.c to work this register
+ * must be enabled.
+ */
+ byte = pci_read_config8(dev, 0x41);
+ pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<5));
+
+ /* power on after power fail */
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
+ byte &= ~0x40;
+ if (!on) {
+ byte |= 0x40;
+ }
+ pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
+
+ /* switch serial irq logic from quiet mode to continuous
+ * mode for Winbond W83627HF Rev. 17
+ */
+ byte = pci_read_config8(dev, 0x4a);
+ pci_write_config8(dev, 0x4a, byte | (1<<6));
+
+ /* Throttle the CPU speed down for testing */
+ on = SLOW_CPU_OFF;
+ get_option(&on, "slow_cpu");
+ if(on) {
+ pm10_bar = (pci_read_config16(dev, 0x58)&0xff00);
+ outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
+ dword = inl(pm10_bar + 0x10);
+ on = 8-on;
+ printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
+ (on*12)+(on>>1),(on&1)*5);
+ }
+
+#if CONFIG_GENERATE_ACPI_TABLES == 1
+ pm_base = pci_read_config16(dev, 0x58) & 0xff00;
+ printk(BIOS_DEBUG, "pm_base: 0x%04x\n",pm_base);
+#endif
+
+}
+
+static void acpi_read_resources(device_t dev)
+{
+ struct resource *resource;
+
+ /* Handle the generic bars */
+ pci_dev_read_resources(dev);
+
+ /* Add the ACPI/SMBUS bar */
+ resource = new_resource(dev, 0x58);
+ resource->base = 0;
+ resource->size = 256;
+ resource->align = log2(256);
+ resource->gran = log2(256);
+ resource->limit = 65536;
+ resource->flags = IORESOURCE_IO;
+ resource->index = 0x58;
+}
+
+static void acpi_enable_resources(device_t dev)
+{
+ uint8_t byte;
+ /* Enable the generic pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable the ACPI/SMBUS Bar */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1 << 7);
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Set the class code */
+ pci_write_config32(dev, 0x60, 0x06800000);
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x7c,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations acpi_ops = {
+ .read_resources = acpi_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = acpi_enable_resources,
+ .init = acpi_init,
+ .scan_bus = scan_static_bus,
+ /* We don't need amd8111_enable, chip ops takes care of it.
+ * It could be useful if these devices were not
+ * enabled by default.
+ */
+// .enable = amd8111_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver acpi_driver __pci_driver = {
+ .ops = &acpi_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_ACPI,
+};
+
+++ /dev/null
-/*
- * (C) 2003 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "amd8111.h"
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x2c,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations ac97audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = amd8111_enable,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97audio_driver __pci_driver = {
- .ops = &ac97audio_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x746D,
-};
-
-
-static struct device_operations ac97modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = amd8111_enable,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97modem_driver __pci_driver = {
- .ops = &ac97modem_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x746E,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <pc80/mc146818rtc.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include "amd8111.h"
-#include "amd8111_smbus.h"
-
-#define PREVIOUS_POWER_STATE 0x43
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-#define SLOW_CPU_OFF 0
-#define SLOW_CPU__ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-
-static int lsmbus_recv_byte(device_t dev)
-{
- unsigned device;
- struct resource *res;
-
- device = dev->path.i2c.device;
- res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, uint8_t val)
-{
- unsigned device;
- struct resource *res;
-
- device = dev->path.i2c.device;
- res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-
-static int lsmbus_read_byte(device_t dev, uint8_t address)
-{
- unsigned device;
- struct resource *res;
-
- device = dev->path.i2c.device;
- res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
-{
- unsigned device;
- struct resource *res;
-
- device = dev->path.i2c.device;
- res = find_resource(get_pbus_smbus(dev)->dev, 0x58);
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-
-#if CONFIG_GENERATE_ACPI_TABLES == 1
-unsigned pm_base;
-#endif
-
-static void acpi_init(struct device *dev)
-{
- uint8_t byte;
- uint16_t pm10_bar;
- uint32_t dword;
- int on;
-
-#if 0
- uint16_t word;
- printk(BIOS_DEBUG, "ACPI: disabling NMI watchdog.. ");
- byte = pci_read_config8(dev, 0x49);
- pci_write_config8(dev, 0x49, byte | (1<<2));
-
-
- byte = pci_read_config8(dev, 0x41);
- pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<2));
-
- /* added from sourceforge */
- byte = pci_read_config8(dev, 0x48);
- pci_write_config8(dev, 0x48, byte | (1<<3));
-
- printk(BIOS_DEBUG, "done.\n");
-
-
- printk(BIOS_DEBUG, "ACPI: Routing IRQ 12 to PS2 port.. ");
- word = pci_read_config16(dev, 0x46);
- pci_write_config16(dev, 0x46, word | (1<<9));
- printk(BIOS_DEBUG, "done.\n");
-#endif
-
- /* To enable the register 0xcf9 in the IO space
- * bit [D5] is set in the amd8111 configuration register.
- * The config. reg. is devBx41. Register 0xcf9 allows
- * hard reset capability to the system. For the ACPI
- * reset.reg values in fadt.c to work this register
- * must be enabled.
- */
- byte = pci_read_config8(dev, 0x41);
- pci_write_config8(dev, 0x41, byte | (1<<6)|(1<<5));
-
- /* power on after power fail */
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
- byte &= ~0x40;
- if (!on) {
- byte |= 0x40;
- }
- pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
-
- /* switch serial irq logic from quiet mode to continuous
- * mode for Winbond W83627HF Rev. 17
- */
- byte = pci_read_config8(dev, 0x4a);
- pci_write_config8(dev, 0x4a, byte | (1<<6));
-
- /* Throttle the CPU speed down for testing */
- on = SLOW_CPU_OFF;
- get_option(&on, "slow_cpu");
- if(on) {
- pm10_bar = (pci_read_config16(dev, 0x58)&0xff00);
- outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
- dword = inl(pm10_bar + 0x10);
- on = 8-on;
- printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
- (on*12)+(on>>1),(on&1)*5);
- }
-
-#if CONFIG_GENERATE_ACPI_TABLES == 1
- pm_base = pci_read_config16(dev, 0x58) & 0xff00;
- printk(BIOS_DEBUG, "pm_base: 0x%04x\n",pm_base);
-#endif
-
-}
-
-static void acpi_read_resources(device_t dev)
-{
- struct resource *resource;
-
- /* Handle the generic bars */
- pci_dev_read_resources(dev);
-
- /* Add the ACPI/SMBUS bar */
- resource = new_resource(dev, 0x58);
- resource->base = 0;
- resource->size = 256;
- resource->align = log2(256);
- resource->gran = log2(256);
- resource->limit = 65536;
- resource->flags = IORESOURCE_IO;
- resource->index = 0x58;
-}
-
-static void acpi_enable_resources(device_t dev)
-{
- uint8_t byte;
- /* Enable the generic pci resources */
- pci_dev_enable_resources(dev);
-
- /* Enable the ACPI/SMBUS Bar */
- byte = pci_read_config8(dev, 0x41);
- byte |= (1 << 7);
- pci_write_config8(dev, 0x41, byte);
-
- /* Set the class code */
- pci_write_config32(dev, 0x60, 0x06800000);
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x7c,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations acpi_ops = {
- .read_resources = acpi_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = acpi_enable_resources,
- .init = acpi_init,
- .scan_bus = scan_static_bus,
- /* We don't need amd8111_enable, chip ops takes care of it.
- * It could be useful if these devices were not
- * enabled by default.
- */
-// .enable = amd8111_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver acpi_driver __pci_driver = {
- .ops = &acpi_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_ACPI,
-};
-
+++ /dev/null
-#include "amd8111.h"
-#include <reset.h>
-
-/* by yhlu 2005.10 */
-static unsigned get_sbdn(unsigned bus)
-{
- device_t dev;
-
- /* Find the device.
- * There can only be one 8111 on a hypertransport chain/bus.
- */
- dev = pci_locate_device_on_bus(
- PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_PCI),
- bus);
-
- return (dev>>15) & 0x1f;
-
-}
-
-static void enable_cf9_x(unsigned sbbusn, unsigned sbdn)
-{
- device_t dev;
- uint8_t byte;
-
- dev = PCI_DEV(sbbusn, sbdn+1, 3); //ACPI
- /* enable cf9 */
- byte = pci_read_config8(dev, 0x41);
- byte |= (1<<6) | (1<<5);
- pci_write_config8(dev, 0x41, byte);
-}
-
-static void enable_cf9(void)
-{
- unsigned sblk = get_sblk();
- unsigned sbbusn = get_sbbusn(sblk);
- unsigned sbdn = get_sbdn(sbbusn);
-
- enable_cf9_x(sbbusn, sbdn);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* reset */
- enable_cf9();
- outb(0x0e, 0x0cf9); // make sure cf9 is enabled
-}
-
-void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
-{
- device_t dev;
-
- dev = PCI_DEV(sbbusn, sbdn+1, 3); // ACPI
-
- pci_write_config8(dev, 0x74, 4);
-
- /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
- pci_write_config32(dev, 0x70, 2<<12);
-
-}
-
-static void soft_reset_x(unsigned sbbusn, unsigned sbdn)
-{
- device_t dev;
-
- dev = PCI_DEV(sbbusn, sbdn+1, 0); //ISA
-
- /* Reset */
- set_bios_reset();
- pci_write_config8(dev, 0x47, 1);
-
-}
-
-void soft_reset(void)
-{
-
- unsigned sblk = get_sblk();
- unsigned sbbusn = get_sbbusn(sblk);
- unsigned sbdn = get_sbdn(sbbusn);
-
- return soft_reset_x(sbbusn, sbdn);
-
-}
+++ /dev/null
-#include "amd8111_smbus.h"
-
-#define SMBUS_IO_BASE 0x0f00
-
-static void enable_smbus(void)
-{
- device_t dev;
- uint8_t enable;
-
- dev = pci_locate_device(PCI_ID(0x1022, 0x746b), 0);
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- }
-
- pci_write_config32(dev, 0x58, SMBUS_IO_BASE | 1);
- enable = pci_read_config8(dev, 0x41);
- pci_write_config8(dev, 0x41, enable | (1 << 7));
-
- /* check that we can see the smbus controller I/O. */
- if (inw(SMBUS_IO_BASE)==0xFF){
- die("SMBUS controller I/O not found\n");
- }
-
- /* clear any lingering errors, so the transaction will run */
- outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
- print_spew("SMBus controller enabled\n");
-}
-
-static inline int smbus_recv_byte(unsigned device)
-{
- return do_smbus_recv_byte(SMBUS_IO_BASE, device);
-}
-
-static inline int smbus_send_byte(unsigned device, unsigned char val)
-{
- return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
-}
-
-static inline int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
-static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-
-/* Enable 5MB ROM access at 0xFFB00000 - 0xFFFFFFFF. */
-static void amd8111_enable_rom(void)
-{
- u8 byte;
- device_t dev;
-
- dev = pci_io_locate_device(PCI_ID(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_8111_ISA), 0);
-
- /* Note: The 0xFFFF0000 - 0xFFFFFFFF range is always enabled. */
-
- /* Set the 5MB enable bits. */
- byte = pci_io_read_config8(dev, 0x43);
- byte |= (1 << 7); /* Enable 0xFFC00000-0xFFFFFFFF (4MB). */
- byte |= (1 << 6); /* Enable 0xFFB00000-0xFFBFFFFF (1MB). */
- pci_io_write_config8(dev, 0x43, byte);
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "amd8111.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_amd_amd8111_config *conf;
- /* Enable ide devices so the linux ide driver will work */
- uint16_t word;
- uint8_t byte;
- conf = dev->chip_info;
-
- word = pci_read_config16(dev, 0x40);
- /* Ensure prefetch is disabled */
- word &= ~((1 << 15) | (1 << 13));
- if (conf->ide1_enable) {
- /* Enable secondary ide interface */
- word |= (1<<0);
- printk(BIOS_DEBUG, "IDE1 ");
- }
- if (conf->ide0_enable) {
- /* Enable primary ide interface */
- word |= (1<<1);
- printk(BIOS_DEBUG, "IDE0 ");
- }
-
- word |= (1<<12);
- word |= (1<<14);
-
- pci_write_config16(dev, 0x40, word);
-
-
- byte = 0x20 ; // Latency: 64-->32
- pci_write_config8(dev, 0xd, byte);
-
- word = 0x0f;
- pci_write_config16(dev, 0x42, word);
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x70,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = amd8111_enable,
- .ops_pci = &lops_pci
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_IDE,
-};
-
+++ /dev/null
-/*
- * (C) 2003 Linux Networx, SuSE Linux AG
- * 2006.1 yhlu add dest apicid for IRQ0
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <cpu/x86/lapic.h>
-#include <arch/ioapic.h>
-#include <stdlib.h>
-#include "amd8111.h"
-
-#define NMI_OFF 0
-
-static void enable_hpet(struct device *dev)
-{
- unsigned long hpet_address;
-
- pci_write_config32(dev,0xa0, 0xfed00001);
- hpet_address = pci_read_config32(dev,0xa0)& 0xfffffffe;
- printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address);
-
-}
-
-static void lpc_init(struct device *dev)
-{
- uint8_t byte;
- int nmi_option;
-
- /* IO APIC initialization */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1;
- pci_write_config8(dev, 0x4B, byte);
- /* Don't rename IO APIC */
- setup_ioapic(IO_APIC_ADDR, 0);
-
- /* posted memory write enable */
- byte = pci_read_config8(dev, 0x46);
- pci_write_config8(dev, 0x46, byte | (1<<0));
-
- /* Enable 5Mib Rom window */
- byte = pci_read_config8(dev, 0x43);
- byte |= 0xc0;
- pci_write_config8(dev, 0x43, byte);
-
- /* Enable Port 92 fast reset */
- byte = pci_read_config8(dev, 0x41);
- byte |= (1 << 5);
- pci_write_config8(dev, 0x41, byte);
-
- /* Enable Error reporting */
- /* Set up sync flood detected */
- byte = pci_read_config8(dev, 0x47);
- byte |= (1 << 1);
- pci_write_config8(dev, 0x47, byte);
-
- /* Set up NMI on errors */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 1); /* clear PW2LPC error */
- byte |= (1 << 6); /* clear LPCERR */
- pci_write_config8(dev, 0x40, byte);
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte |= (1 << 7); /* set NMI */
- pci_write_config8(dev, 0x40, byte);
- }
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- /* Initialize the High Precision Event Timers */
- enable_hpet(dev);
-}
-
-static void amd8111_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x70,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = amd8111_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = amd8111_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_ISA,
-};
+++ /dev/null
-/*
- * (C) 2003 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "amd8111.h"
-
-
-#define CMD3 0x54
-
-typedef enum {
- VAL3 = (1 << 31), /* VAL bit for byte 3 */
- VAL2 = (1 << 23), /* VAL bit for byte 2 */
- VAL1 = (1 << 15), /* VAL bit for byte 1 */
- VAL0 = (1 << 7), /* VAL bit for byte 0 */
-}VAL_BITS;
-
-typedef enum {
- /* VAL3 */
- ASF_INIT_DONE_ALIAS = (1 << 29),
- /* VAL2 */
- JUMBO = (1 << 21),
- VSIZE = (1 << 20),
- VLONLY = (1 << 19),
- VL_TAG_DEL = (1 << 18),
- /* VAL1 */
- EN_PMGR = (1 << 14),
- INTLEVEL = (1 << 13),
- FORCE_FULL_DUPLEX = (1 << 12),
- FORCE_LINK_STATUS = (1 << 11),
- APEP = (1 << 10),
- MPPLBA = (1 << 9),
- /* VAL0 */
- RESET_PHY_PULSE = (1 << 2),
- RESET_PHY = (1 << 1),
- PHY_RST_POL = (1 << 0),
-}CMD3_BITS;
-
-static void nic_init(struct device *dev)
-{
- struct southbridge_amd_amd8111_config *conf;
- struct resource *resource;
- unsigned long mmio;
-
- conf = dev->chip_info;
- resource = find_resource(dev, PCI_BASE_ADDRESS_0);
- mmio = resource->base;
-
- /* Hard Reset PHY */
- printk(BIOS_DEBUG, "Reseting PHY... ");
- if (conf->phy_lowreset) {
- write32((mmio + CMD3), VAL0 | PHY_RST_POL | RESET_PHY);
- } else {
- write32((mmio + CMD3), VAL0 | RESET_PHY);
- }
- mdelay(15);
- write32((mmio + CMD3), RESET_PHY);
- printk(BIOS_DEBUG, "Done\n");
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0xc8,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
- .enable = amd8111_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_NIC,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "amd8111.h"
-
-static void pci_init(struct device *dev)
-{
-
- /* Enable pci error detecting */
- uint32_t dword;
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (7<<28); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
- /* System,Parity,timer,and abort error enable */
- dword = pci_read_config32(dev, 0x3c);
- dword |= (1<<16); /* Parity */
- dword |= (1<<17); /* System */
- dword |= (1<<21); /* Master abort */
-// dword &= ~(1<<21); /* Master abort */
-// dword |= (1<<27); /* Discard timer */
- dword &= ~(1<<27); /* Discard timer */
- dword |= (1<<26); /* DTSTAT error clear */
- pci_write_config32(dev, 0x3c, dword);
-
- /* CRC flood enable */
- dword = pci_read_config32(dev, 0xc4);
- dword |= (1<<1); /* CRC Flood enable */
- dword |= (1<<8); /* Clear any CRC errors */
- dword |= (1<<4); /* Clear any LKFAIL errors */
- pci_write_config32(dev, 0xc4, dword);
-
- /* Clear possible errors */
- dword = pci_read_config32(dev, 0x1c);
- dword |= (1<<27); /* STA */
- dword |= (1<<28); /* RTA */
- dword |= (1<<29); /* RMA */
- dword |= (1<<30); /* RSE */
- dword |= (1<<31); /* DPE */
- dword |= (1<<24); /* MDPE */
- pci_write_config32(dev, 0x1c, dword);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- /* PCI Subordinate bus reset is not implemented */
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_PCI,
-};
-
+++ /dev/null
-#include <arch/io.h>
-#include <reset.h>
-#include <device/pci_ids.h>
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFFF) << 20) | \
- (((DEV) & 0x1F) << 15) | \
- (((FN) & 0x7) << 12))
-
-#define PCI_ID(VENDOR_ID, DEVICE_ID) \
- ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
-
-typedef unsigned device_t;
-
-static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outb(value, 0xCFC + (addr & 3));
-}
-
-static void pci_write_config32(device_t dev, unsigned where, unsigned value)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outl(value, 0xCFC);
-}
-
-static unsigned pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- return inl(0xCFC);
-}
-
-#define PCI_DEV_INVALID (0xffffffffU)
-static device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
-{
- device_t dev, last;
- dev = PCI_DEV(bus, 0, 0);
- last = PCI_DEV(bus, 31, 7);
- for(; dev <= last; dev += PCI_DEV(0,0,1)) {
- unsigned int id;
- id = pci_read_config32(dev, 0);
- if (id == pci_id) {
- return dev;
- }
- }
- return PCI_DEV_INVALID;
-}
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-
-void hard_reset(void)
-{
- device_t dev;
- unsigned bus;
- unsigned node = 0;
- unsigned link = get_sblk();
-
- /* Find the device.
- * There can only be one 8111 on a hypertransport chain/bus.
- */
- bus = node_link_to_bus(node, link);
- dev = pci_locate_device_on_bus(
- PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA),
- bus);
-
- /* Reset */
- set_bios_reset();
- pci_write_config8(dev, 0x47, 1);
-}
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <arch/io.h>
-#include "amd8111.h"
-
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x44,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- /* I haven't seen the 2.0 SMBUS controller used yet. */
-};
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = amd8111_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_SMB,
-};
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "amd8111.h"
-
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x70,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
-// .enable = amd8111_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_USB,
-};
+++ /dev/null
-//2003 Copywright Tyan
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "amd8111.h"
-
-#if 0
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x70,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-#endif
-
-static void amd8111_usb2_enable(device_t dev)
-{
- // Due to buggy USB2 we force it to disable.
- dev->enabled = 0;
- amd8111_enable(dev);
- printk(BIOS_DEBUG, "USB2 disabled.\n");
-}
-
-static struct device_operations usb2_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .scan_bus = 0,
- .enable = amd8111_usb2_enable,
- // .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb2_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_8111_USB2,
-};
-#include "southbridge/amd/amd8111/amd8111_enable_rom.c"
+#include "southbridge/amd/amd8111/enable_rom.c"
static void bootblock_southbridge_init(void)
{
--- /dev/null
+#include "amd8111.h"
+#include <reset.h>
+
+/* by yhlu 2005.10 */
+static unsigned get_sbdn(unsigned bus)
+{
+ device_t dev;
+
+ /* Find the device.
+ * There can only be one 8111 on a hypertransport chain/bus.
+ */
+ dev = pci_locate_device_on_bus(
+ PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_PCI),
+ bus);
+
+ return (dev>>15) & 0x1f;
+
+}
+
+static void enable_cf9_x(unsigned sbbusn, unsigned sbdn)
+{
+ device_t dev;
+ uint8_t byte;
+
+ dev = PCI_DEV(sbbusn, sbdn+1, 3); //ACPI
+ /* enable cf9 */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1<<6) | (1<<5);
+ pci_write_config8(dev, 0x41, byte);
+}
+
+static void enable_cf9(void)
+{
+ unsigned sblk = get_sblk();
+ unsigned sbbusn = get_sbbusn(sblk);
+ unsigned sbdn = get_sbdn(sbbusn);
+
+ enable_cf9_x(sbbusn, sbdn);
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* reset */
+ enable_cf9();
+ outb(0x0e, 0x0cf9); // make sure cf9 is enabled
+}
+
+void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
+{
+ device_t dev;
+
+ dev = PCI_DEV(sbbusn, sbdn+1, 3); // ACPI
+
+ pci_write_config8(dev, 0x74, 4);
+
+ /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
+ pci_write_config32(dev, 0x70, 2<<12);
+
+}
+
+static void soft_reset_x(unsigned sbbusn, unsigned sbdn)
+{
+ device_t dev;
+
+ dev = PCI_DEV(sbbusn, sbdn+1, 0); //ISA
+
+ /* Reset */
+ set_bios_reset();
+ pci_write_config8(dev, 0x47, 1);
+
+}
+
+void soft_reset(void)
+{
+
+ unsigned sblk = get_sblk();
+ unsigned sbbusn = get_sbbusn(sblk);
+ unsigned sbdn = get_sbdn(sbbusn);
+
+ return soft_reset_x(sbbusn, sbdn);
+
+}
--- /dev/null
+#include "amd8111_smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ uint8_t enable;
+
+ dev = pci_locate_device(PCI_ID(0x1022, 0x746b), 0);
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ }
+
+ pci_write_config32(dev, 0x58, SMBUS_IO_BASE | 1);
+ enable = pci_read_config8(dev, 0x41);
+ pci_write_config8(dev, 0x41, enable | (1 << 7));
+
+ /* check that we can see the smbus controller I/O. */
+ if (inw(SMBUS_IO_BASE)==0xFF){
+ die("SMBUS controller I/O not found\n");
+ }
+
+ /* clear any lingering errors, so the transaction will run */
+ outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
+ print_spew("SMBus controller enabled\n");
+}
+
+static inline int smbus_recv_byte(unsigned device)
+{
+ return do_smbus_recv_byte(SMBUS_IO_BASE, device);
+}
+
+static inline int smbus_send_byte(unsigned device, unsigned char val)
+{
+ return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
+}
+
+static inline int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+
+/* Enable 5MB ROM access at 0xFFB00000 - 0xFFFFFFFF. */
+static void amd8111_enable_rom(void)
+{
+ u8 byte;
+ device_t dev;
+
+ dev = pci_io_locate_device(PCI_ID(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_8111_ISA), 0);
+
+ /* Note: The 0xFFFF0000 - 0xFFFFFFFF range is always enabled. */
+
+ /* Set the 5MB enable bits. */
+ byte = pci_io_read_config8(dev, 0x43);
+ byte |= (1 << 7); /* Enable 0xFFC00000-0xFFFFFFFF (4MB). */
+ byte |= (1 << 6); /* Enable 0xFFB00000-0xFFBFFFFF (1MB). */
+ pci_io_write_config8(dev, 0x43, byte);
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_amd_amd8111_config *conf;
+ /* Enable ide devices so the linux ide driver will work */
+ uint16_t word;
+ uint8_t byte;
+ conf = dev->chip_info;
+
+ word = pci_read_config16(dev, 0x40);
+ /* Ensure prefetch is disabled */
+ word &= ~((1 << 15) | (1 << 13));
+ if (conf->ide1_enable) {
+ /* Enable secondary ide interface */
+ word |= (1<<0);
+ printk(BIOS_DEBUG, "IDE1 ");
+ }
+ if (conf->ide0_enable) {
+ /* Enable primary ide interface */
+ word |= (1<<1);
+ printk(BIOS_DEBUG, "IDE0 ");
+ }
+
+ word |= (1<<12);
+ word |= (1<<14);
+
+ pci_write_config16(dev, 0x40, word);
+
+
+ byte = 0x20 ; // Latency: 64-->32
+ pci_write_config8(dev, 0xd, byte);
+
+ word = 0x0f;
+ pci_write_config16(dev, 0x42, word);
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x70,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = amd8111_enable,
+ .ops_pci = &lops_pci
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_IDE,
+};
+
--- /dev/null
+/*
+ * (C) 2003 Linux Networx, SuSE Linux AG
+ * 2006.1 yhlu add dest apicid for IRQ0
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <cpu/x86/lapic.h>
+#include <arch/ioapic.h>
+#include <stdlib.h>
+#include "amd8111.h"
+
+#define NMI_OFF 0
+
+static void enable_hpet(struct device *dev)
+{
+ unsigned long hpet_address;
+
+ pci_write_config32(dev,0xa0, 0xfed00001);
+ hpet_address = pci_read_config32(dev,0xa0)& 0xfffffffe;
+ printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address);
+
+}
+
+static void lpc_init(struct device *dev)
+{
+ uint8_t byte;
+ int nmi_option;
+
+ /* IO APIC initialization */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1;
+ pci_write_config8(dev, 0x4B, byte);
+ /* Don't rename IO APIC */
+ setup_ioapic(IO_APIC_ADDR, 0);
+
+ /* posted memory write enable */
+ byte = pci_read_config8(dev, 0x46);
+ pci_write_config8(dev, 0x46, byte | (1<<0));
+
+ /* Enable 5Mib Rom window */
+ byte = pci_read_config8(dev, 0x43);
+ byte |= 0xc0;
+ pci_write_config8(dev, 0x43, byte);
+
+ /* Enable Port 92 fast reset */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1 << 5);
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Enable Error reporting */
+ /* Set up sync flood detected */
+ byte = pci_read_config8(dev, 0x47);
+ byte |= (1 << 1);
+ pci_write_config8(dev, 0x47, byte);
+
+ /* Set up NMI on errors */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 1); /* clear PW2LPC error */
+ byte |= (1 << 6); /* clear LPCERR */
+ pci_write_config8(dev, 0x40, byte);
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte |= (1 << 7); /* set NMI */
+ pci_write_config8(dev, 0x40, byte);
+ }
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ /* Initialize the High Precision Event Timers */
+ enable_hpet(dev);
+}
+
+static void amd8111_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x70,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = amd8111_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = amd8111_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_ISA,
+};
--- /dev/null
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "amd8111.h"
+
+
+#define CMD3 0x54
+
+typedef enum {
+ VAL3 = (1 << 31), /* VAL bit for byte 3 */
+ VAL2 = (1 << 23), /* VAL bit for byte 2 */
+ VAL1 = (1 << 15), /* VAL bit for byte 1 */
+ VAL0 = (1 << 7), /* VAL bit for byte 0 */
+}VAL_BITS;
+
+typedef enum {
+ /* VAL3 */
+ ASF_INIT_DONE_ALIAS = (1 << 29),
+ /* VAL2 */
+ JUMBO = (1 << 21),
+ VSIZE = (1 << 20),
+ VLONLY = (1 << 19),
+ VL_TAG_DEL = (1 << 18),
+ /* VAL1 */
+ EN_PMGR = (1 << 14),
+ INTLEVEL = (1 << 13),
+ FORCE_FULL_DUPLEX = (1 << 12),
+ FORCE_LINK_STATUS = (1 << 11),
+ APEP = (1 << 10),
+ MPPLBA = (1 << 9),
+ /* VAL0 */
+ RESET_PHY_PULSE = (1 << 2),
+ RESET_PHY = (1 << 1),
+ PHY_RST_POL = (1 << 0),
+}CMD3_BITS;
+
+static void nic_init(struct device *dev)
+{
+ struct southbridge_amd_amd8111_config *conf;
+ struct resource *resource;
+ unsigned long mmio;
+
+ conf = dev->chip_info;
+ resource = find_resource(dev, PCI_BASE_ADDRESS_0);
+ mmio = resource->base;
+
+ /* Hard Reset PHY */
+ printk(BIOS_DEBUG, "Reseting PHY... ");
+ if (conf->phy_lowreset) {
+ write32((mmio + CMD3), VAL0 | PHY_RST_POL | RESET_PHY);
+ } else {
+ write32((mmio + CMD3), VAL0 | RESET_PHY);
+ }
+ mdelay(15);
+ write32((mmio + CMD3), RESET_PHY);
+ printk(BIOS_DEBUG, "Done\n");
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0xc8,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+ .enable = amd8111_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_NIC,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+static void pci_init(struct device *dev)
+{
+
+ /* Enable pci error detecting */
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (7<<28); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+ /* System,Parity,timer,and abort error enable */
+ dword = pci_read_config32(dev, 0x3c);
+ dword |= (1<<16); /* Parity */
+ dword |= (1<<17); /* System */
+ dword |= (1<<21); /* Master abort */
+// dword &= ~(1<<21); /* Master abort */
+// dword |= (1<<27); /* Discard timer */
+ dword &= ~(1<<27); /* Discard timer */
+ dword |= (1<<26); /* DTSTAT error clear */
+ pci_write_config32(dev, 0x3c, dword);
+
+ /* CRC flood enable */
+ dword = pci_read_config32(dev, 0xc4);
+ dword |= (1<<1); /* CRC Flood enable */
+ dword |= (1<<8); /* Clear any CRC errors */
+ dword |= (1<<4); /* Clear any LKFAIL errors */
+ pci_write_config32(dev, 0xc4, dword);
+
+ /* Clear possible errors */
+ dword = pci_read_config32(dev, 0x1c);
+ dword |= (1<<27); /* STA */
+ dword |= (1<<28); /* RTA */
+ dword |= (1<<29); /* RMA */
+ dword |= (1<<30); /* RSE */
+ dword |= (1<<31); /* DPE */
+ dword |= (1<<24); /* MDPE */
+ pci_write_config32(dev, 0x1c, dword);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ /* PCI Subordinate bus reset is not implemented */
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_PCI,
+};
+
--- /dev/null
+#include <arch/io.h>
+#include <reset.h>
+#include <device/pci_ids.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+#define PCI_ID(VENDOR_ID, DEVICE_ID) \
+ ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
+
+typedef unsigned device_t;
+
+static void pci_write_config8(device_t dev, unsigned where, unsigned char value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outb(value, 0xCFC + (addr & 3));
+}
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#define PCI_DEV_INVALID (0xffffffffU)
+static device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
+{
+ device_t dev, last;
+ dev = PCI_DEV(bus, 0, 0);
+ last = PCI_DEV(bus, 31, 7);
+ for(; dev <= last; dev += PCI_DEV(0,0,1)) {
+ unsigned int id;
+ id = pci_read_config32(dev, 0);
+ if (id == pci_id) {
+ return dev;
+ }
+ }
+ return PCI_DEV_INVALID;
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+
+void hard_reset(void)
+{
+ device_t dev;
+ unsigned bus;
+ unsigned node = 0;
+ unsigned link = get_sblk();
+
+ /* Find the device.
+ * There can only be one 8111 on a hypertransport chain/bus.
+ */
+ bus = node_link_to_bus(node, link);
+ dev = pci_locate_device_on_bus(
+ PCI_ID(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_ISA),
+ bus);
+
+ /* Reset */
+ set_bios_reset();
+ pci_write_config8(dev, 0x47, 1);
+}
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "amd8111.h"
+
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x44,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ /* I haven't seen the 2.0 SMBUS controller used yet. */
+};
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = amd8111_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_SMB,
+};
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "amd8111.h"
+
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x70,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+// .enable = amd8111_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_USB,
+};
--- /dev/null
+//2003 Copywright Tyan
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "amd8111.h"
+
+#if 0
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x70,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+#endif
+
+static void amd8111_usb2_enable(device_t dev)
+{
+ // Due to buggy USB2 we force it to disable.
+ dev->enabled = 0;
+ amd8111_enable(dev);
+ printk(BIOS_DEBUG, "USB2 disabled.\n");
+}
+
+static struct device_operations usb2_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .scan_bus = 0,
+ .enable = amd8111_usb2_enable,
+ // .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_8111_USB2,
+};
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-
-static void amd8131_bus_read_resources(device_t dev)
-{
- return;
-}
-
-static void amd8131_bus_set_resources(device_t dev)
-{
-#if 0
- pci_bus_read_resources(dev);
-#endif
- return;
-}
-
-static void amd8131_bus_enable_resources(device_t dev)
-{
-#if 0
- pci_dev_set_resources(dev);
-#endif
- return;
-}
-
-static void amd8131_bus_init(device_t dev)
-{
-#if 0
- pcix_init(dev);
-#endif
- return;
-}
-
-static unsigned int amd8131_scan_bus(device_t bus, unsigned int max)
-{
-#if 0
- max = pcix_scan_bridge(bus, max);
-#endif
- return max;
-}
-
-static void amd8131_enable(device_t dev)
-{
- uint32_t buses;
- uint16_t cr;
-
- /* Clear all status bits and turn off memory, I/O and master enables. */
- pci_write_config16(dev, PCI_COMMAND, 0x0000);
- pci_write_config16(dev, PCI_STATUS, 0xffff);
-
- /*
- * Read the existing primary/secondary/subordinate bus
- * number configuration.
- */
- buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
-
- /* Configure the bus numbers for this bridge: the configuration
- * transactions will not be propagated by the bridge if it is not
- * correctly configured.
- */
- buses &= 0xff000000;
- buses |= (((unsigned int) (dev->bus->secondary) << 0) |
- ((unsigned int) (dev->bus->secondary) << 8) |
- ((unsigned int) (dev->bus->secondary) << 16));
- pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
-}
-
-static struct device_operations pcix_ops = {
- .read_resources = amd8131_bus_read_resources,
- .set_resources = amd8131_bus_set_resources,
- .enable_resources = amd8131_bus_enable_resources,
- .init = amd8131_bus_init,
- .scan_bus = 0,
- .enable = amd8131_enable,
-};
-
-static const struct pci_driver pcix_driver __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7450,
-};
-
-
-static void ioapic_enable(device_t dev)
-{
- uint32_t value;
- value = pci_read_config32(dev, 0x44);
- if (dev->enabled) {
- value |= ((1 << 1) | (1 << 0));
- } else {
- value &= ~((1 << 1) | (1 << 0));
- }
- pci_write_config32(dev, 0x44, value);
-}
-
-static struct device_operations ioapic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = ioapic_enable,
-};
-
-static const struct pci_driver ioapic_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7451,
-
-};
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+
+static void amd8131_bus_read_resources(device_t dev)
+{
+ return;
+}
+
+static void amd8131_bus_set_resources(device_t dev)
+{
+#if 0
+ pci_bus_read_resources(dev);
+#endif
+ return;
+}
+
+static void amd8131_bus_enable_resources(device_t dev)
+{
+#if 0
+ pci_dev_set_resources(dev);
+#endif
+ return;
+}
+
+static void amd8131_bus_init(device_t dev)
+{
+#if 0
+ pcix_init(dev);
+#endif
+ return;
+}
+
+static unsigned int amd8131_scan_bus(device_t bus, unsigned int max)
+{
+#if 0
+ max = pcix_scan_bridge(bus, max);
+#endif
+ return max;
+}
+
+static void amd8131_enable(device_t dev)
+{
+ uint32_t buses;
+ uint16_t cr;
+
+ /* Clear all status bits and turn off memory, I/O and master enables. */
+ pci_write_config16(dev, PCI_COMMAND, 0x0000);
+ pci_write_config16(dev, PCI_STATUS, 0xffff);
+
+ /*
+ * Read the existing primary/secondary/subordinate bus
+ * number configuration.
+ */
+ buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+
+ /* Configure the bus numbers for this bridge: the configuration
+ * transactions will not be propagated by the bridge if it is not
+ * correctly configured.
+ */
+ buses &= 0xff000000;
+ buses |= (((unsigned int) (dev->bus->secondary) << 0) |
+ ((unsigned int) (dev->bus->secondary) << 8) |
+ ((unsigned int) (dev->bus->secondary) << 16));
+ pci_write_config32(dev, PCI_PRIMARY_BUS, buses);
+}
+
+static struct device_operations pcix_ops = {
+ .read_resources = amd8131_bus_read_resources,
+ .set_resources = amd8131_bus_set_resources,
+ .enable_resources = amd8131_bus_enable_resources,
+ .init = amd8131_bus_init,
+ .scan_bus = 0,
+ .enable = amd8131_enable,
+};
+
+static const struct pci_driver pcix_driver __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7450,
+};
+
+
+static void ioapic_enable(device_t dev)
+{
+ uint32_t value;
+ value = pci_read_config32(dev, 0x44);
+ if (dev->enabled) {
+ value |= ((1 << 1) | (1 << 0));
+ } else {
+ value &= ~((1 << 1) | (1 << 0));
+ }
+ pci_write_config32(dev, 0x44, value);
+}
+
+static struct device_operations ioapic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = ioapic_enable,
+};
+
+static const struct pci_driver ioapic_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7451,
+
+};
-driver-y += amd8131_bridge.c
+driver-y += bridge.c
+++ /dev/null
-/*
- * (C) 2003-2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <device/pci_def.h>
-#include <device/pcix.h>
-
-#define NMI_OFF 0
-
-#define NPUML 0xD9 /* Non prefetchable upper memory limit */
-#define NPUMB 0xD8 /* Non prefetchable upper memory base */
-
-static void amd8131_walk_children(struct bus *bus,
- void (*visit)(device_t dev, void *ptr), void *ptr)
-{
- device_t child;
- for(child = bus->children; child; child = child->sibling)
- {
- if (child->path.type != DEVICE_PATH_PCI) {
- continue;
- }
- if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- amd8131_walk_children(child->link_list, visit, ptr);
- }
- visit(child, ptr);
- }
-}
-
-struct amd8131_bus_info {
- unsigned sstatus;
- unsigned rev;
- int errata_56;
- int master_devices;
- int max_func;
-};
-
-static void amd8131_count_dev(device_t dev, void *ptr)
-{
- struct amd8131_bus_info *info = ptr;
- /* Don't count pci bridges */
- if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
- info->master_devices++;
- }
- if (PCI_FUNC(dev->path.pci.devfn) > info->max_func) {
- info->max_func = PCI_FUNC(dev->path.pci.devfn);
- }
-}
-
-
-static void amd8131_pcix_tune_dev(device_t dev, void *ptr)
-{
- struct amd8131_bus_info *info = ptr;
- unsigned cap;
- unsigned status, cmd, orig_cmd;
- unsigned max_read, max_tran;
- int sib_funcs, sibs;
- device_t sib;
-
- if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
- return;
- }
- cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!cap) {
- return;
- }
- /* How many siblings does this device have? */
- sibs = info->master_devices - 1;
- /* Count how many sibling functions this device has */
- sib_funcs = 0;
- for(sib = dev->bus->children; sib; sib = sib->sibling) {
- if (sib == dev) {
- continue;
- }
- if (PCI_SLOT(sib->path.pci.devfn) != PCI_SLOT(dev->path.pci.devfn)) {
- continue;
- }
- sib_funcs++;
- }
-
-
- printk(BIOS_DEBUG, "%s AMD8131 PCI-X tuning\n", dev_path(dev));
- status = pci_read_config32(dev, cap + PCI_X_STATUS);
- orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
-
- max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
- max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
-
- /* Errata #49 don't allow 4K transactions */
- if (max_read >= 2) {
- max_read = 2;
- }
-
- /* Errata #37 Limit the number of split transactions to avoid starvation */
- if (sibs >= 2) {
- /* At most 2 outstanding split transactions when we have
- * 3 or more bus master devices on the bus.
- */
- if (max_tran > 1) {
- max_tran = 1;
- }
- }
- else if (sibs == 1) {
- /* At most 4 outstanding split transactions when we have
- * 2 bus master devices on the bus.
- */
- if (max_tran > 3) {
- max_tran = 3;
- }
- }
- else {
- /* At most 8 outstanding split transactions when we have
- * only one bus master device on the bus.
- */
- if (max_tran > 4) {
- max_tran = 4;
- }
- }
- /* Errata #56 additional limits when the bus runs at 133Mhz */
- if (info->errata_56 &&
- (PCI_X_SSTATUS_MFREQ(info->sstatus) == PCI_X_SSTATUS_MODE1_133MHZ))
- {
- unsigned limit_read;
- /* Look at the number of siblings and compute the
- * largest legal read size.
- */
- if (sib_funcs == 0) {
- /* 2k reads */
- limit_read = 2;
- }
- else if (sib_funcs <= 1) {
- /* 1k reads */
- limit_read = 1;
- }
- else {
- /* 512 byte reads */
- limit_read = 0;
- }
- if (max_read > limit_read) {
- max_read = limit_read;
- }
- /* Look at the read size and the nubmer of siblings
- * and compute how many outstanding transactions I can have.
- */
- if (max_read == 2) {
- /* 2K reads */
- if (max_tran > 0) {
- /* Only 1 outstanding transaction allowed */
- max_tran = 0;
- }
- }
- else if (max_read == 1) {
- /* 1K reads */
- if (max_tran > (1 - sib_funcs)) {
- /* At most 2 outstanding transactions */
- max_tran = 1 - sib_funcs;
- }
- }
- else {
- /* 512 byte reads */
- max_read = 0;
- if (max_tran > (2 - sib_funcs)) {
- /* At most 3 outstanding transactions */
- max_tran = 2 - sib_funcs;
- }
- }
- }
-#if 0
- printk(BIOS_DEBUG, "%s max_read: %d max_tran: %d sibs: %d sib_funcs: %d\n",
- dev_path(dev), max_read, max_tran, sibs, sib_funcs, sib_funcs);
-#endif
- if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
- cmd &= ~PCI_X_CMD_MAX_READ;
- cmd |= max_read << 2;
- }
- if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
- cmd &= ~PCI_X_CMD_MAX_SPLIT;
- cmd |= max_tran << 4;
- }
-
- /* Don't attempt to handle PCI-X errors */
- cmd &= ~PCI_X_CMD_DPERR_E;
- /* The 8131 does not work properly with relax ordering enabled.
- * Errata #58
- */
- cmd &= ~PCI_X_CMD_ERO;
- if (orig_cmd != cmd) {
- pci_write_config16(dev, cap + PCI_X_CMD, cmd);
- }
-}
-static unsigned int amd8131_scan_bus(struct bus *bus,
- unsigned min_devfn, unsigned max_devfn, unsigned int max)
-{
- struct amd8131_bus_info info;
- struct bus *pbus;
- unsigned pos;
-
-
- /* Find the children on the bus */
- max = pci_scan_bus(bus, min_devfn, max_devfn, max);
-
- /* Find the revision of the 8131 */
- info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
-
- /* See which errata apply */
- info.errata_56 = info.rev <= 0x12;
-
- /* Find the pcix capability and get the secondary bus status */
- pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
- info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
-
- /* Print the PCI-X bus speed */
- printk(BIOS_DEBUG, "PCI: %02x: %s\n", bus->secondary, pcix_speed(info.sstatus));
-
-
- /* Examine the bus and find out how loaded it is */
- info.max_func = 0;
- info.master_devices = 0;
- amd8131_walk_children(bus, amd8131_count_dev, &info);
-
- /* Disable the bus if there are no devices on it or
- * we are running at 133Mhz and have a 4 function device.
- * see errata #56
- */
- if (!bus->children ||
- (info.errata_56 &&
- (info.max_func >= 3) &&
- (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_MODE1_133MHZ)))
- {
- unsigned pcix_misc;
- /* Disable all of my children */
- disable_children(bus);
-
- /* Remember the device is disabled */
- bus->dev->enabled = 0;
-
- /* Disable the PCI-X clocks */
- pcix_misc = pci_read_config32(bus->dev, 0x40);
- pcix_misc &= ~(0x1f << 16);
- pci_write_config32(bus->dev, 0x40, pcix_misc);
-
- return max;
- }
-
- /* If we are in conventional PCI mode nothing more is necessary.
- */
- if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
- return max;
- }
-
-
- /* Tune the devices on the bus */
- amd8131_walk_children(bus, amd8131_pcix_tune_dev, &info);
-
- /* Don't allow the 8131 or any of it's parent busses to
- * implement relaxed ordering. Errata #58
- */
- for(pbus = bus; !pbus->disable_relaxed_ordering; pbus = pbus->dev->bus) {
- printk(BIOS_SPEW, "%s disabling relaxed ordering\n",
- bus_path(pbus));
- pbus->disable_relaxed_ordering = 1;
- }
- return max;
-}
-
-static unsigned int amd8131_scan_bridge(device_t dev, unsigned int max)
-{
- return do_pci_scan_bridge(dev, max, amd8131_scan_bus);
-}
-
-
-static void amd8131_pcix_init(device_t dev)
-{
- uint32_t dword;
- uint16_t word;
- uint8_t byte;
- int nmi_option;
-
- /* Enable memory write and invalidate ??? */
- byte = pci_read_config8(dev, 0x04);
- byte |= 0x10;
- pci_write_config8(dev, 0x04, byte);
-
- /* Set drive strength */
- word = pci_read_config16(dev, 0xe0);
- word = 0x0404;
- pci_write_config16(dev, 0xe0, word);
- word = pci_read_config16(dev, 0xe4);
- word = 0x0404;
- pci_write_config16(dev, 0xe4, word);
-
- /* Set impedance */
- word = pci_read_config16(dev, 0xe8);
- word = 0x0404;
- pci_write_config16(dev, 0xe8, word);
-
- /* Set discard unrequested prefetch data */
- /* Errata #51 */
- word = pci_read_config16(dev, 0x4c);
- word |= 1;
- pci_write_config16(dev, 0x4c, word);
-
- /* Set split transaction limits */
- word = pci_read_config16(dev, 0xa8);
- pci_write_config16(dev, 0xaa, word);
- word = pci_read_config16(dev, 0xac);
- pci_write_config16(dev, 0xae, word);
-
- /* Set up error reporting, enable all */
- /* system error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8);
- pci_write_config32(dev, 0x04, dword);
-
- /* system and error parity enable */
- dword = pci_read_config32(dev, 0x3c);
- dword |= (3<<16);
- pci_write_config32(dev, 0x3c, dword);
-
- /* NMI enable */
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if(nmi_option) {
- dword = pci_read_config32(dev, 0x44);
- dword |= (1<<0);
- pci_write_config32(dev, 0x44, dword);
- }
-
- /* Set up CRC flood enable */
- dword = pci_read_config32(dev, 0xc0);
- if(dword) { /* do device A only */
- dword = pci_read_config32(dev, 0xc4);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc4, dword);
- dword = pci_read_config32(dev, 0xc8);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc8, dword);
- }
- return;
-}
-
-#define BRIDGE_40_BIT_SUPPORT 0
-#if BRIDGE_40_BIT_SUPPORT
-static void bridge_read_resources(struct device *dev)
-{
- struct resource *res;
- pci_bus_read_resources(dev);
- res = find_resource(dev, PCI_MEMORY_BASE);
- if (res) {
- res->limit = 0xffffffffffULL;
- }
-}
-
-static void bridge_set_resources(struct device *dev)
-{
- struct resource *res;
- res = find_resource(dev, PCI_MEMORY_BASE);
- if (res) {
- resource_t base, end;
- /* set the memory range */
- dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- res->flags |= IORESOURCE_STORED;
- base = res->base;
- end = resource_end(res);
- pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
- pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
- pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
- pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
-
- report_resource_stored(dev, res, "");
- }
- pci_dev_set_resources(dev);
-}
-#endif /* BRIDGE_40_BIT_SUPPORT */
-
-static struct device_operations pcix_ops = {
-#if BRIDGE_40_BIT_SUPPORT
- .read_resources = bridge_read_resources,
- .set_resources = bridge_set_resources,
-#else
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
-#endif
- .enable_resources = pci_bus_enable_resources,
- .init = amd8131_pcix_init,
- .scan_bus = amd8131_scan_bridge,
- .reset_bus = pci_bus_reset,
-};
-
-static const struct pci_driver pcix_driver __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7450,
-};
-
-
-static void ioapic_enable(device_t dev)
-{
- uint32_t value;
-
- value = pci_read_config32(dev, 0x44);
- if (dev->enabled) {
- value |= ((1 << 1) | (1 << 0));
- } else {
- value &= ~((1 << 1) | (1 << 0));
- }
- pci_write_config32(dev, 0x44, value);
-}
-
-static struct pci_operations pci_ops_pci_dev = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-static struct device_operations ioapic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = ioapic_enable,
- .ops_pci = &pci_ops_pci_dev,
-};
-
-static const struct pci_driver ioapic_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7451,
-
-};
--- /dev/null
+/*
+ * (C) 2003-2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <device/pci_def.h>
+#include <device/pcix.h>
+
+#define NMI_OFF 0
+
+#define NPUML 0xD9 /* Non prefetchable upper memory limit */
+#define NPUMB 0xD8 /* Non prefetchable upper memory base */
+
+static void amd8131_walk_children(struct bus *bus,
+ void (*visit)(device_t dev, void *ptr), void *ptr)
+{
+ device_t child;
+ for(child = bus->children; child; child = child->sibling)
+ {
+ if (child->path.type != DEVICE_PATH_PCI) {
+ continue;
+ }
+ if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ amd8131_walk_children(child->link_list, visit, ptr);
+ }
+ visit(child, ptr);
+ }
+}
+
+struct amd8131_bus_info {
+ unsigned sstatus;
+ unsigned rev;
+ int errata_56;
+ int master_devices;
+ int max_func;
+};
+
+static void amd8131_count_dev(device_t dev, void *ptr)
+{
+ struct amd8131_bus_info *info = ptr;
+ /* Don't count pci bridges */
+ if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+ info->master_devices++;
+ }
+ if (PCI_FUNC(dev->path.pci.devfn) > info->max_func) {
+ info->max_func = PCI_FUNC(dev->path.pci.devfn);
+ }
+}
+
+
+static void amd8131_pcix_tune_dev(device_t dev, void *ptr)
+{
+ struct amd8131_bus_info *info = ptr;
+ unsigned cap;
+ unsigned status, cmd, orig_cmd;
+ unsigned max_read, max_tran;
+ int sib_funcs, sibs;
+ device_t sib;
+
+ if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
+ return;
+ }
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+ if (!cap) {
+ return;
+ }
+ /* How many siblings does this device have? */
+ sibs = info->master_devices - 1;
+ /* Count how many sibling functions this device has */
+ sib_funcs = 0;
+ for(sib = dev->bus->children; sib; sib = sib->sibling) {
+ if (sib == dev) {
+ continue;
+ }
+ if (PCI_SLOT(sib->path.pci.devfn) != PCI_SLOT(dev->path.pci.devfn)) {
+ continue;
+ }
+ sib_funcs++;
+ }
+
+
+ printk(BIOS_DEBUG, "%s AMD8131 PCI-X tuning\n", dev_path(dev));
+ status = pci_read_config32(dev, cap + PCI_X_STATUS);
+ orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
+
+ max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
+ max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
+
+ /* Errata #49 don't allow 4K transactions */
+ if (max_read >= 2) {
+ max_read = 2;
+ }
+
+ /* Errata #37 Limit the number of split transactions to avoid starvation */
+ if (sibs >= 2) {
+ /* At most 2 outstanding split transactions when we have
+ * 3 or more bus master devices on the bus.
+ */
+ if (max_tran > 1) {
+ max_tran = 1;
+ }
+ }
+ else if (sibs == 1) {
+ /* At most 4 outstanding split transactions when we have
+ * 2 bus master devices on the bus.
+ */
+ if (max_tran > 3) {
+ max_tran = 3;
+ }
+ }
+ else {
+ /* At most 8 outstanding split transactions when we have
+ * only one bus master device on the bus.
+ */
+ if (max_tran > 4) {
+ max_tran = 4;
+ }
+ }
+ /* Errata #56 additional limits when the bus runs at 133Mhz */
+ if (info->errata_56 &&
+ (PCI_X_SSTATUS_MFREQ(info->sstatus) == PCI_X_SSTATUS_MODE1_133MHZ))
+ {
+ unsigned limit_read;
+ /* Look at the number of siblings and compute the
+ * largest legal read size.
+ */
+ if (sib_funcs == 0) {
+ /* 2k reads */
+ limit_read = 2;
+ }
+ else if (sib_funcs <= 1) {
+ /* 1k reads */
+ limit_read = 1;
+ }
+ else {
+ /* 512 byte reads */
+ limit_read = 0;
+ }
+ if (max_read > limit_read) {
+ max_read = limit_read;
+ }
+ /* Look at the read size and the nubmer of siblings
+ * and compute how many outstanding transactions I can have.
+ */
+ if (max_read == 2) {
+ /* 2K reads */
+ if (max_tran > 0) {
+ /* Only 1 outstanding transaction allowed */
+ max_tran = 0;
+ }
+ }
+ else if (max_read == 1) {
+ /* 1K reads */
+ if (max_tran > (1 - sib_funcs)) {
+ /* At most 2 outstanding transactions */
+ max_tran = 1 - sib_funcs;
+ }
+ }
+ else {
+ /* 512 byte reads */
+ max_read = 0;
+ if (max_tran > (2 - sib_funcs)) {
+ /* At most 3 outstanding transactions */
+ max_tran = 2 - sib_funcs;
+ }
+ }
+ }
+#if 0
+ printk(BIOS_DEBUG, "%s max_read: %d max_tran: %d sibs: %d sib_funcs: %d\n",
+ dev_path(dev), max_read, max_tran, sibs, sib_funcs, sib_funcs);
+#endif
+ if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
+ cmd &= ~PCI_X_CMD_MAX_READ;
+ cmd |= max_read << 2;
+ }
+ if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
+ cmd &= ~PCI_X_CMD_MAX_SPLIT;
+ cmd |= max_tran << 4;
+ }
+
+ /* Don't attempt to handle PCI-X errors */
+ cmd &= ~PCI_X_CMD_DPERR_E;
+ /* The 8131 does not work properly with relax ordering enabled.
+ * Errata #58
+ */
+ cmd &= ~PCI_X_CMD_ERO;
+ if (orig_cmd != cmd) {
+ pci_write_config16(dev, cap + PCI_X_CMD, cmd);
+ }
+}
+static unsigned int amd8131_scan_bus(struct bus *bus,
+ unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+ struct amd8131_bus_info info;
+ struct bus *pbus;
+ unsigned pos;
+
+
+ /* Find the children on the bus */
+ max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+
+ /* Find the revision of the 8131 */
+ info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
+
+ /* See which errata apply */
+ info.errata_56 = info.rev <= 0x12;
+
+ /* Find the pcix capability and get the secondary bus status */
+ pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
+ info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
+
+ /* Print the PCI-X bus speed */
+ printk(BIOS_DEBUG, "PCI: %02x: %s\n", bus->secondary, pcix_speed(info.sstatus));
+
+
+ /* Examine the bus and find out how loaded it is */
+ info.max_func = 0;
+ info.master_devices = 0;
+ amd8131_walk_children(bus, amd8131_count_dev, &info);
+
+ /* Disable the bus if there are no devices on it or
+ * we are running at 133Mhz and have a 4 function device.
+ * see errata #56
+ */
+ if (!bus->children ||
+ (info.errata_56 &&
+ (info.max_func >= 3) &&
+ (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_MODE1_133MHZ)))
+ {
+ unsigned pcix_misc;
+ /* Disable all of my children */
+ disable_children(bus);
+
+ /* Remember the device is disabled */
+ bus->dev->enabled = 0;
+
+ /* Disable the PCI-X clocks */
+ pcix_misc = pci_read_config32(bus->dev, 0x40);
+ pcix_misc &= ~(0x1f << 16);
+ pci_write_config32(bus->dev, 0x40, pcix_misc);
+
+ return max;
+ }
+
+ /* If we are in conventional PCI mode nothing more is necessary.
+ */
+ if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
+ return max;
+ }
+
+
+ /* Tune the devices on the bus */
+ amd8131_walk_children(bus, amd8131_pcix_tune_dev, &info);
+
+ /* Don't allow the 8131 or any of it's parent busses to
+ * implement relaxed ordering. Errata #58
+ */
+ for(pbus = bus; !pbus->disable_relaxed_ordering; pbus = pbus->dev->bus) {
+ printk(BIOS_SPEW, "%s disabling relaxed ordering\n",
+ bus_path(pbus));
+ pbus->disable_relaxed_ordering = 1;
+ }
+ return max;
+}
+
+static unsigned int amd8131_scan_bridge(device_t dev, unsigned int max)
+{
+ return do_pci_scan_bridge(dev, max, amd8131_scan_bus);
+}
+
+
+static void amd8131_pcix_init(device_t dev)
+{
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+ int nmi_option;
+
+ /* Enable memory write and invalidate ??? */
+ byte = pci_read_config8(dev, 0x04);
+ byte |= 0x10;
+ pci_write_config8(dev, 0x04, byte);
+
+ /* Set drive strength */
+ word = pci_read_config16(dev, 0xe0);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe0, word);
+ word = pci_read_config16(dev, 0xe4);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe4, word);
+
+ /* Set impedance */
+ word = pci_read_config16(dev, 0xe8);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe8, word);
+
+ /* Set discard unrequested prefetch data */
+ /* Errata #51 */
+ word = pci_read_config16(dev, 0x4c);
+ word |= 1;
+ pci_write_config16(dev, 0x4c, word);
+
+ /* Set split transaction limits */
+ word = pci_read_config16(dev, 0xa8);
+ pci_write_config16(dev, 0xaa, word);
+ word = pci_read_config16(dev, 0xac);
+ pci_write_config16(dev, 0xae, word);
+
+ /* Set up error reporting, enable all */
+ /* system error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8);
+ pci_write_config32(dev, 0x04, dword);
+
+ /* system and error parity enable */
+ dword = pci_read_config32(dev, 0x3c);
+ dword |= (3<<16);
+ pci_write_config32(dev, 0x3c, dword);
+
+ /* NMI enable */
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if(nmi_option) {
+ dword = pci_read_config32(dev, 0x44);
+ dword |= (1<<0);
+ pci_write_config32(dev, 0x44, dword);
+ }
+
+ /* Set up CRC flood enable */
+ dword = pci_read_config32(dev, 0xc0);
+ if(dword) { /* do device A only */
+ dword = pci_read_config32(dev, 0xc4);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc4, dword);
+ dword = pci_read_config32(dev, 0xc8);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc8, dword);
+ }
+ return;
+}
+
+#define BRIDGE_40_BIT_SUPPORT 0
+#if BRIDGE_40_BIT_SUPPORT
+static void bridge_read_resources(struct device *dev)
+{
+ struct resource *res;
+ pci_bus_read_resources(dev);
+ res = find_resource(dev, PCI_MEMORY_BASE);
+ if (res) {
+ res->limit = 0xffffffffffULL;
+ }
+}
+
+static void bridge_set_resources(struct device *dev)
+{
+ struct resource *res;
+ res = find_resource(dev, PCI_MEMORY_BASE);
+ if (res) {
+ resource_t base, end;
+ /* set the memory range */
+ dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ res->flags |= IORESOURCE_STORED;
+ base = res->base;
+ end = resource_end(res);
+ pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
+ pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
+ pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
+ pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
+
+ report_resource_stored(dev, res, "");
+ }
+ pci_dev_set_resources(dev);
+}
+#endif /* BRIDGE_40_BIT_SUPPORT */
+
+static struct device_operations pcix_ops = {
+#if BRIDGE_40_BIT_SUPPORT
+ .read_resources = bridge_read_resources,
+ .set_resources = bridge_set_resources,
+#else
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+#endif
+ .enable_resources = pci_bus_enable_resources,
+ .init = amd8131_pcix_init,
+ .scan_bus = amd8131_scan_bridge,
+ .reset_bus = pci_bus_reset,
+};
+
+static const struct pci_driver pcix_driver __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7450,
+};
+
+
+static void ioapic_enable(device_t dev)
+{
+ uint32_t value;
+
+ value = pci_read_config32(dev, 0x44);
+ if (dev->enabled) {
+ value |= ((1 << 1) | (1 << 0));
+ } else {
+ value &= ~((1 << 1) | (1 << 0));
+ }
+ pci_write_config32(dev, 0x44, value);
+}
+
+static struct pci_operations pci_ops_pci_dev = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+static struct device_operations ioapic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = ioapic_enable,
+ .ops_pci = &pci_ops_pci_dev,
+};
+
+static const struct pci_driver ioapic_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7451,
+
+};
-driver-y += amd8132_bridge.c
+driver-y += bridge.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005,2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <device/pci_def.h>
-#include <device/pcix.h>
-
-#define NMI_OFF 0
-
-#define NPUML 0xD9 /* Non prefetchable upper memory limit */
-#define NPUMB 0xD8 /* Non prefetchable upper memory base */
-
-static void amd8132_walk_children(struct bus *bus,
- void (*visit)(device_t dev, void *ptr), void *ptr)
-{
- device_t child;
- for(child = bus->children; child; child = child->sibling)
- {
- if (child->path.type != DEVICE_PATH_PCI) {
- continue;
- }
- if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- amd8132_walk_children(child->link_list, visit, ptr);
- }
- visit(child, ptr);
- }
-}
-
-struct amd8132_bus_info {
- unsigned sstatus;
- unsigned rev;
- int master_devices;
- int max_func;
-};
-
-static void amd8132_count_dev(device_t dev, void *ptr)
-{
- struct amd8132_bus_info *info = ptr;
- /* Don't count pci bridges */
- if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
- info->master_devices++;
- }
- if (PCI_FUNC(dev->path.pci.devfn) > info->max_func) {
- info->max_func = PCI_FUNC(dev->path.pci.devfn);
- }
-}
-
-
-static void amd8132_pcix_tune_dev(device_t dev, void *ptr)
-{
- struct amd8132_bus_info *info = ptr;
- unsigned cap;
- unsigned status, cmd, orig_cmd;
- unsigned max_read, max_tran;
- int sibs;
-
- if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
- return;
- }
- cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
- if (!cap) {
- return;
- }
- /* How many siblings does this device have? */
- sibs = info->master_devices - 1;
-
- printk(BIOS_DEBUG, "%s AMD8132 PCI-X tuning\n", dev_path(dev));
- status = pci_read_config32(dev, cap + PCI_X_STATUS);
- orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
-
- max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
- max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
-
- if (info->rev == 0x01) { // only a1 need it
- /* Errata #53 Limit the number of split transactions to avoid starvation */
- if (sibs >= 2) {
- /* At most 2 outstanding split transactions when we have
- * 3 or more bus master devices on the bus.
- */
- if (max_tran > 1) {
- max_tran = 1;
- }
- }
- else if (sibs == 1) {
- /* At most 4 outstanding split transactions when we have
- * 2 bus master devices on the bus.
- */
- if (max_tran > 3) {
- max_tran = 3;
- }
- }
- else {
- /* At most 8 outstanding split transactions when we have
- * only one bus master device on the bus.
- */
- if (max_tran > 4) {
- max_tran = 4;
- }
- }
- }
-
- if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
- cmd &= ~PCI_X_CMD_MAX_READ;
- cmd |= max_read << 2;
- }
- if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
- cmd &= ~PCI_X_CMD_MAX_SPLIT;
- cmd |= max_tran << 4;
- }
-
- /* Don't attempt to handle PCI-X errors */
- cmd &= ~PCI_X_CMD_DPERR_E;
- if (orig_cmd != cmd) {
- pci_write_config16(dev, cap + PCI_X_CMD, cmd);
- }
-
-
-}
-static unsigned int amd8132_scan_bus(struct bus *bus,
- unsigned min_devfn, unsigned max_devfn, unsigned int max)
-{
- struct amd8132_bus_info info;
- unsigned pos;
-
-
- /* Find the children on the bus */
- max = pci_scan_bus(bus, min_devfn, max_devfn, max);
-
- /* Find the revision of the 8132 */
- info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
-
- /* Find the pcix capability and get the secondary bus status */
- pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
- info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
-
- /* Print the PCI-X bus speed */
- printk(BIOS_DEBUG, "PCI: %02x: %s sstatus=%04x rev=%02x \n", bus->secondary, pcix_speed(info.sstatus), info.sstatus, info.rev);
-
-
- /* Examine the bus and find out how loaded it is */
- info.max_func = 0;
- info.master_devices = 0;
- amd8132_walk_children(bus, amd8132_count_dev, &info);
-
-#if 0
- /* Disable the bus if there are no devices on it
- */
- if (!bus->children)
- {
- unsigned pcix_misc;
- /* Disable all of my children */
- disable_children(bus);
-
- /* Remember the device is disabled */
- bus->dev->enabled = 0;
-
- /* Disable the PCI-X clocks */
- pcix_misc = pci_read_config32(bus->dev, 0x40);
- pcix_misc &= ~(0x1f << 16);
- pci_write_config32(bus->dev, 0x40, pcix_misc);
-
- return max;
- }
-#endif
-
- /* If we are in conventional PCI mode nothing more is necessary.
- */
- if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
- return max;
- }
-
- /* Tune the devices on the bus */
- amd8132_walk_children(bus, amd8132_pcix_tune_dev, &info);
-
- return max;
-}
-
-static unsigned int amd8132_scan_bridge(device_t dev, unsigned int max)
-{
- return do_pci_scan_bridge(dev, max, amd8132_scan_bus);
-}
-
-
-static void amd8132_pcix_init(device_t dev)
-{
- uint32_t dword;
- uint8_t byte;
- unsigned chip_rev;
-
- /* Find the revision of the 8132 */
- chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
-
- /* Enable memory write and invalidate ??? */
- dword = pci_read_config32(dev, 0x04);
- dword |= 0x10;
- dword &= ~(1<<6); // PERSP Parity Error Response
- pci_write_config32(dev, 0x04, dword);
-
- if (chip_rev == 0x01) {
- /* Errata #37 */
- byte = pci_read_config8(dev, 0x0c);
- if(byte == 0x08 )
- pci_write_config8(dev, 0x0c, 0x10);
-
-#if 0
- /* Errata #59*/
- dword = pci_read_config32(dev, 0x40);
- dword &= ~(1<<31);
- pci_write_config32(dev, 0x40, dword);
-#endif
-
- }
-
- /* Set up error reporting, enable all */
- /* system error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8);
- pci_write_config32(dev, 0x04, dword);
-
- /* system and error parity enable */
- dword = pci_read_config32(dev, 0x3c);
- dword |= (3<<16);
- pci_write_config32(dev, 0x3c, dword);
-
- dword = pci_read_config32(dev, 0x40);
-// dword &= ~(1<<31); /* WriteChainEnable */
- dword |= (1<<31);
- dword |= (1<<7);// must set to 1
- dword |= (3<<21); //PCIErrorSerrDisable
- pci_write_config32(dev, 0x40, dword);
-
- /* EXTARB = 1, COMPAT = 0 */
- dword = pci_read_config32(dev, 0x48);
- dword |= (1<<3);
- dword &= ~(1<<0);
- dword |= (1<<15); //CLEARPCILOG_L
- dword |= (1<<19); //PERR FATAL Enable
- dword |= (1<<22); // SERR FATAL Enable
- dword |= (1<<23); // LPMARBENABLE
- dword |= (0x61<<24); //LPMARBCOUNT
- pci_write_config32(dev, 0x48, dword);
-
- dword = pci_read_config32(dev, 0x4c);
- dword |= (1<<6); //intial prefetch for memory read line request
- dword |= (1<<9); //continuous prefetch Enable for memory read line request
- pci_write_config32(dev, 0x4c, dword);
-
-
- /* Disable Single-Bit-Error Correction [30] = 0 */
- dword = pci_read_config32(dev, 0x70);
- dword &= ~(1<<30);
- pci_write_config32(dev, 0x70, dword);
-
- //link
- dword = pci_read_config32(dev, 0xd4);
- dword |= (0x5c<<16);
- pci_write_config32(dev, 0xd4, dword);
-
- /* TxSlack0 [16:17] = 0, RxHwLookahdEn0 [18] = 1, TxSlack1 [24:25] = 0, RxHwLookahdEn1 [26] = 1 */
- dword = pci_read_config32(dev, 0xdc);
- dword |= (1<<1) | (1<<4); // stream disable 1 to 0 , DBLINSRATE
- dword |= (1<<18)|(1<<26);
- dword &= ~((3<<16)|(3<<24));
- pci_write_config32(dev, 0xdc, dword);
-
- /* Set up CRC flood enable */
- dword = pci_read_config32(dev, 0xc0);
- if(dword) { /* do device A only */
-#if 0
- dword = pci_read_config32(dev, 0xc4);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc4, dword);
- dword = pci_read_config32(dev, 0xc8);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc8, dword);
-#endif
-
- if (chip_rev == 0x11) {
- /* [18] Clock Gate Enable = 1 */
- dword = pci_read_config32(dev, 0xf0);
- dword |= 0x00040008;
- pci_write_config32(dev, 0xf0, dword);
- }
-
- }
- return;
-}
-
-#define BRIDGE_40_BIT_SUPPORT 0
-#if BRIDGE_40_BIT_SUPPORT
-static void bridge_read_resources(struct device *dev)
-{
- struct resource *res;
- pci_bus_read_resources(dev);
- res = find_resource(dev, PCI_MEMORY_BASE);
- if (res) {
- res->limit = 0xffffffffffULL;
- }
-}
-
-static void bridge_set_resources(struct device *dev)
-{
- struct resource *res;
- res = find_resource(dev, PCI_MEMORY_BASE);
- if (res) {
- resource_t base, end;
- /* set the memory range */
- dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- res->flags |= IORESOURCE_STORED;
- base = res->base;
- end = resource_end(res);
- pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
- pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
- pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
- pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
-
- report_resource_stored(dev, res, "");
- }
- pci_dev_set_resources(dev);
-}
-#endif /* BRIDGE_40_BIT_SUPPORT */
-
-static struct device_operations pcix_ops = {
-#if BRIDGE_40_BIT_SUPPORT
- .read_resources = bridge_read_resources,
- .set_resources = bridge_set_resources,
-#else
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
-#endif
- .enable_resources = pci_bus_enable_resources,
- .init = amd8132_pcix_init,
- .scan_bus = amd8132_scan_bridge,
- .reset_bus = pci_bus_reset,
-};
-
-static const struct pci_driver pcix_driver __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7458,
-};
-
-static void ioapic_enable(device_t dev)
-{
- uint32_t value;
-
- value = pci_read_config32(dev, 0x44);
- if (dev->enabled) {
- value |= ((1 << 1) | (1 << 0));
- } else {
- value &= ~((1 << 1) | (1 << 0));
- }
- pci_write_config32(dev, 0x44, value);
-}
-static void amd8132_ioapic_init(device_t dev)
-{
- uint32_t dword;
- unsigned chip_rev;
-
- /* Find the revision of the 8132 */
- chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
-
- if (chip_rev == 0x01) {
-#if 0
- /* Errata #43 */
- dword = pci_read_config32(dev, 0xc8);
- dword |= (0x3<<23);
- pci_write_config32(dev, 0xc8, dword);
-#endif
-
- }
-
-
- if( (chip_rev == 0x11) ||(chip_rev == 0x12) ) {
- //for b1 b2
- /* Errata #73 */
- dword = pci_read_config32(dev, 0x80);
- dword |= (0x1f<<5);
- pci_write_config32(dev, 0x80, dword);
- dword = pci_read_config32(dev, 0x88);
- dword |= (0x1f<<5);
- pci_write_config32(dev, 0x88, dword);
-
- /* Errata #74 */
- dword = pci_read_config32(dev, 0x7c);
- dword &= ~(0x3<<30);
- dword |= (0x01<<30);
- pci_write_config32(dev, 0x7c, dword);
- }
-
-}
-
-static struct pci_operations pci_ops_pci_dev = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-static struct device_operations ioapic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = amd8132_ioapic_init,
- .scan_bus = 0,
- .enable = ioapic_enable,
- .ops_pci = &pci_ops_pci_dev,
-};
-
-static const struct pci_driver ioapic_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7459,
-
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005,2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <device/pci_def.h>
+#include <device/pcix.h>
+
+#define NMI_OFF 0
+
+#define NPUML 0xD9 /* Non prefetchable upper memory limit */
+#define NPUMB 0xD8 /* Non prefetchable upper memory base */
+
+static void amd8132_walk_children(struct bus *bus,
+ void (*visit)(device_t dev, void *ptr), void *ptr)
+{
+ device_t child;
+ for(child = bus->children; child; child = child->sibling)
+ {
+ if (child->path.type != DEVICE_PATH_PCI) {
+ continue;
+ }
+ if (child->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+ amd8132_walk_children(child->link_list, visit, ptr);
+ }
+ visit(child, ptr);
+ }
+}
+
+struct amd8132_bus_info {
+ unsigned sstatus;
+ unsigned rev;
+ int master_devices;
+ int max_func;
+};
+
+static void amd8132_count_dev(device_t dev, void *ptr)
+{
+ struct amd8132_bus_info *info = ptr;
+ /* Don't count pci bridges */
+ if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
+ info->master_devices++;
+ }
+ if (PCI_FUNC(dev->path.pci.devfn) > info->max_func) {
+ info->max_func = PCI_FUNC(dev->path.pci.devfn);
+ }
+}
+
+
+static void amd8132_pcix_tune_dev(device_t dev, void *ptr)
+{
+ struct amd8132_bus_info *info = ptr;
+ unsigned cap;
+ unsigned status, cmd, orig_cmd;
+ unsigned max_read, max_tran;
+ int sibs;
+
+ if (dev->hdr_type != PCI_HEADER_TYPE_NORMAL) {
+ return;
+ }
+ cap = pci_find_capability(dev, PCI_CAP_ID_PCIX);
+ if (!cap) {
+ return;
+ }
+ /* How many siblings does this device have? */
+ sibs = info->master_devices - 1;
+
+ printk(BIOS_DEBUG, "%s AMD8132 PCI-X tuning\n", dev_path(dev));
+ status = pci_read_config32(dev, cap + PCI_X_STATUS);
+ orig_cmd = cmd = pci_read_config16(dev,cap + PCI_X_CMD);
+
+ max_read = (status & PCI_X_STATUS_MAX_READ) >> 21;
+ max_tran = (status & PCI_X_STATUS_MAX_SPLIT) >> 23;
+
+ if (info->rev == 0x01) { // only a1 need it
+ /* Errata #53 Limit the number of split transactions to avoid starvation */
+ if (sibs >= 2) {
+ /* At most 2 outstanding split transactions when we have
+ * 3 or more bus master devices on the bus.
+ */
+ if (max_tran > 1) {
+ max_tran = 1;
+ }
+ }
+ else if (sibs == 1) {
+ /* At most 4 outstanding split transactions when we have
+ * 2 bus master devices on the bus.
+ */
+ if (max_tran > 3) {
+ max_tran = 3;
+ }
+ }
+ else {
+ /* At most 8 outstanding split transactions when we have
+ * only one bus master device on the bus.
+ */
+ if (max_tran > 4) {
+ max_tran = 4;
+ }
+ }
+ }
+
+ if (max_read != ((cmd & PCI_X_CMD_MAX_READ) >> 2)) {
+ cmd &= ~PCI_X_CMD_MAX_READ;
+ cmd |= max_read << 2;
+ }
+ if (max_tran != ((cmd & PCI_X_CMD_MAX_SPLIT) >> 4)) {
+ cmd &= ~PCI_X_CMD_MAX_SPLIT;
+ cmd |= max_tran << 4;
+ }
+
+ /* Don't attempt to handle PCI-X errors */
+ cmd &= ~PCI_X_CMD_DPERR_E;
+ if (orig_cmd != cmd) {
+ pci_write_config16(dev, cap + PCI_X_CMD, cmd);
+ }
+
+
+}
+static unsigned int amd8132_scan_bus(struct bus *bus,
+ unsigned min_devfn, unsigned max_devfn, unsigned int max)
+{
+ struct amd8132_bus_info info;
+ unsigned pos;
+
+
+ /* Find the children on the bus */
+ max = pci_scan_bus(bus, min_devfn, max_devfn, max);
+
+ /* Find the revision of the 8132 */
+ info.rev = pci_read_config8(bus->dev, PCI_CLASS_REVISION);
+
+ /* Find the pcix capability and get the secondary bus status */
+ pos = pci_find_capability(bus->dev, PCI_CAP_ID_PCIX);
+ info.sstatus = pci_read_config16(bus->dev, pos + PCI_X_SEC_STATUS);
+
+ /* Print the PCI-X bus speed */
+ printk(BIOS_DEBUG, "PCI: %02x: %s sstatus=%04x rev=%02x \n", bus->secondary, pcix_speed(info.sstatus), info.sstatus, info.rev);
+
+
+ /* Examine the bus and find out how loaded it is */
+ info.max_func = 0;
+ info.master_devices = 0;
+ amd8132_walk_children(bus, amd8132_count_dev, &info);
+
+#if 0
+ /* Disable the bus if there are no devices on it
+ */
+ if (!bus->children)
+ {
+ unsigned pcix_misc;
+ /* Disable all of my children */
+ disable_children(bus);
+
+ /* Remember the device is disabled */
+ bus->dev->enabled = 0;
+
+ /* Disable the PCI-X clocks */
+ pcix_misc = pci_read_config32(bus->dev, 0x40);
+ pcix_misc &= ~(0x1f << 16);
+ pci_write_config32(bus->dev, 0x40, pcix_misc);
+
+ return max;
+ }
+#endif
+
+ /* If we are in conventional PCI mode nothing more is necessary.
+ */
+ if (PCI_X_SSTATUS_MFREQ(info.sstatus) == PCI_X_SSTATUS_CONVENTIONAL_PCI) {
+ return max;
+ }
+
+ /* Tune the devices on the bus */
+ amd8132_walk_children(bus, amd8132_pcix_tune_dev, &info);
+
+ return max;
+}
+
+static unsigned int amd8132_scan_bridge(device_t dev, unsigned int max)
+{
+ return do_pci_scan_bridge(dev, max, amd8132_scan_bus);
+}
+
+
+static void amd8132_pcix_init(device_t dev)
+{
+ uint32_t dword;
+ uint8_t byte;
+ unsigned chip_rev;
+
+ /* Find the revision of the 8132 */
+ chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
+
+ /* Enable memory write and invalidate ??? */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= 0x10;
+ dword &= ~(1<<6); // PERSP Parity Error Response
+ pci_write_config32(dev, 0x04, dword);
+
+ if (chip_rev == 0x01) {
+ /* Errata #37 */
+ byte = pci_read_config8(dev, 0x0c);
+ if(byte == 0x08 )
+ pci_write_config8(dev, 0x0c, 0x10);
+
+#if 0
+ /* Errata #59*/
+ dword = pci_read_config32(dev, 0x40);
+ dword &= ~(1<<31);
+ pci_write_config32(dev, 0x40, dword);
+#endif
+
+ }
+
+ /* Set up error reporting, enable all */
+ /* system error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8);
+ pci_write_config32(dev, 0x04, dword);
+
+ /* system and error parity enable */
+ dword = pci_read_config32(dev, 0x3c);
+ dword |= (3<<16);
+ pci_write_config32(dev, 0x3c, dword);
+
+ dword = pci_read_config32(dev, 0x40);
+// dword &= ~(1<<31); /* WriteChainEnable */
+ dword |= (1<<31);
+ dword |= (1<<7);// must set to 1
+ dword |= (3<<21); //PCIErrorSerrDisable
+ pci_write_config32(dev, 0x40, dword);
+
+ /* EXTARB = 1, COMPAT = 0 */
+ dword = pci_read_config32(dev, 0x48);
+ dword |= (1<<3);
+ dword &= ~(1<<0);
+ dword |= (1<<15); //CLEARPCILOG_L
+ dword |= (1<<19); //PERR FATAL Enable
+ dword |= (1<<22); // SERR FATAL Enable
+ dword |= (1<<23); // LPMARBENABLE
+ dword |= (0x61<<24); //LPMARBCOUNT
+ pci_write_config32(dev, 0x48, dword);
+
+ dword = pci_read_config32(dev, 0x4c);
+ dword |= (1<<6); //intial prefetch for memory read line request
+ dword |= (1<<9); //continuous prefetch Enable for memory read line request
+ pci_write_config32(dev, 0x4c, dword);
+
+
+ /* Disable Single-Bit-Error Correction [30] = 0 */
+ dword = pci_read_config32(dev, 0x70);
+ dword &= ~(1<<30);
+ pci_write_config32(dev, 0x70, dword);
+
+ //link
+ dword = pci_read_config32(dev, 0xd4);
+ dword |= (0x5c<<16);
+ pci_write_config32(dev, 0xd4, dword);
+
+ /* TxSlack0 [16:17] = 0, RxHwLookahdEn0 [18] = 1, TxSlack1 [24:25] = 0, RxHwLookahdEn1 [26] = 1 */
+ dword = pci_read_config32(dev, 0xdc);
+ dword |= (1<<1) | (1<<4); // stream disable 1 to 0 , DBLINSRATE
+ dword |= (1<<18)|(1<<26);
+ dword &= ~((3<<16)|(3<<24));
+ pci_write_config32(dev, 0xdc, dword);
+
+ /* Set up CRC flood enable */
+ dword = pci_read_config32(dev, 0xc0);
+ if(dword) { /* do device A only */
+#if 0
+ dword = pci_read_config32(dev, 0xc4);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc4, dword);
+ dword = pci_read_config32(dev, 0xc8);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc8, dword);
+#endif
+
+ if (chip_rev == 0x11) {
+ /* [18] Clock Gate Enable = 1 */
+ dword = pci_read_config32(dev, 0xf0);
+ dword |= 0x00040008;
+ pci_write_config32(dev, 0xf0, dword);
+ }
+
+ }
+ return;
+}
+
+#define BRIDGE_40_BIT_SUPPORT 0
+#if BRIDGE_40_BIT_SUPPORT
+static void bridge_read_resources(struct device *dev)
+{
+ struct resource *res;
+ pci_bus_read_resources(dev);
+ res = find_resource(dev, PCI_MEMORY_BASE);
+ if (res) {
+ res->limit = 0xffffffffffULL;
+ }
+}
+
+static void bridge_set_resources(struct device *dev)
+{
+ struct resource *res;
+ res = find_resource(dev, PCI_MEMORY_BASE);
+ if (res) {
+ resource_t base, end;
+ /* set the memory range */
+ dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+ res->flags |= IORESOURCE_STORED;
+ base = res->base;
+ end = resource_end(res);
+ pci_write_config16(dev, PCI_MEMORY_BASE, base >> 16);
+ pci_write_config8(dev, NPUML, (base >> 32) & 0xff);
+ pci_write_config16(dev, PCI_MEMORY_LIMIT, end >> 16);
+ pci_write_config8(dev, NPUMB, (end >> 32) & 0xff);
+
+ report_resource_stored(dev, res, "");
+ }
+ pci_dev_set_resources(dev);
+}
+#endif /* BRIDGE_40_BIT_SUPPORT */
+
+static struct device_operations pcix_ops = {
+#if BRIDGE_40_BIT_SUPPORT
+ .read_resources = bridge_read_resources,
+ .set_resources = bridge_set_resources,
+#else
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+#endif
+ .enable_resources = pci_bus_enable_resources,
+ .init = amd8132_pcix_init,
+ .scan_bus = amd8132_scan_bridge,
+ .reset_bus = pci_bus_reset,
+};
+
+static const struct pci_driver pcix_driver __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7458,
+};
+
+static void ioapic_enable(device_t dev)
+{
+ uint32_t value;
+
+ value = pci_read_config32(dev, 0x44);
+ if (dev->enabled) {
+ value |= ((1 << 1) | (1 << 0));
+ } else {
+ value &= ~((1 << 1) | (1 << 0));
+ }
+ pci_write_config32(dev, 0x44, value);
+}
+static void amd8132_ioapic_init(device_t dev)
+{
+ uint32_t dword;
+ unsigned chip_rev;
+
+ /* Find the revision of the 8132 */
+ chip_rev = pci_read_config8(dev, PCI_CLASS_REVISION);
+
+ if (chip_rev == 0x01) {
+#if 0
+ /* Errata #43 */
+ dword = pci_read_config32(dev, 0xc8);
+ dword |= (0x3<<23);
+ pci_write_config32(dev, 0xc8, dword);
+#endif
+
+ }
+
+
+ if( (chip_rev == 0x11) ||(chip_rev == 0x12) ) {
+ //for b1 b2
+ /* Errata #73 */
+ dword = pci_read_config32(dev, 0x80);
+ dword |= (0x1f<<5);
+ pci_write_config32(dev, 0x80, dword);
+ dword = pci_read_config32(dev, 0x88);
+ dword |= (0x1f<<5);
+ pci_write_config32(dev, 0x88, dword);
+
+ /* Errata #74 */
+ dword = pci_read_config32(dev, 0x7c);
+ dword &= ~(0x3<<30);
+ dword |= (0x01<<30);
+ pci_write_config32(dev, 0x7c, dword);
+ }
+
+}
+
+static struct pci_operations pci_ops_pci_dev = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+static struct device_operations ioapic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = amd8132_ioapic_init,
+ .scan_bus = 0,
+ .enable = ioapic_enable,
+ .ops_pci = &pci_ops_pci_dev,
+};
+
+static const struct pci_driver ioapic_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7459,
+
+};
-driver-y += amd8151_agp3.c
+driver-y += agp3.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+static void agp3bridge_init(device_t dev)
+{
+ uint8_t byte;
+
+ /* Enable BM, MEM and IO */
+ byte = pci_read_config32(dev, 0x04);
+ byte |= 0x07;
+ pci_write_config8(dev, 0x04, byte);
+
+ return;
+}
+
+static struct device_operations agp3bridge_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = agp3bridge_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+static const struct pci_driver agp3bridge_driver __pci_driver = {
+ .ops = &agp3bridge_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7455, // AGP Bridge
+};
+
+static void agp3dev_enable(device_t dev)
+{
+ uint32_t value;
+
+ /* AGP enable */
+ value = pci_read_config32(dev, 0xa8);
+ value |= (3<<8)|2; //AGP 8x
+ pci_write_config32(dev, 0xa8, value);
+
+ /* enable BM and MEM */
+ value = pci_read_config32(dev, 0x4);
+ value |= 6;
+ pci_write_config32(dev, 0x4, value);
+#if 0
+ /* FIXME: should we add agp aperture base and size here ?
+ * or it is done by AGP drivers */
+#endif
+}
+
+static struct pci_operations pci_ops_pci_dev = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations agp3dev_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = agp3dev_enable,
+ .ops_pci = &pci_ops_pci_dev,
+};
+
+static const struct pci_driver agp3dev_driver __pci_driver = {
+ .ops = &agp3dev_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = 0x7454, //AGP Device
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-
-static void agp3bridge_init(device_t dev)
-{
- uint8_t byte;
-
- /* Enable BM, MEM and IO */
- byte = pci_read_config32(dev, 0x04);
- byte |= 0x07;
- pci_write_config8(dev, 0x04, byte);
-
- return;
-}
-
-static struct device_operations agp3bridge_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = agp3bridge_init,
- .scan_bus = pci_scan_bridge,
-};
-
-static const struct pci_driver agp3bridge_driver __pci_driver = {
- .ops = &agp3bridge_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7455, // AGP Bridge
-};
-
-static void agp3dev_enable(device_t dev)
-{
- uint32_t value;
-
- /* AGP enable */
- value = pci_read_config32(dev, 0xa8);
- value |= (3<<8)|2; //AGP 8x
- pci_write_config32(dev, 0xa8, value);
-
- /* enable BM and MEM */
- value = pci_read_config32(dev, 0x4);
- value |= 6;
- pci_write_config32(dev, 0x4, value);
-#if 0
- /* FIXME: should we add agp aperture base and size here ?
- * or it is done by AGP drivers */
-#endif
-}
-
-static struct pci_operations pci_ops_pci_dev = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations agp3dev_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = agp3dev_enable,
- .ops_pci = &pci_ops_pci_dev,
-};
-
-static const struct pci_driver agp3dev_driver __pci_driver = {
- .ops = &agp3dev_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = 0x7454, //AGP Device
-};
##
driver-y += cs5530.c
-driver-y += cs5530_isa.c
-driver-y += cs5530_ide.c
-driver-y += cs5530_vga.c
-driver-y += cs5530_pirq.c
+driver-y += isa.c
+driver-y += ide.c
+driver-y += vga.c
+driver-y += pirq.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include "cs5530.h"
-
-static void cs5530_enable_rom(void)
-{
- uint8_t reg8;
-
- /* So far all CS5530(A) ISA bridges we've seen are at 00:12.0. */
- device_t dev = PCI_DEV(0, 0x12, 0);
-
- /*
- * Decode 0x000E0000-0x000FFFFF (128 KB), not just 64 KB, and
- * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 KB.
- *
- * Make the ROM write-protected.
- */
- reg8 = pci_read_config8(dev, ROM_AT_LOGIC_CONTROL_REG);
- reg8 |= LOWER_ROM_ADDRESS_RANGE;
- reg8 |= UPPER_ROM_ADDRESS_RANGE;
- reg8 &= ~ROM_WRITE_ENABLE;
- pci_write_config8(dev, ROM_AT_LOGIC_CONTROL_REG, reg8);
-
- /* Set positive decode on ROM. */
- reg8 = pci_read_config8(dev, DECODE_CONTROL_REG2);
- reg8 |= BIOS_ROM_POSITIVE_DECODE;
- pci_write_config8(dev, DECODE_CONTROL_REG2, reg8);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "cs5530.h"
-
-/**
- * Initialize the IDE controller.
- *
- * Depending on the configuration variables 'ide0_enable' and 'ide1_enable'
- * enable or disable the primary and secondary IDE interface, respectively.
- *
- * @param dev The device to use.
- */
-static void ide_init(struct device *dev)
-{
- uint8_t reg8;
- struct southbridge_amd_cs5530_config *conf = dev->chip_info;
-
- reg8 = pci_read_config8(dev, DECODE_CONTROL_REG2);
-
- /* Enable/disable the primary IDE interface. */
- if (conf->ide0_enable) {
- reg8 |= PRIMARY_IDE_ENABLE;
- } else {
- reg8 &= ~(PRIMARY_IDE_ENABLE);
- }
-
- /* Enable/disable the secondary IDE interface. */
- if (conf->ide1_enable) {
- reg8 |= SECONDARY_IDE_ENABLE;
- } else {
- reg8 &= ~(SECONDARY_IDE_ENABLE);
- }
-
- pci_write_config8(dev, DECODE_CONTROL_REG2, reg8);
-
- printk(BIOS_INFO, "%s IDE interface %s\n", "Primary",
- conf->ide0_enable ? "enabled" : "disabled");
- printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary",
- conf->ide1_enable ? "enabled" : "disabled");
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = 0,
- .scan_bus = scan_static_bus,
- .ops_pci = 0,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_CYRIX,
- .device = PCI_DEVICE_ID_CYRIX_5530_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "cs5530.h"
-
-static void cs5530_read_resources(device_t dev)
-{
- struct resource* res;
-
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 1);
- res->base = 0x0UL;
- res->size = 0x1000UL;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void isa_init(struct device *dev)
-{
-}
-
-static struct device_operations isa_ops = {
- .read_resources = cs5530_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = isa_init,
- .enable = 0,
- .scan_bus = scan_static_bus,
-};
-
-static const struct pci_driver isa_driver __pci_driver = {
- .ops = &isa_ops,
- .vendor = PCI_VENDOR_ID_CYRIX,
- .device = PCI_DEVICE_ID_CYRIX_5530_LEGACY,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/pirq_routing.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
-void pirq_assign_irqs(const unsigned char pIntAtoD[4])
-{
- device_t pdev;
-
- pdev = dev_find_device(PCI_VENDOR_ID_CYRIX,
- PCI_DEVICE_ID_CYRIX_5530_LEGACY, 0);
-
- if (pdev) {
- pci_write_config8(pdev, 0x5c, (pIntAtoD[1] << 4 | pIntAtoD[0]));
- pci_write_config8(pdev, 0x5d, (pIntAtoD[3] << 4 | pIntAtoD[2]));
- }
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Juergen Beisert <juergen@kreuzholzen.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
- */
-
-/**
- * @brief Activate the VGA feature in a Geode GX1 based system with one
- * of five possible VESA modes: VGA, SVGA, XGA, 4:3 SXGA and 5:4 SXGA.
- * Also it is prepared to display a splash screen.
- *
- * In a Geode GX1 environment the companion CS5530 is the VGA
- * interface only. It contains a PLL for pixel clock generation,
- * DACs to generate the analogue RGB signals, drivers for HSYNC
- * and VSYNC and drivers for a digital flatpanel.
- * The graphic feature itself (framebuffer, acceleration unit)
- * is not part of this device. It is part of the CPU device.
- * But both depend on each other, we cannot divide them into
- * different drivers. So this driver is not only a CS5530 driver,
- * it is also a Geode GX1 chipset graphic driver.
- */
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <cpu/amd/gx1def.h>
-#include <delay.h>
-
-#if CONFIG_GX1_VIDEO == 1
-/*
- * Some register descriptions that are no listed in cpu/amd/gx1def.h
- */
-#define CS5530_DOT_CLK_CONFIG 0x0024
-#define CS5530_DISPLAY_CONFIG 0x0004
-
-#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */
-#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */
-#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset */
-#define DC_VID_ST_OFFSET 0x8320 /* video start offset */
-#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */
-#define DC_BUF_SIZE 0x8328 /* fb and cb line size */
-#define DC_H_TIMING_1 0x8330 /* horizontal timing... */
-#define DC_H_TIMING_2 0x8334
-#define DC_H_TIMING_3 0x8338
-#define DC_FP_H_TIMING 0x833C
-#define DC_V_TIMING_1 0x8340 /* vertical timing... */
-#define DC_V_TIMING_2 0x8344
-#define DC_V_TIMING_3 0x8348
-#define DC_FP_V_TIMING 0x834C
-#define DC_TIMING_CFG 0x8308
-#define DC_OUTPUT_CFG 0x830C
-
-/**
- * what colour depth should be used as default (in bpp)
- * Note: Currently no other value than 16 is supported
- */
-#define COLOUR_DEPTH 16
-
-/**
- * Support for a few basic video modes
- * Note: all modes only for CRT. The flatpanel feature is
- * not supported here (due to the lack of hardware to test)
- */
-struct video_mode {
- int pixel_clock; /*<< pixel clock in Hz */
- unsigned long pll_value; /*<< pll register value for this clock */
-
- int visible_pixel; /*<< visible pixels in one line */
- int hsync_start; /*<< start of hsync behind visible pixels */
- int hsync_end; /*<< end of hsync behind its start */
- int line_length; /*<< whole line length */
-
- int visible_lines; /*<< visible lines on screen */
- int vsync_start; /*<< vsync start behind last visible line */
- int vsync_end; /*<< end of vsync behind its start */
- int picture_length; /*<< whole screen length */
-
- int sync_pol; /*<< 0: low, 1: high, bit 0 hsync, bit 1 vsync */
-};
-
-/*
- * values for .sync_pol in struct video_mode
- */
-#define HSYNC_HIGH_POL 0
-#define HSYNC_LOW_POL 1
-#define VSYNC_HIGH_POL 0
-#define VSYNC_LOW_POL 2
-
-/**
- * 640x480 @ 72Hz hsync: 37.9kHz
- * VESA standard mode for classic 4:3 monitors
- * Copied from X11:
- * ModeLine "640x480" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync
- */
-static const struct video_mode mode_640x480 = {
- .pixel_clock = 31500000,
- .pll_value = 0x33915801,
-
- .visible_pixel = 640,
- .hsync_start = 664,
- .hsync_end = 704, /* 1.27 us sync length */
- .line_length = 832, /* 26.39us */
-
- .visible_lines = 480,
- .vsync_start = 489,
- .vsync_end = 491,
- .picture_length = 520, /* 13.89ms */
-
- .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL,
-};
-
-/**
- * 800x600 @ 72Hz hsync: 48.1kHz
- * VESA standard mode for classic 4:3 monitors
- * Copied from X11:
- * ModeLine "800x600" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync
- */
-static const struct video_mode mode_800x600 = {
- .pixel_clock = 50000000,
- .pll_value = 0x23088801,
-
- .visible_pixel = 800,
- .hsync_start = 856,
- .hsync_end = 976,
- .line_length = 1040, /* 20.8us */
-
- .visible_lines = 600,
- .vsync_start = 637,
- .vsync_end = 643,
- .picture_length = 666, /* 13.89ms */
-
- .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
-};
-
-/**
- * 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
- * Standard mode for classic 4:3 monitors
- * Copied from X11:
- * ModeLine "1024x768" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
- */
-static const struct video_mode mode_1024x768 = {
- .pixel_clock = 75000000,
- .pll_value = 0x37E22801,
-
- .visible_pixel = 1024,
- .hsync_start = 1048,
- .hsync_end = 1184,
- .line_length = 1328, /* 17.7us */
-
- .visible_lines = 768,
- .vsync_start = 771,
- .vsync_end = 777,
- .picture_length = 806, /* 14.3us */
-
- .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL,
-};
-
-/**
- * 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
- * Mode for classic 4:3 monitors
- * Copied from X11:
- * ModeLine "1280x960" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync
- */
-static const struct video_mode mode_1280x960 = {
- .pixel_clock = 108000000,
- .pll_value = 0x2710C805,
-
- .visible_pixel = 1280,
- .hsync_start = 1376,
- .hsync_end = 1488,
- .line_length = 1800, /* 16.67us */
-
- .visible_lines = 960,
- .vsync_start = 961,
- .vsync_end = 964,
- .picture_length = 1000, /* 16.67ms */
-
- .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
-};
-
-/**
- * 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
- * Mode for modern 5:4 flat screens
- * Copied from X11:
- * ModeLine "1280x1024" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
- */
-static const struct video_mode mode_1280x1024 = {
- .pixel_clock = 108000000,
- .pll_value = 0x2710C805,
-
- .visible_pixel = 1280,
- .hsync_start = 1328,
- .hsync_end = 1440,
- .line_length = 1688, /* 15.6us */
-
- .visible_lines = 1024,
- .vsync_start = 1025,
- .vsync_end = 1028,
- .picture_length = 1066,
-
- .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
-};
-
-/**
- * List of supported common modes
- */
-static const struct video_mode *modes[] = {
- &mode_640x480, /* CONFIG_GX1_VIDEOMODE = 0 */
- &mode_800x600, /* CONFIG_GX1_VIDEOMODE = 1 */
- &mode_1024x768, /* CONFIG_GX1_VIDEOMODE = 2 */
- &mode_1280x960, /* CONFIG_GX1_VIDEOMODE = 3 */
- &mode_1280x1024 /* CONFIG_GX1_VIDEOMODE = 4 */
-};
-
-/* make a sanity check at buildtime */
-#if CONFIG_GX1_VIDEOMODE > 4
-# error Requested video mode is unknown!
-#endif
-
-/**
- * Setup the pixel PLL in the companion chip
- * @param[in] base register's base address
- * @param[in] pll_val pll register value to be set
- *
- * The PLL to program here is located in the CS5530
- */
-static void cs5530_set_clock_frequency(u32 io_base, unsigned long pll_val)
-{
- unsigned long reg;
-
- /* disable the PLL first, reset and power it down */
- reg = read32(io_base+CS5530_DOT_CLK_CONFIG) & ~0x20;
- reg |= 0x80000100;
- write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
-
- /* write the new PLL setting */
- reg |= (pll_val & ~0x80000920);
- write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
-
- mdelay(1); /* wait for control voltage to be 0V */
-
- /* enable the PLL */
- reg |= 0x00000800;
- write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
-
- /* clear reset */
- reg &= ~0x80000000;
- write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
-
- /* clear bypass */
- reg &= ~0x00000100;
- write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
-}
-
-/**
- * Setup memory layout
- * @param[in] gx_base GX register area
- * @param[in] mode Data about the video mode to setup
- *
- * Memory layout must be setup in Geode GX1's chipset.
- * Note: This routine assumes unlocked DC registers.
- * Note: Using compressed buffer is not supported yet!
- * (makes more sense later, but not while booting)
- *
- * At this point a check is missed if the requested video
- * mode is possible with the provided video memory.
- * Check if symbol CONFIG_VIDEO_MB is at least:
- * - 1 (=1MiB) for VGA and SVGA
- * - 2 (=2MiB) for XGA
- * - 4 (=4MiB) for SXGA
- */
-static void dc_setup_layout(u32 gx_base, const struct video_mode *mode)
-{
- u32 base = 0x00000000;
-
- write32(gx_base + DC_FB_ST_OFFSET, base);
-
- base += (COLOUR_DEPTH>>3) * mode->visible_pixel * mode->visible_lines;
-
- write32(gx_base + DC_CB_ST_OFFSET, base);
- write32(gx_base + DC_CURS_ST_OFFSET, base);
- write32(gx_base + DC_VID_ST_OFFSET, base);
- write32(gx_base + DC_LINE_DELTA, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 2);
- write32(gx_base + DC_BUF_SIZE, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 3);
-}
-
-/**
- * Setup the HSYNC/VSYNC, active video timing
- * @param[in] gx_base GX register area
- * @param[in] mode Data about the video mode to setup
- *
- * Sync signal generation is done in Geode GX1's chipset.
- * Note: This routine assumes unlocked DC registers
- *
- * |<------------------------- htotal ----------------------------->|
- * |<------------ hactive -------------->| |
- * | hblankstart-->| |
- * | hblankend-->|
- * | hsyncstart-->| |
- * | hsyncend-->| |
- * |#####################################___________________________| RGB data
- * |______________________________________________---------_________| HSYNC
- *
- * |<------------------------- vtotal ----------------------------->|
- * |<------------ vactive -------------->| |
- * | vblankstart-->| |
- * | vblankend-->|
- * | vsyncstart-->| |
- * | vsyncend-->| |
- * |#####################################___________________________| line data
- * |______________________________________________---------_________| YSYNC
- */
-static void dc_setup_timing(u32 gx_base, const struct video_mode *mode)
-{
- u32 hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal;
- u32 vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal;
-
- hactive = mode->visible_pixel & 0x7FF;
- hblankstart = hactive;
- hsyncstart = mode->hsync_start & 0x7FF;
- hsyncend = mode->hsync_end & 0x7FF;
- hblankend = mode->line_length & 0x7FF;
- htotal = hblankend;
-
- vactive = mode->visible_lines & 0x7FF;
- vblankstart = vactive;
- vsyncstart = mode->vsync_start & 0x7FF;
- vsyncend = mode->vsync_end & 0x7FF;
- vblankend = mode->picture_length & 0x7FF;
- vtotal = vblankend;
-
- /* row description */
- write32(gx_base + DC_H_TIMING_1, (hactive - 1) | ((htotal - 1) << 16));
- /* horizontal blank description */
- write32(gx_base + DC_H_TIMING_2, (hblankstart - 1) | ((hblankend - 1) << 16));
- /* horizontal sync description */
- write32(gx_base + DC_H_TIMING_3, (hsyncstart - 1) | ((hsyncend - 1) << 16));
- write32(gx_base + DC_FP_H_TIMING, (hsyncstart - 1) | ((hsyncend - 1) << 16));
-
- /* line description */
- write32(gx_base + DC_V_TIMING_1, (vactive - 1) | ((vtotal - 1) << 16));
- /* vertical blank description */
- write32(gx_base + DC_V_TIMING_2, (vblankstart - 1) | ((vblankend - 1) << 16));
- /* vertical sync description */
- write32(gx_base + DC_V_TIMING_3, (vsyncstart - 1) | ((vsyncend - 1) << 16));
- write32(gx_base + DC_FP_V_TIMING, (vsyncstart - 2) | ((vsyncend - 2) << 16));
-}
-
-/**
- * Setup required internals to bring the mode up and running
- * @param[in] gx_base GX register area
- * @param[in] mode Data about the video mode to setup
- *
- * Must be setup in Geode GX1's chipset.
- * Note: This routine assumes unlocked DC registers.
- */
-static void cs5530_activate_mode(u32 gx_base, const struct video_mode *mode)
-{
- write32(gx_base + DC_GENERAL_CFG, 0x00000080);
- mdelay(1);
- dc_setup_layout(gx_base,mode);
- dc_setup_timing(gx_base,mode);
-
- write32(gx_base + DC_GENERAL_CFG, 0x2000C581);
- write32(gx_base + DC_TIMING_CFG, 0x0000002F);
- write32(gx_base + DC_OUTPUT_CFG, 0x00003004);
-}
-
-/**
- * Activate the current mode to be "visible" outside
- * @param[in] gx_base GX register area
- * @param[in] mode Data about the video mode to setup
- *
- * As we now activate the interface this must be done
- * in the CS5530
- */
-static void cs5530_activate_video(u32 io_base, const struct video_mode *mode)
-{
- u32 val;
-
- val = (u32)mode->sync_pol << 8;
- write32(io_base + CS5530_DISPLAY_CONFIG, val | 0x0020002F);
-}
-
-#if CONFIG_SPLASH_GRAPHIC == 1
-
-/*
- * This bitmap file must provide:
- * int width: pixel count in one line
- * int height: line count
- * int colours: ount of used colour
- * unsigned long colour_map[]: RGB 565 colours to be used
- * unsigned char bitmap[]: index per pixel into colour_map[], width*height pixels
- */
-#include "bitmap.c"
-
-/*
- * show a boot splash screen in the right lower corner of the screen
- * swidth: screen width in pixel
- * sheight: screen height in lines
- * pitch: line pitch in bytes
- * base: screen base address
- *
- * This routine assumes we are using a 16 bit colour depth!
- */
-static void show_boot_splash_16(u32 swidth, u32 sheight, u32 pitch,void *base)
-{
- int word_count,i;
- unsigned short *adr;
- u32 xstart,ystart,x,y;
- /*
- * fill the screen with the colour of the
- * left top pixel in the graphic
- */
- word_count = pitch * sheight;
- adr = (unsigned short*)base;
- for (i = 0; i < word_count; i++, adr++)
- *adr = colour_map[bitmap[0]];
-
- /*
- * paint the splash
- */
- xstart = swidth-width;
- ystart = sheight-height;
- for (y = 0; y < height; y++) {
- adr=(unsigned short*)(base + pitch*(y+ystart) + 2 * xstart);
- for (x = 0; x < width; x++) {
- *adr=(unsigned short)colour_map[(int)bitmap[x + y * width]];
- adr++;
- }
- }
-}
-#else
-# define show_boot_splash_16(w, x, y , z)
-#endif
-
-/**
- * coreboot management part
- * @param[in] dev Info about the PCI device to initialise
- */
-static void cs5530_vga_init(device_t dev)
-{
- const struct video_mode *mode;
- u32 io_base, gx_base;
-
- io_base = pci_read_config32(dev, 0x10);
- gx_base = GX_BASE;
- mode = modes[CONFIG_GX1_VIDEOMODE];
-
- printk(BIOS_DEBUG, "Setting up video mode %dx%d with %d Hz clock\n",
- mode->visible_pixel, mode->visible_lines, mode->pixel_clock);
-
- cs5530_set_clock_frequency(io_base, mode->pll_value);
-
- write32(gx_base + DC_UNLOCK, DC_UNLOCK_MAGIC);
-
- show_boot_splash_16(mode->visible_pixel, mode->visible_lines,
- mode->visible_pixel * (COLOUR_DEPTH>>3), (void*)(GX_BASE + 0x800000));
-
- cs5530_activate_mode(gx_base, mode);
-
- cs5530_activate_video(io_base, mode);
- write32(gx_base + DC_UNLOCK, 0x00000000);
-}
-
-static struct device_operations vga_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = cs5530_vga_init,
- .enable = NULL, /* not required */
-};
-
-static const struct pci_driver vga_pci_driver __pci_driver = {
- .ops = &vga_ops,
- .vendor = PCI_VENDOR_ID_CYRIX,
- .device = PCI_DEVICE_ID_CYRIX_5530_VIDEO,
-};
-
-#endif /* #if CONFIG_GX1_VIDEO == 1 */
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include "cs5530.h"
+
+static void cs5530_enable_rom(void)
+{
+ uint8_t reg8;
+
+ /* So far all CS5530(A) ISA bridges we've seen are at 00:12.0. */
+ device_t dev = PCI_DEV(0, 0x12, 0);
+
+ /*
+ * Decode 0x000E0000-0x000FFFFF (128 KB), not just 64 KB, and
+ * decode 0xFF000000-0xFFFFFFFF (16 MB), not just 256 KB.
+ *
+ * Make the ROM write-protected.
+ */
+ reg8 = pci_read_config8(dev, ROM_AT_LOGIC_CONTROL_REG);
+ reg8 |= LOWER_ROM_ADDRESS_RANGE;
+ reg8 |= UPPER_ROM_ADDRESS_RANGE;
+ reg8 &= ~ROM_WRITE_ENABLE;
+ pci_write_config8(dev, ROM_AT_LOGIC_CONTROL_REG, reg8);
+
+ /* Set positive decode on ROM. */
+ reg8 = pci_read_config8(dev, DECODE_CONTROL_REG2);
+ reg8 |= BIOS_ROM_POSITIVE_DECODE;
+ pci_write_config8(dev, DECODE_CONTROL_REG2, reg8);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "cs5530.h"
+
+/**
+ * Initialize the IDE controller.
+ *
+ * Depending on the configuration variables 'ide0_enable' and 'ide1_enable'
+ * enable or disable the primary and secondary IDE interface, respectively.
+ *
+ * @param dev The device to use.
+ */
+static void ide_init(struct device *dev)
+{
+ uint8_t reg8;
+ struct southbridge_amd_cs5530_config *conf = dev->chip_info;
+
+ reg8 = pci_read_config8(dev, DECODE_CONTROL_REG2);
+
+ /* Enable/disable the primary IDE interface. */
+ if (conf->ide0_enable) {
+ reg8 |= PRIMARY_IDE_ENABLE;
+ } else {
+ reg8 &= ~(PRIMARY_IDE_ENABLE);
+ }
+
+ /* Enable/disable the secondary IDE interface. */
+ if (conf->ide1_enable) {
+ reg8 |= SECONDARY_IDE_ENABLE;
+ } else {
+ reg8 &= ~(SECONDARY_IDE_ENABLE);
+ }
+
+ pci_write_config8(dev, DECODE_CONTROL_REG2, reg8);
+
+ printk(BIOS_INFO, "%s IDE interface %s\n", "Primary",
+ conf->ide0_enable ? "enabled" : "disabled");
+ printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary",
+ conf->ide1_enable ? "enabled" : "disabled");
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = 0,
+ .scan_bus = scan_static_bus,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_CYRIX,
+ .device = PCI_DEVICE_ID_CYRIX_5530_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "cs5530.h"
+
+static void cs5530_read_resources(device_t dev)
+{
+ struct resource* res;
+
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 1);
+ res->base = 0x0UL;
+ res->size = 0x1000UL;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void isa_init(struct device *dev)
+{
+}
+
+static struct device_operations isa_ops = {
+ .read_resources = cs5530_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = isa_init,
+ .enable = 0,
+ .scan_bus = scan_static_bus,
+};
+
+static const struct pci_driver isa_driver __pci_driver = {
+ .ops = &isa_ops,
+ .vendor = PCI_VENDOR_ID_CYRIX,
+ .device = PCI_DEVICE_ID_CYRIX_5530_LEGACY,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/pirq_routing.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
+void pirq_assign_irqs(const unsigned char pIntAtoD[4])
+{
+ device_t pdev;
+
+ pdev = dev_find_device(PCI_VENDOR_ID_CYRIX,
+ PCI_DEVICE_ID_CYRIX_5530_LEGACY, 0);
+
+ if (pdev) {
+ pci_write_config8(pdev, 0x5c, (pIntAtoD[1] << 4 | pIntAtoD[0]));
+ pci_write_config8(pdev, 0x5d, (pIntAtoD[3] << 4 | pIntAtoD[2]));
+ }
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Juergen Beisert <juergen@kreuzholzen.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+/**
+ * @brief Activate the VGA feature in a Geode GX1 based system with one
+ * of five possible VESA modes: VGA, SVGA, XGA, 4:3 SXGA and 5:4 SXGA.
+ * Also it is prepared to display a splash screen.
+ *
+ * In a Geode GX1 environment the companion CS5530 is the VGA
+ * interface only. It contains a PLL for pixel clock generation,
+ * DACs to generate the analogue RGB signals, drivers for HSYNC
+ * and VSYNC and drivers for a digital flatpanel.
+ * The graphic feature itself (framebuffer, acceleration unit)
+ * is not part of this device. It is part of the CPU device.
+ * But both depend on each other, we cannot divide them into
+ * different drivers. So this driver is not only a CS5530 driver,
+ * it is also a Geode GX1 chipset graphic driver.
+ */
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <cpu/amd/gx1def.h>
+#include <delay.h>
+
+#if CONFIG_GX1_VIDEO == 1
+/*
+ * Some register descriptions that are no listed in cpu/amd/gx1def.h
+ */
+#define CS5530_DOT_CLK_CONFIG 0x0024
+#define CS5530_DISPLAY_CONFIG 0x0004
+
+#define DC_FB_ST_OFFSET 0x8310 /* framebuffer start offset */
+#define DC_CB_ST_OFFSET 0x8314 /* compression start offset */
+#define DC_CURS_ST_OFFSET 0x8318 /* cursor start offset */
+#define DC_VID_ST_OFFSET 0x8320 /* video start offset */
+#define DC_LINE_DELTA 0x8324 /* fb and cb skip counts */
+#define DC_BUF_SIZE 0x8328 /* fb and cb line size */
+#define DC_H_TIMING_1 0x8330 /* horizontal timing... */
+#define DC_H_TIMING_2 0x8334
+#define DC_H_TIMING_3 0x8338
+#define DC_FP_H_TIMING 0x833C
+#define DC_V_TIMING_1 0x8340 /* vertical timing... */
+#define DC_V_TIMING_2 0x8344
+#define DC_V_TIMING_3 0x8348
+#define DC_FP_V_TIMING 0x834C
+#define DC_TIMING_CFG 0x8308
+#define DC_OUTPUT_CFG 0x830C
+
+/**
+ * what colour depth should be used as default (in bpp)
+ * Note: Currently no other value than 16 is supported
+ */
+#define COLOUR_DEPTH 16
+
+/**
+ * Support for a few basic video modes
+ * Note: all modes only for CRT. The flatpanel feature is
+ * not supported here (due to the lack of hardware to test)
+ */
+struct video_mode {
+ int pixel_clock; /*<< pixel clock in Hz */
+ unsigned long pll_value; /*<< pll register value for this clock */
+
+ int visible_pixel; /*<< visible pixels in one line */
+ int hsync_start; /*<< start of hsync behind visible pixels */
+ int hsync_end; /*<< end of hsync behind its start */
+ int line_length; /*<< whole line length */
+
+ int visible_lines; /*<< visible lines on screen */
+ int vsync_start; /*<< vsync start behind last visible line */
+ int vsync_end; /*<< end of vsync behind its start */
+ int picture_length; /*<< whole screen length */
+
+ int sync_pol; /*<< 0: low, 1: high, bit 0 hsync, bit 1 vsync */
+};
+
+/*
+ * values for .sync_pol in struct video_mode
+ */
+#define HSYNC_HIGH_POL 0
+#define HSYNC_LOW_POL 1
+#define VSYNC_HIGH_POL 0
+#define VSYNC_LOW_POL 2
+
+/**
+ * 640x480 @ 72Hz hsync: 37.9kHz
+ * VESA standard mode for classic 4:3 monitors
+ * Copied from X11:
+ * ModeLine "640x480" 31.5 640 664 704 832 480 489 491 520 -hsync -vsync
+ */
+static const struct video_mode mode_640x480 = {
+ .pixel_clock = 31500000,
+ .pll_value = 0x33915801,
+
+ .visible_pixel = 640,
+ .hsync_start = 664,
+ .hsync_end = 704, /* 1.27 us sync length */
+ .line_length = 832, /* 26.39us */
+
+ .visible_lines = 480,
+ .vsync_start = 489,
+ .vsync_end = 491,
+ .picture_length = 520, /* 13.89ms */
+
+ .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL,
+};
+
+/**
+ * 800x600 @ 72Hz hsync: 48.1kHz
+ * VESA standard mode for classic 4:3 monitors
+ * Copied from X11:
+ * ModeLine "800x600" 50.0 800 856 976 1040 600 637 643 666 +hsync +vsync
+ */
+static const struct video_mode mode_800x600 = {
+ .pixel_clock = 50000000,
+ .pll_value = 0x23088801,
+
+ .visible_pixel = 800,
+ .hsync_start = 856,
+ .hsync_end = 976,
+ .line_length = 1040, /* 20.8us */
+
+ .visible_lines = 600,
+ .vsync_start = 637,
+ .vsync_end = 643,
+ .picture_length = 666, /* 13.89ms */
+
+ .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
+};
+
+/**
+ * 1024x768 @ 70Hz (VESA) hsync: 56.5kHz
+ * Standard mode for classic 4:3 monitors
+ * Copied from X11:
+ * ModeLine "1024x768" 75.0 1024 1048 1184 1328 768 771 777 806 -hsync -vsync
+ */
+static const struct video_mode mode_1024x768 = {
+ .pixel_clock = 75000000,
+ .pll_value = 0x37E22801,
+
+ .visible_pixel = 1024,
+ .hsync_start = 1048,
+ .hsync_end = 1184,
+ .line_length = 1328, /* 17.7us */
+
+ .visible_lines = 768,
+ .vsync_start = 771,
+ .vsync_end = 777,
+ .picture_length = 806, /* 14.3us */
+
+ .sync_pol = HSYNC_LOW_POL | VSYNC_LOW_POL,
+};
+
+/**
+ * 1280x960 @ 60Hz (VESA) hsync: 60.0kHz
+ * Mode for classic 4:3 monitors
+ * Copied from X11:
+ * ModeLine "1280x960" 108.0 1280 1376 1488 1800 960 961 964 1000 +hsync +vsync
+ */
+static const struct video_mode mode_1280x960 = {
+ .pixel_clock = 108000000,
+ .pll_value = 0x2710C805,
+
+ .visible_pixel = 1280,
+ .hsync_start = 1376,
+ .hsync_end = 1488,
+ .line_length = 1800, /* 16.67us */
+
+ .visible_lines = 960,
+ .vsync_start = 961,
+ .vsync_end = 964,
+ .picture_length = 1000, /* 16.67ms */
+
+ .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
+};
+
+/**
+ * 1280x1024 @ 60Hz (VESA) hsync: 64.0kHz
+ * Mode for modern 5:4 flat screens
+ * Copied from X11:
+ * ModeLine "1280x1024" 108.0 1280 1328 1440 1688 1024 1025 1028 1066 +hsync +vsync
+ */
+static const struct video_mode mode_1280x1024 = {
+ .pixel_clock = 108000000,
+ .pll_value = 0x2710C805,
+
+ .visible_pixel = 1280,
+ .hsync_start = 1328,
+ .hsync_end = 1440,
+ .line_length = 1688, /* 15.6us */
+
+ .visible_lines = 1024,
+ .vsync_start = 1025,
+ .vsync_end = 1028,
+ .picture_length = 1066,
+
+ .sync_pol = HSYNC_HIGH_POL | VSYNC_HIGH_POL,
+};
+
+/**
+ * List of supported common modes
+ */
+static const struct video_mode *modes[] = {
+ &mode_640x480, /* CONFIG_GX1_VIDEOMODE = 0 */
+ &mode_800x600, /* CONFIG_GX1_VIDEOMODE = 1 */
+ &mode_1024x768, /* CONFIG_GX1_VIDEOMODE = 2 */
+ &mode_1280x960, /* CONFIG_GX1_VIDEOMODE = 3 */
+ &mode_1280x1024 /* CONFIG_GX1_VIDEOMODE = 4 */
+};
+
+/* make a sanity check at buildtime */
+#if CONFIG_GX1_VIDEOMODE > 4
+# error Requested video mode is unknown!
+#endif
+
+/**
+ * Setup the pixel PLL in the companion chip
+ * @param[in] base register's base address
+ * @param[in] pll_val pll register value to be set
+ *
+ * The PLL to program here is located in the CS5530
+ */
+static void cs5530_set_clock_frequency(u32 io_base, unsigned long pll_val)
+{
+ unsigned long reg;
+
+ /* disable the PLL first, reset and power it down */
+ reg = read32(io_base+CS5530_DOT_CLK_CONFIG) & ~0x20;
+ reg |= 0x80000100;
+ write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
+
+ /* write the new PLL setting */
+ reg |= (pll_val & ~0x80000920);
+ write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
+
+ mdelay(1); /* wait for control voltage to be 0V */
+
+ /* enable the PLL */
+ reg |= 0x00000800;
+ write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
+
+ /* clear reset */
+ reg &= ~0x80000000;
+ write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
+
+ /* clear bypass */
+ reg &= ~0x00000100;
+ write32(io_base+CS5530_DOT_CLK_CONFIG, reg);
+}
+
+/**
+ * Setup memory layout
+ * @param[in] gx_base GX register area
+ * @param[in] mode Data about the video mode to setup
+ *
+ * Memory layout must be setup in Geode GX1's chipset.
+ * Note: This routine assumes unlocked DC registers.
+ * Note: Using compressed buffer is not supported yet!
+ * (makes more sense later, but not while booting)
+ *
+ * At this point a check is missed if the requested video
+ * mode is possible with the provided video memory.
+ * Check if symbol CONFIG_VIDEO_MB is at least:
+ * - 1 (=1MiB) for VGA and SVGA
+ * - 2 (=2MiB) for XGA
+ * - 4 (=4MiB) for SXGA
+ */
+static void dc_setup_layout(u32 gx_base, const struct video_mode *mode)
+{
+ u32 base = 0x00000000;
+
+ write32(gx_base + DC_FB_ST_OFFSET, base);
+
+ base += (COLOUR_DEPTH>>3) * mode->visible_pixel * mode->visible_lines;
+
+ write32(gx_base + DC_CB_ST_OFFSET, base);
+ write32(gx_base + DC_CURS_ST_OFFSET, base);
+ write32(gx_base + DC_VID_ST_OFFSET, base);
+ write32(gx_base + DC_LINE_DELTA, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 2);
+ write32(gx_base + DC_BUF_SIZE, ((COLOUR_DEPTH>>3) * mode->visible_pixel) >> 3);
+}
+
+/**
+ * Setup the HSYNC/VSYNC, active video timing
+ * @param[in] gx_base GX register area
+ * @param[in] mode Data about the video mode to setup
+ *
+ * Sync signal generation is done in Geode GX1's chipset.
+ * Note: This routine assumes unlocked DC registers
+ *
+ * |<------------------------- htotal ----------------------------->|
+ * |<------------ hactive -------------->| |
+ * | hblankstart-->| |
+ * | hblankend-->|
+ * | hsyncstart-->| |
+ * | hsyncend-->| |
+ * |#####################################___________________________| RGB data
+ * |______________________________________________---------_________| HSYNC
+ *
+ * |<------------------------- vtotal ----------------------------->|
+ * |<------------ vactive -------------->| |
+ * | vblankstart-->| |
+ * | vblankend-->|
+ * | vsyncstart-->| |
+ * | vsyncend-->| |
+ * |#####################################___________________________| line data
+ * |______________________________________________---------_________| YSYNC
+ */
+static void dc_setup_timing(u32 gx_base, const struct video_mode *mode)
+{
+ u32 hactive, hblankstart, hsyncstart, hsyncend, hblankend, htotal;
+ u32 vactive, vblankstart, vsyncstart, vsyncend, vblankend, vtotal;
+
+ hactive = mode->visible_pixel & 0x7FF;
+ hblankstart = hactive;
+ hsyncstart = mode->hsync_start & 0x7FF;
+ hsyncend = mode->hsync_end & 0x7FF;
+ hblankend = mode->line_length & 0x7FF;
+ htotal = hblankend;
+
+ vactive = mode->visible_lines & 0x7FF;
+ vblankstart = vactive;
+ vsyncstart = mode->vsync_start & 0x7FF;
+ vsyncend = mode->vsync_end & 0x7FF;
+ vblankend = mode->picture_length & 0x7FF;
+ vtotal = vblankend;
+
+ /* row description */
+ write32(gx_base + DC_H_TIMING_1, (hactive - 1) | ((htotal - 1) << 16));
+ /* horizontal blank description */
+ write32(gx_base + DC_H_TIMING_2, (hblankstart - 1) | ((hblankend - 1) << 16));
+ /* horizontal sync description */
+ write32(gx_base + DC_H_TIMING_3, (hsyncstart - 1) | ((hsyncend - 1) << 16));
+ write32(gx_base + DC_FP_H_TIMING, (hsyncstart - 1) | ((hsyncend - 1) << 16));
+
+ /* line description */
+ write32(gx_base + DC_V_TIMING_1, (vactive - 1) | ((vtotal - 1) << 16));
+ /* vertical blank description */
+ write32(gx_base + DC_V_TIMING_2, (vblankstart - 1) | ((vblankend - 1) << 16));
+ /* vertical sync description */
+ write32(gx_base + DC_V_TIMING_3, (vsyncstart - 1) | ((vsyncend - 1) << 16));
+ write32(gx_base + DC_FP_V_TIMING, (vsyncstart - 2) | ((vsyncend - 2) << 16));
+}
+
+/**
+ * Setup required internals to bring the mode up and running
+ * @param[in] gx_base GX register area
+ * @param[in] mode Data about the video mode to setup
+ *
+ * Must be setup in Geode GX1's chipset.
+ * Note: This routine assumes unlocked DC registers.
+ */
+static void cs5530_activate_mode(u32 gx_base, const struct video_mode *mode)
+{
+ write32(gx_base + DC_GENERAL_CFG, 0x00000080);
+ mdelay(1);
+ dc_setup_layout(gx_base,mode);
+ dc_setup_timing(gx_base,mode);
+
+ write32(gx_base + DC_GENERAL_CFG, 0x2000C581);
+ write32(gx_base + DC_TIMING_CFG, 0x0000002F);
+ write32(gx_base + DC_OUTPUT_CFG, 0x00003004);
+}
+
+/**
+ * Activate the current mode to be "visible" outside
+ * @param[in] gx_base GX register area
+ * @param[in] mode Data about the video mode to setup
+ *
+ * As we now activate the interface this must be done
+ * in the CS5530
+ */
+static void cs5530_activate_video(u32 io_base, const struct video_mode *mode)
+{
+ u32 val;
+
+ val = (u32)mode->sync_pol << 8;
+ write32(io_base + CS5530_DISPLAY_CONFIG, val | 0x0020002F);
+}
+
+#if CONFIG_SPLASH_GRAPHIC == 1
+
+/*
+ * This bitmap file must provide:
+ * int width: pixel count in one line
+ * int height: line count
+ * int colours: ount of used colour
+ * unsigned long colour_map[]: RGB 565 colours to be used
+ * unsigned char bitmap[]: index per pixel into colour_map[], width*height pixels
+ */
+#include "bitmap.c"
+
+/*
+ * show a boot splash screen in the right lower corner of the screen
+ * swidth: screen width in pixel
+ * sheight: screen height in lines
+ * pitch: line pitch in bytes
+ * base: screen base address
+ *
+ * This routine assumes we are using a 16 bit colour depth!
+ */
+static void show_boot_splash_16(u32 swidth, u32 sheight, u32 pitch,void *base)
+{
+ int word_count,i;
+ unsigned short *adr;
+ u32 xstart,ystart,x,y;
+ /*
+ * fill the screen with the colour of the
+ * left top pixel in the graphic
+ */
+ word_count = pitch * sheight;
+ adr = (unsigned short*)base;
+ for (i = 0; i < word_count; i++, adr++)
+ *adr = colour_map[bitmap[0]];
+
+ /*
+ * paint the splash
+ */
+ xstart = swidth-width;
+ ystart = sheight-height;
+ for (y = 0; y < height; y++) {
+ adr=(unsigned short*)(base + pitch*(y+ystart) + 2 * xstart);
+ for (x = 0; x < width; x++) {
+ *adr=(unsigned short)colour_map[(int)bitmap[x + y * width]];
+ adr++;
+ }
+ }
+}
+#else
+# define show_boot_splash_16(w, x, y , z)
+#endif
+
+/**
+ * coreboot management part
+ * @param[in] dev Info about the PCI device to initialise
+ */
+static void cs5530_vga_init(device_t dev)
+{
+ const struct video_mode *mode;
+ u32 io_base, gx_base;
+
+ io_base = pci_read_config32(dev, 0x10);
+ gx_base = GX_BASE;
+ mode = modes[CONFIG_GX1_VIDEOMODE];
+
+ printk(BIOS_DEBUG, "Setting up video mode %dx%d with %d Hz clock\n",
+ mode->visible_pixel, mode->visible_lines, mode->pixel_clock);
+
+ cs5530_set_clock_frequency(io_base, mode->pll_value);
+
+ write32(gx_base + DC_UNLOCK, DC_UNLOCK_MAGIC);
+
+ show_boot_splash_16(mode->visible_pixel, mode->visible_lines,
+ mode->visible_pixel * (COLOUR_DEPTH>>3), (void*)(GX_BASE + 0x800000));
+
+ cs5530_activate_mode(gx_base, mode);
+
+ cs5530_activate_video(io_base, mode);
+ write32(gx_base + DC_UNLOCK, 0x00000000);
+}
+
+static struct device_operations vga_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = cs5530_vga_init,
+ .enable = NULL, /* not required */
+};
+
+static const struct pci_driver vga_pci_driver __pci_driver = {
+ .ops = &vga_ops,
+ .vendor = PCI_VENDOR_ID_CYRIX,
+ .device = PCI_DEVICE_ID_CYRIX_5530_VIDEO,
+};
+
+#endif /* #if CONFIG_GX1_VIDEO == 1 */
driver-y += cs5535.c
-#driver-y += cs5535_pci.c
-#driver-y += cs5535_ide.c
+#driver-y += pci.c
+#driver-y += ide.c
ramstage-y += chipsetinit.c
+++ /dev/null
-/*
- *
- * cs5535_early_setup.c: Early chipset initialization for CS5535 companion device
- *
- *
- * This file implements the initialization sequence documented in section 4.2 of
- * AMD Geode GX Processor CS5535 Companion Device GoedeROM Porting Guide.
- *
- */
-
-/**
- * @brief Setup PCI IDSEL for CS5535
- *
- *
- */
-
-static void cs5535_setup_extmsr(void)
-{
- msr_t msr;
-
- /* forward MSR access to CS5535_GLINK_PORT_NUM to CS5535_DEV_NUM */
- msr.hi = msr.lo = 0x00000000;
-#if CS5535_GLINK_PORT_NUM <= 4
- msr.lo = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 1) * 8);
-#else
- msr.hi = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 5) * 8);
-#endif
- wrmsr(0x5000201e, msr);
-}
-
-static void cs5535_setup_idsel(void)
-{
- /* write IDSEL to the write once register at address 0x0000 */
- outl(0x1 << (CS5535_DEV_NUM + 10), 0);
-}
-
-static void cs5535_usb_swapsif(void)
-{
- msr_t msr;
-
- msr = rdmsr(0x51600005);
- //USB Serial short detect bit.
- if (msr.hi & 0x10) {
- /* We need to preserve bits 32,33,35 and not clear any BIST error, but clear the
- * SERSHRT error bit */
- msr.hi &= 0xFFFFFFFB;
- wrmsr(0x51600005, msr);
- }
-}
-
-static void cs5535_setup_iobase(void)
-{
- msr_t msr;
- /* setup LBAR for SMBus controller */
- msr.hi = 0x0000f001;
- msr.lo = SMBUS_IO_BASE;
- wrmsr(MDD_LBAR_SMB, msr);
-
- /* setup LBAR for GPIO */
- msr.hi = 0x0000f001;
- msr.lo = GPIO_IO_BASE;
- wrmsr(MDD_LBAR_GPIO, msr);
-
- /* setup LBAR for MFGPT */
- msr.hi = 0x0000f001;
- msr.lo = MFGPT_IO_BASE;
- wrmsr(MDD_LBAR_MFGPT, msr);
-
- /* setup LBAR for ACPI */
- msr.hi = 0x0000f001;
- msr.lo = ACPI_IO_BASE;
- wrmsr(MDD_LBAR_ACPI, msr);
-
- /* setup LBAR for PM Support */
- msr.hi = 0x0000f001;
- msr.lo = PMS_IO_BASE;
- wrmsr(MDD_LBAR_PMS, msr);
-}
-
-static void cs5535_setup_gpio(void)
-{
- uint32_t val;
-
- /* setup GPIO pins 14/15 for SDA/SCL */
- val = (1<<14 | 1<<15);
- /* Output Enable */
- outl(0x3fffc000, 0x6100 + 0x04);
- //outl(val, 0x6100 + 0x04);
- /* Output AUX1 */
- outl(0x3fffc000, 0x6100 + 0x10);
- //outl(val, 0x6100 + 0x10);
- /* Input Enable */
- //outl(0x0f5af0a5, 0x6100 + 0x20);
- outl(0x3fffc000, 0x6100 + 0x20);
- //outl(val, 0x6100 + 0x20);
- /* Input AUX1 */
- //outl(0x3ffbc004, 0x6100 + 0x34);
- outl(0x3fffc000, 0x6100 + 0x34);
- //outl(val, 0x6100 + 0x34);
-}
-
-void cs5535_disable_internal_uart(void)
-{
-}
-
-static void cs5535_setup_cis_mode(void)
-{
- msr_t msr;
-
- /* setup CPU interface serial to mode C on both sides */
- msr = rdmsr(GLPCI_SB_CTRL);
- msr.lo &= ~0x18;
- msr.lo |= 0x10;
- wrmsr(GLPCI_SB_CTRL, msr);
- //Only do this if we are building for 5535
- msr.lo = 0x2;
- msr.hi = 0x0;
- wrmsr(VIP_GIO_MSR_SEL, msr);
-}
-
-static void dummy(void)
-{
-}
-
-static void cs5535_early_setup(void)
-{
- msr_t msr;
-
- cs5535_setup_extmsr();
-
- msr = rdmsr(GLCP_SYS_RSTPLL);
- if (msr.lo & (0x3f << 26)) {
- /* PLL is already set and we are reboot from PLL reset */
- print_debug("reboot from BIOS reset\n");
- return;
- }
- print_debug("Setup idsel\n");
- cs5535_setup_idsel();
- print_debug("Setup iobase\n");
- cs5535_usb_swapsif();
- cs5535_setup_iobase();
- print_debug("Setup gpio\n");
- cs5535_setup_gpio();
- print_debug("Setup cis_mode\n");
- cs5535_setup_cis_mode();
- print_debug("Setup smbus\n");
- cs5535_enable_smbus();
- dummy();
-}
+++ /dev/null
-#include "cs5535_smbus.h"
-
-#define SMBUS_IO_BASE 0x6000
-
-/* initialization for SMBus Controller */
-static void cs5535_enable_smbus(void)
-{
- unsigned char val;
-
- /* reset SMBUS controller */
- outb(0, SMBUS_IO_BASE + SMB_CTRL2);
-
- /* Set SCL freq and enable SMB controller */
- val = inb(SMBUS_IO_BASE + SMB_CTRL2);
- val |= ((0x20 << 1) | SMB_CTRL2_ENABLE);
- outb(val, SMBUS_IO_BASE + SMB_CTRL2);
-
- /* Setup SMBus host controller address to 0xEF */
- val = inb(SMBUS_IO_BASE + SMB_ADD);
- val |= (0xEF | SMB_ADD_SAEN);
- outb(val, SMBUS_IO_BASE + SMB_ADD);
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "cs5535.h"
-
-static void ide_init(struct device *dev)
-{
- printk(BIOS_SPEW, "cs5535_ide: %s\n", __func__);
-}
-
-static void ide_enable(struct device *dev)
-{
- printk(BIOS_SPEW, "cs5535_ide: %s\n", __func__);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = ide_enable,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_NS,
- .device = PCI_DEVICE_ID_NS_CS5535_IDE,
-};
+++ /dev/null
-//#include <device/smbus_def.h>
-#define SMBUS_ERROR -1
-#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
-#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
-
-#define SMB_SDA 0x00
-#define SMB_STS 0x01
-#define SMB_CTRL_STS 0x02
-#define SMB_CTRL1 0x03
-#define SMB_ADD 0x04
-#define SMB_CTRL2 0x05
-#define SMB_CTRL3 0x06
-
-#define SMB_STS_SLVSTP (0x01 << 7)
-#define SMB_STS_SDAST (0x01 << 6)
-#define SMB_STS_BER (0x01 << 5)
-#define SMB_STS_NEGACK (0x01 << 4)
-#define SMB_STS_STASTR (0x01 << 3)
-#define SMB_STS_NMATCH (0x01 << 2)
-#define SMB_STS_MASTER (0x01 << 1)
-#define SMB_STS_XMIT (0x01 << 0)
-
-#define SMB_CSTS_TGSCL (0x01 << 5)
-#define SMB_CSTS_TSDA (0x01 << 4)
-#define SMB_CSTS_GCMTCH (0x01 << 3)
-#define SMB_CSTS_MATCH (0x01 << 2)
-#define SMB_CSTS_BB (0x01 << 1)
-#define SMB_CSTS_BUSY (0x01 << 0)
-
-#define SMB_CTRL1_STASTRE (0x01 << 7)
-#define SMB_CTRL1_NMINTE (0x01 << 6)
-#define SMB_CTRL1_GCMEN (0x01 << 5)
-#define SMB_CTRL1_ACK (0x01 << 4)
-#define SMB_CTRL1_RSVD (0x01 << 3)
-#define SMB_CTRL1_INTEN (0x01 << 2)
-#define SMB_CTRL1_STOP (0x01 << 1)
-#define SMB_CTRL1_START (0x01 << 0)
-
-#define SMB_ADD_SAEN (0x01 << 7)
-
-#define SMB_CTRL2_ENABLE 0x01
-
-#define SMBUS_TIMEOUT (100*1000*10)
-#define SMBUS_STATUS_MASK 0xfbff
-
-#define SMBUS_IO_BASE 0x6000
--- /dev/null
+/*
+ *
+ * cs5535_early_setup.c: Early chipset initialization for CS5535 companion device
+ *
+ *
+ * This file implements the initialization sequence documented in section 4.2 of
+ * AMD Geode GX Processor CS5535 Companion Device GoedeROM Porting Guide.
+ *
+ */
+
+/**
+ * @brief Setup PCI IDSEL for CS5535
+ *
+ *
+ */
+
+static void cs5535_setup_extmsr(void)
+{
+ msr_t msr;
+
+ /* forward MSR access to CS5535_GLINK_PORT_NUM to CS5535_DEV_NUM */
+ msr.hi = msr.lo = 0x00000000;
+#if CS5535_GLINK_PORT_NUM <= 4
+ msr.lo = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 1) * 8);
+#else
+ msr.hi = CS5535_DEV_NUM << ((CS5535_GLINK_PORT_NUM - 5) * 8);
+#endif
+ wrmsr(0x5000201e, msr);
+}
+
+static void cs5535_setup_idsel(void)
+{
+ /* write IDSEL to the write once register at address 0x0000 */
+ outl(0x1 << (CS5535_DEV_NUM + 10), 0);
+}
+
+static void cs5535_usb_swapsif(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(0x51600005);
+ //USB Serial short detect bit.
+ if (msr.hi & 0x10) {
+ /* We need to preserve bits 32,33,35 and not clear any BIST error, but clear the
+ * SERSHRT error bit */
+ msr.hi &= 0xFFFFFFFB;
+ wrmsr(0x51600005, msr);
+ }
+}
+
+static void cs5535_setup_iobase(void)
+{
+ msr_t msr;
+ /* setup LBAR for SMBus controller */
+ msr.hi = 0x0000f001;
+ msr.lo = SMBUS_IO_BASE;
+ wrmsr(MDD_LBAR_SMB, msr);
+
+ /* setup LBAR for GPIO */
+ msr.hi = 0x0000f001;
+ msr.lo = GPIO_IO_BASE;
+ wrmsr(MDD_LBAR_GPIO, msr);
+
+ /* setup LBAR for MFGPT */
+ msr.hi = 0x0000f001;
+ msr.lo = MFGPT_IO_BASE;
+ wrmsr(MDD_LBAR_MFGPT, msr);
+
+ /* setup LBAR for ACPI */
+ msr.hi = 0x0000f001;
+ msr.lo = ACPI_IO_BASE;
+ wrmsr(MDD_LBAR_ACPI, msr);
+
+ /* setup LBAR for PM Support */
+ msr.hi = 0x0000f001;
+ msr.lo = PMS_IO_BASE;
+ wrmsr(MDD_LBAR_PMS, msr);
+}
+
+static void cs5535_setup_gpio(void)
+{
+ uint32_t val;
+
+ /* setup GPIO pins 14/15 for SDA/SCL */
+ val = (1<<14 | 1<<15);
+ /* Output Enable */
+ outl(0x3fffc000, 0x6100 + 0x04);
+ //outl(val, 0x6100 + 0x04);
+ /* Output AUX1 */
+ outl(0x3fffc000, 0x6100 + 0x10);
+ //outl(val, 0x6100 + 0x10);
+ /* Input Enable */
+ //outl(0x0f5af0a5, 0x6100 + 0x20);
+ outl(0x3fffc000, 0x6100 + 0x20);
+ //outl(val, 0x6100 + 0x20);
+ /* Input AUX1 */
+ //outl(0x3ffbc004, 0x6100 + 0x34);
+ outl(0x3fffc000, 0x6100 + 0x34);
+ //outl(val, 0x6100 + 0x34);
+}
+
+void cs5535_disable_internal_uart(void)
+{
+}
+
+static void cs5535_setup_cis_mode(void)
+{
+ msr_t msr;
+
+ /* setup CPU interface serial to mode C on both sides */
+ msr = rdmsr(GLPCI_SB_CTRL);
+ msr.lo &= ~0x18;
+ msr.lo |= 0x10;
+ wrmsr(GLPCI_SB_CTRL, msr);
+ //Only do this if we are building for 5535
+ msr.lo = 0x2;
+ msr.hi = 0x0;
+ wrmsr(VIP_GIO_MSR_SEL, msr);
+}
+
+static void dummy(void)
+{
+}
+
+static void cs5535_early_setup(void)
+{
+ msr_t msr;
+
+ cs5535_setup_extmsr();
+
+ msr = rdmsr(GLCP_SYS_RSTPLL);
+ if (msr.lo & (0x3f << 26)) {
+ /* PLL is already set and we are reboot from PLL reset */
+ print_debug("reboot from BIOS reset\n");
+ return;
+ }
+ print_debug("Setup idsel\n");
+ cs5535_setup_idsel();
+ print_debug("Setup iobase\n");
+ cs5535_usb_swapsif();
+ cs5535_setup_iobase();
+ print_debug("Setup gpio\n");
+ cs5535_setup_gpio();
+ print_debug("Setup cis_mode\n");
+ cs5535_setup_cis_mode();
+ print_debug("Setup smbus\n");
+ cs5535_enable_smbus();
+ dummy();
+}
--- /dev/null
+#include "smbus.h"
+
+#define SMBUS_IO_BASE 0x6000
+
+/* initialization for SMBus Controller */
+static void cs5535_enable_smbus(void)
+{
+ unsigned char val;
+
+ /* reset SMBUS controller */
+ outb(0, SMBUS_IO_BASE + SMB_CTRL2);
+
+ /* Set SCL freq and enable SMB controller */
+ val = inb(SMBUS_IO_BASE + SMB_CTRL2);
+ val |= ((0x20 << 1) | SMB_CTRL2_ENABLE);
+ outb(val, SMBUS_IO_BASE + SMB_CTRL2);
+
+ /* Setup SMBus host controller address to 0xEF */
+ val = inb(SMBUS_IO_BASE + SMB_ADD);
+ val |= (0xEF | SMB_ADD_SAEN);
+ outb(val, SMBUS_IO_BASE + SMB_ADD);
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "cs5535.h"
+
+static void ide_init(struct device *dev)
+{
+ printk(BIOS_SPEW, "cs5535_ide: %s\n", __func__);
+}
+
+static void ide_enable(struct device *dev)
+{
+ printk(BIOS_SPEW, "cs5535_ide: %s\n", __func__);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = ide_enable,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_NS,
+ .device = PCI_DEVICE_ID_NS_CS5535_IDE,
+};
--- /dev/null
+//#include <device/smbus_def.h>
+#define SMBUS_ERROR -1
+#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
+#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
+
+#define SMB_SDA 0x00
+#define SMB_STS 0x01
+#define SMB_CTRL_STS 0x02
+#define SMB_CTRL1 0x03
+#define SMB_ADD 0x04
+#define SMB_CTRL2 0x05
+#define SMB_CTRL3 0x06
+
+#define SMB_STS_SLVSTP (0x01 << 7)
+#define SMB_STS_SDAST (0x01 << 6)
+#define SMB_STS_BER (0x01 << 5)
+#define SMB_STS_NEGACK (0x01 << 4)
+#define SMB_STS_STASTR (0x01 << 3)
+#define SMB_STS_NMATCH (0x01 << 2)
+#define SMB_STS_MASTER (0x01 << 1)
+#define SMB_STS_XMIT (0x01 << 0)
+
+#define SMB_CSTS_TGSCL (0x01 << 5)
+#define SMB_CSTS_TSDA (0x01 << 4)
+#define SMB_CSTS_GCMTCH (0x01 << 3)
+#define SMB_CSTS_MATCH (0x01 << 2)
+#define SMB_CSTS_BB (0x01 << 1)
+#define SMB_CSTS_BUSY (0x01 << 0)
+
+#define SMB_CTRL1_STASTRE (0x01 << 7)
+#define SMB_CTRL1_NMINTE (0x01 << 6)
+#define SMB_CTRL1_GCMEN (0x01 << 5)
+#define SMB_CTRL1_ACK (0x01 << 4)
+#define SMB_CTRL1_RSVD (0x01 << 3)
+#define SMB_CTRL1_INTEN (0x01 << 2)
+#define SMB_CTRL1_STOP (0x01 << 1)
+#define SMB_CTRL1_START (0x01 << 0)
+
+#define SMB_ADD_SAEN (0x01 << 7)
+
+#define SMB_CTRL2_ENABLE 0x01
+
+#define SMBUS_TIMEOUT (100*1000*10)
+#define SMBUS_STATUS_MASK 0xfbff
+
+#define SMBUS_IO_BASE 0x6000
##
driver-y += cs5536.c
-driver-y += cs5536_ide.c
-driver-y += cs5536_pirq.c
+driver-y += ide.c
+driver-y += pirq.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
- * This file implements the initialization sequence documented in section 4.2 of
- * AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
- */
-
-/**
- * @brief Setup PCI IDSEL for CS5536
- */
-static 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);
-#endif
- wrmsr(GLPCI_ExtMSR, msr);
-}
-
-static void cs5536_setup_idsel(void)
-{
- /* write IDSEL to the write once register at address 0x0000 */
- outl(0x1 << (CS5536_DEV_NUM + 10), 0);
-}
-
-static void cs5536_usb_swapsif(void)
-{
- msr_t msr;
-
- msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
- //USB Serial short detect bit.
- if (msr.hi & 0x10) {
- /* We need to preserve bits 32,33,35 and not clear any BIST
- * error, but clear the SERSHRT error bit */
-
- msr.hi &= 0xFFFFFFFB;
- wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
- }
-}
-
-static void cs5536_setup_iobase(void)
-{
- msr_t msr;
- /* setup LBAR for SMBus controller */
- msr.hi = 0x0000f001;
- msr.lo = SMBUS_IO_BASE;
- wrmsr(MDD_LBAR_SMB, msr);
-
- /* setup LBAR for GPIO */
- msr.hi = 0x0000f001;
- msr.lo = GPIO_IO_BASE;
- wrmsr(MDD_LBAR_GPIO, msr);
-
- /* setup LBAR for MFGPT */
- msr.hi = 0x0000f001;
- msr.lo = MFGPT_IO_BASE;
- wrmsr(MDD_LBAR_MFGPT, msr);
-
- /* setup LBAR for ACPI */
- msr.hi = 0x0000f001;
- msr.lo = ACPI_IO_BASE;
- wrmsr(MDD_LBAR_ACPI, msr);
-
- /* setup LBAR for PM Support */
- msr.hi = 0x0000f001;
- msr.lo = PMS_IO_BASE;
- wrmsr(MDD_LBAR_PMS, msr);
-}
-
-static void cs5536_setup_power_button(void)
-{
-#if CONFIG_ENABLE_POWER_BUTTON
- outl(0x40020000, PMS_IO_BASE + 0x40);
-#endif
-
- /* setup WORK_AUX/GPIO24, it is the external signal for 5536
- * vsb_work_aux controls all voltage rails except Vstandby & Vmem.
- * We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
- * If WORK_AUX/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);
-
-}
-
-static void cs5536_setup_gpio(void)
-{
- uint32_t val;
-
- /* setup GPIO pins 14/15 for SDA/SCL */
- val = GPIOL_15_SET | GPIOL_14_SET;
- /* Output Enable */
- outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
- /* Output AUX1 */
- outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
- /* Input Enable */
- outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
- /* Input AUX1 */
- outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
-}
-
-void cs5536_disable_internal_uart(void)
-{
- msr_t msr;
- /* The UARTs default to enabled.
- * Disable and reset them and configure them later. (SIO init)
- */
- msr = rdmsr(MDD_UART1_CONF);
- msr.lo = 1; // reset
- wrmsr(MDD_UART1_CONF, msr);
- msr.lo = 0; // disabled
- wrmsr(MDD_UART1_CONF, msr);
-
- msr = rdmsr(MDD_UART2_CONF);
- msr.lo = 1; // reset
- wrmsr(MDD_UART2_CONF, msr);
- msr.lo = 0; // disabled
- wrmsr(MDD_UART2_CONF, msr);
-}
-
-static void cs5536_setup_cis_mode(void)
-{
- msr_t msr;
-
- /* setup CPU interface serial to mode B to match CPU */
- msr = rdmsr(GLPCI_SB_CTRL);
- msr.lo &= ~0x18;
- msr.lo |= 0x10;
- wrmsr(GLPCI_SB_CTRL, msr);
-}
-
-/**
- * Enable the on-chip UART.
- *
- * See page 412 of the AMD Geode CS5536 Companion Device data book.
- */
-static void cs5536_setup_onchipuart1(void)
-{
- msr_t msr;
-
- /* Setup early for polling only mode.
- * 1. Enable GPIO 8 to OUT_AUX1, 9 to IN_AUX1.
- * GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
- * 2. Enable UART I/O space in MDD.
- * MSR 0x51400014 bit 18:16
- * 3. Enable UART controller.
- * MSR 0x5140003A bit 0, 1
- */
-
- /* GPIO8 - UART1_TX */
- /* Set: Output Enable (0x4) */
- outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
- /* Set: OUTAUX1 Select (0x10) */
- outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
-
- /* GPIO9 - UART1_RX */
- /* Set: Input Enable (0x20) */
- outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
- /* Set: INAUX1 Select (0x34) */
- outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
-
- /* Set address to 0x3F8. */
- msr = rdmsr(MDD_LEG_IO);
- msr.lo |= 0x7 << 16;
- wrmsr(MDD_LEG_IO, msr);
-
- /* Bit 1 = DEVEN (device enable)
- * Bit 4 = EN_BANKS (allow access to the upper banks)
- */
- msr.lo = (1 << 4) | (1 << 1);
- msr.hi = 0;
-
- /* Enable COM1. */
- wrmsr(MDD_UART1_CONF, msr);
-}
-
-static void cs5536_setup_onchipuart2(void)
-{
- msr_t msr;
-
- /* GPIO4 - UART2_TX */
- /* Set: Output Enable (0x4) */
- outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
- /* Set: OUTAUX1 Select (0x10) */
- outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
- /* GPIO4 - UART2_RX */
- /* Set: Input Enable (0x20) */
- outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
- /* Set: INAUX1 Select (0x34) */
- outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
-
- /* Set: GPIO 3 + 3 Pull Up (0x18) */
- outl(GPIOL_3_SET | GPIOL_4_SET,
- GPIO_IO_BASE + GPIOL_PULLUP_ENABLE);
-
- /* set address to 2F8 */
- msr = rdmsr(MDD_LEG_IO);
- msr.lo |= 0x5 << 20;
- wrmsr(MDD_LEG_IO, msr);
-
- /* Bit 1 = DEVEN (device enable)
- * Bit 4 = EN_BANKS (allow access to the upper banks
- */
- msr.lo = (1 << 4) | (1 << 1);
- msr.hi = 0;
-
- /* enable COM2 */
- wrmsr(MDD_UART2_CONF, msr);
-}
-
-void cs5536_setup_onchipuart(int uart)
-{
- switch (uart) {
- case 1:
- cs5536_setup_onchipuart1();
- break;
- case 2:
- cs5536_setup_onchipuart2();
- break;
- }
-}
-
-
-/* note: you can't do prints in here in most cases,
- * and we don't want to hang on serial, so they are
- * commented out
- */
-static void cs5536_early_setup(void)
-{
- msr_t msr;
-
- cs5536_setup_extmsr();
- cs5536_setup_cis_mode();
-
- msr = rdmsr(GLCP_SYS_RSTPLL);
- if (msr.lo & (0x3f << 26)) {
- /* PLL is already set and we are reboot from PLL reset */
- //print_debug("reboot from BIOS reset\n");
- return;
- }
- //print_debug("Setup idsel\n");
- cs5536_setup_idsel();
- //print_debug("Setup iobase\n");
- cs5536_usb_swapsif();
- cs5536_setup_iobase();
- //print_debug("Setup gpio\n");
- cs5536_setup_gpio();
- //print_debug("Setup smbus\n");
- cs5536_enable_smbus();
- //print_debug("Setup power button\n");
- cs5536_setup_power_button();
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "cs5536.h"
-
-#define SMBUS_ERROR -1
-#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
-#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
-#define SMBUS_TIMEOUT (1000)
-
-/* initialization for SMBus Controller */
-static void cs5536_enable_smbus(void)
-{
-
- /* Set SCL freq and enable SMB controller */
- /*outb((0x20 << 1) | SMB_CTRL2_ENABLE, smbus_io_base + SMB_CTRL2); */
- outb((0x7F << 1) | SMB_CTRL2_ENABLE, SMBUS_IO_BASE + SMB_CTRL2);
-
- /* Setup SMBus host controller address to 0xEF */
- outb((0xEF | SMB_ADD_SAEN), SMBUS_IO_BASE + SMB_ADD);
-
-}
-
-static void smbus_delay(void)
-{
- /* inb(0x80); */
-}
-
-static int smbus_wait(unsigned smbus_io_base)
-{
- unsigned long loops = SMBUS_TIMEOUT;
- unsigned char val;
-
- do {
- smbus_delay();
- val = inb(smbus_io_base + SMB_STS);
- if ((val & SMB_STS_SDAST) != 0)
- break;
- if (val & (SMB_STS_BER | SMB_STS_NEGACK)) {
- /*printk(BIOS_DEBUG, "SMBUS WAIT ERROR %x\n", val); */
- return SMBUS_ERROR;
- }
- } while (--loops);
- return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-}
-
-/* generate a smbus start condition */
-static int smbus_start_condition(unsigned smbus_io_base)
-{
- unsigned char val;
-
- /* issue a START condition */
- val = inb(smbus_io_base + SMB_CTRL1);
- outb(val | SMB_CTRL1_START, smbus_io_base + SMB_CTRL1);
-
- /* check for bus conflict */
- val = inb(smbus_io_base + SMB_STS);
- if ((val & SMB_STS_BER) != 0)
- return SMBUS_ERROR;
-
- return smbus_wait(smbus_io_base);
-}
-
-static int smbus_check_stop_condition(unsigned smbus_io_base)
-{
- unsigned char val;
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- /* check for SDA status */
- do {
- smbus_delay();
- val = inb(smbus_io_base + SMB_CTRL1);
- if ((val & SMB_CTRL1_STOP) == 0) {
- break;
- }
- outb((0x7F << 1) | SMB_CTRL2_ENABLE, smbus_io_base + SMB_CTRL2);
- } while (--loops);
- return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-}
-
-static int smbus_stop_condition(unsigned smbus_io_base)
-{
- outb(SMB_CTRL1_STOP, smbus_io_base + SMB_CTRL1);
- return smbus_wait(smbus_io_base);
-}
-
-static int smbus_ack(unsigned smbus_io_base, int state)
-{
- unsigned char val = inb(smbus_io_base + SMB_CTRL1);
-
-/* if (state) */
- outb(val | SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
-/* else
- outb(val & ~SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
-*/
- return 0;
-}
-
-static int smbus_send_slave_address(unsigned smbus_io_base,
- unsigned char device)
-{
- unsigned char val;
-
- /* send the slave address */
- outb(device, smbus_io_base + SMB_SDA);
-
- /* check for bus conflict and NACK */
- val = inb(smbus_io_base + SMB_STS);
- if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0)) {
- /* printk(BIOS_DEBUG, "SEND SLAVE ERROR (%x)\n", val); */
- return SMBUS_ERROR;
- }
- return smbus_wait(smbus_io_base);
-}
-
-static int smbus_send_command(unsigned smbus_io_base, unsigned char command)
-{
- unsigned char val;
-
- /* send the command */
- outb(command, smbus_io_base + SMB_SDA);
-
- /* check for bus conflict and NACK */
- val = inb(smbus_io_base + SMB_STS);
- if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0))
- return SMBUS_ERROR;
-
- return smbus_wait(smbus_io_base);
-}
-
-static unsigned char smbus_get_result(unsigned smbus_io_base)
-{
- return inb(smbus_io_base + SMB_SDA);
-}
-
-static unsigned char do_smbus_read_byte(unsigned smbus_io_base,
- unsigned char device,
- unsigned char address)
-{
- unsigned char error = 0;
-
- if ((smbus_check_stop_condition(smbus_io_base))) {
- error = 1;
- goto err;
- }
-
- if ((smbus_start_condition(smbus_io_base))) {
- error = 2;
- goto err;
- }
-
- if ((smbus_send_slave_address(smbus_io_base, device << 1))) {
- error = 3;
- goto err;
- }
-
- smbus_ack(smbus_io_base, 1);
-
- if ((smbus_send_command(smbus_io_base, address))) {
- error = 4;
- goto err;
- }
-
- if ((smbus_start_condition(smbus_io_base))) {
- error = 5;
- goto err;
- }
-
- if ((smbus_send_slave_address(smbus_io_base, (device << 1) | 0x01))) {
- error = 6;
- goto err;
- }
-
- if ((smbus_stop_condition(smbus_io_base))) {
- error = 7;
- goto err;
- }
-
- return smbus_get_result(smbus_io_base);
-
- err:
- print_debug("SMBUS READ ERROR:");
- print_debug_hex8(error);
- print_debug(" device:");
- print_debug_hex8(device);
- print_debug("\n");
- /* stop, clean up the error, and leave */
- smbus_stop_condition(smbus_io_base);
- outb(inb(smbus_io_base + SMB_STS), smbus_io_base + SMB_STS);
- outb(0x0, smbus_io_base + SMB_STS);
- return 0xFF;
-}
-
-static inline int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "cs5536.h"
-
-#define IDE_CFG 0x40
- #define CHANEN (1L << 1)
- #define PWB (1L << 14)
- #define CABLE (1L << 16)
-#define IDE_DTC 0x48
-#define IDE_CAST 0x4C
-#define IDE_ETC 0x50
-
-static void ide_init(struct device *dev)
-{
- uint32_t ide_cfg;
-
- printk(BIOS_SPEW, "cs5536_ide: %s\n", __func__);
- /* GPIO and IRQ setup are handled in the main chipset code. */
-
- // Enable the channel and Post Write Buffer
- // NOTE: Only 32-bit writes to the data buffer are allowed when PWB is set
- ide_cfg = pci_read_config32(dev, IDE_CFG);
- ide_cfg |= CHANEN | PWB;
- pci_write_config32(dev, IDE_CFG, ide_cfg);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = 0,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_CS5536_B0_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/pirq_routing.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
-void pirq_assign_irqs(const unsigned char pIntAtoD[4])
-{
- device_t pdev;
-
- pdev = dev_find_device(PCI_VENDOR_ID_AMD,
- PCI_DEVICE_ID_AMD_CS5536_ISA, 0);
-
- if (pdev) {
- pci_write_config16(pdev, 0x5c, (pIntAtoD[3] << 12
- | pIntAtoD[2] << 8 | pIntAtoD[1] << 4 | pIntAtoD[0]));
- }
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#define SMBUS_ERROR -1
-#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
-#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
-
-#define SMB_SDA 0x00
-#define SMB_STS 0x01
-#define SMB_CTRL_STS 0x02
-#define SMB_CTRL1 0x03
-#define SMB_ADD 0x04
-#define SMB_CTRL2 0x05
-#define SMB_CTRL3 0x06
-
-#define SMB_STS_SLVSTP (0x01 << 7)
-#define SMB_STS_SDAST (0x01 << 6)
-#define SMB_STS_BER (0x01 << 5)
-#define SMB_STS_NEGACK (0x01 << 4)
-#define SMB_STS_STASTR (0x01 << 3)
-#define SMB_STS_NMATCH (0x01 << 2)
-#define SMB_STS_MASTER (0x01 << 1)
-#define SMB_STS_XMIT (0x01 << 0)
-
-#define SMB_CSTS_TGSCL (0x01 << 5)
-#define SMB_CSTS_TSDA (0x01 << 4)
-#define SMB_CSTS_GCMTCH (0x01 << 3)
-#define SMB_CSTS_MATCH (0x01 << 2)
-#define SMB_CSTS_BB (0x01 << 1)
-#define SMB_CSTS_BUSY (0x01 << 0)
-
-#define SMB_CTRL1_STASTRE (0x01 << 7)
-#define SMB_CTRL1_NMINTE (0x01 << 6)
-#define SMB_CTRL1_GCMEN (0x01 << 5)
-#define SMB_CTRL1_ACK (0x01 << 4)
-#define SMB_CTRL1_RSVD (0x01 << 3)
-#define SMB_CTRL1_INTEN (0x01 << 2)
-#define SMB_CTRL1_STOP (0x01 << 1)
-#define SMB_CTRL1_START (0x01 << 0)
-
-#define SMB_ADD_SAEN (0x01 << 7)
-
-#define SMB_CTRL2_ENABLE 0x01
-
-#define SMBUS_TIMEOUT (100*1000*10)
-#define SMBUS_STATUS_MASK 0xfbff
-
-static void smbus_delay(void)
-{
- inb(0x80);
-}
-
-static int smbus_wait(unsigned smbus_io_base)
-{
- unsigned long loops = SMBUS_TIMEOUT;
- unsigned char val;
-
- do {
- smbus_delay();
- val = inb(smbus_io_base + SMB_STS);
- if ((val & SMB_STS_SDAST) != 0)
- break;
- if (val & (SMB_STS_BER | SMB_STS_NEGACK)) {
- printk(BIOS_DEBUG, "SMBUS WAIT ERROR %x\n", val);
- return SMBUS_ERROR;
- }
- } while (--loops);
-
- outb(0, smbus_io_base + SMB_STS);
- return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-}
-
-static int smbus_write(unsigned smbus_io_base, unsigned char byte)
-{
-
- outb(byte, smbus_io_base + SMB_SDA);
- return smbus_wait(smbus_io_base);
-}
-
-/* generate a smbus start condition */
-static int smbus_start_condition(unsigned smbus_io_base)
-{
- unsigned char val;
-
- /* issue a START condition */
- val = inb(smbus_io_base + SMB_CTRL1);
- outb(val | SMB_CTRL1_START, smbus_io_base + SMB_CTRL1);
-
- /* check for bus conflict */
- val = inb(smbus_io_base + SMB_STS);
- if ((val & SMB_STS_BER) != 0)
- return SMBUS_ERROR;
-
- return smbus_wait(smbus_io_base);
-}
-
-static int smbus_check_stop_condition(unsigned smbus_io_base)
-{
- unsigned char val;
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- /* check for SDA status */
- do {
- smbus_delay();
- val = inb(smbus_io_base + SMB_CTRL1);
- if ((val & SMB_CTRL1_STOP) == 0) {
- break;
- }
- } while (--loops);
- return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-
- /* Make sure everything is cleared and ready to go */
-
- val = inb(smbus_io_base + SMB_CTRL1);
- outb(val & ~(SMB_CTRL1_STASTRE | SMB_CTRL1_NMINTE),
- smbus_io_base + SMB_CTRL1);
-
- outb(SMB_STS_BER | SMB_STS_NEGACK | SMB_STS_STASTR,
- smbus_io_base + SMB_STS);
-
- val = inb(smbus_io_base + SMB_CTRL_STS);
- outb(val | SMB_CSTS_BB, smbus_io_base + SMB_CTRL_STS);
-}
-
-static int smbus_stop_condition(unsigned smbus_io_base)
-{
- unsigned char val;
- val = inb(smbus_io_base + SMB_CTRL1);
- outb(SMB_CTRL1_STOP, smbus_io_base + SMB_CTRL1);
-
- return 0;
-}
-
-static int smbus_ack(unsigned smbus_io_base, int state)
-{
- unsigned char val = inb(smbus_io_base + SMB_CTRL1);
-
- if (state)
- outb(val | SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
- else
- outb(val & ~SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
-
- return 0;
-}
-
-static int smbus_send_slave_address(unsigned smbus_io_base,
- unsigned char device)
-{
- unsigned char val;
-
- /* send the slave address */
- outb(device, smbus_io_base + SMB_SDA);
-
- /* check for bus conflict and NACK */
- val = inb(smbus_io_base + SMB_STS);
- if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0)) {
- printk(BIOS_DEBUG, "SEND SLAVE ERROR (%x)\n", val);
- return SMBUS_ERROR;
- }
- return smbus_wait(smbus_io_base);
-}
-
-static int smbus_send_command(unsigned smbus_io_base, unsigned char command)
-{
- unsigned char val;
-
- /* send the command */
- outb(command, smbus_io_base + SMB_SDA);
-
- /* check for bus conflict and NACK */
- val = inb(smbus_io_base + SMB_STS);
- if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0))
- return SMBUS_ERROR;
-
- return smbus_wait(smbus_io_base);
-}
-
-static void _doread(unsigned smbus_io_base, unsigned char device,
- unsigned char address, unsigned char *data, int count)
-{
- int ret;
- int index = 0;
- unsigned char val;
-
- if ((ret = smbus_check_stop_condition(smbus_io_base)))
- goto err;
-
- index++;
-
- if ((ret = smbus_start_condition(smbus_io_base)))
- goto err;
-
- index++; /* 2 */
- if ((ret = smbus_send_slave_address(smbus_io_base, device)))
- goto err;
-
- index++;
- if ((ret = smbus_send_command(smbus_io_base, address)))
- goto err;
-
- index++;
- if ((ret = smbus_start_condition(smbus_io_base)))
- goto err;
-
- /* Clear the ack for multiple byte reads */
- smbus_ack(smbus_io_base, (count == 1) ? 1 : 0);
-
- index++;
- if ((ret = smbus_send_slave_address(smbus_io_base, device | 0x01)))
- goto err;
-
- while (count) {
- /* Set the ACK if this is the next to last byte */
- smbus_ack(smbus_io_base, (count == 2) ? 1 : 0);
-
- /* Set the stop bit if this is the last byte to read */
-
- if (count == 1)
- smbus_stop_condition(smbus_io_base);
-
- val = inb(smbus_io_base + SMB_SDA);
- *data++ = val;
-
- if (count > 1) {
- ret = smbus_wait(smbus_io_base);
- if (ret)
- return;
- }
-
- count--;
- }
-
- return;
-
- err:
- printk(BIOS_DEBUG, "SMBUS READ ERROR (%d): %d\n", index, ret);
-}
-
-static inline unsigned char do_smbus_read_byte(unsigned smbus_io_base,
- unsigned char device, unsigned char address)
-{
- unsigned char val = 0;
- _doread(smbus_io_base, device, address, &val, sizeof(val));
- return val;
-}
-
-static inline unsigned short do_smbus_read_word(unsigned smbus_io_base,
- unsigned char device, unsigned char address)
-{
- unsigned short val = 0;
- _doread(smbus_io_base, device, address, (unsigned char *)&val,
- sizeof(val));
- return val;
-}
-
-static int _dowrite(unsigned smbus_io_base, unsigned char device,
- unsigned char address, unsigned char *data, int count)
-{
-
- int ret;
-
- if ((ret = smbus_check_stop_condition(smbus_io_base)))
- goto err;
-
- if ((ret = smbus_start_condition(smbus_io_base)))
- goto err;
-
- if ((ret = smbus_send_slave_address(smbus_io_base, device)))
- goto err;
-
- if ((ret = smbus_send_command(smbus_io_base, address)))
- goto err;
-
- while (count) {
- if ((ret = smbus_write(smbus_io_base, *data++)))
- goto err;
- count--;
- }
-
- smbus_stop_condition(smbus_io_base);
- return 0;
-
- err:
- printk(BIOS_DEBUG, "SMBUS WRITE ERROR: %d\n", ret);
- return -1;
-}
-
-static inline int do_smbus_write_byte(unsigned smbus_io_base,
- unsigned char device, unsigned char address, unsigned char data)
-{
- return _dowrite(smbus_io_base, device, address,
- (unsigned char *)&data, 1);
-}
-
-static inline int do_smbus_write_word(unsigned smbus_io_base,
- unsigned char device, unsigned char address, unsigned short data)
-{
- return _dowrite(smbus_io_base, device, address, (unsigned char *)&data,
- 2);
-}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * cs5536_early_setup.c: Early chipset initialization for CS5536 companion device
+ * This file implements the initialization sequence documented in section 4.2 of
+ * AMD Geode GX Processor CS5536 Companion Device GoedeROM Porting Guide.
+ */
+
+/**
+ * @brief Setup PCI IDSEL for CS5536
+ */
+static 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);
+#endif
+ wrmsr(GLPCI_ExtMSR, msr);
+}
+
+static void cs5536_setup_idsel(void)
+{
+ /* write IDSEL to the write once register at address 0x0000 */
+ outl(0x1 << (CS5536_DEV_NUM + 10), 0);
+}
+
+static void cs5536_usb_swapsif(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(USB1_SB_GLD_MSR_CAP + 0x5);
+ //USB Serial short detect bit.
+ if (msr.hi & 0x10) {
+ /* We need to preserve bits 32,33,35 and not clear any BIST
+ * error, but clear the SERSHRT error bit */
+
+ msr.hi &= 0xFFFFFFFB;
+ wrmsr(USB1_SB_GLD_MSR_CAP + 0x5, msr);
+ }
+}
+
+static void cs5536_setup_iobase(void)
+{
+ msr_t msr;
+ /* setup LBAR for SMBus controller */
+ msr.hi = 0x0000f001;
+ msr.lo = SMBUS_IO_BASE;
+ wrmsr(MDD_LBAR_SMB, msr);
+
+ /* setup LBAR for GPIO */
+ msr.hi = 0x0000f001;
+ msr.lo = GPIO_IO_BASE;
+ wrmsr(MDD_LBAR_GPIO, msr);
+
+ /* setup LBAR for MFGPT */
+ msr.hi = 0x0000f001;
+ msr.lo = MFGPT_IO_BASE;
+ wrmsr(MDD_LBAR_MFGPT, msr);
+
+ /* setup LBAR for ACPI */
+ msr.hi = 0x0000f001;
+ msr.lo = ACPI_IO_BASE;
+ wrmsr(MDD_LBAR_ACPI, msr);
+
+ /* setup LBAR for PM Support */
+ msr.hi = 0x0000f001;
+ msr.lo = PMS_IO_BASE;
+ wrmsr(MDD_LBAR_PMS, msr);
+}
+
+static void cs5536_setup_power_button(void)
+{
+#if CONFIG_ENABLE_POWER_BUTTON
+ outl(0x40020000, PMS_IO_BASE + 0x40);
+#endif
+
+ /* setup WORK_AUX/GPIO24, it is the external signal for 5536
+ * vsb_work_aux controls all voltage rails except Vstandby & Vmem.
+ * We need to enable, OUT_AUX1 and OUTPUT_ENABLE in this order.
+ * If WORK_AUX/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);
+
+}
+
+static void cs5536_setup_gpio(void)
+{
+ uint32_t val;
+
+ /* setup GPIO pins 14/15 for SDA/SCL */
+ val = GPIOL_15_SET | GPIOL_14_SET;
+ /* Output Enable */
+ outl(val, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
+ /* Output AUX1 */
+ outl(val, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
+ /* Input Enable */
+ outl(val, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
+ /* Input AUX1 */
+ outl(val, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
+}
+
+void cs5536_disable_internal_uart(void)
+{
+ msr_t msr;
+ /* The UARTs default to enabled.
+ * Disable and reset them and configure them later. (SIO init)
+ */
+ msr = rdmsr(MDD_UART1_CONF);
+ msr.lo = 1; // reset
+ wrmsr(MDD_UART1_CONF, msr);
+ msr.lo = 0; // disabled
+ wrmsr(MDD_UART1_CONF, msr);
+
+ msr = rdmsr(MDD_UART2_CONF);
+ msr.lo = 1; // reset
+ wrmsr(MDD_UART2_CONF, msr);
+ msr.lo = 0; // disabled
+ wrmsr(MDD_UART2_CONF, msr);
+}
+
+static void cs5536_setup_cis_mode(void)
+{
+ msr_t msr;
+
+ /* setup CPU interface serial to mode B to match CPU */
+ msr = rdmsr(GLPCI_SB_CTRL);
+ msr.lo &= ~0x18;
+ msr.lo |= 0x10;
+ wrmsr(GLPCI_SB_CTRL, msr);
+}
+
+/**
+ * Enable the on-chip UART.
+ *
+ * See page 412 of the AMD Geode CS5536 Companion Device data book.
+ */
+static void cs5536_setup_onchipuart1(void)
+{
+ msr_t msr;
+
+ /* Setup early for polling only mode.
+ * 1. Enable GPIO 8 to OUT_AUX1, 9 to IN_AUX1.
+ * GPIO LBAR + 0x04, LBAR + 0x10, LBAR + 0x20, LBAR + 34
+ * 2. Enable UART I/O space in MDD.
+ * MSR 0x51400014 bit 18:16
+ * 3. Enable UART controller.
+ * MSR 0x5140003A bit 0, 1
+ */
+
+ /* GPIO8 - UART1_TX */
+ /* Set: Output Enable (0x4) */
+ outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
+ /* Set: OUTAUX1 Select (0x10) */
+ outl(GPIOL_8_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
+
+ /* GPIO9 - UART1_RX */
+ /* Set: Input Enable (0x20) */
+ outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
+ /* Set: INAUX1 Select (0x34) */
+ outl(GPIOL_9_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
+
+ /* Set address to 0x3F8. */
+ msr = rdmsr(MDD_LEG_IO);
+ msr.lo |= 0x7 << 16;
+ wrmsr(MDD_LEG_IO, msr);
+
+ /* Bit 1 = DEVEN (device enable)
+ * Bit 4 = EN_BANKS (allow access to the upper banks)
+ */
+ msr.lo = (1 << 4) | (1 << 1);
+ msr.hi = 0;
+
+ /* Enable COM1. */
+ wrmsr(MDD_UART1_CONF, msr);
+}
+
+static void cs5536_setup_onchipuart2(void)
+{
+ msr_t msr;
+
+ /* GPIO4 - UART2_TX */
+ /* Set: Output Enable (0x4) */
+ outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUTPUT_ENABLE);
+ /* Set: OUTAUX1 Select (0x10) */
+ outl(GPIOL_4_SET, GPIO_IO_BASE + GPIOL_OUT_AUX1_SELECT);
+ /* GPIO4 - UART2_RX */
+ /* Set: Input Enable (0x20) */
+ outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_INPUT_ENABLE);
+ /* Set: INAUX1 Select (0x34) */
+ outl(GPIOL_3_SET, GPIO_IO_BASE + GPIOL_IN_AUX1_SELECT);
+
+ /* Set: GPIO 3 + 3 Pull Up (0x18) */
+ outl(GPIOL_3_SET | GPIOL_4_SET,
+ GPIO_IO_BASE + GPIOL_PULLUP_ENABLE);
+
+ /* set address to 2F8 */
+ msr = rdmsr(MDD_LEG_IO);
+ msr.lo |= 0x5 << 20;
+ wrmsr(MDD_LEG_IO, msr);
+
+ /* Bit 1 = DEVEN (device enable)
+ * Bit 4 = EN_BANKS (allow access to the upper banks
+ */
+ msr.lo = (1 << 4) | (1 << 1);
+ msr.hi = 0;
+
+ /* enable COM2 */
+ wrmsr(MDD_UART2_CONF, msr);
+}
+
+void cs5536_setup_onchipuart(int uart)
+{
+ switch (uart) {
+ case 1:
+ cs5536_setup_onchipuart1();
+ break;
+ case 2:
+ cs5536_setup_onchipuart2();
+ break;
+ }
+}
+
+
+/* note: you can't do prints in here in most cases,
+ * and we don't want to hang on serial, so they are
+ * commented out
+ */
+static void cs5536_early_setup(void)
+{
+ msr_t msr;
+
+ cs5536_setup_extmsr();
+ cs5536_setup_cis_mode();
+
+ msr = rdmsr(GLCP_SYS_RSTPLL);
+ if (msr.lo & (0x3f << 26)) {
+ /* PLL is already set and we are reboot from PLL reset */
+ //print_debug("reboot from BIOS reset\n");
+ return;
+ }
+ //print_debug("Setup idsel\n");
+ cs5536_setup_idsel();
+ //print_debug("Setup iobase\n");
+ cs5536_usb_swapsif();
+ cs5536_setup_iobase();
+ //print_debug("Setup gpio\n");
+ cs5536_setup_gpio();
+ //print_debug("Setup smbus\n");
+ cs5536_enable_smbus();
+ //print_debug("Setup power button\n");
+ cs5536_setup_power_button();
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "cs5536.h"
+
+#define SMBUS_ERROR -1
+#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
+#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
+#define SMBUS_TIMEOUT (1000)
+
+/* initialization for SMBus Controller */
+static void cs5536_enable_smbus(void)
+{
+
+ /* Set SCL freq and enable SMB controller */
+ /*outb((0x20 << 1) | SMB_CTRL2_ENABLE, smbus_io_base + SMB_CTRL2); */
+ outb((0x7F << 1) | SMB_CTRL2_ENABLE, SMBUS_IO_BASE + SMB_CTRL2);
+
+ /* Setup SMBus host controller address to 0xEF */
+ outb((0xEF | SMB_ADD_SAEN), SMBUS_IO_BASE + SMB_ADD);
+
+}
+
+static void smbus_delay(void)
+{
+ /* inb(0x80); */
+}
+
+static int smbus_wait(unsigned smbus_io_base)
+{
+ unsigned long loops = SMBUS_TIMEOUT;
+ unsigned char val;
+
+ do {
+ smbus_delay();
+ val = inb(smbus_io_base + SMB_STS);
+ if ((val & SMB_STS_SDAST) != 0)
+ break;
+ if (val & (SMB_STS_BER | SMB_STS_NEGACK)) {
+ /*printk(BIOS_DEBUG, "SMBUS WAIT ERROR %x\n", val); */
+ return SMBUS_ERROR;
+ }
+ } while (--loops);
+ return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+}
+
+/* generate a smbus start condition */
+static int smbus_start_condition(unsigned smbus_io_base)
+{
+ unsigned char val;
+
+ /* issue a START condition */
+ val = inb(smbus_io_base + SMB_CTRL1);
+ outb(val | SMB_CTRL1_START, smbus_io_base + SMB_CTRL1);
+
+ /* check for bus conflict */
+ val = inb(smbus_io_base + SMB_STS);
+ if ((val & SMB_STS_BER) != 0)
+ return SMBUS_ERROR;
+
+ return smbus_wait(smbus_io_base);
+}
+
+static int smbus_check_stop_condition(unsigned smbus_io_base)
+{
+ unsigned char val;
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ /* check for SDA status */
+ do {
+ smbus_delay();
+ val = inb(smbus_io_base + SMB_CTRL1);
+ if ((val & SMB_CTRL1_STOP) == 0) {
+ break;
+ }
+ outb((0x7F << 1) | SMB_CTRL2_ENABLE, smbus_io_base + SMB_CTRL2);
+ } while (--loops);
+ return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+}
+
+static int smbus_stop_condition(unsigned smbus_io_base)
+{
+ outb(SMB_CTRL1_STOP, smbus_io_base + SMB_CTRL1);
+ return smbus_wait(smbus_io_base);
+}
+
+static int smbus_ack(unsigned smbus_io_base, int state)
+{
+ unsigned char val = inb(smbus_io_base + SMB_CTRL1);
+
+/* if (state) */
+ outb(val | SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
+/* else
+ outb(val & ~SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
+*/
+ return 0;
+}
+
+static int smbus_send_slave_address(unsigned smbus_io_base,
+ unsigned char device)
+{
+ unsigned char val;
+
+ /* send the slave address */
+ outb(device, smbus_io_base + SMB_SDA);
+
+ /* check for bus conflict and NACK */
+ val = inb(smbus_io_base + SMB_STS);
+ if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0)) {
+ /* printk(BIOS_DEBUG, "SEND SLAVE ERROR (%x)\n", val); */
+ return SMBUS_ERROR;
+ }
+ return smbus_wait(smbus_io_base);
+}
+
+static int smbus_send_command(unsigned smbus_io_base, unsigned char command)
+{
+ unsigned char val;
+
+ /* send the command */
+ outb(command, smbus_io_base + SMB_SDA);
+
+ /* check for bus conflict and NACK */
+ val = inb(smbus_io_base + SMB_STS);
+ if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0))
+ return SMBUS_ERROR;
+
+ return smbus_wait(smbus_io_base);
+}
+
+static unsigned char smbus_get_result(unsigned smbus_io_base)
+{
+ return inb(smbus_io_base + SMB_SDA);
+}
+
+static unsigned char do_smbus_read_byte(unsigned smbus_io_base,
+ unsigned char device,
+ unsigned char address)
+{
+ unsigned char error = 0;
+
+ if ((smbus_check_stop_condition(smbus_io_base))) {
+ error = 1;
+ goto err;
+ }
+
+ if ((smbus_start_condition(smbus_io_base))) {
+ error = 2;
+ goto err;
+ }
+
+ if ((smbus_send_slave_address(smbus_io_base, device << 1))) {
+ error = 3;
+ goto err;
+ }
+
+ smbus_ack(smbus_io_base, 1);
+
+ if ((smbus_send_command(smbus_io_base, address))) {
+ error = 4;
+ goto err;
+ }
+
+ if ((smbus_start_condition(smbus_io_base))) {
+ error = 5;
+ goto err;
+ }
+
+ if ((smbus_send_slave_address(smbus_io_base, (device << 1) | 0x01))) {
+ error = 6;
+ goto err;
+ }
+
+ if ((smbus_stop_condition(smbus_io_base))) {
+ error = 7;
+ goto err;
+ }
+
+ return smbus_get_result(smbus_io_base);
+
+ err:
+ print_debug("SMBUS READ ERROR:");
+ print_debug_hex8(error);
+ print_debug(" device:");
+ print_debug_hex8(device);
+ print_debug("\n");
+ /* stop, clean up the error, and leave */
+ smbus_stop_condition(smbus_io_base);
+ outb(inb(smbus_io_base + SMB_STS), smbus_io_base + SMB_STS);
+ outb(0x0, smbus_io_base + SMB_STS);
+ return 0xFF;
+}
+
+static inline int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "cs5536.h"
+
+#define IDE_CFG 0x40
+ #define CHANEN (1L << 1)
+ #define PWB (1L << 14)
+ #define CABLE (1L << 16)
+#define IDE_DTC 0x48
+#define IDE_CAST 0x4C
+#define IDE_ETC 0x50
+
+static void ide_init(struct device *dev)
+{
+ uint32_t ide_cfg;
+
+ printk(BIOS_SPEW, "cs5536_ide: %s\n", __func__);
+ /* GPIO and IRQ setup are handled in the main chipset code. */
+
+ // Enable the channel and Post Write Buffer
+ // NOTE: Only 32-bit writes to the data buffer are allowed when PWB is set
+ ide_cfg = pci_read_config32(dev, IDE_CFG);
+ ide_cfg |= CHANEN | PWB;
+ pci_write_config32(dev, IDE_CFG, ide_cfg);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = 0,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_CS5536_B0_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/pirq_routing.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
+void pirq_assign_irqs(const unsigned char pIntAtoD[4])
+{
+ device_t pdev;
+
+ pdev = dev_find_device(PCI_VENDOR_ID_AMD,
+ PCI_DEVICE_ID_AMD_CS5536_ISA, 0);
+
+ if (pdev) {
+ pci_write_config16(pdev, 0x5c, (pIntAtoD[3] << 12
+ | pIntAtoD[2] << 8 | pIntAtoD[1] << 4 | pIntAtoD[0]));
+ }
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define SMBUS_ERROR -1
+#define SMBUS_WAIT_UNTIL_READY_TIMEOUT -2
+#define SMBUS_WAIT_UNTIL_DONE_TIMEOUT -3
+
+#define SMB_SDA 0x00
+#define SMB_STS 0x01
+#define SMB_CTRL_STS 0x02
+#define SMB_CTRL1 0x03
+#define SMB_ADD 0x04
+#define SMB_CTRL2 0x05
+#define SMB_CTRL3 0x06
+
+#define SMB_STS_SLVSTP (0x01 << 7)
+#define SMB_STS_SDAST (0x01 << 6)
+#define SMB_STS_BER (0x01 << 5)
+#define SMB_STS_NEGACK (0x01 << 4)
+#define SMB_STS_STASTR (0x01 << 3)
+#define SMB_STS_NMATCH (0x01 << 2)
+#define SMB_STS_MASTER (0x01 << 1)
+#define SMB_STS_XMIT (0x01 << 0)
+
+#define SMB_CSTS_TGSCL (0x01 << 5)
+#define SMB_CSTS_TSDA (0x01 << 4)
+#define SMB_CSTS_GCMTCH (0x01 << 3)
+#define SMB_CSTS_MATCH (0x01 << 2)
+#define SMB_CSTS_BB (0x01 << 1)
+#define SMB_CSTS_BUSY (0x01 << 0)
+
+#define SMB_CTRL1_STASTRE (0x01 << 7)
+#define SMB_CTRL1_NMINTE (0x01 << 6)
+#define SMB_CTRL1_GCMEN (0x01 << 5)
+#define SMB_CTRL1_ACK (0x01 << 4)
+#define SMB_CTRL1_RSVD (0x01 << 3)
+#define SMB_CTRL1_INTEN (0x01 << 2)
+#define SMB_CTRL1_STOP (0x01 << 1)
+#define SMB_CTRL1_START (0x01 << 0)
+
+#define SMB_ADD_SAEN (0x01 << 7)
+
+#define SMB_CTRL2_ENABLE 0x01
+
+#define SMBUS_TIMEOUT (100*1000*10)
+#define SMBUS_STATUS_MASK 0xfbff
+
+static void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+static int smbus_wait(unsigned smbus_io_base)
+{
+ unsigned long loops = SMBUS_TIMEOUT;
+ unsigned char val;
+
+ do {
+ smbus_delay();
+ val = inb(smbus_io_base + SMB_STS);
+ if ((val & SMB_STS_SDAST) != 0)
+ break;
+ if (val & (SMB_STS_BER | SMB_STS_NEGACK)) {
+ printk(BIOS_DEBUG, "SMBUS WAIT ERROR %x\n", val);
+ return SMBUS_ERROR;
+ }
+ } while (--loops);
+
+ outb(0, smbus_io_base + SMB_STS);
+ return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+}
+
+static int smbus_write(unsigned smbus_io_base, unsigned char byte)
+{
+
+ outb(byte, smbus_io_base + SMB_SDA);
+ return smbus_wait(smbus_io_base);
+}
+
+/* generate a smbus start condition */
+static int smbus_start_condition(unsigned smbus_io_base)
+{
+ unsigned char val;
+
+ /* issue a START condition */
+ val = inb(smbus_io_base + SMB_CTRL1);
+ outb(val | SMB_CTRL1_START, smbus_io_base + SMB_CTRL1);
+
+ /* check for bus conflict */
+ val = inb(smbus_io_base + SMB_STS);
+ if ((val & SMB_STS_BER) != 0)
+ return SMBUS_ERROR;
+
+ return smbus_wait(smbus_io_base);
+}
+
+static int smbus_check_stop_condition(unsigned smbus_io_base)
+{
+ unsigned char val;
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ /* check for SDA status */
+ do {
+ smbus_delay();
+ val = inb(smbus_io_base + SMB_CTRL1);
+ if ((val & SMB_CTRL1_STOP) == 0) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+
+ /* Make sure everything is cleared and ready to go */
+
+ val = inb(smbus_io_base + SMB_CTRL1);
+ outb(val & ~(SMB_CTRL1_STASTRE | SMB_CTRL1_NMINTE),
+ smbus_io_base + SMB_CTRL1);
+
+ outb(SMB_STS_BER | SMB_STS_NEGACK | SMB_STS_STASTR,
+ smbus_io_base + SMB_STS);
+
+ val = inb(smbus_io_base + SMB_CTRL_STS);
+ outb(val | SMB_CSTS_BB, smbus_io_base + SMB_CTRL_STS);
+}
+
+static int smbus_stop_condition(unsigned smbus_io_base)
+{
+ unsigned char val;
+ val = inb(smbus_io_base + SMB_CTRL1);
+ outb(SMB_CTRL1_STOP, smbus_io_base + SMB_CTRL1);
+
+ return 0;
+}
+
+static int smbus_ack(unsigned smbus_io_base, int state)
+{
+ unsigned char val = inb(smbus_io_base + SMB_CTRL1);
+
+ if (state)
+ outb(val | SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
+ else
+ outb(val & ~SMB_CTRL1_ACK, smbus_io_base + SMB_CTRL1);
+
+ return 0;
+}
+
+static int smbus_send_slave_address(unsigned smbus_io_base,
+ unsigned char device)
+{
+ unsigned char val;
+
+ /* send the slave address */
+ outb(device, smbus_io_base + SMB_SDA);
+
+ /* check for bus conflict and NACK */
+ val = inb(smbus_io_base + SMB_STS);
+ if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0)) {
+ printk(BIOS_DEBUG, "SEND SLAVE ERROR (%x)\n", val);
+ return SMBUS_ERROR;
+ }
+ return smbus_wait(smbus_io_base);
+}
+
+static int smbus_send_command(unsigned smbus_io_base, unsigned char command)
+{
+ unsigned char val;
+
+ /* send the command */
+ outb(command, smbus_io_base + SMB_SDA);
+
+ /* check for bus conflict and NACK */
+ val = inb(smbus_io_base + SMB_STS);
+ if (((val & SMB_STS_BER) != 0) || ((val & SMB_STS_NEGACK) != 0))
+ return SMBUS_ERROR;
+
+ return smbus_wait(smbus_io_base);
+}
+
+static void _doread(unsigned smbus_io_base, unsigned char device,
+ unsigned char address, unsigned char *data, int count)
+{
+ int ret;
+ int index = 0;
+ unsigned char val;
+
+ if ((ret = smbus_check_stop_condition(smbus_io_base)))
+ goto err;
+
+ index++;
+
+ if ((ret = smbus_start_condition(smbus_io_base)))
+ goto err;
+
+ index++; /* 2 */
+ if ((ret = smbus_send_slave_address(smbus_io_base, device)))
+ goto err;
+
+ index++;
+ if ((ret = smbus_send_command(smbus_io_base, address)))
+ goto err;
+
+ index++;
+ if ((ret = smbus_start_condition(smbus_io_base)))
+ goto err;
+
+ /* Clear the ack for multiple byte reads */
+ smbus_ack(smbus_io_base, (count == 1) ? 1 : 0);
+
+ index++;
+ if ((ret = smbus_send_slave_address(smbus_io_base, device | 0x01)))
+ goto err;
+
+ while (count) {
+ /* Set the ACK if this is the next to last byte */
+ smbus_ack(smbus_io_base, (count == 2) ? 1 : 0);
+
+ /* Set the stop bit if this is the last byte to read */
+
+ if (count == 1)
+ smbus_stop_condition(smbus_io_base);
+
+ val = inb(smbus_io_base + SMB_SDA);
+ *data++ = val;
+
+ if (count > 1) {
+ ret = smbus_wait(smbus_io_base);
+ if (ret)
+ return;
+ }
+
+ count--;
+ }
+
+ return;
+
+ err:
+ printk(BIOS_DEBUG, "SMBUS READ ERROR (%d): %d\n", index, ret);
+}
+
+static inline unsigned char do_smbus_read_byte(unsigned smbus_io_base,
+ unsigned char device, unsigned char address)
+{
+ unsigned char val = 0;
+ _doread(smbus_io_base, device, address, &val, sizeof(val));
+ return val;
+}
+
+static inline unsigned short do_smbus_read_word(unsigned smbus_io_base,
+ unsigned char device, unsigned char address)
+{
+ unsigned short val = 0;
+ _doread(smbus_io_base, device, address, (unsigned char *)&val,
+ sizeof(val));
+ return val;
+}
+
+static int _dowrite(unsigned smbus_io_base, unsigned char device,
+ unsigned char address, unsigned char *data, int count)
+{
+
+ int ret;
+
+ if ((ret = smbus_check_stop_condition(smbus_io_base)))
+ goto err;
+
+ if ((ret = smbus_start_condition(smbus_io_base)))
+ goto err;
+
+ if ((ret = smbus_send_slave_address(smbus_io_base, device)))
+ goto err;
+
+ if ((ret = smbus_send_command(smbus_io_base, address)))
+ goto err;
+
+ while (count) {
+ if ((ret = smbus_write(smbus_io_base, *data++)))
+ goto err;
+ count--;
+ }
+
+ smbus_stop_condition(smbus_io_base);
+ return 0;
+
+ err:
+ printk(BIOS_DEBUG, "SMBUS WRITE ERROR: %d\n", ret);
+ return -1;
+}
+
+static inline int do_smbus_write_byte(unsigned smbus_io_base,
+ unsigned char device, unsigned char address, unsigned char data)
+{
+ return _dowrite(smbus_io_base, device, address,
+ (unsigned char *)&data, 1);
+}
+
+static inline int do_smbus_write_word(unsigned smbus_io_base,
+ unsigned char device, unsigned char address, unsigned short data)
+{
+ return _dowrite(smbus_io_base, device, address, (unsigned char *)&data,
+ 2);
+}
driver-y += rs690.c
-driver-y += rs690_cmn.c
-driver-y += rs690_pcie.c
-driver-y += rs690_ht.c
-driver-y += rs690_gfx.c
+driver-y += cmn.c
+driver-y += pcie.c
+driver-y += ht.c
+driver-y += gfx.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+
+#include <arch/io.h>
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <boot/coreboot_tables.h>
+#include <delay.h>
+#include "rs690.h"
+
+static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
+{
+ pci_write_config32(dev, index_reg, index);
+ return pci_read_config32(dev, index_reg + 0x4);
+}
+
+static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
+{
+
+ pci_write_config32(dev, index_reg, index);
+ pci_write_config32(dev, index_reg + 0x4, data);
+
+}
+
+/* extension registers */
+u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
+{
+ /*get BAR3 base address for nbcfg0x1c */
+ u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
+ printk(BIOS_DEBUG, "addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
+ dev->path.pci.devfn);
+ addr |= dev->bus->secondary << 20 | /* bus num */
+ dev->path.pci.devfn << 12 | reg;
+ return *((u32 *) addr);
+}
+
+void pci_ext_write_config32(device_t nb_dev, device_t dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+
+ /*get BAR3 base address for nbcfg0x1c */
+ u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
+ /*printk(BIOS_DEBUG, "write: addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
+ dev->path.pci.devfn);*/
+ addr |= dev->bus->secondary << 20 | /* bus num */
+ dev->path.pci.devfn << 12 | reg_pos;
+
+ reg = reg_old = *((u32 *) addr);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ *((u32 *) addr) = reg;
+ }
+}
+
+u32 nbmisc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMISC_INDEX, (index));
+}
+
+void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
+}
+
+u32 nbpcie_p_read_index(device_t dev, u32 index)
+{
+ return nb_read_index((dev), NBPCIE_INDEX, (index));
+}
+
+void nbpcie_p_write_index(device_t dev, u32 index, u32 data)
+{
+ nb_write_index((dev), NBPCIE_INDEX, (index), (data));
+}
+
+u32 nbpcie_ind_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBPCIE_INDEX, (index));
+}
+
+void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBPCIE_INDEX, (index), (data));
+}
+
+u32 htiu_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
+}
+
+void htiu_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
+}
+
+u32 nbmc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMC_INDEX, (index));
+}
+
+void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
+}
+
+void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = pci_read_config32(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config32(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask, u8 val)
+{
+ u8 reg_old, reg;
+ reg = reg_old = pci_read_config8(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config8(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = htiu_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ htiu_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmisc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_pcie_enable_bits(device_t dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nb_read_index(dev, NBPCIE_INDEX, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nb_write_index(dev, NBPCIE_INDEX, reg_pos, reg);
+ }
+}
+
+/***********************************************************
+* To access bar3 we need to program PCI MMIO 7 in K8.
+* in_out:
+* 1: enable/enter k8 temp mmio base
+* 0: disable/restore
+***********************************************************/
+void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
+{
+ /* K8 Function1 is address map */
+ device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+
+ if (in_out) {
+ u32 dword, sblk;
+
+ /* Get SBLink value (HyperTransport I/O Hub Link ID). */
+ dword = pci_read_config32(k8_f0, 0x64);
+ sblk = (dword >> 8) & 0x3;
+
+ /* Fill MMIO limit/base pair. */
+ pci_write_config32(k8_f1, 0xbc,
+ (((pcie_base_add + 0x10000000 -
+ 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
+ pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
+ pci_write_config32(k8_f1, 0xb4,
+ (((mmio_base_add + 0x10000000 -
+ 1) >> 8) & 0xffffff00) | (sblk << 4));
+ pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
+ } else {
+ pci_write_config32(k8_f1, 0xb8, 0);
+ pci_write_config32(k8_f1, 0xbc, 0);
+ pci_write_config32(k8_f1, 0xb0, 0);
+ pci_write_config32(k8_f1, 0xb4, 0);
+ }
+}
+
+void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port)
+{
+ switch (port) {
+ case 2: /* GFX, bit4-5 */
+ case 3:
+ set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
+ 1 << (port + 2), 0 << (port + 2));
+ break;
+ case 4: /* GPP, bit20-24 */
+ case 5:
+ case 6:
+ case 7:
+ set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
+ 1 << (port + 17), 0 << (port + 17));
+ break;
+ }
+}
+
+/********************************************************************************************************
+* Output:
+* 0: no device is present.
+* 1: device is present and is trained.
+********************************************************************************************************/
+u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port)
+{
+ u16 count = 5000;
+ u32 lc_state, reg;
+ int8_t current, res = 0;
+
+ while (count--) {
+ mdelay(40);
+ udelay(200);
+ lc_state = nbpcie_p_read_index(dev, 0xa5); /* lc_state */
+ printk(BIOS_DEBUG, "PcieLinkTraining port=%x:lc current state=%x\n",
+ port, lc_state);
+ current = lc_state & 0x3f; /* get LC_CURRENT_STATE, bit0-5 */
+
+ switch (current) {
+ case 0x00: /* 0x00-0x04 means no device is present */
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ res = 0;
+ count = 0;
+ break;
+ case 0x07: /* device is in compliance state (training sequence is doen). Move to train the next device */
+ res = 1; /* TODO: CIM sets it to 0 */
+ count = 0;
+ break;
+ case 0x10:
+ reg =
+ pci_ext_read_config32(nb_dev, dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ printk(BIOS_DEBUG, "PcieTrainPort reg=0x%x\n", reg);
+ /* check bit1 */
+ if (reg & VC_NEGOTIATION_PENDING) { /* bit1=1 means the link needs to be re-trained. */
+ /* set bit8=1, bit0-2=bit4-6 */
+ u32 tmp;
+ reg =
+ nbpcie_p_read_index(dev,
+ PCIE_LC_LINK_WIDTH);
+ tmp = (reg >> 4) && 0x3; /* get bit4-6 */
+ reg &= 0xfff8; /* clear bit0-2 */
+ reg += tmp; /* merge */
+ reg |= 1 << 8;
+ count++; /* CIM said "keep in loop"? */
+ } else {
+ res = 1;
+ count = 0;
+ }
+ break;
+ default: /* reset pcie */
+ res = 0;
+ count = 0; /* break loop */
+ break;
+ }
+ }
+ return res;
+}
+
+/*
+* Compliant with CIM_33's ATINB_SetToms.
+* Set Top Of Memory below and above 4G.
+*/
+void rs690_set_tom(device_t nb_dev)
+{
+ extern uint64_t uma_memory_base;
+
+ /* set TOM */
+ pci_write_config32(nb_dev, 0x90, uma_memory_base);
+ nbmc_write_index(nb_dev, 0x1e, uma_memory_base);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008 Carl-Daniel Hailfinger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#define NBHTIU_INDEX 0xA8
+#define NBMISC_INDEX 0x60
+#define NBMC_INDEX 0xE8
+
+static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
+{
+ pci_write_config32(dev, index_reg, index);
+ return pci_read_config32(dev, index_reg + 0x4);
+}
+
+static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
+{
+ pci_write_config32(dev, index_reg, index /* | 0x80 */ );
+ pci_write_config32(dev, index_reg + 0x4, data);
+}
+
+static u32 nbmisc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMISC_INDEX, (index));
+}
+
+static void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
+}
+
+static u32 htiu_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
+}
+
+static void htiu_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
+}
+
+static u32 nbmc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMC_INDEX, (index));
+}
+
+static void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
+}
+
+static void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = htiu_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ htiu_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmisc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = pci_read_config32(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config32(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask,
+ u8 val)
+{
+ u8 reg_old, reg;
+ reg = reg_old = pci_read_config8(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config8(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+/*
+* Compliant with CIM_33's ATINB_PrepareInit
+*/
+static void get_cpu_rev(void)
+{
+ u32 eax, ebx, ecx, edx;
+ __asm__ volatile ("cpuid":"=a" (eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
+ :"0"(1));
+ printk(BIOS_INFO, "get_cpu_rev EAX=0x%x.\n", eax);
+ if (eax <= 0xfff)
+ printk(BIOS_INFO, "CPU Rev is K8_Cx.\n");
+ else if (eax <= 0x10fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Dx.\n");
+ else if (eax <= 0x20fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Ex.\n");
+ else if (eax <= 0x40fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Fx.\n");
+ else if (eax == 0x60fb1 || eax == 0x60f81) /*These two IDS are exception, they are G1. */
+ printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
+ else if (eax <= 0X60FF0)
+ printk(BIOS_INFO, "CPU Rev is K8_G0.\n");
+ else if (eax <= 0x100000)
+ printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
+ else
+ printk(BIOS_INFO, "CPU Rev is K8_10.\n");
+}
+
+static u8 get_nb_rev(device_t nb_dev)
+{
+ u32 reg;
+ reg = pci_read_config32(nb_dev, 0x00);
+ if (0x7911 == (reg >> 16))
+ return 7;
+ reg = pci_read_config8(nb_dev, 0x89); /* copy from CIM, can't find in doc */
+ if (reg & 0x2) /* check bit1 */
+ return 7;
+ if (reg & 0x1) /* check bit0 */
+ return 6;
+ else
+ return 5;
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_HTInit
+* Init HT link speed/width for rs690 -- k8 link
+*****************************************/
+static void rs690_htinit(void)
+{
+ /*
+ * About HT, it has been done in enumerate_ht_chain().
+ */
+ device_t k8_f0, rs690_f0;
+ u32 reg;
+ u8 reg8;
+ u8 k8_ht_freq;
+
+ k8_f0 = PCI_DEV(0, 0x18, 0);
+ /************************
+ * get k8's ht freq, in k8's function 0, offset 0x88
+ * bit11-8, specifics the maximum operation frequency of the link's transmitter clock.
+ * The link frequency field (Frq) is cleared by cold reset. SW can write a nonzero
+ * value to this reg, and that value takes effect on the next warm reset or
+ * LDTSTOP_L disconnect sequence.
+ * 0000b = 200Mhz
+ * 0010b = 400Mhz
+ * 0100b = 600Mhz
+ * 0101b = 800Mhz
+ * 0110b = 1Ghz
+ * 1111b = 1Ghz
+ ************************/
+ reg = pci_read_config32(k8_f0, 0x88);
+ k8_ht_freq = (reg & 0xf00) >> 8;
+ printk(BIOS_SPEW, "rs690_htinit k8_ht_freq=%x.\n", k8_ht_freq);
+ rs690_f0 = PCI_DEV(0, 0, 0);
+ reg8 = pci_read_config8(rs690_f0, 0x9c);
+ printk(BIOS_SPEW, "rs690_htinit NB_CFG_Q_F1000_800=%x\n", reg8);
+ /* For 1000 MHz HT, NB_CFG_Q_F1000_800 bit 0 MUST be set.
+ * For any other HT frequency, NB_CFG_Q_F1000_800 bit 0 MUST NOT be set.
+ */
+ if (((k8_ht_freq == 0x6) || (k8_ht_freq == 0xf)) && (!(reg8 & 0x1))) {
+ printk(BIOS_INFO, "rs690_htinit setting bit 0 in NB_CFG_Q_F1000_800 to use 1 GHz HT\n");
+ reg8 |= 0x1;
+ pci_write_config8(rs690_f0, 0x9c, reg8);
+ } else if ((k8_ht_freq != 0x6) && (k8_ht_freq != 0xf) && (reg8 & 0x1)) {
+ printk(BIOS_INFO, "rs690_htinit clearing bit 0 in NB_CFG_Q_F1000_800 to not use 1 GHz HT\n");
+ reg8 &= ~0x1;
+ pci_write_config8(rs690_f0, 0x9c, reg8);
+ }
+}
+
+/*******************************************************
+* Optimize k8 with UMA.
+* See BKDG_NPT_0F guide for details.
+* The processor node is addressed by its Node ID on the HT link and can be
+* accessed with a device number in the PCI configuration space on Bus0.
+* The Node ID 0 is mapped to Device 24 (0x18), the Node ID 1 is mapped
+* to Device 25, and so on.
+* The processor implements configuration registers in PCI configuration
+* space using the following four headers
+* Function0: HT technology configuration
+* Function1: Address map configuration
+* Function2: DRAM and HT technology Trace mode configuration
+* Function3: Miscellaneous configuration
+*******************************************************/
+static void k8_optimization(void)
+{
+ device_t k8_f0, k8_f2, k8_f3;
+ msr_t msr;
+
+ printk(BIOS_INFO, "k8_optimization()\n");
+ k8_f0 = PCI_DEV(0, 0x18, 0);
+ k8_f2 = PCI_DEV(0, 0x18, 2);
+ k8_f3 = PCI_DEV(0, 0x18, 3);
+
+ pci_write_config32(k8_f0, 0x90, 0x01700178); /* CIM NPT_Optimization */
+ set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 28, 0 << 28);
+ set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 26 | 1 << 27,
+ 1 << 26 | 1 << 27);
+ set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 11, 1 << 11);
+ set_nbcfg_enable_bits(k8_f0, 0x84, 1 << 11 | 1 << 13 | 1 << 15, 1 << 11 | 1 << 13 | 1 << 15); /* TODO */
+
+ pci_write_config32(k8_f3, 0x70, 0x51320111); /* CIM NPT_Optimization */
+ pci_write_config32(k8_f3, 0x74, 0x50304021);
+ pci_write_config32(k8_f3, 0x78, 0x08002A00);
+ if (pci_read_config32(k8_f3, 0xE8) & 0x3<<12)
+ pci_write_config32(k8_f3, 0x7C, 0x0000211B); /* dual core */
+ else
+ pci_write_config32(k8_f3, 0x7C, 0x0000211C); /* single core */
+ set_nbcfg_enable_bits_8(k8_f3, 0xDC, 0xFF, 0x25);
+
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
+ set_nbcfg_enable_bits(k8_f2, 0x94, 0xF << 24, 7 << 24);
+ set_nbcfg_enable_bits(k8_f2, 0x90, 1 << 10, 1 << 10);
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 3 << 2, 3 << 2);
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
+
+ msr = rdmsr(0xC001001F);
+ msr.lo &= ~(1 << 9);
+ msr.hi &= ~(1 << 4);
+ wrmsr(0xC001001F, msr);
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_PCICFG_POR_TABLE
+*****************************************/
+static void rs690_por_pcicfg_init(device_t nb_dev)
+{
+ /* enable PCI Memory Access */
+ set_nbcfg_enable_bits_8(nb_dev, 0x04, (u8)(~0xFD), 0x02);
+ /* Set RCRB Enable */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x1);
+ /* allow decode of 640k-1MB */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xEF), 0x10);
+ /* Enable PM2_CNTL(BAR2) IO mapped cfg write access to be broadcast to both NB and SB */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x4);
+ /* Power Management Register Enable */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x80);
+
+ /* Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
+ * Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
+ * BMMsgEn */
+ set_nbcfg_enable_bits_8(nb_dev, 0x4C, (u8)(~0x00), 0x42 | 1);
+
+ /* Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
+ * Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge */
+ set_nbcfg_enable_bits_8(nb_dev, 0x4E, (u8)(~0xFF), 0x05);
+ /* Reg94h[4:0] = 0x0 P drive strength offset 0
+ * Reg94h[6:5] = 0x2 P drive strength additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x94, (u8)(~0x80), 0x40);
+
+ /* Reg94h[20:16] = 0x0 N drive strength offset 0
+ * Reg94h[22:21] = 0x2 N drive strength additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x96, (u8)(~0x80), 0x40);
+
+ /* Reg80h[4:0] = 0x0 Termination offset
+ * Reg80h[6:5] = 0x2 Termination additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x80, (u8)(~0x80), 0x40);
+
+ /* Reg80h[14] = 0x1 Enable receiver termination control */
+ set_nbcfg_enable_bits_8(nb_dev, 0x81, (u8)(~0xFF), 0x40);
+
+ /* Reg94h[15] = 0x1 Enables HT transmitter advanced features to be turned on
+ * Reg94h[14] = 0x1 Enable drive strength control */
+ set_nbcfg_enable_bits_8(nb_dev, 0x95, (u8)(~0x3F), 0xC4);
+
+ /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */
+ set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
+
+ /*Reg8Ch[10:9] = 0x3 Enables Gfx Debug BAR,
+ * force this BAR as mem type in rs690_gfx.c */
+ set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x03);
+
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_MCIndex_POR_TABLE
+*****************************************/
+static void rs690_por_mc_index_init(device_t nb_dev)
+{
+ set_nbmc_enable_bits(nb_dev, 0x7A, ~0xFFFFFF80, 0x0000005F);
+ set_nbmc_enable_bits(nb_dev, 0xD8, ~0x00000000, 0x00600060);
+ set_nbmc_enable_bits(nb_dev, 0xD9, ~0x00000000, 0x00600060);
+ set_nbmc_enable_bits(nb_dev, 0xE0, ~0x00000000, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xE1, ~0x00000000, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xE8, ~0x00000000, 0x003E003E);
+ set_nbmc_enable_bits(nb_dev, 0xE9, ~0x00000000, 0x003E003E);
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_MISCIND_POR_TABLE
+* Compliant with CIM_33's MISC_INIT_TBL
+*****************************************/
+static void rs690_por_misc_index_init(device_t nb_dev)
+{
+ /* NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
+ * Block non-snoop DMA request if PMArbDis is set.
+ * Set BMSetDis */
+ set_nbmisc_enable_bits(nb_dev, 0x0B, ~0xFFFF0000, 0x00000180);
+ set_nbmisc_enable_bits(nb_dev, 0x01, ~0xFFFFFFFF, 0x00000040);
+
+ /* NBCFG (NBMISCIND 0x0): NB_CNTL -
+ * HIDE_NB_AGP_CAP ([0], default=1)HIDE
+ * HIDE_P2P_AGP_CAP ([1], default=1)HIDE
+ * HIDE_NB_GART_BAR ([2], default=1)HIDE
+ * AGPMODE30 ([4], default=0)DISABLE
+ * AGP30ENCHANCED ([5], default=0)DISABLE
+ * HIDE_AGP_CAP ([8], default=1)ENABLE */
+ set_nbmisc_enable_bits(nb_dev, 0x00, ~0xFFFF0000, 0x00000506); /* set bit 10 for MSI */
+
+ /* NBMISCIND:0x6A[16]= 1 SB link can get a full swing
+ * set_nbmisc_enable_bits(nb_dev, 0x6A, 0ffffffffh, 000010000);
+ * NBMISCIND:0x6A[17]=1 Set CMGOOD_OVERRIDE. */
+ set_nbmisc_enable_bits(nb_dev, 0x6A, ~0xffffffff, 0x00020000);
+
+ /* NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow LVDS or PWM features to work. */
+ set_nbmisc_enable_bits(nb_dev, 0x40, ~0xffffffff, 0x00000500);
+
+ /* NBMISIND:0xC Bit[13]=1 Enable GSM mode for C1e or C3 with pop-up. */
+ set_nbmisc_enable_bits(nb_dev, 0x0C, ~0xffffffff, 0x00002000);
+
+ /* Set NBMISIND:0x1F[3] to map NB F2 interrupt pin to INTB# */
+ set_nbmisc_enable_bits(nb_dev, 0x1F, ~0xffffffff, 0x00000008);
+
+ /* Compliant with CIM_33's MISC_INIT_TBL, except Hide NB_BAR3_PCIE
+ * Enable access to DEV8
+ * Enable setPower message for all ports
+ */
+ set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 6, 1 << 6);
+ set_nbmisc_enable_bits(nb_dev, 0x0b, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x51, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x53, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x55, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x57, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x59, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x5B, 1 << 20, 1 << 20);
+
+ set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 7, 1 << 7);
+ set_nbmisc_enable_bits(nb_dev, 0x07, 0x000000f0, 0x30);
+ /* Disable bus-master trigger event from SB and Enable set_slot_power message to SB */
+ set_nbmisc_enable_bits(nb_dev, 0x0B, 0xffffffff, 0x500180);
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_HTIUNBIND_POR_TABLE
+*****************************************/
+static void rs690_por_htiu_index_init(device_t nb_dev)
+{
+ /* 0xBC:
+ * Enables GSM mode for C1e or C3 with pop-up
+ * Prevents AllowLdtStop from being asserted during HT link recovery
+ * Allows FID cycles to be serviced faster. Needed for RS690 A12. No harm in RS690 A11 */
+ set_htiu_enable_bits(nb_dev, 0x05, ~0xffffffff, 0x0BC);
+ /* 0x4203A202:
+ * Enables writes to pass in-progress reads
+ * Enables streaming of CPU writes
+ * Enables extended write buffer for CPU writes
+ * Enables additional response buffers
+ * Enables special reads to pass writes
+ * Enables decoding of C1e/C3 and FID cycles
+ * Enables HTIU-display handshake bypass.
+ * Enables tagging fix */
+ set_htiu_enable_bits(nb_dev, 0x06, ~0xFFFFFFFE, 0x4203A202);
+
+ /* Enables byte-write optimization for IOC requests
+ * Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used.
+ * Disables upstream system-management delay */
+ set_htiu_enable_bits(nb_dev, 0x07, ~0xFFFFFFF9, 0x001);
+
+ /* HTIUNBIND 0x16 [1] = 0x1 Enable crc decoding fix */
+ set_htiu_enable_bits(nb_dev, 0x16, ~0xFFFFFFFF, 0x2);
+}
+
+/*****************************************
+* Compliant with CIM_33's ATINB_POR_INIT_JMPDI
+* Configure RS690 registers to power-on default RPR.
+* POR: Power On Reset
+* RPR: Register Programming Requirements
+*****************************************/
+static void rs690_por_init(device_t nb_dev)
+{
+ printk(BIOS_INFO, "rs690_por_init\n");
+ /* ATINB_PCICFG_POR_TABLE, initialize the values for rs690 PCI Config registers */
+ rs690_por_pcicfg_init(nb_dev);
+
+ /* ATINB_MCIND_POR_TABLE */
+ rs690_por_mc_index_init(nb_dev);
+
+ /* ATINB_MISCIND_POR_TABLE */
+ rs690_por_misc_index_init(nb_dev);
+
+ /* ATINB_HTIUNBIND_POR_TABLE */
+ rs690_por_htiu_index_init(nb_dev);
+
+ /* ATINB_CLKCFG_PORT_TABLE */
+ /* rs690 A11 SB Link full swing? */
+}
+
+/* enable CFG access to Dev8, which is the SB P2P Bridge */
+static void enable_rs690_dev8(void)
+{
+ set_nbmisc_enable_bits(PCI_DEV(0, 0, 0), 0x00, 1 << 6, 1 << 6);
+}
+
+
+
+/*
+* Compliant with CIM_33's AtiNBInitEarlyPost (AtiInitNBBeforePCIInit).
+*/
+static void rs690_before_pci_init(void)
+{
+}
+
+/*
+* The calling sequence is same as CIM.
+*/
+static void rs690_early_setup(void)
+{
+ device_t nb_dev = PCI_DEV(0, 0, 0);
+ printk(BIOS_INFO, "rs690_early_setup()\n");
+
+ /*ATINB_PrepareInit */
+ get_cpu_rev();
+ switch (get_nb_rev(nb_dev)) { /* PCIEMiscInit */
+ case 5:
+ printk(BIOS_INFO, "NB Revision is A11.\n");
+ break;
+ case 6:
+ printk(BIOS_INFO, "NB Revision is A12.\n");
+ break;
+ case 7:
+ printk(BIOS_INFO, "NB Revision is A21.\n");
+ break;
+ }
+
+ k8_optimization();
+ rs690_por_init(nb_dev);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * for rs690 internal graphics device
+ * device id of internal grphics:
+ * RS690M/T: 0x791f
+ * RS690: 0x791e
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+#include "rs690.h"
+
+#define CLK_CNTL_INDEX 0x8
+#define CLK_CNTL_DATA 0xC
+
+#ifdef UNUSED_CODE
+static u32 clkind_read(device_t dev, u32 index)
+{
+ u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
+
+ *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
+ return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
+}
+#endif
+
+static void clkind_write(device_t dev, u32 index, u32 data)
+{
+ u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
+ /* printk(BIOS_INFO, "gfx bar 2 %02x\n", gfx_bar2); */
+
+ *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
+ *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
+}
+
+/*
+* pci_dev_read_resources thinks it is a IO type.
+* We have to force it to mem type.
+*/
+static void rs690_gfx_read_resources(device_t dev)
+{
+ printk(BIOS_INFO, "rs690_gfx_read_resources.\n");
+
+ /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
+ Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
+ which tells us it is a memory address base.
+ */
+ pci_write_config32(dev, 0x24, 0x00000000);
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+ compact_resources(dev);
+}
+
+static void internal_gfx_pci_dev_init(struct device *dev)
+{
+ u16 deviceid, vendorid;
+ deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
+ vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
+ printk(BIOS_INFO, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
+ deviceid, vendorid);
+
+ pci_dev_init(dev);
+
+ /* clk ind */
+ clkind_write(dev, 0x08, 0x01);
+ clkind_write(dev, 0x0C, 0x22);
+ clkind_write(dev, 0x0F, 0x0);
+ clkind_write(dev, 0x11, 0x0);
+ clkind_write(dev, 0x12, 0x0);
+ clkind_write(dev, 0x14, 0x0);
+ clkind_write(dev, 0x15, 0x0);
+ clkind_write(dev, 0x16, 0x0);
+ clkind_write(dev, 0x17, 0x0);
+ clkind_write(dev, 0x18, 0x0);
+ clkind_write(dev, 0x19, 0x0);
+ clkind_write(dev, 0x1A, 0x0);
+ clkind_write(dev, 0x1B, 0x0);
+ clkind_write(dev, 0x1C, 0x0);
+ clkind_write(dev, 0x1D, 0x0);
+ clkind_write(dev, 0x1E, 0x0);
+ clkind_write(dev, 0x26, 0x0);
+ clkind_write(dev, 0x27, 0x0);
+ clkind_write(dev, 0x28, 0x0);
+ clkind_write(dev, 0x5C, 0x0);
+}
+
+
+/*
+* Set registers in RS690 and CPU to enable the internal GFX.
+* Please refer to CIM source code and BKDG.
+*/
+static void rs690_internal_gfx_enable(device_t dev)
+{
+ u32 l_dword;
+ int i;
+ device_t k8_f0 = 0, k8_f2 = 0;
+ device_t nb_dev = dev_find_slot(0, 0);
+
+ printk(BIOS_INFO, "rs690_internal_gfx_enable dev=0x%p, nb_dev=0x%p.\n", dev,
+ nb_dev);
+
+ /* set APERTURE_SIZE, 128M. */
+ l_dword = pci_read_config32(nb_dev, 0x8c);
+ printk(BIOS_INFO, "nb_dev, 0x8c=0x%x\n", l_dword);
+ l_dword &= 0xffffff8f;
+ pci_write_config32(nb_dev, 0x8c, l_dword);
+
+ /* set TOM */
+ rs690_set_tom(nb_dev);
+
+ /* LPC DMA Deadlock workaround? */
+ k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ l_dword = pci_read_config32(k8_f0, 0x68);
+ l_dword &= ~(1 << 22);
+ l_dword |= (1 << 21);
+ pci_write_config32(k8_f0, 0x68, l_dword);
+
+ /* Enable 64bit mode. */
+ set_nbmc_enable_bits(nb_dev, 0x5f, 0, 1 << 9);
+ set_nbmc_enable_bits(nb_dev, 0xb0, 0, 1 << 8);
+
+ /* 64bit Latency. */
+ set_nbmc_enable_bits(nb_dev, 0x5f, 0x7c00, 0x800);
+
+ /* UMA dual channel control register. */
+ nbmc_write_index(nb_dev, 0x86, 0x3d);
+
+ /* check the setting later!! */
+ set_htiu_enable_bits(nb_dev, 0x07, 1 << 7, 0);
+
+ /* UMA mode, powerdown memory PLL. */
+ set_nbmc_enable_bits(nb_dev, 0x74, 0, 1 << 31);
+
+ /* Copy CPU DDR Controller to NB MC. */
+ /* Why K8_MC_REG80 is special? */
+ k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ for (i = 0; i <= (0x80 - 0x40) / 4; i++) {
+ l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
+ nbmc_write_index(nb_dev, 0x63 + i, l_dword);
+ }
+
+ /* Set K8 MC for UMA, Family F. */
+ l_dword = pci_read_config32(k8_f2, 0xa0);
+ l_dword |= 0x2c;
+ pci_write_config32(k8_f2, 0xa0, l_dword);
+ l_dword = pci_read_config32(k8_f2, 0x94);
+ l_dword &= 0xf0ffffff;
+ l_dword |= 0x07000000;
+ pci_write_config32(k8_f2, 0x94, l_dword);
+
+ /* set FB size and location. */
+ nbmc_write_index(nb_dev, 0x1b, 0x00);
+ l_dword = nbmc_read_index(nb_dev, 0x1c);
+ l_dword &= 0xffff0;
+ l_dword |= 0x400 << 20;
+ l_dword |= 0x4;
+ nbmc_write_index(nb_dev, 0x1c, l_dword);
+ l_dword = nbmc_read_index(nb_dev, 0x1d);
+ l_dword &= 0xfffff000;
+ l_dword |= 0x0400;
+ nbmc_write_index(nb_dev, 0x1d, l_dword);
+ nbmc_write_index(nb_dev, 0x100, 0x3fff3800);
+
+ /* Program MC table. */
+ set_nbmc_enable_bits(nb_dev, 0x00, 0, 1 << 31);
+ l_dword = nbmc_read_index(nb_dev, 0x91);
+ l_dword |= 0x5;
+ nbmc_write_index(nb_dev, 0x91, l_dword);
+ set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1 << 6);
+ set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1);
+
+ /* TODO: the optimization of voltage and frequency */
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = rs690_gfx_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = internal_gfx_pci_dev_init, /* The option ROM initializes the device. rs690_gfx_init, */
+ .scan_bus = 0,
+ .enable = rs690_internal_gfx_enable,
+ .ops_pci = &lops_pci,
+};
+
+/*
+ * The dev id of 690G is 791E, while the id of 690M, 690T is 791F.
+ * We should list both of them here.
+ * */
+static const struct pci_driver pcie_driver_690t __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS690MT_INT_GFX,
+};
+
+static const struct pci_driver pcie_driver_690 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS690_INT_GFX,
+};
+
+/* step 12 ~ step 14 from rpr */
+static void single_port_configuration(device_t nb_dev, device_t dev)
+{
+ u8 result, width;
+ u32 reg32;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ printk(BIOS_INFO, "rs690_gfx_init single_port_configuration.\n");
+
+ /* step 12 training, releases hold training for GFX port 0 (device 2) */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0<<4);
+ PcieReleasePortTraining(nb_dev, dev, 2);
+ result = PcieTrainPort(nb_dev, dev, 2);
+ printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step12.\n");
+
+ /* step 13 Power Down Control */
+ /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
+
+ /* step 13.a Link Training was NOT successful */
+ if (!result) {
+ set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
+ set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
+ if (cfg->gfx_tmds)
+ nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
+ else {
+ nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
+ }
+ } else { /* step 13.b Link Training was successful */
+
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ width = (reg32 >> 4) & 0x7;
+ printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
+ switch (width) {
+ case 1:
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
+ break;
+ case 4:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
+ break;
+ case 8:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
+ break;
+ }
+ }
+ printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step13.\n");
+
+ /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
+ set_pcie_enable_bits(dev, 0x70, 1 << 19, 0 << 19);
+ printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step14.\n");
+}
+
+/* step 15 ~ step 18 from rpr */
+static void dual_port_configuration(device_t nb_dev, device_t dev)
+{
+ u8 result, width;
+ u32 reg32;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ /* step 15: Training for Device 2 */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
+ /* Releases hold training for GFX port 0 (device 2) */
+ PcieReleasePortTraining(nb_dev, dev, 2);
+ /* PCIE Link Training Sequence */
+ result = PcieTrainPort(nb_dev, dev, 2);
+
+ /* step 16: Power Down Control for Device 2 */
+ /* step 16.a Link Training was NOT successful */
+ if (!result) {
+ /* Powers down all lanes for port A */
+ nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f);
+ } else { /* step 16.b Link Training was successful */
+
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ width = (reg32 >> 4) & 0x7;
+ printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
+ switch (width) {
+ case 1:
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
+ break;
+ case 4:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
+ break;
+ }
+ }
+
+ /* step 17: Training for Device 3 */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 5, 0 << 5);
+ /* Releases hold training for GFX port 0 (device 3) */
+ PcieReleasePortTraining(nb_dev, dev, 3);
+ /* PCIE Link Training Sequence */
+ result = PcieTrainPort(nb_dev, dev, 3);
+
+ /*step 18: Power Down Control for Device 3 */
+ /* step 18.a Link Training was NOT successful */
+ if (!result) {
+ /* Powers down all lanes for port B and PLL1 */
+ nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
+ } else { /* step 18.b Link Training was successful */
+
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ width = (reg32 >> 4) & 0x7;
+ printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
+ switch (width) {
+ case 1:
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x7070 : 0xe0e0);
+ break;
+ case 4:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x3030 : 0xc0c0);
+ break;
+ }
+ }
+}
+
+
+/* For single port GFX configuration Only
+* width:
+* 000 = x16
+* 001 = x1
+* 010 = x2
+* 011 = x4
+* 100 = x8
+* 101 = x12 (not supported)
+* 110 = x16
+*/
+static void dynamic_link_width_control(device_t nb_dev, device_t dev, u8 width)
+{
+ u32 reg32;
+ device_t sb_dev;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ /* step 5.9.1.1 */
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+
+ /* step 5.9.1.2 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
+ /* step 5.9.1.3 */
+ set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
+ /* step 5.9.1.4 */
+ set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
+ /* step 5.9.2.4 */
+ if (0 == cfg->gfx_reconfiguration)
+ set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
+
+ /* step 5.9.1.5 */
+ do {
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ }
+ while (reg32 & 0x100);
+
+ /* step 5.9.1.6 */
+ sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
+ do {
+ reg32 = pci_ext_read_config32(nb_dev, sb_dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ } while (reg32 & VC_NEGOTIATION_PENDING);
+
+ /* step 5.9.1.7 */
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ if (((reg32 & 0x70) >> 4) != 0x6) {
+ /* the unused lanes should be powered off. */
+ }
+
+ /* step 5.9.1.8 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
+}
+
+/*
+* GFX Core initialization, dev2, dev3
+*/
+void rs690_gfx_init(device_t nb_dev, device_t dev, u32 port)
+{
+ u16 reg16;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ printk(BIOS_INFO, "rs690_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
+ nb_dev, dev, port);
+
+ /* step 0, REFCLK_SEL, skip A11 revision */
+ set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 9,
+ cfg->gfx_dev2_dev3 ? 1 << 9 : 0 << 9);
+ printk(BIOS_INFO, "rs690_gfx_init step0.\n");
+
+ /* step 1, lane reversal (only need if CMOS option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ if (cfg->gfx_dual_slot)
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
+ }
+ printk(BIOS_INFO, "rs690_gfx_init step1.\n");
+
+ /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
+ /* AMD calls the configuration CrossFire */
+ if (cfg->gfx_dual_slot)
+ set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
+ printk(BIOS_INFO, "rs690_gfx_init step2.\n");
+
+ /* step 2, TMDS, (only need if CMOS option is enabled) */
+ if (cfg->gfx_tmds) {
+ }
+
+ /* step 3, GFX overclocking, (only need if CMOS option is enabled) */
+ /* skip */
+
+ /* step 4, reset the GFX link */
+ /* step 4.1 asserts both calibration reset and global reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
+
+ /* step 4.2 de-asserts calibration reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
+
+ /* step 4.3 wait for at least 200us */
+ udelay(200);
+
+ /* step 4.4 de-asserts global reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
+
+ /* step 4.5 asserts both calibration reset and global reset */
+ /* a weird step in RPR, don't do that */
+ /* set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14); */
+
+ /* step 4.6 bring external GFX device out of reset, wait for 1ms */
+ mdelay(1);
+ printk(BIOS_INFO, "rs690_gfx_init step4.\n");
+
+ /* step 5 program PCIE memory mapped configuration space */
+ /* done by enable_pci_bar3() before */
+
+ /* step 6 SBIOS compile flags */
+ if (cfg->gfx_tmds) {
+ /* step 6.2.2 Clock-Muxing Control */
+ /* step 6.2.2.1 */
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 16, 1 << 16);
+
+ /* step 6.2.2.2 */
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 8, 1 << 8);
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 10, 1 << 10);
+
+ /* step 6.2.2.3 */
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 26, 1 << 26);
+
+ /* step 6.2.3 Lane-Muxing Control */
+ /* step 6.2.3.1 */
+ set_nbmisc_enable_bits(nb_dev, 0x37, 0x3 << 8, 0x2 << 8);
+
+ /* step 6.2.4 Received Data Control */
+ /* step 6.2.4.1 */
+ set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 16, 0x2 << 16);
+
+ /* step 6.2.4.2 */
+ set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 18, 0x3 << 18);
+
+ /* step 6.2.4.3 */
+ set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 20, 0x0 << 20);
+
+ /* step 6.2.4.4 */
+ set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 22, 0x1 << 22);
+
+ /* step 6.2.5 PLL Power Down Control */
+ /* step 6.2.5.1 */
+ set_nbmisc_enable_bits(nb_dev, 0x35, 0x3 << 6, 0x0 << 6);
+
+ /* step 6.2.6 Driving Strength Control */
+ /* step 6.2.6.1 */
+ set_nbmisc_enable_bits(nb_dev, 0x34, 0x1 << 24, 0x0 << 24);
+
+ /* step 6.2.6.2 */
+ set_nbmisc_enable_bits(nb_dev, 0x35, 0x3 << 2, 0x3 << 2);
+ }
+
+ printk(BIOS_INFO, "rs690_gfx_init step6.\n");
+
+ /* step 7 compliance state, (only need if CMOS option is enabled) */
+ /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
+ if (cfg->gfx_compliance) {
+ /* force compliance */
+ set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
+ /* release hold training for device 2. GFX initialization is done. */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
+ dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
+ printk(BIOS_INFO, "rs690_gfx_init step7.\n");
+ return;
+ }
+
+ /* step 8 common initialization */
+ /* step 8.1 sets RCB timeout to be 25ms */
+ set_pcie_enable_bits(dev, 0x70, 7 << 16, 3 << 16);
+ printk(BIOS_INFO, "rs690_gfx_init step8.1.\n");
+
+ /* step 8.2 disables slave ordering logic */
+ set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
+ printk(BIOS_INFO, "rs690_gfx_init step8.2.\n");
+
+ /* step 8.3 sets DMA payload size to 64 bytes */
+ set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
+ printk(BIOS_INFO, "rs690_gfx_init step8.3.\n");
+
+ /* step 8.4 if the LTSSM could not see all 8 TS1 during Polling Active, it can still
+ * time out and go back to Detect Idle.*/
+ set_pcie_enable_bits(dev, 0x02, 1 << 14, 1 << 14);
+ printk(BIOS_INFO, "rs690_gfx_init step8.4.\n");
+
+ /* step 8.5 shortens the enumeration timer */
+ set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
+ printk(BIOS_INFO, "rs690_gfx_init step8.5.\n");
+
+ /* step 8.6 blocks DMA traffic during C3 state */
+ set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
+ printk(BIOS_INFO, "rs690_gfx_init step8.6.\n");
+
+ /* step 8.7 Do not gate the electrical idle form the PHY
+ * step 8.8 Enables the escape from L1L23 */
+ set_pcie_enable_bits(dev, 0xa0, 3 << 30, 3 << 30);
+ printk(BIOS_INFO, "rs690_gfx_init step8.8.\n");
+
+ /* step 8.9 Setting this register to 0x1 will workaround a PCI Compliance failure reported by Vista DTM.
+ * SLOT_IMPLEMENTED@PCIE_CAP */
+ reg16 = pci_read_config16(dev, 0x5a);
+ reg16 |= 0x100;
+ pci_write_config16(dev, 0x5a, reg16);
+ printk(BIOS_INFO, "rs690_gfx_init step8.9.\n");
+
+ /* step 8.10 Setting this register to 0x1 will hide the Advanced Error Rporting Capabilities in the PCIE Brider.
+ * This will workaround several failures reported by the PCI Compliance test under Vista DTM. */
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 31, 0 << 31);
+ printk(BIOS_INFO, "rs690_gfx_init step8.10.\n");
+
+ /* step 8.11 Sets REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs during L1 so that txclk can be turned off. */
+ set_pcie_enable_bits(nb_dev, 0x02, 1 << 0, 1 << 0);
+ printk(BIOS_INFO, "rs690_gfx_init step8.11.\n");
+
+ /* step 8.12 Sets REGS_LC_DONT_GO_TO_L0S_IF_L1_ARMED to prevent lc to go to from L0 to Rcv_L0s if L1 is armed. */
+ set_pcie_enable_bits(nb_dev, 0x02, 1 << 6, 1 << 6);
+ printk(BIOS_INFO, "rs690_gfx_init step8.12.\n");
+
+ /* step 8.13 Sets CMGOOD_OVERRIDE. */
+ set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
+ printk(BIOS_INFO, "rs690_gfx_init step8.13.\n");
+
+ /* step 9 Enable TLP Flushing, for non-AMD GFX devices and Hot-Plug devices only. */
+ /* skip */
+
+ /* step 10 Optional Features, only needed if CMOS option is enabled. */
+ /* step 10.a: L0s */
+ /* enabling L0s in the RS690 GFX port(s) */
+ set_pcie_enable_bits(nb_dev, 0xF9, 3 << 13, 2 << 13);
+ set_pcie_enable_bits(dev, 0xA0, 0xf << 8, 8 << 8);
+ reg16 = pci_read_config16(dev, 0x68);
+ reg16 |= 1 << 0;
+ /* L0s is intended as a power saving state */
+ /* pci_write_config16(dev, 0x68, reg16); */
+
+ /* enabling L0s in the External GFX Device(s) */
+
+ /* step 10.b: active state power management (ASPM L1) */
+ /* TO DO */
+
+ /* step 10.c: turning off PLL During L1/L23 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
+
+ /* step 10.d: TXCLK clock gating */
+ set_nbmisc_enable_bits(nb_dev, 0x7, 3, 3);
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
+ set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
+
+ /* step 10.e: LCLK clock gating, done in rs690_config_misc_clk() */
+
+ /* step 11 Poll GPIO to determine whether it is single-port or dual-port configuration.
+ * While details will be added later in the document, for now assue the single-port configuration. */
+ /* skip */
+
+ /* Single-port/Dual-port configureation. */
+ switch (cfg->gfx_dual_slot) {
+ case 0:
+ single_port_configuration(nb_dev, dev);
+ break;
+ case 1:
+ dual_port_configuration(nb_dev, dev);
+ break;
+ default:
+ printk(BIOS_INFO, "Incorrect configuration of external gfx slot.\n");
+ break;
+ }
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "rs690.h"
+
+/* for UMA internal graphics */
+void avoid_lpc_dma_deadlock(device_t nb_dev, device_t sb_dev)
+{
+ device_t k8_f0;
+ u8 reg;
+
+ k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ set_nbcfg_enable_bits(k8_f0, 0x68, 3 << 21, 1 << 21);
+
+ reg = nbpcie_p_read_index(sb_dev, 0x10);
+ reg |= 0x100; /* bit9=1 */
+ nbpcie_p_write_index(sb_dev, 0x10, reg);
+
+ reg = nbpcie_p_read_index(nb_dev, 0x10);
+ reg |= 0x100; /* bit9=1 */
+ nbpcie_p_write_index(nb_dev, 0x10, reg);
+
+ /* Enable NP protocol over PCIE for memory-mapped writes targeting LPC
+ * Set this bit to avoid a deadlock condition. */
+ reg = htiu_read_index(nb_dev, 0x6);
+ reg |= 0x1000000; /* bit26 */
+ htiu_write_index(nb_dev, 0x6, reg);
+}
+
+static void pcie_init(struct device *dev)
+{
+ /* Enable pci error detecting */
+ u32 dword;
+
+ printk(BIOS_INFO, "pcie_init in rs690_ht.c\n");
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* System error enable */
+ dword |= (1 << 30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+ /*
+ * 1 is APIC enable
+ * 18 is enable nb to accept A4 interrupt request from SB.
+ */
+ dword = pci_read_config32(dev, 0x4C);
+ dword |= 1 << 1 | 1 << 18; /* Clear possible errors */
+ pci_write_config32(dev, 0x4C, dword);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = pcie_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS690_HT,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+#include "rs690.h"
+
+/*------------------------------------------------
+* Global variable
+------------------------------------------------*/
+PCIE_CFG AtiPcieCfg = {
+ PCIE_ENABLE_STATIC_DEV_REMAP, /* Config */
+ 0, /* ResetReleaseDelay */
+ 0, /* Gfx0Width */
+ 0, /* Gfx1Width */
+ 0, /* GfxPayload */
+ 0, /* GppPayload */
+ 0, /* PortDetect, filled by GppSbInit */
+ 0, /* PortHp */
+ 0, /* DbgConfig */
+ 0, /* DbgConfig2 */
+ 0, /* GfxLx */
+ 0, /* GppLx */
+ 0, /* NBSBLx */
+ 0, /* PortSlotInit */
+ 0, /* Gfx0Pwr */
+ 0, /* Gfx1Pwr */
+ 0 /* GppPwr */
+};
+
+static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port);
+static void ValidatePortEn(device_t nb_dev);
+
+static void ValidatePortEn(device_t nb_dev)
+{
+}
+
+
+/*****************************************************************
+* Compliant with CIM_33's PCIEPowerOffGppPorts
+* Power off unused GPP lines
+*****************************************************************/
+static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
+{
+ u32 reg;
+ u16 state_save;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+ u8 state = cfg->port_enable;
+
+ if (!(AtiPcieCfg.Config & PCIE_DISABLE_HIDE_UNUSED_PORTS))
+ state &= AtiPcieCfg.PortDetect;
+ state = ~state;
+ state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7);
+ state_save = state << 17;
+ state &= !(AtiPcieCfg.PortHp);
+ reg = nbmisc_read_index(nb_dev, 0x0c);
+ reg |= state;
+ nbmisc_write_index(nb_dev, 0x0c, reg);
+
+ reg = nbmisc_read_index(nb_dev, 0x08);
+ reg |= state_save;
+ nbmisc_write_index(nb_dev, 0x08, reg);
+
+ if ((AtiPcieCfg.Config & PCIE_OFF_UNUSED_GPP_LANES)
+ && !(AtiPcieCfg.
+ Config & (PCIE_DISABLE_HIDE_UNUSED_PORTS +
+ PCIE_GFX_COMPLIANCE))) {
+ }
+
+ if (!cfg->gfx_tmds){
+ /* step 3 Power Down Control for Southbridge */
+ reg = nbpcie_p_read_index(dev, 0xa2);
+
+ switch ((reg >> 4) & 0x7) { /* get bit 4-6, LC_LINK_WIDTH_RD */
+ case 1:
+ nbpcie_ind_write_index(nb_dev, 0x65, 0x0e0e);
+ break;
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65, 0x0c0c);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#ifdef UNUSED_CODE
+static void pcie_init(struct device *dev)
+{
+ /* Enable pci error detecting */
+ u32 dword;
+
+ printk(BIOS_DEBUG, "pcie_init in rs690_pcie.c\n");
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* System error enable */
+ dword |= (1 << 30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+}
+#endif
+
+/**********************************************************************
+**********************************************************************/
+static void switching_gpp_configurations(device_t nb_dev, device_t sb_dev)
+{
+ u32 reg;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ /* enables GPP reconfiguration */
+ reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
+ reg |=
+ (RECONFIG_GPPSB_EN + RECONFIG_GPPSB_LINK_CONFIG +
+ RECONFIG_GPPSB_ATOMIC_RESET);
+ nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
+
+ /* sets desired GPPSB configurations, bit4-7 */
+ reg = nbmisc_read_index(nb_dev, 0x67);
+ reg &= 0xffffff0f; /* clean */
+ reg |= cfg->gpp_configuration << 4;
+ nbmisc_write_index(nb_dev, 0x67, reg);
+
+ /* read bit14 and write back its inverst value */
+ reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
+ reg ^= RECONFIG_GPPSB_GPPSB;
+ nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
+
+ /* delay 1ms */
+ mdelay(1);
+
+ /* waits until SB has trained to L0, poll for bit0-5 = 0x10 */
+ do {
+ reg = nbpcie_p_read_index(sb_dev, PCIE_LC_STATE0);
+ reg &= 0x3f; /* remain LSB [5:0] bits */
+ } while (LC_STATE_RECONFIG_GPPSB != reg);
+
+ /* ensures that virtual channel negotiation is completed. poll for bit1 = 0 */
+ do {
+ reg =
+ pci_ext_read_config32(nb_dev, sb_dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ } while (reg & VC_NEGOTIATION_PENDING);
+}
+
+/*****************************************************************
+* The rs690 uses NBCONFIG:0x1c (BAR3) to map the PCIE Extended Configuration
+* Space to a 256MB range within the first 4GB of addressable memory.
+*****************************************************************/
+void enable_pcie_bar3(device_t nb_dev)
+{
+ printk(BIOS_DEBUG, "enable_pcie_bar3()\n");
+ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register. */
+ set_nbcfg_enable_bits(nb_dev, 0x84, 7 << 16, 0 << 16);
+
+ pci_write_config32(nb_dev, 0x1C, EXT_CONF_BASE_ADDRESS); /* PCIEMiscInit */
+ pci_write_config32(nb_dev, 0x20, 0x00000000);
+ set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
+ ProgK8TempMmioBase(1, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
+}
+
+/*****************************************************************
+* We should disable bar3 when we want to exit rs690_enable, because bar3 will be
+* remapped in set_resource later.
+*****************************************************************/
+void disable_pcie_bar3(device_t nb_dev)
+{
+ printk(BIOS_DEBUG, "disable_pcie_bar3()\n");
+ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */
+ pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */
+ ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
+}
+
+/*****************************************
+* Compliant with CIM_33's PCIEGPPInit
+* nb_dev:
+* root bridge struct
+* dev:
+* p2p bridge struct
+* port:
+* p2p bridge number, 4-8
+*****************************************/
+void rs690_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
+{
+ u8 reg8;
+ u16 reg16;
+ device_t sb_dev;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+ printk(BIOS_DEBUG, "gpp_sb_init nb_dev=0x%p, dev=0x%p, port=0x%x\n", nb_dev, dev, port);
+
+ /* init GPP core */
+ set_pcie_enable_bits(nb_dev, 0x20 | PCIE_CORE_INDEX_GPPSB, 1 << 8,
+ 1 << 8);
+ /* PCIE initialization 5.10.2: rpr 2.12*/
+ set_pcie_enable_bits(nb_dev, 0x02 | PCIE_CORE_INDEX_GPPSB, 1 << 0, 1 << 0); /* no description in datasheet. */
+
+ /* init GPPSB port */
+ /* Sets RCB timeout to be 100ms by setting bits[18:16] to 3 b101 and shortens the enumeration timer by setting bit[19] to 1*/
+ set_pcie_enable_bits(dev, 0x70, 0xF << 16, 0xd << 16);
+ /* PCIE initialization 5.10.2: rpr 2.4 */
+ set_pcie_enable_bits(dev, 0x02, ~0xffffffff, 1 << 14);
+ /* Do not gate the electrical idle from the PHY and enables the escape from L1L23 */
+ set_pcie_enable_bits(dev, 0xA0, ~0xffffffbf, (3 << 30) | (3 << 12) | (3 << 4));
+ /* PCIE initialization 5.10.2: rpr 2.13 */
+ set_pcie_enable_bits(dev, 0x02, ~0xffffffff, 1 << 6);
+
+ /* SLOT_IMPLEMENTED in pcieConfig space */
+ reg8 = pci_read_config8(dev, 0x5b);
+ reg8 |= 1 << 0;
+ pci_write_config8(dev, 0x5b, reg8);
+
+ reg16 = pci_read_config16(dev, 0x5a);
+ reg16 |= 0x100;
+ pci_write_config16(dev, 0x5a, reg16);
+ nbmisc_write_index(nb_dev, 0x34, 0);
+
+ /* check compliance rpr step 2.1*/
+ if (AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE) {
+ u32 tmp;
+ tmp = nbmisc_read_index(nb_dev, 0x67);
+ tmp |= 1 << 3;
+ nbmisc_write_index(nb_dev, 0x67, tmp);
+ }
+
+ /* step 5: dynamic slave CPL buffer allocation */
+ set_pcie_enable_bits(nb_dev, 0x20 | PCIE_CORE_INDEX_GPPSB, 1 << 11, 1 << 11);
+
+ /* step 5a: Training for GPP devices */
+ /* init GPP */
+ switch (port) {
+ case 4: /* GPP */
+ case 5:
+ case 6:
+ case 7:
+ /* Blocks DMA traffic during C3 state */
+ set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
+ /* Enabels TLP flushing */
+ set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
+
+ /* check port enable */
+ if (cfg->port_enable & (1 << port)) {
+ PcieReleasePortTraining(nb_dev, dev, port);
+ if (!(AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE)) {
+ u8 res = PcieTrainPort(nb_dev, dev, port);
+ printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res);
+ if (res) {
+ AtiPcieCfg.PortDetect |= 1 << port;
+ }
+ }
+ }
+ break;
+ case 8: /* SB */
+ break;
+ }
+ PciePowerOffGppPorts(nb_dev, dev, port);
+
+ /* step 5b: GFX devices in a GPP slot */
+
+ /* step 6a: VCI */
+ sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
+ if (port == 8) {
+ /* The code below between #if and #endif causes a hang on HDA init.
+ * So we skip it. */
+#if 0
+ /* Clear bits 7:1 */
+ pci_ext_write_config32(nb_dev, sb_dev, 0x114, 0x3f << 1, 0 << 1);
+ /* Maps Traffic Class 1-7 to VC1 */
+ pci_ext_write_config32(nb_dev, sb_dev, 0x120, 0x7f << 1, 0x7f << 1);
+ /* Assigns VC ID to 1 */
+ pci_ext_write_config32(nb_dev, sb_dev, 0x120, 7 << 24, 1 << 24);
+ /* Enables VC1 */
+ pci_ext_write_config32(nb_dev, sb_dev, 0x120, 1 << 31, 1 << 31);
+
+ do {
+ reg16 = pci_ext_read_config32(nb_dev, sb_dev, 0x124);
+ reg16 &= 0x2;
+ } while (reg16); /*bit[1] = 0 means VC1 flow control initialization is successful */
+#endif
+ }
+
+ /* step 6b: L0s for the southbridge link */
+ /* To enalbe L0s in the southbridage*/
+
+ /* step 6c: L0s for the GPP link(s) */
+ /* To eable L0s in the RS690 for the GPP port(s) */
+ set_pcie_enable_bits(nb_dev, 0xf9, 3 << 13, 2 << 13);
+ set_pcie_enable_bits(dev, 0xa0, 0xf << 8, 0x9 << 8);
+ reg16 = pci_read_config16(dev, 0x68);
+ reg16 |= 1 << 0;
+ pci_write_config16(dev, 0x68, reg16);
+
+ /* step 6d: ASPM L1 for the southbridge link */
+ /* To enalbe L1s in the southbridage*/
+
+ /* step 6e: ASPM L1 for GPP link(s) */;
+ set_pcie_enable_bits(nb_dev, 0xf9, 3 << 13, 2 << 13);
+ set_pcie_enable_bits(dev, 0xa0, 3 << 12, 3 << 12);
+ set_pcie_enable_bits(dev, 0xa0, 0xf << 4, 3 << 4);
+ reg16 = pci_read_config16(dev, 0x68);
+ reg16 &= ~0xff;
+ reg16 |= 1 << 1;
+ pci_write_config16(dev, 0x68, reg16);
+
+ /* step 6f: Turning off PLL during L1/L23 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
+
+ /* step 6g: TXCLK clock gating */
+ set_nbmisc_enable_bits(nb_dev, 0x7, 3 << 4, 3 << 4);
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
+ set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
+
+ /* step 6h: LCLK clock gating, done in rs690_config_misc_clk() */
+}
+
+/*****************************************
+* Compliant with CIM_33's PCIEConfigureGPPCore
+*****************************************/
+void config_gpp_core(device_t nb_dev, device_t sb_dev)
+{
+ u32 reg;
+ struct southbridge_amd_rs690_config *cfg =
+ (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
+
+ reg = nbmisc_read_index(nb_dev, 0x20);
+ if (AtiPcieCfg.Config & PCIE_ENABLE_STATIC_DEV_REMAP)
+ reg &= 0xfffffffd; /* set bit1 = 0 */
+ else
+ reg |= 0x2; /* set bit1 = 1 */
+ nbmisc_write_index(nb_dev, 0x20, reg);
+
+ reg = nbmisc_read_index(nb_dev, 0x67); /* get STRAP_BIF_LINK_CONFIG_GPPSB at bit 4-7 */
+ if (cfg->gpp_configuration != ((reg >> 4) & 0xf))
+ switching_gpp_configurations(nb_dev, sb_dev);
+ ValidatePortEn(nb_dev);
+}
+
+#ifdef UNUSED_CODE
+/*****************************************
+* Compliant with CIM_33's PCIEMiscClkProg
+*****************************************/
+void pcie_config_misc_clk(device_t nb_dev)
+{
+ u32 reg;
+ struct bus pbus; /* fake bus for dev0 fun1 */
+
+ reg = pci_read_config32(nb_dev, 0x4c);
+ reg |= 1 << 0;
+ pci_write_config32(nb_dev, 0x4c, reg);
+
+ if (AtiPcieCfg.Config & PCIE_GFX_CLK_GATING) {
+ /* TXCLK Clock Gating */
+ set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 0, 3 << 0);
+ set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22);
+ set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_GFX, (3 << 6) | (~0xf), 3 << 6);
+
+ /* LCLK Clock Gating */
+ reg = pci_cf8_conf1.read32(&pbus, 0, 1, 0x94);
+ reg &= ~(1 << 16);
+ pci_cf8_conf1.write32(&pbus, 0, 1, 0x94, reg);
+ }
+
+ if (AtiPcieCfg.Config & PCIE_GPP_CLK_GATING) {
+ /* TXCLK Clock Gating */
+ set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 4, 3 << 4);
+ set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22);
+ set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_GPPSB, (3 << 6) | (~0xf), 3 << 6);
+
+ /* LCLK Clock Gating */
+ reg = pci_cf8_conf1.read32(&pbus, 0, 1, 0x94);
+ reg &= ~(1 << 24);
+ pci_cf8_conf1.write32(&pbus, 0, 1, 0x94, reg);
+ }
+
+ reg = pci_read_config32(nb_dev, 0x4c);
+ reg &= ~(1 << 0);
+ pci_write_config32(nb_dev, 0x4c, reg);
+}
+#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-
-#include <arch/io.h>
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-#include <boot/coreboot_tables.h>
-#include <delay.h>
-#include "rs690.h"
-
-static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
-{
- pci_write_config32(dev, index_reg, index);
- return pci_read_config32(dev, index_reg + 0x4);
-}
-
-static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
-{
-
- pci_write_config32(dev, index_reg, index);
- pci_write_config32(dev, index_reg + 0x4, data);
-
-}
-
-/* extension registers */
-u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
-{
- /*get BAR3 base address for nbcfg0x1c */
- u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
- printk(BIOS_DEBUG, "addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
- dev->path.pci.devfn);
- addr |= dev->bus->secondary << 20 | /* bus num */
- dev->path.pci.devfn << 12 | reg;
- return *((u32 *) addr);
-}
-
-void pci_ext_write_config32(device_t nb_dev, device_t dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
-
- /*get BAR3 base address for nbcfg0x1c */
- u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
- /*printk(BIOS_DEBUG, "write: addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
- dev->path.pci.devfn);*/
- addr |= dev->bus->secondary << 20 | /* bus num */
- dev->path.pci.devfn << 12 | reg_pos;
-
- reg = reg_old = *((u32 *) addr);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- *((u32 *) addr) = reg;
- }
-}
-
-u32 nbmisc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMISC_INDEX, (index));
-}
-
-void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
-}
-
-u32 nbpcie_p_read_index(device_t dev, u32 index)
-{
- return nb_read_index((dev), NBPCIE_INDEX, (index));
-}
-
-void nbpcie_p_write_index(device_t dev, u32 index, u32 data)
-{
- nb_write_index((dev), NBPCIE_INDEX, (index), (data));
-}
-
-u32 nbpcie_ind_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBPCIE_INDEX, (index));
-}
-
-void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBPCIE_INDEX, (index), (data));
-}
-
-u32 htiu_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
-}
-
-void htiu_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
-}
-
-u32 nbmc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMC_INDEX, (index));
-}
-
-void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
-}
-
-void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = pci_read_config32(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config32(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask, u8 val)
-{
- u8 reg_old, reg;
- reg = reg_old = pci_read_config8(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config8(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = htiu_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- htiu_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmisc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_pcie_enable_bits(device_t dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nb_read_index(dev, NBPCIE_INDEX, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nb_write_index(dev, NBPCIE_INDEX, reg_pos, reg);
- }
-}
-
-/***********************************************************
-* To access bar3 we need to program PCI MMIO 7 in K8.
-* in_out:
-* 1: enable/enter k8 temp mmio base
-* 0: disable/restore
-***********************************************************/
-void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
-{
- /* K8 Function1 is address map */
- device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
- device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
-
- if (in_out) {
- u32 dword, sblk;
-
- /* Get SBLink value (HyperTransport I/O Hub Link ID). */
- dword = pci_read_config32(k8_f0, 0x64);
- sblk = (dword >> 8) & 0x3;
-
- /* Fill MMIO limit/base pair. */
- pci_write_config32(k8_f1, 0xbc,
- (((pcie_base_add + 0x10000000 -
- 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
- pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
- pci_write_config32(k8_f1, 0xb4,
- (((mmio_base_add + 0x10000000 -
- 1) >> 8) & 0xffffff00) | (sblk << 4));
- pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
- } else {
- pci_write_config32(k8_f1, 0xb8, 0);
- pci_write_config32(k8_f1, 0xbc, 0);
- pci_write_config32(k8_f1, 0xb0, 0);
- pci_write_config32(k8_f1, 0xb4, 0);
- }
-}
-
-void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port)
-{
- switch (port) {
- case 2: /* GFX, bit4-5 */
- case 3:
- set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
- 1 << (port + 2), 0 << (port + 2));
- break;
- case 4: /* GPP, bit20-24 */
- case 5:
- case 6:
- case 7:
- set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
- 1 << (port + 17), 0 << (port + 17));
- break;
- }
-}
-
-/********************************************************************************************************
-* Output:
-* 0: no device is present.
-* 1: device is present and is trained.
-********************************************************************************************************/
-u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port)
-{
- u16 count = 5000;
- u32 lc_state, reg;
- int8_t current, res = 0;
-
- while (count--) {
- mdelay(40);
- udelay(200);
- lc_state = nbpcie_p_read_index(dev, 0xa5); /* lc_state */
- printk(BIOS_DEBUG, "PcieLinkTraining port=%x:lc current state=%x\n",
- port, lc_state);
- current = lc_state & 0x3f; /* get LC_CURRENT_STATE, bit0-5 */
-
- switch (current) {
- case 0x00: /* 0x00-0x04 means no device is present */
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- res = 0;
- count = 0;
- break;
- case 0x07: /* device is in compliance state (training sequence is doen). Move to train the next device */
- res = 1; /* TODO: CIM sets it to 0 */
- count = 0;
- break;
- case 0x10:
- reg =
- pci_ext_read_config32(nb_dev, dev,
- PCIE_VC0_RESOURCE_STATUS);
- printk(BIOS_DEBUG, "PcieTrainPort reg=0x%x\n", reg);
- /* check bit1 */
- if (reg & VC_NEGOTIATION_PENDING) { /* bit1=1 means the link needs to be re-trained. */
- /* set bit8=1, bit0-2=bit4-6 */
- u32 tmp;
- reg =
- nbpcie_p_read_index(dev,
- PCIE_LC_LINK_WIDTH);
- tmp = (reg >> 4) && 0x3; /* get bit4-6 */
- reg &= 0xfff8; /* clear bit0-2 */
- reg += tmp; /* merge */
- reg |= 1 << 8;
- count++; /* CIM said "keep in loop"? */
- } else {
- res = 1;
- count = 0;
- }
- break;
- default: /* reset pcie */
- res = 0;
- count = 0; /* break loop */
- break;
- }
- }
- return res;
-}
-
-/*
-* Compliant with CIM_33's ATINB_SetToms.
-* Set Top Of Memory below and above 4G.
-*/
-void rs690_set_tom(device_t nb_dev)
-{
- extern uint64_t uma_memory_base;
-
- /* set TOM */
- pci_write_config32(nb_dev, 0x90, uma_memory_base);
- nbmc_write_index(nb_dev, 0x1e, uma_memory_base);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2008 Carl-Daniel Hailfinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#define NBHTIU_INDEX 0xA8
-#define NBMISC_INDEX 0x60
-#define NBMC_INDEX 0xE8
-
-static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
-{
- pci_write_config32(dev, index_reg, index);
- return pci_read_config32(dev, index_reg + 0x4);
-}
-
-static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
-{
- pci_write_config32(dev, index_reg, index /* | 0x80 */ );
- pci_write_config32(dev, index_reg + 0x4, data);
-}
-
-static u32 nbmisc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMISC_INDEX, (index));
-}
-
-static void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
-}
-
-static u32 htiu_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
-}
-
-static void htiu_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
-}
-
-static u32 nbmc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMC_INDEX, (index));
-}
-
-static void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
-}
-
-static void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = htiu_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- htiu_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmisc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = pci_read_config32(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config32(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask,
- u8 val)
-{
- u8 reg_old, reg;
- reg = reg_old = pci_read_config8(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config8(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-/*
-* Compliant with CIM_33's ATINB_PrepareInit
-*/
-static void get_cpu_rev(void)
-{
- u32 eax, ebx, ecx, edx;
- __asm__ volatile ("cpuid":"=a" (eax), "=b"(ebx), "=c"(ecx), "=d"(edx)
- :"0"(1));
- printk(BIOS_INFO, "get_cpu_rev EAX=0x%x.\n", eax);
- if (eax <= 0xfff)
- printk(BIOS_INFO, "CPU Rev is K8_Cx.\n");
- else if (eax <= 0x10fff)
- printk(BIOS_INFO, "CPU Rev is K8_Dx.\n");
- else if (eax <= 0x20fff)
- printk(BIOS_INFO, "CPU Rev is K8_Ex.\n");
- else if (eax <= 0x40fff)
- printk(BIOS_INFO, "CPU Rev is K8_Fx.\n");
- else if (eax == 0x60fb1 || eax == 0x60f81) /*These two IDS are exception, they are G1. */
- printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
- else if (eax <= 0X60FF0)
- printk(BIOS_INFO, "CPU Rev is K8_G0.\n");
- else if (eax <= 0x100000)
- printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
- else
- printk(BIOS_INFO, "CPU Rev is K8_10.\n");
-}
-
-static u8 get_nb_rev(device_t nb_dev)
-{
- u32 reg;
- reg = pci_read_config32(nb_dev, 0x00);
- if (0x7911 == (reg >> 16))
- return 7;
- reg = pci_read_config8(nb_dev, 0x89); /* copy from CIM, can't find in doc */
- if (reg & 0x2) /* check bit1 */
- return 7;
- if (reg & 0x1) /* check bit0 */
- return 6;
- else
- return 5;
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_HTInit
-* Init HT link speed/width for rs690 -- k8 link
-*****************************************/
-static void rs690_htinit(void)
-{
- /*
- * About HT, it has been done in enumerate_ht_chain().
- */
- device_t k8_f0, rs690_f0;
- u32 reg;
- u8 reg8;
- u8 k8_ht_freq;
-
- k8_f0 = PCI_DEV(0, 0x18, 0);
- /************************
- * get k8's ht freq, in k8's function 0, offset 0x88
- * bit11-8, specifics the maximum operation frequency of the link's transmitter clock.
- * The link frequency field (Frq) is cleared by cold reset. SW can write a nonzero
- * value to this reg, and that value takes effect on the next warm reset or
- * LDTSTOP_L disconnect sequence.
- * 0000b = 200Mhz
- * 0010b = 400Mhz
- * 0100b = 600Mhz
- * 0101b = 800Mhz
- * 0110b = 1Ghz
- * 1111b = 1Ghz
- ************************/
- reg = pci_read_config32(k8_f0, 0x88);
- k8_ht_freq = (reg & 0xf00) >> 8;
- printk(BIOS_SPEW, "rs690_htinit k8_ht_freq=%x.\n", k8_ht_freq);
- rs690_f0 = PCI_DEV(0, 0, 0);
- reg8 = pci_read_config8(rs690_f0, 0x9c);
- printk(BIOS_SPEW, "rs690_htinit NB_CFG_Q_F1000_800=%x\n", reg8);
- /* For 1000 MHz HT, NB_CFG_Q_F1000_800 bit 0 MUST be set.
- * For any other HT frequency, NB_CFG_Q_F1000_800 bit 0 MUST NOT be set.
- */
- if (((k8_ht_freq == 0x6) || (k8_ht_freq == 0xf)) && (!(reg8 & 0x1))) {
- printk(BIOS_INFO, "rs690_htinit setting bit 0 in NB_CFG_Q_F1000_800 to use 1 GHz HT\n");
- reg8 |= 0x1;
- pci_write_config8(rs690_f0, 0x9c, reg8);
- } else if ((k8_ht_freq != 0x6) && (k8_ht_freq != 0xf) && (reg8 & 0x1)) {
- printk(BIOS_INFO, "rs690_htinit clearing bit 0 in NB_CFG_Q_F1000_800 to not use 1 GHz HT\n");
- reg8 &= ~0x1;
- pci_write_config8(rs690_f0, 0x9c, reg8);
- }
-}
-
-/*******************************************************
-* Optimize k8 with UMA.
-* See BKDG_NPT_0F guide for details.
-* The processor node is addressed by its Node ID on the HT link and can be
-* accessed with a device number in the PCI configuration space on Bus0.
-* The Node ID 0 is mapped to Device 24 (0x18), the Node ID 1 is mapped
-* to Device 25, and so on.
-* The processor implements configuration registers in PCI configuration
-* space using the following four headers
-* Function0: HT technology configuration
-* Function1: Address map configuration
-* Function2: DRAM and HT technology Trace mode configuration
-* Function3: Miscellaneous configuration
-*******************************************************/
-static void k8_optimization(void)
-{
- device_t k8_f0, k8_f2, k8_f3;
- msr_t msr;
-
- printk(BIOS_INFO, "k8_optimization()\n");
- k8_f0 = PCI_DEV(0, 0x18, 0);
- k8_f2 = PCI_DEV(0, 0x18, 2);
- k8_f3 = PCI_DEV(0, 0x18, 3);
-
- pci_write_config32(k8_f0, 0x90, 0x01700178); /* CIM NPT_Optimization */
- set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 28, 0 << 28);
- set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 26 | 1 << 27,
- 1 << 26 | 1 << 27);
- set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 11, 1 << 11);
- set_nbcfg_enable_bits(k8_f0, 0x84, 1 << 11 | 1 << 13 | 1 << 15, 1 << 11 | 1 << 13 | 1 << 15); /* TODO */
-
- pci_write_config32(k8_f3, 0x70, 0x51320111); /* CIM NPT_Optimization */
- pci_write_config32(k8_f3, 0x74, 0x50304021);
- pci_write_config32(k8_f3, 0x78, 0x08002A00);
- if (pci_read_config32(k8_f3, 0xE8) & 0x3<<12)
- pci_write_config32(k8_f3, 0x7C, 0x0000211B); /* dual core */
- else
- pci_write_config32(k8_f3, 0x7C, 0x0000211C); /* single core */
- set_nbcfg_enable_bits_8(k8_f3, 0xDC, 0xFF, 0x25);
-
- set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
- set_nbcfg_enable_bits(k8_f2, 0x94, 0xF << 24, 7 << 24);
- set_nbcfg_enable_bits(k8_f2, 0x90, 1 << 10, 1 << 10);
- set_nbcfg_enable_bits(k8_f2, 0xA0, 3 << 2, 3 << 2);
- set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
-
- msr = rdmsr(0xC001001F);
- msr.lo &= ~(1 << 9);
- msr.hi &= ~(1 << 4);
- wrmsr(0xC001001F, msr);
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_PCICFG_POR_TABLE
-*****************************************/
-static void rs690_por_pcicfg_init(device_t nb_dev)
-{
- /* enable PCI Memory Access */
- set_nbcfg_enable_bits_8(nb_dev, 0x04, (u8)(~0xFD), 0x02);
- /* Set RCRB Enable */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x1);
- /* allow decode of 640k-1MB */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xEF), 0x10);
- /* Enable PM2_CNTL(BAR2) IO mapped cfg write access to be broadcast to both NB and SB */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x4);
- /* Power Management Register Enable */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x80);
-
- /* Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
- * Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
- * BMMsgEn */
- set_nbcfg_enable_bits_8(nb_dev, 0x4C, (u8)(~0x00), 0x42 | 1);
-
- /* Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
- * Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge */
- set_nbcfg_enable_bits_8(nb_dev, 0x4E, (u8)(~0xFF), 0x05);
- /* Reg94h[4:0] = 0x0 P drive strength offset 0
- * Reg94h[6:5] = 0x2 P drive strength additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x94, (u8)(~0x80), 0x40);
-
- /* Reg94h[20:16] = 0x0 N drive strength offset 0
- * Reg94h[22:21] = 0x2 N drive strength additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x96, (u8)(~0x80), 0x40);
-
- /* Reg80h[4:0] = 0x0 Termination offset
- * Reg80h[6:5] = 0x2 Termination additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x80, (u8)(~0x80), 0x40);
-
- /* Reg80h[14] = 0x1 Enable receiver termination control */
- set_nbcfg_enable_bits_8(nb_dev, 0x81, (u8)(~0xFF), 0x40);
-
- /* Reg94h[15] = 0x1 Enables HT transmitter advanced features to be turned on
- * Reg94h[14] = 0x1 Enable drive strength control */
- set_nbcfg_enable_bits_8(nb_dev, 0x95, (u8)(~0x3F), 0xC4);
-
- /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */
- set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
-
- /*Reg8Ch[10:9] = 0x3 Enables Gfx Debug BAR,
- * force this BAR as mem type in rs690_gfx.c */
- set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x03);
-
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_MCIndex_POR_TABLE
-*****************************************/
-static void rs690_por_mc_index_init(device_t nb_dev)
-{
- set_nbmc_enable_bits(nb_dev, 0x7A, ~0xFFFFFF80, 0x0000005F);
- set_nbmc_enable_bits(nb_dev, 0xD8, ~0x00000000, 0x00600060);
- set_nbmc_enable_bits(nb_dev, 0xD9, ~0x00000000, 0x00600060);
- set_nbmc_enable_bits(nb_dev, 0xE0, ~0x00000000, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xE1, ~0x00000000, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xE8, ~0x00000000, 0x003E003E);
- set_nbmc_enable_bits(nb_dev, 0xE9, ~0x00000000, 0x003E003E);
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_MISCIND_POR_TABLE
-* Compliant with CIM_33's MISC_INIT_TBL
-*****************************************/
-static void rs690_por_misc_index_init(device_t nb_dev)
-{
- /* NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
- * Block non-snoop DMA request if PMArbDis is set.
- * Set BMSetDis */
- set_nbmisc_enable_bits(nb_dev, 0x0B, ~0xFFFF0000, 0x00000180);
- set_nbmisc_enable_bits(nb_dev, 0x01, ~0xFFFFFFFF, 0x00000040);
-
- /* NBCFG (NBMISCIND 0x0): NB_CNTL -
- * HIDE_NB_AGP_CAP ([0], default=1)HIDE
- * HIDE_P2P_AGP_CAP ([1], default=1)HIDE
- * HIDE_NB_GART_BAR ([2], default=1)HIDE
- * AGPMODE30 ([4], default=0)DISABLE
- * AGP30ENCHANCED ([5], default=0)DISABLE
- * HIDE_AGP_CAP ([8], default=1)ENABLE */
- set_nbmisc_enable_bits(nb_dev, 0x00, ~0xFFFF0000, 0x00000506); /* set bit 10 for MSI */
-
- /* NBMISCIND:0x6A[16]= 1 SB link can get a full swing
- * set_nbmisc_enable_bits(nb_dev, 0x6A, 0ffffffffh, 000010000);
- * NBMISCIND:0x6A[17]=1 Set CMGOOD_OVERRIDE. */
- set_nbmisc_enable_bits(nb_dev, 0x6A, ~0xffffffff, 0x00020000);
-
- /* NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow LVDS or PWM features to work. */
- set_nbmisc_enable_bits(nb_dev, 0x40, ~0xffffffff, 0x00000500);
-
- /* NBMISIND:0xC Bit[13]=1 Enable GSM mode for C1e or C3 with pop-up. */
- set_nbmisc_enable_bits(nb_dev, 0x0C, ~0xffffffff, 0x00002000);
-
- /* Set NBMISIND:0x1F[3] to map NB F2 interrupt pin to INTB# */
- set_nbmisc_enable_bits(nb_dev, 0x1F, ~0xffffffff, 0x00000008);
-
- /* Compliant with CIM_33's MISC_INIT_TBL, except Hide NB_BAR3_PCIE
- * Enable access to DEV8
- * Enable setPower message for all ports
- */
- set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 6, 1 << 6);
- set_nbmisc_enable_bits(nb_dev, 0x0b, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x51, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x53, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x55, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x57, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x59, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x5B, 1 << 20, 1 << 20);
-
- set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 7, 1 << 7);
- set_nbmisc_enable_bits(nb_dev, 0x07, 0x000000f0, 0x30);
- /* Disable bus-master trigger event from SB and Enable set_slot_power message to SB */
- set_nbmisc_enable_bits(nb_dev, 0x0B, 0xffffffff, 0x500180);
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_HTIUNBIND_POR_TABLE
-*****************************************/
-static void rs690_por_htiu_index_init(device_t nb_dev)
-{
- /* 0xBC:
- * Enables GSM mode for C1e or C3 with pop-up
- * Prevents AllowLdtStop from being asserted during HT link recovery
- * Allows FID cycles to be serviced faster. Needed for RS690 A12. No harm in RS690 A11 */
- set_htiu_enable_bits(nb_dev, 0x05, ~0xffffffff, 0x0BC);
- /* 0x4203A202:
- * Enables writes to pass in-progress reads
- * Enables streaming of CPU writes
- * Enables extended write buffer for CPU writes
- * Enables additional response buffers
- * Enables special reads to pass writes
- * Enables decoding of C1e/C3 and FID cycles
- * Enables HTIU-display handshake bypass.
- * Enables tagging fix */
- set_htiu_enable_bits(nb_dev, 0x06, ~0xFFFFFFFE, 0x4203A202);
-
- /* Enables byte-write optimization for IOC requests
- * Disables delaying STPCLK de-assert during FID sequence. Needed when enhanced UMA arbitration is used.
- * Disables upstream system-management delay */
- set_htiu_enable_bits(nb_dev, 0x07, ~0xFFFFFFF9, 0x001);
-
- /* HTIUNBIND 0x16 [1] = 0x1 Enable crc decoding fix */
- set_htiu_enable_bits(nb_dev, 0x16, ~0xFFFFFFFF, 0x2);
-}
-
-/*****************************************
-* Compliant with CIM_33's ATINB_POR_INIT_JMPDI
-* Configure RS690 registers to power-on default RPR.
-* POR: Power On Reset
-* RPR: Register Programming Requirements
-*****************************************/
-static void rs690_por_init(device_t nb_dev)
-{
- printk(BIOS_INFO, "rs690_por_init\n");
- /* ATINB_PCICFG_POR_TABLE, initialize the values for rs690 PCI Config registers */
- rs690_por_pcicfg_init(nb_dev);
-
- /* ATINB_MCIND_POR_TABLE */
- rs690_por_mc_index_init(nb_dev);
-
- /* ATINB_MISCIND_POR_TABLE */
- rs690_por_misc_index_init(nb_dev);
-
- /* ATINB_HTIUNBIND_POR_TABLE */
- rs690_por_htiu_index_init(nb_dev);
-
- /* ATINB_CLKCFG_PORT_TABLE */
- /* rs690 A11 SB Link full swing? */
-}
-
-/* enable CFG access to Dev8, which is the SB P2P Bridge */
-static void enable_rs690_dev8(void)
-{
- set_nbmisc_enable_bits(PCI_DEV(0, 0, 0), 0x00, 1 << 6, 1 << 6);
-}
-
-
-
-/*
-* Compliant with CIM_33's AtiNBInitEarlyPost (AtiInitNBBeforePCIInit).
-*/
-static void rs690_before_pci_init(void)
-{
-}
-
-/*
-* The calling sequence is same as CIM.
-*/
-static void rs690_early_setup(void)
-{
- device_t nb_dev = PCI_DEV(0, 0, 0);
- printk(BIOS_INFO, "rs690_early_setup()\n");
-
- /*ATINB_PrepareInit */
- get_cpu_rev();
- switch (get_nb_rev(nb_dev)) { /* PCIEMiscInit */
- case 5:
- printk(BIOS_INFO, "NB Revision is A11.\n");
- break;
- case 6:
- printk(BIOS_INFO, "NB Revision is A12.\n");
- break;
- case 7:
- printk(BIOS_INFO, "NB Revision is A21.\n");
- break;
- }
-
- k8_optimization();
- rs690_por_init(nb_dev);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * for rs690 internal graphics device
- * device id of internal grphics:
- * RS690M/T: 0x791f
- * RS690: 0x791e
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <delay.h>
-#include "rs690.h"
-
-#define CLK_CNTL_INDEX 0x8
-#define CLK_CNTL_DATA 0xC
-
-#ifdef UNUSED_CODE
-static u32 clkind_read(device_t dev, u32 index)
-{
- u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
-
- *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
- return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
-}
-#endif
-
-static void clkind_write(device_t dev, u32 index, u32 data)
-{
- u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
- /* printk(BIOS_INFO, "gfx bar 2 %02x\n", gfx_bar2); */
-
- *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
- *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
-}
-
-/*
-* pci_dev_read_resources thinks it is a IO type.
-* We have to force it to mem type.
-*/
-static void rs690_gfx_read_resources(device_t dev)
-{
- printk(BIOS_INFO, "rs690_gfx_read_resources.\n");
-
- /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
- Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
- which tells us it is a memory address base.
- */
- pci_write_config32(dev, 0x24, 0x00000000);
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
- compact_resources(dev);
-}
-
-static void internal_gfx_pci_dev_init(struct device *dev)
-{
- u16 deviceid, vendorid;
- deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
- vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
- printk(BIOS_INFO, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
- deviceid, vendorid);
-
- pci_dev_init(dev);
-
- /* clk ind */
- clkind_write(dev, 0x08, 0x01);
- clkind_write(dev, 0x0C, 0x22);
- clkind_write(dev, 0x0F, 0x0);
- clkind_write(dev, 0x11, 0x0);
- clkind_write(dev, 0x12, 0x0);
- clkind_write(dev, 0x14, 0x0);
- clkind_write(dev, 0x15, 0x0);
- clkind_write(dev, 0x16, 0x0);
- clkind_write(dev, 0x17, 0x0);
- clkind_write(dev, 0x18, 0x0);
- clkind_write(dev, 0x19, 0x0);
- clkind_write(dev, 0x1A, 0x0);
- clkind_write(dev, 0x1B, 0x0);
- clkind_write(dev, 0x1C, 0x0);
- clkind_write(dev, 0x1D, 0x0);
- clkind_write(dev, 0x1E, 0x0);
- clkind_write(dev, 0x26, 0x0);
- clkind_write(dev, 0x27, 0x0);
- clkind_write(dev, 0x28, 0x0);
- clkind_write(dev, 0x5C, 0x0);
-}
-
-
-/*
-* Set registers in RS690 and CPU to enable the internal GFX.
-* Please refer to CIM source code and BKDG.
-*/
-static void rs690_internal_gfx_enable(device_t dev)
-{
- u32 l_dword;
- int i;
- device_t k8_f0 = 0, k8_f2 = 0;
- device_t nb_dev = dev_find_slot(0, 0);
-
- printk(BIOS_INFO, "rs690_internal_gfx_enable dev=0x%p, nb_dev=0x%p.\n", dev,
- nb_dev);
-
- /* set APERTURE_SIZE, 128M. */
- l_dword = pci_read_config32(nb_dev, 0x8c);
- printk(BIOS_INFO, "nb_dev, 0x8c=0x%x\n", l_dword);
- l_dword &= 0xffffff8f;
- pci_write_config32(nb_dev, 0x8c, l_dword);
-
- /* set TOM */
- rs690_set_tom(nb_dev);
-
- /* LPC DMA Deadlock workaround? */
- k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- l_dword = pci_read_config32(k8_f0, 0x68);
- l_dword &= ~(1 << 22);
- l_dword |= (1 << 21);
- pci_write_config32(k8_f0, 0x68, l_dword);
-
- /* Enable 64bit mode. */
- set_nbmc_enable_bits(nb_dev, 0x5f, 0, 1 << 9);
- set_nbmc_enable_bits(nb_dev, 0xb0, 0, 1 << 8);
-
- /* 64bit Latency. */
- set_nbmc_enable_bits(nb_dev, 0x5f, 0x7c00, 0x800);
-
- /* UMA dual channel control register. */
- nbmc_write_index(nb_dev, 0x86, 0x3d);
-
- /* check the setting later!! */
- set_htiu_enable_bits(nb_dev, 0x07, 1 << 7, 0);
-
- /* UMA mode, powerdown memory PLL. */
- set_nbmc_enable_bits(nb_dev, 0x74, 0, 1 << 31);
-
- /* Copy CPU DDR Controller to NB MC. */
- /* Why K8_MC_REG80 is special? */
- k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
- for (i = 0; i <= (0x80 - 0x40) / 4; i++) {
- l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
- nbmc_write_index(nb_dev, 0x63 + i, l_dword);
- }
-
- /* Set K8 MC for UMA, Family F. */
- l_dword = pci_read_config32(k8_f2, 0xa0);
- l_dword |= 0x2c;
- pci_write_config32(k8_f2, 0xa0, l_dword);
- l_dword = pci_read_config32(k8_f2, 0x94);
- l_dword &= 0xf0ffffff;
- l_dword |= 0x07000000;
- pci_write_config32(k8_f2, 0x94, l_dword);
-
- /* set FB size and location. */
- nbmc_write_index(nb_dev, 0x1b, 0x00);
- l_dword = nbmc_read_index(nb_dev, 0x1c);
- l_dword &= 0xffff0;
- l_dword |= 0x400 << 20;
- l_dword |= 0x4;
- nbmc_write_index(nb_dev, 0x1c, l_dword);
- l_dword = nbmc_read_index(nb_dev, 0x1d);
- l_dword &= 0xfffff000;
- l_dword |= 0x0400;
- nbmc_write_index(nb_dev, 0x1d, l_dword);
- nbmc_write_index(nb_dev, 0x100, 0x3fff3800);
-
- /* Program MC table. */
- set_nbmc_enable_bits(nb_dev, 0x00, 0, 1 << 31);
- l_dword = nbmc_read_index(nb_dev, 0x91);
- l_dword |= 0x5;
- nbmc_write_index(nb_dev, 0x91, l_dword);
- set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1 << 6);
- set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1);
-
- /* TODO: the optimization of voltage and frequency */
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations pcie_ops = {
- .read_resources = rs690_gfx_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = internal_gfx_pci_dev_init, /* The option ROM initializes the device. rs690_gfx_init, */
- .scan_bus = 0,
- .enable = rs690_internal_gfx_enable,
- .ops_pci = &lops_pci,
-};
-
-/*
- * The dev id of 690G is 791E, while the id of 690M, 690T is 791F.
- * We should list both of them here.
- * */
-static const struct pci_driver pcie_driver_690t __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS690MT_INT_GFX,
-};
-
-static const struct pci_driver pcie_driver_690 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS690_INT_GFX,
-};
-
-/* step 12 ~ step 14 from rpr */
-static void single_port_configuration(device_t nb_dev, device_t dev)
-{
- u8 result, width;
- u32 reg32;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- printk(BIOS_INFO, "rs690_gfx_init single_port_configuration.\n");
-
- /* step 12 training, releases hold training for GFX port 0 (device 2) */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0<<4);
- PcieReleasePortTraining(nb_dev, dev, 2);
- result = PcieTrainPort(nb_dev, dev, 2);
- printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step12.\n");
-
- /* step 13 Power Down Control */
- /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
-
- /* step 13.a Link Training was NOT successful */
- if (!result) {
- set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
- set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
- if (cfg->gfx_tmds)
- nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
- else {
- nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
- }
- } else { /* step 13.b Link Training was successful */
-
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- width = (reg32 >> 4) & 0x7;
- printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
- switch (width) {
- case 1:
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
- break;
- case 4:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
- break;
- case 8:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
- break;
- }
- }
- printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step13.\n");
-
- /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
- set_pcie_enable_bits(dev, 0x70, 1 << 19, 0 << 19);
- printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step14.\n");
-}
-
-/* step 15 ~ step 18 from rpr */
-static void dual_port_configuration(device_t nb_dev, device_t dev)
-{
- u8 result, width;
- u32 reg32;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- /* step 15: Training for Device 2 */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
- /* Releases hold training for GFX port 0 (device 2) */
- PcieReleasePortTraining(nb_dev, dev, 2);
- /* PCIE Link Training Sequence */
- result = PcieTrainPort(nb_dev, dev, 2);
-
- /* step 16: Power Down Control for Device 2 */
- /* step 16.a Link Training was NOT successful */
- if (!result) {
- /* Powers down all lanes for port A */
- nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f);
- } else { /* step 16.b Link Training was successful */
-
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- width = (reg32 >> 4) & 0x7;
- printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
- switch (width) {
- case 1:
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
- break;
- case 4:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
- break;
- }
- }
-
- /* step 17: Training for Device 3 */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 5, 0 << 5);
- /* Releases hold training for GFX port 0 (device 3) */
- PcieReleasePortTraining(nb_dev, dev, 3);
- /* PCIE Link Training Sequence */
- result = PcieTrainPort(nb_dev, dev, 3);
-
- /*step 18: Power Down Control for Device 3 */
- /* step 18.a Link Training was NOT successful */
- if (!result) {
- /* Powers down all lanes for port B and PLL1 */
- nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
- } else { /* step 18.b Link Training was successful */
-
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- width = (reg32 >> 4) & 0x7;
- printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
- switch (width) {
- case 1:
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x7070 : 0xe0e0);
- break;
- case 4:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x3030 : 0xc0c0);
- break;
- }
- }
-}
-
-
-/* For single port GFX configuration Only
-* width:
-* 000 = x16
-* 001 = x1
-* 010 = x2
-* 011 = x4
-* 100 = x8
-* 101 = x12 (not supported)
-* 110 = x16
-*/
-static void dynamic_link_width_control(device_t nb_dev, device_t dev, u8 width)
-{
- u32 reg32;
- device_t sb_dev;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- /* step 5.9.1.1 */
- reg32 = nbpcie_p_read_index(dev, 0xa2);
-
- /* step 5.9.1.2 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
- /* step 5.9.1.3 */
- set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
- /* step 5.9.1.4 */
- set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
- /* step 5.9.2.4 */
- if (0 == cfg->gfx_reconfiguration)
- set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
-
- /* step 5.9.1.5 */
- do {
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- }
- while (reg32 & 0x100);
-
- /* step 5.9.1.6 */
- sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
- do {
- reg32 = pci_ext_read_config32(nb_dev, sb_dev,
- PCIE_VC0_RESOURCE_STATUS);
- } while (reg32 & VC_NEGOTIATION_PENDING);
-
- /* step 5.9.1.7 */
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- if (((reg32 & 0x70) >> 4) != 0x6) {
- /* the unused lanes should be powered off. */
- }
-
- /* step 5.9.1.8 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
-}
-
-/*
-* GFX Core initialization, dev2, dev3
-*/
-void rs690_gfx_init(device_t nb_dev, device_t dev, u32 port)
-{
- u16 reg16;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- printk(BIOS_INFO, "rs690_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
- nb_dev, dev, port);
-
- /* step 0, REFCLK_SEL, skip A11 revision */
- set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 9,
- cfg->gfx_dev2_dev3 ? 1 << 9 : 0 << 9);
- printk(BIOS_INFO, "rs690_gfx_init step0.\n");
-
- /* step 1, lane reversal (only need if CMOS option is enabled) */
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- if (cfg->gfx_dual_slot)
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
- }
- printk(BIOS_INFO, "rs690_gfx_init step1.\n");
-
- /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
- /* AMD calls the configuration CrossFire */
- if (cfg->gfx_dual_slot)
- set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
- printk(BIOS_INFO, "rs690_gfx_init step2.\n");
-
- /* step 2, TMDS, (only need if CMOS option is enabled) */
- if (cfg->gfx_tmds) {
- }
-
- /* step 3, GFX overclocking, (only need if CMOS option is enabled) */
- /* skip */
-
- /* step 4, reset the GFX link */
- /* step 4.1 asserts both calibration reset and global reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
-
- /* step 4.2 de-asserts calibration reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
-
- /* step 4.3 wait for at least 200us */
- udelay(200);
-
- /* step 4.4 de-asserts global reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
-
- /* step 4.5 asserts both calibration reset and global reset */
- /* a weird step in RPR, don't do that */
- /* set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14); */
-
- /* step 4.6 bring external GFX device out of reset, wait for 1ms */
- mdelay(1);
- printk(BIOS_INFO, "rs690_gfx_init step4.\n");
-
- /* step 5 program PCIE memory mapped configuration space */
- /* done by enable_pci_bar3() before */
-
- /* step 6 SBIOS compile flags */
- if (cfg->gfx_tmds) {
- /* step 6.2.2 Clock-Muxing Control */
- /* step 6.2.2.1 */
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 16, 1 << 16);
-
- /* step 6.2.2.2 */
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 8, 1 << 8);
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 10, 1 << 10);
-
- /* step 6.2.2.3 */
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 26, 1 << 26);
-
- /* step 6.2.3 Lane-Muxing Control */
- /* step 6.2.3.1 */
- set_nbmisc_enable_bits(nb_dev, 0x37, 0x3 << 8, 0x2 << 8);
-
- /* step 6.2.4 Received Data Control */
- /* step 6.2.4.1 */
- set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 16, 0x2 << 16);
-
- /* step 6.2.4.2 */
- set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 18, 0x3 << 18);
-
- /* step 6.2.4.3 */
- set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 20, 0x0 << 20);
-
- /* step 6.2.4.4 */
- set_pcie_enable_bits(nb_dev, 0x40, 0x3 << 22, 0x1 << 22);
-
- /* step 6.2.5 PLL Power Down Control */
- /* step 6.2.5.1 */
- set_nbmisc_enable_bits(nb_dev, 0x35, 0x3 << 6, 0x0 << 6);
-
- /* step 6.2.6 Driving Strength Control */
- /* step 6.2.6.1 */
- set_nbmisc_enable_bits(nb_dev, 0x34, 0x1 << 24, 0x0 << 24);
-
- /* step 6.2.6.2 */
- set_nbmisc_enable_bits(nb_dev, 0x35, 0x3 << 2, 0x3 << 2);
- }
-
- printk(BIOS_INFO, "rs690_gfx_init step6.\n");
-
- /* step 7 compliance state, (only need if CMOS option is enabled) */
- /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
- if (cfg->gfx_compliance) {
- /* force compliance */
- set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
- /* release hold training for device 2. GFX initialization is done. */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
- dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
- printk(BIOS_INFO, "rs690_gfx_init step7.\n");
- return;
- }
-
- /* step 8 common initialization */
- /* step 8.1 sets RCB timeout to be 25ms */
- set_pcie_enable_bits(dev, 0x70, 7 << 16, 3 << 16);
- printk(BIOS_INFO, "rs690_gfx_init step8.1.\n");
-
- /* step 8.2 disables slave ordering logic */
- set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
- printk(BIOS_INFO, "rs690_gfx_init step8.2.\n");
-
- /* step 8.3 sets DMA payload size to 64 bytes */
- set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
- printk(BIOS_INFO, "rs690_gfx_init step8.3.\n");
-
- /* step 8.4 if the LTSSM could not see all 8 TS1 during Polling Active, it can still
- * time out and go back to Detect Idle.*/
- set_pcie_enable_bits(dev, 0x02, 1 << 14, 1 << 14);
- printk(BIOS_INFO, "rs690_gfx_init step8.4.\n");
-
- /* step 8.5 shortens the enumeration timer */
- set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
- printk(BIOS_INFO, "rs690_gfx_init step8.5.\n");
-
- /* step 8.6 blocks DMA traffic during C3 state */
- set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
- printk(BIOS_INFO, "rs690_gfx_init step8.6.\n");
-
- /* step 8.7 Do not gate the electrical idle form the PHY
- * step 8.8 Enables the escape from L1L23 */
- set_pcie_enable_bits(dev, 0xa0, 3 << 30, 3 << 30);
- printk(BIOS_INFO, "rs690_gfx_init step8.8.\n");
-
- /* step 8.9 Setting this register to 0x1 will workaround a PCI Compliance failure reported by Vista DTM.
- * SLOT_IMPLEMENTED@PCIE_CAP */
- reg16 = pci_read_config16(dev, 0x5a);
- reg16 |= 0x100;
- pci_write_config16(dev, 0x5a, reg16);
- printk(BIOS_INFO, "rs690_gfx_init step8.9.\n");
-
- /* step 8.10 Setting this register to 0x1 will hide the Advanced Error Rporting Capabilities in the PCIE Brider.
- * This will workaround several failures reported by the PCI Compliance test under Vista DTM. */
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 31, 0 << 31);
- printk(BIOS_INFO, "rs690_gfx_init step8.10.\n");
-
- /* step 8.11 Sets REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs during L1 so that txclk can be turned off. */
- set_pcie_enable_bits(nb_dev, 0x02, 1 << 0, 1 << 0);
- printk(BIOS_INFO, "rs690_gfx_init step8.11.\n");
-
- /* step 8.12 Sets REGS_LC_DONT_GO_TO_L0S_IF_L1_ARMED to prevent lc to go to from L0 to Rcv_L0s if L1 is armed. */
- set_pcie_enable_bits(nb_dev, 0x02, 1 << 6, 1 << 6);
- printk(BIOS_INFO, "rs690_gfx_init step8.12.\n");
-
- /* step 8.13 Sets CMGOOD_OVERRIDE. */
- set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
- printk(BIOS_INFO, "rs690_gfx_init step8.13.\n");
-
- /* step 9 Enable TLP Flushing, for non-AMD GFX devices and Hot-Plug devices only. */
- /* skip */
-
- /* step 10 Optional Features, only needed if CMOS option is enabled. */
- /* step 10.a: L0s */
- /* enabling L0s in the RS690 GFX port(s) */
- set_pcie_enable_bits(nb_dev, 0xF9, 3 << 13, 2 << 13);
- set_pcie_enable_bits(dev, 0xA0, 0xf << 8, 8 << 8);
- reg16 = pci_read_config16(dev, 0x68);
- reg16 |= 1 << 0;
- /* L0s is intended as a power saving state */
- /* pci_write_config16(dev, 0x68, reg16); */
-
- /* enabling L0s in the External GFX Device(s) */
-
- /* step 10.b: active state power management (ASPM L1) */
- /* TO DO */
-
- /* step 10.c: turning off PLL During L1/L23 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
-
- /* step 10.d: TXCLK clock gating */
- set_nbmisc_enable_bits(nb_dev, 0x7, 3, 3);
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
- set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
-
- /* step 10.e: LCLK clock gating, done in rs690_config_misc_clk() */
-
- /* step 11 Poll GPIO to determine whether it is single-port or dual-port configuration.
- * While details will be added later in the document, for now assue the single-port configuration. */
- /* skip */
-
- /* Single-port/Dual-port configureation. */
- switch (cfg->gfx_dual_slot) {
- case 0:
- single_port_configuration(nb_dev, dev);
- break;
- case 1:
- dual_port_configuration(nb_dev, dev);
- break;
- default:
- printk(BIOS_INFO, "Incorrect configuration of external gfx slot.\n");
- break;
- }
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "rs690.h"
-
-/* for UMA internal graphics */
-void avoid_lpc_dma_deadlock(device_t nb_dev, device_t sb_dev)
-{
- device_t k8_f0;
- u8 reg;
-
- k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- set_nbcfg_enable_bits(k8_f0, 0x68, 3 << 21, 1 << 21);
-
- reg = nbpcie_p_read_index(sb_dev, 0x10);
- reg |= 0x100; /* bit9=1 */
- nbpcie_p_write_index(sb_dev, 0x10, reg);
-
- reg = nbpcie_p_read_index(nb_dev, 0x10);
- reg |= 0x100; /* bit9=1 */
- nbpcie_p_write_index(nb_dev, 0x10, reg);
-
- /* Enable NP protocol over PCIE for memory-mapped writes targeting LPC
- * Set this bit to avoid a deadlock condition. */
- reg = htiu_read_index(nb_dev, 0x6);
- reg |= 0x1000000; /* bit26 */
- htiu_write_index(nb_dev, 0x6, reg);
-}
-
-static void pcie_init(struct device *dev)
-{
- /* Enable pci error detecting */
- u32 dword;
-
- printk(BIOS_INFO, "pcie_init in rs690_ht.c\n");
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* System error enable */
- dword |= (1 << 30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
- /*
- * 1 is APIC enable
- * 18 is enable nb to accept A4 interrupt request from SB.
- */
- dword = pci_read_config32(dev, 0x4C);
- dword |= 1 << 1 | 1 << 18; /* Clear possible errors */
- pci_write_config32(dev, 0x4C, dword);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations ht_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = pcie_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ht_driver __pci_driver = {
- .ops = &ht_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS690_HT,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <delay.h>
-#include "rs690.h"
-
-/*------------------------------------------------
-* Global variable
-------------------------------------------------*/
-PCIE_CFG AtiPcieCfg = {
- PCIE_ENABLE_STATIC_DEV_REMAP, /* Config */
- 0, /* ResetReleaseDelay */
- 0, /* Gfx0Width */
- 0, /* Gfx1Width */
- 0, /* GfxPayload */
- 0, /* GppPayload */
- 0, /* PortDetect, filled by GppSbInit */
- 0, /* PortHp */
- 0, /* DbgConfig */
- 0, /* DbgConfig2 */
- 0, /* GfxLx */
- 0, /* GppLx */
- 0, /* NBSBLx */
- 0, /* PortSlotInit */
- 0, /* Gfx0Pwr */
- 0, /* Gfx1Pwr */
- 0 /* GppPwr */
-};
-
-static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port);
-static void ValidatePortEn(device_t nb_dev);
-
-static void ValidatePortEn(device_t nb_dev)
-{
-}
-
-
-/*****************************************************************
-* Compliant with CIM_33's PCIEPowerOffGppPorts
-* Power off unused GPP lines
-*****************************************************************/
-static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
-{
- u32 reg;
- u16 state_save;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
- u8 state = cfg->port_enable;
-
- if (!(AtiPcieCfg.Config & PCIE_DISABLE_HIDE_UNUSED_PORTS))
- state &= AtiPcieCfg.PortDetect;
- state = ~state;
- state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7);
- state_save = state << 17;
- state &= !(AtiPcieCfg.PortHp);
- reg = nbmisc_read_index(nb_dev, 0x0c);
- reg |= state;
- nbmisc_write_index(nb_dev, 0x0c, reg);
-
- reg = nbmisc_read_index(nb_dev, 0x08);
- reg |= state_save;
- nbmisc_write_index(nb_dev, 0x08, reg);
-
- if ((AtiPcieCfg.Config & PCIE_OFF_UNUSED_GPP_LANES)
- && !(AtiPcieCfg.
- Config & (PCIE_DISABLE_HIDE_UNUSED_PORTS +
- PCIE_GFX_COMPLIANCE))) {
- }
-
- if (!cfg->gfx_tmds){
- /* step 3 Power Down Control for Southbridge */
- reg = nbpcie_p_read_index(dev, 0xa2);
-
- switch ((reg >> 4) & 0x7) { /* get bit 4-6, LC_LINK_WIDTH_RD */
- case 1:
- nbpcie_ind_write_index(nb_dev, 0x65, 0x0e0e);
- break;
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65, 0x0c0c);
- break;
- default:
- break;
- }
- }
-}
-
-#ifdef UNUSED_CODE
-static void pcie_init(struct device *dev)
-{
- /* Enable pci error detecting */
- u32 dword;
-
- printk(BIOS_DEBUG, "pcie_init in rs690_pcie.c\n");
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* System error enable */
- dword |= (1 << 30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-}
-#endif
-
-/**********************************************************************
-**********************************************************************/
-static void switching_gpp_configurations(device_t nb_dev, device_t sb_dev)
-{
- u32 reg;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- /* enables GPP reconfiguration */
- reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
- reg |=
- (RECONFIG_GPPSB_EN + RECONFIG_GPPSB_LINK_CONFIG +
- RECONFIG_GPPSB_ATOMIC_RESET);
- nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
-
- /* sets desired GPPSB configurations, bit4-7 */
- reg = nbmisc_read_index(nb_dev, 0x67);
- reg &= 0xffffff0f; /* clean */
- reg |= cfg->gpp_configuration << 4;
- nbmisc_write_index(nb_dev, 0x67, reg);
-
- /* read bit14 and write back its inverst value */
- reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
- reg ^= RECONFIG_GPPSB_GPPSB;
- nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
-
- /* delay 1ms */
- mdelay(1);
-
- /* waits until SB has trained to L0, poll for bit0-5 = 0x10 */
- do {
- reg = nbpcie_p_read_index(sb_dev, PCIE_LC_STATE0);
- reg &= 0x3f; /* remain LSB [5:0] bits */
- } while (LC_STATE_RECONFIG_GPPSB != reg);
-
- /* ensures that virtual channel negotiation is completed. poll for bit1 = 0 */
- do {
- reg =
- pci_ext_read_config32(nb_dev, sb_dev,
- PCIE_VC0_RESOURCE_STATUS);
- } while (reg & VC_NEGOTIATION_PENDING);
-}
-
-/*****************************************************************
-* The rs690 uses NBCONFIG:0x1c (BAR3) to map the PCIE Extended Configuration
-* Space to a 256MB range within the first 4GB of addressable memory.
-*****************************************************************/
-void enable_pcie_bar3(device_t nb_dev)
-{
- printk(BIOS_DEBUG, "enable_pcie_bar3()\n");
- set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register. */
- set_nbcfg_enable_bits(nb_dev, 0x84, 7 << 16, 0 << 16);
-
- pci_write_config32(nb_dev, 0x1C, EXT_CONF_BASE_ADDRESS); /* PCIEMiscInit */
- pci_write_config32(nb_dev, 0x20, 0x00000000);
- set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
- ProgK8TempMmioBase(1, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
-}
-
-/*****************************************************************
-* We should disable bar3 when we want to exit rs690_enable, because bar3 will be
-* remapped in set_resource later.
-*****************************************************************/
-void disable_pcie_bar3(device_t nb_dev)
-{
- printk(BIOS_DEBUG, "disable_pcie_bar3()\n");
- set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */
- pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */
- ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
-}
-
-/*****************************************
-* Compliant with CIM_33's PCIEGPPInit
-* nb_dev:
-* root bridge struct
-* dev:
-* p2p bridge struct
-* port:
-* p2p bridge number, 4-8
-*****************************************/
-void rs690_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
-{
- u8 reg8;
- u16 reg16;
- device_t sb_dev;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
- printk(BIOS_DEBUG, "gpp_sb_init nb_dev=0x%p, dev=0x%p, port=0x%x\n", nb_dev, dev, port);
-
- /* init GPP core */
- set_pcie_enable_bits(nb_dev, 0x20 | PCIE_CORE_INDEX_GPPSB, 1 << 8,
- 1 << 8);
- /* PCIE initialization 5.10.2: rpr 2.12*/
- set_pcie_enable_bits(nb_dev, 0x02 | PCIE_CORE_INDEX_GPPSB, 1 << 0, 1 << 0); /* no description in datasheet. */
-
- /* init GPPSB port */
- /* Sets RCB timeout to be 100ms by setting bits[18:16] to 3 b101 and shortens the enumeration timer by setting bit[19] to 1*/
- set_pcie_enable_bits(dev, 0x70, 0xF << 16, 0xd << 16);
- /* PCIE initialization 5.10.2: rpr 2.4 */
- set_pcie_enable_bits(dev, 0x02, ~0xffffffff, 1 << 14);
- /* Do not gate the electrical idle from the PHY and enables the escape from L1L23 */
- set_pcie_enable_bits(dev, 0xA0, ~0xffffffbf, (3 << 30) | (3 << 12) | (3 << 4));
- /* PCIE initialization 5.10.2: rpr 2.13 */
- set_pcie_enable_bits(dev, 0x02, ~0xffffffff, 1 << 6);
-
- /* SLOT_IMPLEMENTED in pcieConfig space */
- reg8 = pci_read_config8(dev, 0x5b);
- reg8 |= 1 << 0;
- pci_write_config8(dev, 0x5b, reg8);
-
- reg16 = pci_read_config16(dev, 0x5a);
- reg16 |= 0x100;
- pci_write_config16(dev, 0x5a, reg16);
- nbmisc_write_index(nb_dev, 0x34, 0);
-
- /* check compliance rpr step 2.1*/
- if (AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE) {
- u32 tmp;
- tmp = nbmisc_read_index(nb_dev, 0x67);
- tmp |= 1 << 3;
- nbmisc_write_index(nb_dev, 0x67, tmp);
- }
-
- /* step 5: dynamic slave CPL buffer allocation */
- set_pcie_enable_bits(nb_dev, 0x20 | PCIE_CORE_INDEX_GPPSB, 1 << 11, 1 << 11);
-
- /* step 5a: Training for GPP devices */
- /* init GPP */
- switch (port) {
- case 4: /* GPP */
- case 5:
- case 6:
- case 7:
- /* Blocks DMA traffic during C3 state */
- set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
- /* Enabels TLP flushing */
- set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
-
- /* check port enable */
- if (cfg->port_enable & (1 << port)) {
- PcieReleasePortTraining(nb_dev, dev, port);
- if (!(AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE)) {
- u8 res = PcieTrainPort(nb_dev, dev, port);
- printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res);
- if (res) {
- AtiPcieCfg.PortDetect |= 1 << port;
- }
- }
- }
- break;
- case 8: /* SB */
- break;
- }
- PciePowerOffGppPorts(nb_dev, dev, port);
-
- /* step 5b: GFX devices in a GPP slot */
-
- /* step 6a: VCI */
- sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
- if (port == 8) {
- /* The code below between #if and #endif causes a hang on HDA init.
- * So we skip it. */
-#if 0
- /* Clear bits 7:1 */
- pci_ext_write_config32(nb_dev, sb_dev, 0x114, 0x3f << 1, 0 << 1);
- /* Maps Traffic Class 1-7 to VC1 */
- pci_ext_write_config32(nb_dev, sb_dev, 0x120, 0x7f << 1, 0x7f << 1);
- /* Assigns VC ID to 1 */
- pci_ext_write_config32(nb_dev, sb_dev, 0x120, 7 << 24, 1 << 24);
- /* Enables VC1 */
- pci_ext_write_config32(nb_dev, sb_dev, 0x120, 1 << 31, 1 << 31);
-
- do {
- reg16 = pci_ext_read_config32(nb_dev, sb_dev, 0x124);
- reg16 &= 0x2;
- } while (reg16); /*bit[1] = 0 means VC1 flow control initialization is successful */
-#endif
- }
-
- /* step 6b: L0s for the southbridge link */
- /* To enalbe L0s in the southbridage*/
-
- /* step 6c: L0s for the GPP link(s) */
- /* To eable L0s in the RS690 for the GPP port(s) */
- set_pcie_enable_bits(nb_dev, 0xf9, 3 << 13, 2 << 13);
- set_pcie_enable_bits(dev, 0xa0, 0xf << 8, 0x9 << 8);
- reg16 = pci_read_config16(dev, 0x68);
- reg16 |= 1 << 0;
- pci_write_config16(dev, 0x68, reg16);
-
- /* step 6d: ASPM L1 for the southbridge link */
- /* To enalbe L1s in the southbridage*/
-
- /* step 6e: ASPM L1 for GPP link(s) */;
- set_pcie_enable_bits(nb_dev, 0xf9, 3 << 13, 2 << 13);
- set_pcie_enable_bits(dev, 0xa0, 3 << 12, 3 << 12);
- set_pcie_enable_bits(dev, 0xa0, 0xf << 4, 3 << 4);
- reg16 = pci_read_config16(dev, 0x68);
- reg16 &= ~0xff;
- reg16 |= 1 << 1;
- pci_write_config16(dev, 0x68, reg16);
-
- /* step 6f: Turning off PLL during L1/L23 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
-
- /* step 6g: TXCLK clock gating */
- set_nbmisc_enable_bits(nb_dev, 0x7, 3 << 4, 3 << 4);
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
- set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
-
- /* step 6h: LCLK clock gating, done in rs690_config_misc_clk() */
-}
-
-/*****************************************
-* Compliant with CIM_33's PCIEConfigureGPPCore
-*****************************************/
-void config_gpp_core(device_t nb_dev, device_t sb_dev)
-{
- u32 reg;
- struct southbridge_amd_rs690_config *cfg =
- (struct southbridge_amd_rs690_config *)nb_dev->chip_info;
-
- reg = nbmisc_read_index(nb_dev, 0x20);
- if (AtiPcieCfg.Config & PCIE_ENABLE_STATIC_DEV_REMAP)
- reg &= 0xfffffffd; /* set bit1 = 0 */
- else
- reg |= 0x2; /* set bit1 = 1 */
- nbmisc_write_index(nb_dev, 0x20, reg);
-
- reg = nbmisc_read_index(nb_dev, 0x67); /* get STRAP_BIF_LINK_CONFIG_GPPSB at bit 4-7 */
- if (cfg->gpp_configuration != ((reg >> 4) & 0xf))
- switching_gpp_configurations(nb_dev, sb_dev);
- ValidatePortEn(nb_dev);
-}
-
-#ifdef UNUSED_CODE
-/*****************************************
-* Compliant with CIM_33's PCIEMiscClkProg
-*****************************************/
-void pcie_config_misc_clk(device_t nb_dev)
-{
- u32 reg;
- struct bus pbus; /* fake bus for dev0 fun1 */
-
- reg = pci_read_config32(nb_dev, 0x4c);
- reg |= 1 << 0;
- pci_write_config32(nb_dev, 0x4c, reg);
-
- if (AtiPcieCfg.Config & PCIE_GFX_CLK_GATING) {
- /* TXCLK Clock Gating */
- set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 0, 3 << 0);
- set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22);
- set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_GFX, (3 << 6) | (~0xf), 3 << 6);
-
- /* LCLK Clock Gating */
- reg = pci_cf8_conf1.read32(&pbus, 0, 1, 0x94);
- reg &= ~(1 << 16);
- pci_cf8_conf1.write32(&pbus, 0, 1, 0x94, reg);
- }
-
- if (AtiPcieCfg.Config & PCIE_GPP_CLK_GATING) {
- /* TXCLK Clock Gating */
- set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 4, 3 << 4);
- set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22);
- set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_GPPSB, (3 << 6) | (~0xf), 3 << 6);
-
- /* LCLK Clock Gating */
- reg = pci_cf8_conf1.read32(&pbus, 0, 1, 0x94);
- reg &= ~(1 << 24);
- pci_cf8_conf1.write32(&pbus, 0, 1, 0x94, reg);
- }
-
- reg = pci_read_config32(nb_dev, 0x4c);
- reg &= ~(1 << 0);
- pci_write_config32(nb_dev, 0x4c, reg);
-}
-#endif
driver-y += rs780.c
-driver-y += rs780_cmn.c
-driver-y += rs780_pcie.c
-driver-y += rs780_ht.c
-driver-y += rs780_gfx.c
+driver-y += cmn.c
+driver-y += pcie.c
+driver-y += ht.c
+driver-y += gfx.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+
+#include <arch/io.h>
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <boot/coreboot_tables.h>
+#include <delay.h>
+#include <cpu/cpu.h>
+#include "rs780.h"
+
+static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
+{
+ pci_write_config32(dev, index_reg, index);
+ return pci_read_config32(dev, index_reg + 0x4);
+}
+
+static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
+{
+ pci_write_config32(dev, index_reg, index);
+ pci_write_config32(dev, index_reg + 0x4, data);
+}
+
+/* extension registers */
+u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
+{
+ /*get BAR3 base address for nbcfg0x1c */
+ u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
+ printk(BIOS_DEBUG, "addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
+ dev->path.pci.devfn);
+ addr |= dev->bus->secondary << 20 | /* bus num */
+ dev->path.pci.devfn << 12 | reg;
+ return *((u32 *) addr);
+}
+
+void pci_ext_write_config32(device_t nb_dev, device_t dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+
+ /*get BAR3 base address for nbcfg0x1c */
+ u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
+ /*printk(BIOS_DEBUG, "write: addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
+ dev->path.pci.devfn);*/
+ addr |= dev->bus->secondary << 20 | /* bus num */
+ dev->path.pci.devfn << 12 | reg_pos;
+
+ reg = reg_old = *((u32 *) addr);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ *((u32 *) addr) = reg;
+ }
+}
+
+u32 nbmisc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMISC_INDEX, (index));
+}
+
+void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
+}
+
+u32 nbpcie_p_read_index(device_t dev, u32 index)
+{
+ return nb_read_index((dev), NBPCIE_INDEX, (index));
+}
+
+void nbpcie_p_write_index(device_t dev, u32 index, u32 data)
+{
+ nb_write_index((dev), NBPCIE_INDEX, (index), (data));
+}
+
+u32 nbpcie_ind_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBPCIE_INDEX, (index));
+}
+
+void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBPCIE_INDEX, (index), (data));
+}
+
+u32 htiu_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
+}
+
+void htiu_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
+}
+
+u32 nbmc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMC_INDEX, (index));
+}
+
+void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
+}
+
+void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = pci_read_config32(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config32(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask, u8 val)
+{
+ u8 reg_old, reg;
+ reg = reg_old = pci_read_config8(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config8(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = htiu_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ htiu_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmisc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+void set_pcie_enable_bits(device_t dev, u32 reg_pos, u32 mask, u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nb_read_index(dev, NBPCIE_INDEX, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nb_write_index(dev, NBPCIE_INDEX, reg_pos, reg);
+ }
+}
+
+/***********************************************************
+* To access bar3 we need to program PCI MMIO 7 in K8.
+* in_out:
+* 1: enable/enter k8 temp mmio base
+* 0: disable/restore
+***********************************************************/
+void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
+{
+ /* K8 Function1 is address map */
+ device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+
+ if (in_out) {
+ u32 dword, sblk;
+
+ /* Get SBLink value (HyperTransport I/O Hub Link ID). */
+ dword = pci_read_config32(k8_f0, 0x64);
+ sblk = (dword >> 8) & 0x3;
+
+ /* Fill MMIO limit/base pair. */
+ pci_write_config32(k8_f1, 0xbc,
+ (((pcie_base_add + 0x10000000 -
+ 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
+ pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
+ pci_write_config32(k8_f1, 0xb4,
+ (((mmio_base_add + 0x10000000 -
+ 1) >> 8) & 0xffffff00) | (sblk << 4));
+ pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
+ } else {
+ pci_write_config32(k8_f1, 0xb8, 0);
+ pci_write_config32(k8_f1, 0xbc, 0);
+ pci_write_config32(k8_f1, 0xb0, 0);
+ pci_write_config32(k8_f1, 0xb4, 0);
+ }
+}
+
+void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port)
+{
+ switch (port) {
+ case 2: /* GFX, bit4-5 */
+ case 3:
+ set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
+ 1 << (port + 2), 0 << (port + 2));
+ break;
+ case 4: /* GPPSB, bit20-24 */
+ case 5:
+ case 6:
+ case 7:
+ set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
+ 1 << (port + 17), 0 << (port + 17));
+ break;
+ case 9: /* GPP, bit 4,5 of miscind 0x2D */
+ case 10:
+ set_nbmisc_enable_bits(nb_dev, 0x2D,
+ 1 << (port - 5), 0 << (port - 5));
+ break;
+ }
+}
+
+/********************************************************************************************************
+* Output:
+* 0: no device is present.
+* 1: device is present and is trained.
+********************************************************************************************************/
+u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port)
+{
+ u16 count = 5000;
+ u32 lc_state, reg, current_link_width, lane_mask;
+ int8_t current, res = 0;
+ u32 gfx_gpp_sb_sel;
+ void set_pcie_dereset(void);
+ void set_pcie_reset(void);
+
+ switch (port) {
+ case 2 ... 3:
+ gfx_gpp_sb_sel = PCIE_CORE_INDEX_GFX;
+ break;
+ case 4 ... 7:
+ gfx_gpp_sb_sel = PCIE_CORE_INDEX_GPPSB;
+ break;
+ case 9 ... 10:
+ gfx_gpp_sb_sel = PCIE_CORE_INDEX_GPP;
+ break;
+ default:
+ gfx_gpp_sb_sel = -1;
+ return 0;
+ }
+
+ while (count--) {
+ mdelay(40);
+ udelay(200);
+ lc_state = nbpcie_p_read_index(dev, 0xa5); /* lc_state */
+ printk(BIOS_DEBUG, "PcieLinkTraining port=%x:lc current state=%x\n",
+ port, lc_state);
+ current = lc_state & 0x3f; /* get LC_CURRENT_STATE, bit0-5 */
+
+ switch (current) {
+ case 0x00: /* 0x00-0x04 means no device is present */
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x04:
+ res = 0;
+ count = 0;
+ break;
+ case 0x06:
+ /* read back current link width [6:4]. */
+ current_link_width = (nbpcie_p_read_index(dev, 0xA2) >> 4) & 0x7;
+ /* 4 means 7:4 and 15:12
+ * 3 means 7:2 and 15:10
+ * 2 means 7:1 and 15:9
+ * egnoring the reversal case
+ */
+ lane_mask = (0xFF << (current_link_width - 2) * 2) & 0xFF;
+ reg = nbpcie_ind_read_index(nb_dev, 0x65 | gfx_gpp_sb_sel);
+ reg |= lane_mask << 8 | lane_mask;
+ reg = 0xE0E0; /* TODO: See the comments in rs780_pcie.c, at about line 145. */
+ nbpcie_ind_write_index(nb_dev, 0x65 | gfx_gpp_sb_sel, reg);
+ printk(BIOS_DEBUG, "link_width=%x, lane_mask=%x",
+ current_link_width, lane_mask);
+ set_pcie_reset();
+ mdelay(1);
+ set_pcie_dereset();
+ break;
+ case 0x07: /* device is in compliance state (training sequence is done). Move to train the next device */
+ res = 0;
+ count = 0;
+ break;
+ case 0x10:
+ reg =
+ pci_ext_read_config32(nb_dev, dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ printk(BIOS_DEBUG, "PcieTrainPort reg=0x%x\n", reg);
+ /* check bit1 */
+ if (reg & VC_NEGOTIATION_PENDING) { /* bit1=1 means the link needs to be re-trained. */
+ /* set bit8=1, bit0-2=bit4-6 */
+ u32 tmp;
+ reg =
+ nbpcie_p_read_index(dev,
+ PCIE_LC_LINK_WIDTH);
+ tmp = (reg >> 4) && 0x3; /* get bit4-6 */
+ reg &= 0xfff8; /* clear bit0-2 */
+ reg += tmp; /* merge */
+ reg |= 1 << 8;
+ count++; /* CIM said "keep in loop"? */
+ } else {
+ res = 1;
+ count = 0;
+ }
+ break;
+ default: /* reset pcie */
+ res = 0;
+ count = 0; /* break loop */
+ break;
+ }
+ }
+ return res;
+}
+
+/*
+* Compliant with CIM_33's ATINB_SetToms.
+* Set Top Of Memory below and above 4G.
+*/
+void rs780_set_tom(device_t nb_dev)
+{
+ extern uint64_t uma_memory_base;
+
+ /* set TOM */
+ pci_write_config32(nb_dev, 0x90, uma_memory_base);
+ //nbmc_write_index(nb_dev, 0x1e, uma_memory_base);
+}
+
+// extract single bit
+u32 extractbit(u32 data, int bit_number)
+{
+ return (data >> bit_number) & 1;
+}
+
+// extract bit field
+u32 extractbits(u32 source, int lsb, int msb)
+{
+ int field_width = msb - lsb + 1;
+ u32 mask = 0xFFFFFFFF >> (32 - field_width);
+ return (source >> lsb) & mask;
+}
+
+// return AMD cpuid family
+int cpuidFamily(void)
+{
+ u32 baseFamily, extendedFamily, fms;
+
+ fms = cpuid_eax (1);
+ baseFamily = extractbits (fms, 8, 11);
+ extendedFamily = extractbits (fms, 20, 27);
+ return baseFamily + extendedFamily;
+}
+
+
+// return non-zero for AMD family 0Fh processor found
+int is_family0Fh(void)
+{
+ return cpuidFamily() == 0x0F;
+}
+
+
+// return non-zero for AMD family 10h processor found
+int is_family10h(void)
+{
+ return cpuidFamily() == 0x10;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef CONFIG_NORTHBRIDGE_AMD_AMDFAM10
+#define CONFIG_NORTHBRIDGE_AMD_AMDFAM10 0
+#endif
+
+#include "rev.h"
+
+#define NBHTIU_INDEX 0x94 /* Note: It is different with RS690, whose HTIU index is 0xA8 */
+#define NBMISC_INDEX 0x60
+#define NBMC_INDEX 0xE8
+
+static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
+{
+ pci_write_config32(dev, index_reg, index);
+ return pci_read_config32(dev, index_reg + 0x4);
+}
+
+static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
+{
+ pci_write_config32(dev, index_reg, index /* | 0x80 */ );
+ pci_write_config32(dev, index_reg + 0x4, data);
+}
+
+static u32 nbmisc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMISC_INDEX, (index));
+}
+
+static void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
+}
+
+static u32 htiu_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
+}
+
+static void htiu_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
+}
+
+static u32 nbmc_read_index(device_t nb_dev, u32 index)
+{
+ return nb_read_index((nb_dev), NBMC_INDEX, (index));
+}
+
+static void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
+{
+ nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
+}
+
+static void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = htiu_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ htiu_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmisc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = pci_read_config32(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config32(nb_dev, reg_pos, reg);
+ }
+}
+/* family 10 only, for reg > 0xFF */
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1
+static void set_fam10_ext_cfg_enable_bits(device_t fam10_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = Get_NB32(fam10_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ Set_NB32(fam10_dev, reg_pos, reg);
+ }
+}
+#else
+#define set_fam10_ext_cfg_enable_bits(a, b, c, d) do {} while (0)
+#endif
+
+
+static void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask,
+ u8 val)
+{
+ u8 reg_old, reg;
+ reg = reg_old = pci_read_config8(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ pci_write_config8(nb_dev, reg_pos, reg);
+ }
+}
+
+static void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
+ u32 val)
+{
+ u32 reg_old, reg;
+ reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
+ reg &= ~mask;
+ reg |= val;
+ if (reg != reg_old) {
+ nbmc_write_index(nb_dev, reg_pos, reg);
+ }
+}
+
+static void get_cpu_rev(void)
+{
+ u32 eax;
+
+ eax = cpuid_eax(1);
+ printk(BIOS_INFO, "get_cpu_rev EAX=0x%x.\n", eax);
+ if (eax <= 0xfff)
+ printk(BIOS_INFO, "CPU Rev is K8_Cx.\n");
+ else if (eax <= 0x10fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Dx.\n");
+ else if (eax <= 0x20fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Ex.\n");
+ else if (eax <= 0x40fff)
+ printk(BIOS_INFO, "CPU Rev is K8_Fx.\n");
+ else if (eax == 0x60fb1 || eax == 0x60f81) /*These two IDS are exception, they are G1. */
+ printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
+ else if (eax <= 0X60FF0)
+ printk(BIOS_INFO, "CPU Rev is K8_G0.\n");
+ else if (eax <= 0x100000)
+ printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
+ else if (eax <= 0x100f00)
+ printk(BIOS_INFO, "CPU Rev is Fam 10.\n");
+ else
+ printk(BIOS_INFO, "CPU Rev is K8_10.\n");
+}
+
+static u8 is_famly10(void)
+{
+ return (cpuid_eax(1) & 0xff00000) != 0;
+}
+
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
+static u8 l3_cache(void)
+{
+ return (cpuid_edx(0x80000006) & (0x3FFF << 18)) != 0;
+}
+
+static u8 cpu_core_number(void)
+{
+ return (cpuid_ecx(0x80000008) & 0xFF) + 1;
+}
+#endif
+
+static u8 get_nb_rev(device_t nb_dev)
+{
+ u8 reg;
+ reg = pci_read_config8(nb_dev, 0x89); /* copy from CIM, can't find in doc */
+ switch(reg & 3)
+ {
+ case 0x01:
+ reg = REV_RS780_A12;
+ break;
+ case 0x02:
+ reg = REV_RS780_A13;
+ break;
+ default:
+ reg = REV_RS780_A11;
+ break;
+ }
+ return reg;
+}
+
+/*****************************************
+ * Init HT link speed/width for rs780 -- k8 link
+ * 1: Check CPU Family, Family10?
+ * 2: Get CPU's HT speed and width
+ * 3: Decide HT mode 1 or 3 by HT Speed. >1GHz: HT3, else HT1
+ *****************************************/
+static const u8 rs780_ibias[] = {
+ /* 1, 3 are reserved. */
+ [0x0] = 0x4C, /* 200Mhz HyperTransport 1 only */
+ [0x2] = 0x4C, /* 400Mhz HyperTransport 1 only */
+ [0x4] = 0xB6, /* 600Mhz HyperTransport 1 only */
+ [0x5] = 0x4C, /* 800Mhz HyperTransport 1 only */
+ [0x6] = 0x9D, /* 1Ghz HyperTransport 1 only */
+ /* HT3 for Family 10 */
+ [0x7] = 0xB6, /* 1.2Ghz HyperTransport 3 only */
+ [0x8] = 0x2B, /* 1.4Ghz HyperTransport 3 only */
+ [0x9] = 0x4C, /* 1.6Ghz HyperTransport 3 only */
+ [0xa] = 0x6C, /* 1.8Ghz HyperTransport 3 only */
+ [0xb] = 0x9D, /* 2.0Ghz HyperTransport 3 only */
+ [0xc] = 0xAD, /* 2.2Ghz HyperTransport 3 only */
+ [0xd] = 0xB6, /* 2.4Ghz HyperTransport 3 only */
+ [0xe] = 0xC6, /* 2.6Ghz HyperTransport 3 only */
+};
+
+static void rs780_htinit(void)
+{
+ /*
+ * About HT, it has been done in enumerate_ht_chain().
+ */
+ device_t cpu_f0, rs780_f0, clk_f1;
+ u32 reg;
+ u8 cpu_ht_freq, ibias;
+
+ cpu_f0 = PCI_DEV(0, 0x18, 0);
+ /************************
+ * get cpu's ht freq, in cpu's function 0, offset 0x88
+ * bit11-8, specifics the maximum operation frequency of the link's transmitter clock.
+ * The link frequency field (Frq) is cleared by cold reset. SW can write a nonzero
+ * value to this reg, and that value takes effect on the next warm reset or
+ * LDTSTOP_L disconnect sequence.
+ * please see the table rs780_ibias about the value and its corresponding frequency.
+ ************************/
+ reg = pci_read_config32(cpu_f0, 0x88);
+ cpu_ht_freq = (reg & 0xf00) >> 8;
+ printk(BIOS_INFO, "rs780_htinit cpu_ht_freq=%x.\n", cpu_ht_freq);
+ rs780_f0 = PCI_DEV(0, 0, 0);
+ //set_nbcfg_enable_bits(rs780_f0, 0xC8, 0x7<<24 | 0x7<<28, 1<<24 | 1<<28);
+
+ clk_f1 = PCI_DEV(0, 0, 1); /* We need to make sure the F1 is accessible. */
+
+ ibias = rs780_ibias[cpu_ht_freq];
+
+ /* If HT freq>1GHz, we assume the CPU is fam10, else it is K8.
+ * Is it appropriate?
+ * Frequency is 1GHz, i.e. cpu_ht_freq is 6, in most cases.
+ * So we check 6 only, it would be faster. */
+ if ((cpu_ht_freq == 0x6) || (cpu_ht_freq == 0x5) || (cpu_ht_freq == 0x4) ||
+ (cpu_ht_freq == 0x2) || (cpu_ht_freq == 0x0)) {
+ printk(BIOS_INFO, "rs780_htinit: HT1 mode\n");
+
+ /* HT1 mode, RPR 8.4.2 */
+ /* set IBIAS code */
+ set_nbcfg_enable_bits(clk_f1, 0xD8, 0x3FF, ibias);
+ /* Optimizes chipset HT transmitter drive strength */
+ set_htiu_enable_bits(rs780_f0, 0x2A, 0x3, 0x1);
+ } else if ((cpu_ht_freq > 0x6) && (cpu_ht_freq < 0xf)) {
+ printk(BIOS_INFO, "rs780_htinit: HT3 mode\n");
+
+ #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
+ /* HT3 mode, RPR 8.4.3 */
+ set_nbcfg_enable_bits(rs780_f0, 0x9c, 0x3 << 16, 0);
+
+ /* set IBIAS code */
+ set_nbcfg_enable_bits(clk_f1, 0xD8, 0x3FF, ibias);
+ /* Optimizes chipset HT transmitter drive strength */
+ set_htiu_enable_bits(rs780_f0, 0x2A, 0x3, 0x1);
+ /* Enables error-retry mode */
+ set_nbcfg_enable_bits(rs780_f0, 0x44, 0x1, 0x1);
+ /* Enables scrambling and Disalbes command throttling */
+ set_nbcfg_enable_bits(rs780_f0, 0xac, (1 << 3) | (1 << 14), (1 << 3) | (1 << 14));
+ /* Enables transmitter de-emphasis */
+ set_nbcfg_enable_bits(rs780_f0, 0xa4, 1 << 31, 1 << 31);
+ /* Enabels transmitter de-emphasis level */
+ /* Sets training 0 time */
+ set_nbcfg_enable_bits(rs780_f0, 0xa0, 0x3F, 0x14);
+
+ /* Enables strict TM4 detection */
+ set_htiu_enable_bits(rs780_f0, 0x15, 0x1 << 22, 0x1 << 22);
+ /* Enables proprer DLL reset sequence */
+ set_htiu_enable_bits(rs780_f0, 0x16, 0x1 << 10, 0x1 << 10);
+
+ /* HyperTransport 3 Processor register settings to be done in northbridge */
+ /* Enables error-retry mode */
+ set_fam10_ext_cfg_enable_bits(cpu_f0, 0x130, 1 << 0, 1 << 0);
+ /* Enables scrambling */
+ set_fam10_ext_cfg_enable_bits(cpu_f0, 0x170, 1 << 3, 1 << 3);
+ /* Enables transmitter de-emphasis
+ * This depends on the PCB design and the trace */
+ /* TODO: */
+ /* Disables command throttling */
+ set_fam10_ext_cfg_enable_bits(cpu_f0, 0x168, 1 << 10, 1 << 10);
+ /* Sets Training 0 Time. See T0Time table for encodings */
+ set_fam10_ext_cfg_enable_bits(cpu_f0, 0x16C, 0x3F, 0x20);
+ /* TODO: */
+ #endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 */
+ }
+}
+
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1 /* save some spaces */
+/*******************************************************
+* Optimize k8 with UMA.
+* See BKDG_NPT_0F guide for details.
+* The processor node is addressed by its Node ID on the HT link and can be
+* accessed with a device number in the PCI configuration space on Bus0.
+* The Node ID 0 is mapped to Device 24 (0x18), the Node ID 1 is mapped
+* to Device 25, and so on.
+* The processor implements configuration registers in PCI configuration
+* space using the following four headers
+* Function0: HT technology configuration
+* Function1: Address map configuration
+* Function2: DRAM and HT technology Trace mode configuration
+* Function3: Miscellaneous configuration
+*******************************************************/
+static void k8_optimization(void)
+{
+ device_t k8_f0, k8_f2, k8_f3;
+ msr_t msr;
+
+ printk(BIOS_INFO, "k8_optimization()\n");
+ k8_f0 = PCI_DEV(0, 0x18, 0);
+ k8_f2 = PCI_DEV(0, 0x18, 2);
+ k8_f3 = PCI_DEV(0, 0x18, 3);
+
+ /* 8.6.6 K8 Buffer Allocation Settings */
+ pci_write_config32(k8_f0, 0x90, 0x01700169); /* CIM NPT_Optimization */
+ set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 28, 0 << 28);
+ set_nbcfg_enable_bits(k8_f0, 0x68, 3 << 26, 3 << 26);
+ set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 11, 1 << 11);
+ /* set_nbcfg_enable_bits(k8_f0, 0x84, 1 << 11 | 1 << 13 | 1 << 15, 1 << 11 | 1 << 13 | 1 << 15); */ /* TODO */
+
+ pci_write_config32(k8_f3, 0x70, 0x51220111);
+ pci_write_config32(k8_f3, 0x74, 0x50404021);
+ pci_write_config32(k8_f3, 0x78, 0x08002A00);
+ if (pci_read_config32(k8_f3, 0xE8) & 0x3<<12)
+ pci_write_config32(k8_f3, 0x7C, 0x0000211A); /* dual core */
+ else
+ pci_write_config32(k8_f3, 0x7C, 0x0000212B); /* single core */
+ set_nbcfg_enable_bits_8(k8_f3, 0xDC, 0xFF, 0x25);
+
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
+ set_nbcfg_enable_bits(k8_f2, 0x94, 0xF << 24, 7 << 24);
+ set_nbcfg_enable_bits(k8_f2, 0x90, 1 << 10, 0 << 10);
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 3 << 2, 3 << 2);
+ set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
+
+ msr = rdmsr(0xC001001F);
+ msr.lo &= ~(1 << 9);
+ msr.hi &= ~(1 << 4);
+ wrmsr(0xC001001F, msr);
+}
+#else
+#define k8_optimization() do{}while(0)
+#endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1 */
+
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
+static void fam10_optimization(void)
+{
+ device_t cpu_f0, cpu_f2, cpu_f3;
+ u32 val;
+
+ printk(BIOS_INFO, "fam10_optimization()\n");
+
+ cpu_f0 = PCI_DEV(0, 0x18, 0);
+ cpu_f2 = PCI_DEV(0, 0x18, 2);
+ cpu_f3 = PCI_DEV(0, 0x18, 3);
+
+ /* 8.6.4.1 */
+ /* Table 8-13 */
+ pci_write_config32(cpu_f0, 0x90, 0x808502D0);
+ /* Table 8-14 */
+ pci_write_config32(cpu_f0, 0x94, 0x00000000);
+
+ /* Table 8-15 */
+ val = pci_read_config32(cpu_f0, 0x68);
+ val |= 1 << 24;
+ pci_write_config32(cpu_f0, 0x68, val);
+
+ /* Table 8-16 */
+ val = pci_read_config32(cpu_f0, 0x84);
+ val &= ~(1 << 12);
+ pci_write_config32(cpu_f0, 0x84, val);
+
+ /* Table 8-17 */
+ val = pci_read_config32(cpu_f2, 0x90);
+ val &= ~(1 << 10);
+ pci_write_config32(cpu_f2, 0x90, val);
+
+ /* Table 8-18 */
+ pci_write_config32(cpu_f3, 0x6C, 0x60018051);
+ /* Table 8-19 */
+ pci_write_config32(cpu_f3, 0x70, 0x60321151);
+ /* Table 8-20 */
+ pci_write_config32(cpu_f3, 0x74, 0x00980101);
+ /* Table 8-21 */
+ pci_write_config32(cpu_f3, 0x78, 0x00200C14);
+ /* Table 8-22 */
+ pci_write_config32(cpu_f3, 0x7C, 0x00070811); /* TODO: Check if L3 Cache is enabled. */
+
+ /* Table 8-23 */
+ Set_NB32(cpu_f3, 0x140, 0x00D33656);
+ /* Table 8-24 */
+ Set_NB32(cpu_f3, 0x144, 0x00000036);
+ /* Table 8-25 */
+ Set_NB32(cpu_f3, 0x148, 0x8000832A);
+ /* Table 8-26 */
+ Set_NB32(cpu_f3, 0x158, 0);
+ /* L3 Disabled: L3 Enabled: */
+ /* cores: 2 3 4 2 3 4 */
+ /* bit8:4 28 26 24 24 20 16 */
+ if (!l3_cache()) {
+ Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (24 + 2*(4-cpu_core_number())) << 4 | 2);
+ } else {
+ Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (16 + 4*(4-cpu_core_number())) << 4 | 4);
+ }
+}
+#else
+#define fam10_optimization() do{}while(0)
+#endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 */
+
+/*****************************************
+* rs780_por_pcicfg_init()
+*****************************************/
+static void rs780_por_pcicfg_init(device_t nb_dev)
+{
+ /* enable PCI Memory Access */
+ set_nbcfg_enable_bits_8(nb_dev, 0x04, (u8)(~0xFD), 0x02);
+ /* Set RCRB Enable */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x1);
+ /* allow decode of 640k-1MB */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xEF), 0x10);
+ /* Enable PM2_CNTL(BAR2) IO mapped cfg write access to be broadcast to both NB and SB */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x4);
+ /* Power Management Register Enable */
+ set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x80);
+
+ /* Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
+ * Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
+ * BMMsgEn */
+ set_nbcfg_enable_bits_8(nb_dev, 0x4C, (u8)(~0x00), 0x42 | 1);
+
+ /* Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
+ * Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge */
+ set_nbcfg_enable_bits_8(nb_dev, 0x4E, (u8)(~0xFF), 0x05);
+ /* Reg94h[4:0] = 0x0 P drive strength offset 0
+ * Reg94h[6:5] = 0x2 P drive strength additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x94, (u8)(~0x80), 0x40);
+
+ /* Reg94h[20:16] = 0x0 N drive strength offset 0
+ * Reg94h[22:21] = 0x2 N drive strength additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x96, (u8)(~0x80), 0x40);
+
+ /* Reg80h[4:0] = 0x0 Termination offset
+ * Reg80h[6:5] = 0x2 Termination additive adjust */
+ set_nbcfg_enable_bits_8(nb_dev, 0x80, (u8)(~0x80), 0x40);
+
+ /* Reg80h[14] = 0x1 Enable receiver termination control */
+ set_nbcfg_enable_bits_8(nb_dev, 0x81, (u8)(~0xFF), 0x40);
+
+ /* Reg94h[15] = 0x1 Enables HT transmitter advanced features to be turned on
+ * Reg94h[14] = 0x1 Enable drive strength control */
+ set_nbcfg_enable_bits_8(nb_dev, 0x95, (u8)(~0x3F), 0xC4);
+
+ /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */
+ set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
+
+ /* Reg8Ch[9] enables Gfx Debug BAR programming
+ * Reg8Ch[10] enables Gfx Debug BAR operation
+ * Enable programming of the debug bar now, but enable
+ * operation only after it has been programmed */
+ set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x02);
+}
+
+static void rs780_por_mc_index_init(device_t nb_dev)
+{
+ set_nbmc_enable_bits(nb_dev, 0x7A, ~0xFFFFFF80, 0x0000005F);
+ set_nbmc_enable_bits(nb_dev, 0xD8, ~0x00000000, 0x00600060);
+ set_nbmc_enable_bits(nb_dev, 0xD9, ~0x00000000, 0x00600060);
+ set_nbmc_enable_bits(nb_dev, 0xE0, ~0x00000000, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xE1, ~0x00000000, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xE8, ~0x00000000, 0x003E003E);
+ set_nbmc_enable_bits(nb_dev, 0xE9, ~0x00000000, 0x003E003E);
+}
+
+static void rs780_por_misc_index_init(device_t nb_dev)
+{
+ /* NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
+ * Block non-snoop DMA request if PMArbDis is set.
+ * Set BMSetDis */
+ set_nbmisc_enable_bits(nb_dev, 0x0B, ~0xFFFF0000, 0x00000180);
+ set_nbmisc_enable_bits(nb_dev, 0x01, ~0xFFFFFFFF, 0x00000040);
+
+ /* NBCFG (NBMISCIND 0x0): NB_CNTL -
+ * HIDE_NB_AGP_CAP ([0], default=1)HIDE
+ * HIDE_P2P_AGP_CAP ([1], default=1)HIDE
+ * HIDE_NB_GART_BAR ([2], default=1)HIDE
+ * AGPMODE30 ([4], default=0)DISABLE
+ * AGP30ENCHANCED ([5], default=0)DISABLE
+ * HIDE_AGP_CAP ([8], default=1)ENABLE */
+ set_nbmisc_enable_bits(nb_dev, 0x00, ~0xFFFF0000, 0x00000506); /* set bit 10 for MSI */
+
+ /* NBMISCIND:0x6A[16]= 1 SB link can get a full swing
+ * set_nbmisc_enable_bits(nb_dev, 0x6A, 0ffffffffh, 000010000);
+ * NBMISCIND:0x6A[17]=1 Set CMGOOD_OVERRIDE. */
+ set_nbmisc_enable_bits(nb_dev, 0x6A, ~0xffffffff, 0x00020000);
+
+ /* NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow LVDS or PWM features to work. */
+ set_nbmisc_enable_bits(nb_dev, 0x40, ~0xffffffff, 0x00000500);
+
+ /* NBMISIND:0xC Bit[13]=1 Enable GSM mode for C1e or C3 with pop-up. */
+ set_nbmisc_enable_bits(nb_dev, 0x0C, ~0xffffffff, 0x00002000);
+
+ /* Set NBMISIND:0x1F[3] to map NB F2 interrupt pin to INTB# */
+ set_nbmisc_enable_bits(nb_dev, 0x1F, ~0xffffffff, 0x00000008);
+
+ /*
+ * Enable access to DEV8
+ * Enable setPower message for all ports
+ */
+ set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 6, 1 << 6);
+ set_nbmisc_enable_bits(nb_dev, 0x0b, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x51, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x53, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x55, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x57, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x59, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x5B, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x5D, 1 << 20, 1 << 20);
+ set_nbmisc_enable_bits(nb_dev, 0x5F, 1 << 20, 1 << 20);
+
+ set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 7, 1 << 7);
+ set_nbmisc_enable_bits(nb_dev, 0x07, 0x000000f0, 0x30);
+
+ set_nbmisc_enable_bits(nb_dev, 0x01, 0xFFFFFFFF, 0x48);
+ /* Disable bus-master trigger event from SB and Enable set_slot_power message to SB */
+ set_nbmisc_enable_bits(nb_dev, 0x0B, 0xffffffff, 0x500180);
+}
+
+/*****************************************
+* Some setting is from rpr. Some is from CIMx.
+*****************************************/
+static void rs780_por_htiu_index_init(device_t nb_dev)
+{
+#if 0 /* get from rpr. */
+ set_htiu_enable_bits(nb_dev, 0x1C, 0x1<<17, 0x1<<17);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<0, 0x0<<0);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<1, 0x1<<1);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<9, 0x1<<9);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<13, 0x1<<13);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<17, 0x1<<17);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x3<<15, 0x3<<15);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<25, 0x1<<25);
+ set_htiu_enable_bits(nb_dev, 0x06, 0x1<<30, 0x1<<30);
+
+ set_htiu_enable_bits(nb_dev, 0x07, 0x1<<0, 0x1<<0);
+ set_htiu_enable_bits(nb_dev, 0x07, 0x1<<1, 0x0<<1);
+ set_htiu_enable_bits(nb_dev, 0x07, 0x1<<2, 0x0<<2);
+ set_htiu_enable_bits(nb_dev, 0x07, 0x1<<15, 0x1<<15);
+
+ set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<0, 0x1<<0);
+ set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<2, 0x2<<2);
+ set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<4, 0x0<<4);
+
+ /* A12 only */
+ set_htiu_enable_bits(nb_dev, 0x2D, 0x1<<4, 0x1<<4);
+ set_htiu_enable_bits(nb_dev, 0x2D, 0x1<<6, 0x1<<6);
+ set_htiu_enable_bits(nb_dev, 0x05, 0x1<<2, 0x1<<2);
+
+ set_htiu_enable_bits(nb_dev, 0x1E, 0xFFFFFFFF, 0xFFFFFFFF);
+#else /* get from CIM. It is more reliable than above. */
+ set_htiu_enable_bits(nb_dev, 0x05, (1<<10|1<<9), 1<<10 | 1<<9);
+ set_htiu_enable_bits(nb_dev, 0x06, ~0xFFFFFFFE, 0x04203A202);
+
+ set_htiu_enable_bits(nb_dev, 0x07, ~0xFFFFFFF9, 0x8001/* | 7 << 8 */); /* fam 10 */
+
+ set_htiu_enable_bits(nb_dev, 0x15, ~0xFFFFFFFF, 1<<31| 1<<30 | 1<<27);
+ set_htiu_enable_bits(nb_dev, 0x1C, ~0xFFFFFFFF, 0xFFFE0000);
+
+ set_htiu_enable_bits(nb_dev, 0x4B, (1<<11), 1<<11);
+
+ set_htiu_enable_bits(nb_dev, 0x0C, ~0xFFFFFFC0, 1<<0|1<<3);
+
+ set_htiu_enable_bits(nb_dev, 0x17, (1<<27|1<<1), 0x1<<1);
+ set_htiu_enable_bits(nb_dev, 0x17, 0x1 << 30, 0x1<<30);
+
+ set_htiu_enable_bits(nb_dev, 0x19, (0xFFFFF+(1<<31)), 0x186A0+(1<<31));
+
+ set_htiu_enable_bits(nb_dev, 0x16, (0x3F<<10), 0x7<<10);
+
+ set_htiu_enable_bits(nb_dev, 0x23, 0xFFFFFFF, 1<<28);
+
+ set_htiu_enable_bits(nb_dev, 0x1E, 0xFFFFFFFF, 0xFFFFFFFF);
+#endif
+}
+
+/*****************************************
+* Configure RS780 registers to power-on default RPR.
+* POR: Power On Reset
+* RPR: Register Programming Requirements
+*****************************************/
+static void rs780_por_init(device_t nb_dev)
+{
+ printk(BIOS_INFO, "rs780_por_init\n");
+ /* ATINB_PCICFG_POR_TABLE, initialize the values for rs780 PCI Config registers */
+ rs780_por_pcicfg_init(nb_dev);
+
+ /* ATINB_MCIND_POR_TABLE */
+ rs780_por_mc_index_init(nb_dev);
+
+ /* ATINB_MISCIND_POR_TABLE */
+ rs780_por_misc_index_init(nb_dev);
+
+ /* ATINB_HTIUNBIND_POR_TABLE */
+ rs780_por_htiu_index_init(nb_dev);
+
+ /* ATINB_CLKCFG_PORT_TABLE */
+ /* rs780 A11 SB Link full swing? */
+}
+
+/* enable CFG access to Dev8, which is the SB P2P Bridge */
+static void enable_rs780_dev8(void)
+{
+ set_nbmisc_enable_bits(PCI_DEV(0, 0, 0), 0x00, 1 << 6, 1 << 6);
+}
+
+static void rs780_before_pci_init(void)
+{
+}
+
+static void rs780_early_setup(void)
+{
+ device_t nb_dev = PCI_DEV(0, 0, 0);
+ printk(BIOS_INFO, "rs780_early_setup()\n");
+
+ get_cpu_rev();
+
+ /* The printk(BIOS_INFO, s) below cause the system unstable. */
+ switch (get_nb_rev(nb_dev)) {
+ case REV_RS780_A11:
+ /* printk(BIOS_INFO, "NB Revision is A11.\n"); */
+ break;
+ case REV_RS780_A12:
+ /* printk(BIOS_INFO, "NB Revision is A12.\n"); */
+ break;
+ case REV_RS780_A13:
+ /* printk(BIOS_INFO, "NB Revision is A13.\n"); */
+ break;
+ }
+
+ if (is_famly10())
+ fam10_optimization();
+ else
+ k8_optimization();
+
+ rs780_por_init(nb_dev);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * for rs780 internal graphics device
+ * device id of internal grphics:
+ * RS780: 0x9610
+ * RS780C: 0x9611
+ * RS780M: 0x9612
+ * RS780MC:0x9613
+ * RS780E: 0x9615
+ * RS785G: 0x9710 - just works, not much tested
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+#include <cpu/x86/msr.h>
+#include "rs780.h"
+extern int is_dev3_present(void);
+void set_pcie_reset(void);
+void set_pcie_dereset(void);
+
+extern uint64_t uma_memory_base, uma_memory_size;
+
+/* Trust the original resource allocation. Don't do it again. */
+#undef DONT_TRUST_RESOURCE_ALLOCATION
+//#define DONT_TRUST_RESOURCE_ALLOCATION
+
+#define CLK_CNTL_INDEX 0x8
+#define CLK_CNTL_DATA 0xC
+
+/* The Integrated Info Table. */
+ATOM_INTEGRATED_SYSTEM_INFO_V2 vgainfo;
+
+#ifdef UNUSED_CODE
+static u32 clkind_read(device_t dev, u32 index)
+{
+ u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
+
+ *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
+ return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
+}
+#endif
+
+static void clkind_write(device_t dev, u32 index, u32 data)
+{
+ u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
+ /* printk(BIOS_DEBUG, "gfx bar 2 %02x\n", gfx_bar2); */
+
+ *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
+ *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
+}
+
+/*
+* pci_dev_read_resources thinks it is a IO type.
+* We have to force it to mem type.
+*/
+static void rs780_gfx_read_resources(device_t dev)
+{
+ printk(BIOS_DEBUG, "rs780_gfx_read_resources.\n");
+
+ /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
+ Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
+ which tells us it is a memory address base.
+ */
+ pci_write_config32(dev, 0x24, 0x00000000);
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+ compact_resources(dev);
+}
+
+typedef struct _MMIORANGE
+{
+ u32 Base;
+ u32 Limit;
+ u8 Attribute;
+} MMIORANGE;
+
+MMIORANGE MMIO[8], CreativeMMIO[8];
+
+#define CIM_STATUS u32
+#define CIM_SUCCESS 0x00000000
+#define CIM_ERROR 0x80000000
+#define CIM_UNSUPPORTED 0x80000001
+#define CIM_DISABLEPORT 0x80000002
+
+#define MMIO_ATTRIB_NP_ONLY 1
+#define MMIO_ATTRIB_BOTTOM_TO_TOP 1<<1
+#define MMIO_ATTRIB_SKIP_ZERO 1<<2
+
+#ifdef DONT_TRUST_RESOURCE_ALLOCATION
+static MMIORANGE* AllocMMIO(MMIORANGE* pMMIO)
+{
+ int i;
+ for (i=0; i<8; i++) {
+ if (pMMIO[i].Limit == 0)
+ return &pMMIO[i];
+ }
+ return 0;
+}
+
+static void FreeMMIO(MMIORANGE* pMMIO)
+{
+ pMMIO->Base = 0;
+ pMMIO->Limit = 0;
+}
+
+static u32 SetMMIO(u32 Base, u32 Limit, u8 Attribute, MMIORANGE *pMMIO)
+{
+ int i;
+ MMIORANGE * TempRange;
+ for(i=0; i<8; i++)
+ {
+ if(pMMIO[i].Attribute != Attribute && Base >= pMMIO[i].Base && Limit <= pMMIO[i].Limit)
+ {
+ TempRange = AllocMMIO(pMMIO);
+ if(TempRange == 0) return 0x80000000;
+ TempRange->Base = Limit;
+ TempRange->Limit = pMMIO[i].Limit;
+ TempRange->Attribute = pMMIO[i].Attribute;
+ pMMIO[i].Limit = Base;
+ }
+ }
+ TempRange = AllocMMIO(pMMIO);
+ if(TempRange == 0) return 0x80000000;
+ TempRange->Base = Base;
+ TempRange->Limit = Limit;
+ TempRange->Attribute = Attribute;
+ return 0;
+}
+
+static u8 FinalizeMMIO(MMIORANGE *pMMIO)
+{
+ int i, j, n = 0;
+ for(i=0; i<8; i++)
+ {
+ if (pMMIO[i].Base == pMMIO[i].Limit)
+ {
+ FreeMMIO(&pMMIO[i]);
+ continue;
+ }
+ for(j=0; j<i; j++)
+ {
+ if (i!=j && pMMIO[i].Attribute == pMMIO[j].Attribute)
+ {
+ if (pMMIO[i].Base == pMMIO[j].Limit)
+ {
+ pMMIO[j].Limit = pMMIO[i].Limit;
+ FreeMMIO(&pMMIO[i]);
+ }
+ if (pMMIO[i].Limit == pMMIO[j].Base)
+ {
+ pMMIO[j].Base = pMMIO[i].Base;
+ FreeMMIO(&pMMIO[i]);
+ }
+ }
+ }
+ }
+ for (i=0; i<8; i++)
+ {
+ if (pMMIO[i].Limit != 0) n++;
+ }
+ return n;
+}
+
+static CIM_STATUS GetCreativeMMIO(MMIORANGE *pMMIO)
+{
+ CIM_STATUS Status = CIM_UNSUPPORTED;
+ u8 Bus, Dev, Reg, BusStart, BusEnd;
+ u32 Value;
+ device_t dev0x14 = dev_find_slot(0, PCI_DEVFN(0x14, 4));
+ device_t tempdev;
+ Value = pci_read_config32(dev0x14, 0x18);
+ BusStart = (Value >> 8) & 0xFF;
+ BusEnd = (Value >> 16) & 0xFF;
+ for(Bus = BusStart; Bus <= BusEnd; Bus++)
+ {
+ for(Dev = 0; Dev <= 0x1f; Dev++)
+ {
+ tempdev = dev_find_slot(Bus, Dev << 3);
+ Value = pci_read_config32(tempdev, 0);
+ printk(BIOS_DEBUG, "Dev ID %x \n", Value);
+ if((Value & 0xffff) == 0x1102)
+ {//Creative
+ //Found Creative SB
+ u32 MMIOStart = 0xffffffff;
+ u32 MMIOLimit = 0;
+ for(Reg = 0x10; Reg < 0x20; Reg+=4)
+ {
+ u32 BaseA, LimitA;
+ BaseA = pci_read_config32(tempdev, Reg);
+ Value = BaseA;
+ if(!(Value & 0x01))
+ {
+ Value = Value & 0xffffff00;
+ if(Value != 0)
+ {
+ if(MMIOStart > Value)
+ MMIOStart = Value;
+ LimitA = 0xffffffff;
+ //WritePCI(PciAddress,AccWidthUint32,&LimitA);
+ pci_write_config32(tempdev, Reg, LimitA);
+ //ReadPCI(PciAddress,AccWidthUint32,&LimitA);
+ LimitA = pci_read_config32(tempdev, Reg);
+ LimitA = Value + (~LimitA + 1);
+ //WritePCI(PciAddress,AccWidthUint32,&BaseA);
+ pci_write_config32(tempdev, Reg, BaseA);
+ if (LimitA > MMIOLimit)
+ MMIOLimit = LimitA;
+ }
+ }
+ }
+ printk(BIOS_DEBUG, " MMIOStart %x MMIOLimit %x \n", MMIOStart, MMIOLimit);
+ if (MMIOStart < MMIOLimit)
+ {
+ Status = SetMMIO(MMIOStart>>8, MMIOLimit>>8, 0x80, pMMIO);
+ if(Status == CIM_ERROR) return Status;
+ }
+ }
+ }
+ }
+ if(Status == CIM_SUCCESS)
+ {
+ //Lets optimize MMIO
+ if(FinalizeMMIO(pMMIO) > 4)
+ {
+ Status = CIM_ERROR;
+ }
+ }
+
+ return Status;
+}
+
+static void ProgramMMIO(MMIORANGE *pMMIO, u8 LinkID, u8 Attribute)
+{
+ int i, j, n = 7;
+ device_t k8_f1;
+
+ k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+
+ for(i = 0; i < 8; i++)
+ {
+ int k = 0, MmioReg;
+ u32 Base = 0;
+ u32 Limit = 0;
+ for(j = 0; j < 8; j++)
+ {
+ if (Base < pMMIO[j].Base)
+ {
+ Base = pMMIO[j].Base;
+ k = j;
+ }
+ }
+ if(pMMIO[k].Limit != 0)
+ {
+ if(Attribute & MMIO_ATTRIB_NP_ONLY && pMMIO[k].Attribute == 0 )
+ {
+ Base = 0;
+ }
+ else
+ {
+ Base = pMMIO[k].Base | 0x3;
+ Limit= ((pMMIO[k].Limit - 1) & 0xffffff00) | pMMIO[k].Attribute | (LinkID << 4);
+ }
+ FreeMMIO(&pMMIO[k]);
+ }
+ if (Attribute & MMIO_ATTRIB_SKIP_ZERO && Base == 0 && Limit == 0) continue;
+ MmioReg = (Attribute & MMIO_ATTRIB_BOTTOM_TO_TOP)?n:(7-n);
+ n--;
+ //RWPCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,0x0,0x0);
+ pci_write_config32(k8_f1, 0x80+MmioReg*8, 0);
+
+ //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x84+MmioReg*8),AccWidthUint32 |S3_SAVE,&Limit);
+ pci_write_config32(k8_f1, 0x84+MmioReg*8, Limit);
+
+ //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,&Base);
+ pci_write_config32(k8_f1, 0x80+MmioReg*8, Base);
+ }
+}
+#endif
+
+static void internal_gfx_pci_dev_init(struct device *dev)
+{
+ unsigned char * bpointer;
+ volatile u32 * GpuF0MMReg;
+ volatile u32 * pointer;
+ int i;
+ u16 command;
+ u32 value;
+ u16 deviceid, vendorid;
+ device_t nb_dev = dev_find_slot(0, 0);
+ device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ static const u8 ht_freq_lookup [] = {2, 0, 4, 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 0, 0, 28, 30, 32};
+ static const u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0};
+ static const u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200};
+ static const u16 memclk_lookup_fam10 [] = {200, 266, 333, 400, 533, 667, 800, 800};
+
+ /* We definetely will use this in future. Just leave it here. */
+ /*struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)dev->chip_info;*/
+
+ deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
+ vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
+ printk(BIOS_DEBUG, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
+ deviceid, vendorid);
+
+ command = pci_read_config16(dev, 0x04);
+ command |= 0x7;
+ pci_write_config16(dev, 0x04, command);
+
+ /* Clear vgainfo. */
+ bpointer = (unsigned char *) &vgainfo;
+ for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i++)
+ {
+ *bpointer = 0;
+ bpointer++;
+ }
+
+ GpuF0MMReg = (u32 *)pci_read_config32(dev, 0x18);
+
+ /* GFX_InitFBAccess. */
+ value = nbmc_read_index(nb_dev, 0x10);
+ *(GpuF0MMReg + 0x2000/4) = 0x11;
+ *(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8);
+ *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8);
+ *(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16);
+ *(GpuF0MMReg + 0xF774/4) = 0xffffffff;
+ *(GpuF0MMReg + 0xF770/4) = 0x00000001;
+ *(GpuF0MMReg + 0x2000/4) = 0x00000011;
+ *(GpuF0MMReg + 0x200c/4) = 0x00000020;
+ *(GpuF0MMReg + 0x2010/4) = 0x10204810;
+ *(GpuF0MMReg + 0x2010/4) = 0x00204810;
+ *(GpuF0MMReg + 0x2014/4) = 0x10408810;
+ *(GpuF0MMReg + 0x2014/4) = 0x00408810;
+ *(GpuF0MMReg + 0x2414/4) = 0x00000080;
+ *(GpuF0MMReg + 0x2418/4) = 0x84422415;
+ *(GpuF0MMReg + 0x2418/4) = 0x04422415;
+ *(GpuF0MMReg + 0x5490/4) = 0x00000001;
+ *(GpuF0MMReg + 0x7de4/4) |= (1<<3) | (1<<4);
+ /* Force allow LDT_STOP Cool'n'Quiet workaround. */
+ *(GpuF0MMReg + 0x655c/4) |= 1<<4;
+
+ // disable write combining, needed for stability
+ // reference bios does this only for RS780 rev A11
+ // need to figure out why we need it for all revs
+ *(GpuF0MMReg + 0x2000/4) = 0x00000010;
+ *(GpuF0MMReg + 0x2408/4) = 1 << 9;
+ *(GpuF0MMReg + 0x2000/4) = 0x00000011;
+
+ /* GFX_InitFBAccess finished. */
+
+#if (CONFIG_GFXUMA == 1) /* for UMA mode. */
+ /* GFX_StartMC. */
+ set_nbmc_enable_bits(nb_dev, 0x02, 0x00000000, 0x80000000);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000001);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000004);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0x00040000, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xB1, 0xFFFF0000, 0x00000040);
+ set_nbmc_enable_bits(nb_dev, 0xC3, 0x00000000, 0x00000001);
+ set_nbmc_enable_bits(nb_dev, 0x07, 0xFFFFFFFF, 0x00000018);
+ set_nbmc_enable_bits(nb_dev, 0x06, 0xFFFFFFFF, 0x00000102);
+ set_nbmc_enable_bits(nb_dev, 0x09, 0xFFFFFFFF, 0x40000008);
+ set_nbmc_enable_bits(nb_dev, 0x06, 0x00000000, 0x80000000);
+ /* GFX_StartMC finished. */
+#else
+ /* for SP mode. */
+ set_nbmc_enable_bits(nb_dev, 0xaa, 0xf0, 0x30);
+ set_nbmc_enable_bits(nb_dev, 0xce, 0xf0, 0x30);
+ set_nbmc_enable_bits(nb_dev, 0xca, 0xff000000, 0x47000000);
+ set_nbmc_enable_bits(nb_dev, 0xcb, 0x3f000000, 0x01000000);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<0);
+ set_nbmc_enable_bits(nb_dev, 0x04, 0, 1<<31);
+ set_nbmc_enable_bits(nb_dev, 0xb4, 0x3f, 0x3f);
+ set_nbmc_enable_bits(nb_dev, 0xb4, 0, 1<<6);
+ set_nbmc_enable_bits(nb_dev, 0xc3, 1<<11, 0);
+ set_nbmc_enable_bits(nb_dev, 0xa0, 1<<29, 0);
+ nbmc_write_index(nb_dev, 0xa4, 0x3484576f);
+ nbmc_write_index(nb_dev, 0xa5, 0x222222df);
+ nbmc_write_index(nb_dev, 0xa6, 0x00000000);
+ nbmc_write_index(nb_dev, 0xa7, 0x00000000);
+ set_nbmc_enable_bits(nb_dev, 0xc3, 1<<8, 0);
+ udelay(10);
+ set_nbmc_enable_bits(nb_dev, 0xc3, 1<<9, 0);
+ udelay(10);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<2);
+ udelay(200);
+ set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<3);
+ set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<31);
+ udelay(500);
+ set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<31);
+ set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<30);
+ set_nbmc_enable_bits(nb_dev, 0xa0, 1<<31, 0);
+ set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<29);
+ nbmc_write_index(nb_dev, 0xa4, 0x23484576);
+ nbmc_write_index(nb_dev, 0xa5, 0x00000000);
+ nbmc_write_index(nb_dev, 0xa6, 0x00000000);
+ nbmc_write_index(nb_dev, 0xa7, 0x00000000);
+ /* GFX_StartMC finished. */
+
+ /* GFX_SPPowerManagment, don't care for new. */
+ /* Post MC Init table programming. */
+ set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b);
+
+ /* Do we need Write and Read Calibration? */
+ /* GFX_Init finished. */
+#endif
+
+ /* GFX_InitIntegratedInfo. */
+ /* fill the Integrated Info Table. */
+ vgainfo.sHeader.usStructureSize = sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2);
+ vgainfo.sHeader.ucTableFormatRevision = 1;
+ vgainfo.sHeader.ucTableContentRevision = 2;
+
+#if (CONFIG_GFXUMA == 0) /* SP mode. */
+ // Side port support is incomplete, do not use it
+ // These parameters must match the motherboard
+ vgainfo.ulBootUpSidePortClock = 667*100;
+ vgainfo.ucMemoryType = 3; // 3=ddr3 sp mem, 2=ddr2 sp mem
+ vgainfo.ulMinSidePortClock = 333*100;
+#endif
+
+ vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default
+
+ // find the DDR memory frequency
+ if (is_family10h()) {
+ value = pci_read_config32(k8_f2, 0x94); // read channel 0 DRAM Configuration High Register
+ if (extractbit(value, 14)) // if channel 0 disabled, channel 1 must have memory
+ value = pci_read_config32(k8_f2, 0x194);// read channel 1 DRAM Configuration High Register
+ vgainfo.ulBootUpUMAClock = memclk_lookup_fam10 [extractbits (value, 0, 2)] * 100;
+ }
+ if (is_family0Fh()) {
+ value = pci_read_config32(k8_f2, 0x94);
+ vgainfo.ulBootUpUMAClock = memclk_lookup_fam0F [extractbits (value, 20, 22)] * 100;
+ }
+
+ /* UMA Channel Number: 1 or 2. */
+ vgainfo.ucUMAChannelNumber = 1;
+ if (is_family0Fh()) {
+ value = pci_read_config32(k8_f2, 0x90);
+ if (extractbit(value, 11)) // 128-bit mode
+ vgainfo.ucUMAChannelNumber = 2;
+ }
+ if (is_family10h()) {
+ u32 dch0 = pci_read_config32(k8_f2, 0x94);
+ u32 dch1 = pci_read_config32(k8_f2, 0x194);
+ if (extractbit(dch0, 14) == 0 && extractbit(dch1, 14) == 0) { // both channels enabled
+ value = pci_read_config32(k8_f2, 0x110);
+ if (extractbit(value, 4)) // ganged mode
+ vgainfo.ucUMAChannelNumber = 2;
+ }
+ }
+
+ // processor type
+ if (is_family0Fh())
+ vgainfo.ulCPUCapInfo = 3;
+ if (is_family10h())
+ vgainfo.ulCPUCapInfo = 2;
+
+ /* HT speed */
+ value = pci_read_config8(nb_dev, 0xd1);
+ value = ht_freq_lookup [value] * 100; // HT link frequency in MHz
+ vgainfo.ulHTLinkFreq = value * 100; // HT frequency in units of 100 MHz
+ vgainfo.ulHighVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
+ vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
+
+ if (value <= 1800)
+ vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
+ else {
+ int sblink, cpuLnkFreqCap, nbLnkFreqCap;
+ value = pci_read_config32(k8_f0, 0x64);
+ sblink = extractbits(value, 8, 10);
+ cpuLnkFreqCap = pci_read_config16(k8_f0, 0x8a + sblink * 0x20);
+ nbLnkFreqCap = pci_read_config16(nb_dev, 0xd2);
+ if (cpuLnkFreqCap & nbLnkFreqCap & (1 << 10)) // if both 1800 MHz capable
+ vgainfo.ulLowVoltageHTLinkFreq = 1800*100;
+ }
+
+ /* HT width. */
+ value = pci_read_config8(nb_dev, 0xcb);
+ vgainfo.usMinDownStreamHTLinkWidth =
+ vgainfo.usMaxDownStreamHTLinkWidth =
+ vgainfo.usMinUpStreamHTLinkWidth =
+ vgainfo.usMaxUpStreamHTLinkWidth =
+ vgainfo.usMinHTLinkWidth =
+ vgainfo.usMaxHTLinkWidth = ht_width_lookup [extractbits(value, 0, 2)];
+
+ if (is_family0Fh()) {
+ vgainfo.usUMASyncStartDelay = 322;
+ vgainfo.usUMADataReturnTime = 286;
+ }
+
+ if (is_family10h()) {
+ static u16 t0mult_lookup [] = {10, 50, 200, 2000};
+ int t0time, t0scale;
+ value = pci_read_config32(k8_f0, 0x16c);
+ t0time = extractbits(value, 0, 3);
+ t0scale = extractbits(value, 4, 5);
+ vgainfo.usLinkStatusZeroTime = t0mult_lookup [t0scale] * t0time;
+ vgainfo.usUMASyncStartDelay = 100;
+ if (vgainfo.ulHTLinkFreq < 1000 * 100) { // less than 1000 MHz
+ vgainfo.usUMADataReturnTime = 300;
+ vgainfo.usLinkStatusZeroTime = 6 * 100; // 6us for GH in HT1 mode
+ }
+ else {
+ int lssel;
+ value = pci_read_config32(nb_dev, 0xac);
+ lssel = extractbits (value, 7, 8);
+ vgainfo.usUMADataReturnTime = 1300;
+ if (lssel == 0) vgainfo.usUMADataReturnTime = 150;
+ }
+ }
+
+ /* Transfer the Table to VBIOS. */
+ pointer = (u32 *)&vgainfo;
+ for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i+=4)
+ {
+#if (CONFIG_GFXUMA == 1)
+ *GpuF0MMReg = 0x80000000 + uma_memory_size - 512 + i;
+#else
+ *GpuF0MMReg = 0x80000000 + 0x8000000 - 512 + i;
+#endif
+ *(GpuF0MMReg+1) = *pointer++;
+ }
+
+ /* GFX_InitLate. */
+ {
+ u32 temp;
+ temp = pci_read_config8(dev, 0x4);
+ //temp &= ~1; /* CIM clears this bit. Strangely, I can'd. */
+ temp |= 1<<1|1<<2;
+ pci_write_config8(dev, 0x4, temp);
+
+ // if the GFX debug bar is writable, then it has
+ // been programmed and can be safely enabled now
+ temp = pci_read_config32(nb_dev, 0x8c);
+
+ // if bits 1 (intgfx_enable) and 9 (gfx_debug_bar_enable)
+ // then enable gfx debug bar (set gxf_debug_decode_enable)
+ if (temp & 0x202)
+ temp |= (1 << 10);
+ pci_write_config32(nb_dev, 0x8c, temp);
+
+ }
+
+#ifdef DONT_TRUST_RESOURCE_ALLOCATION
+ /* NB_SetupMGMMIO. */
+
+ /* clear MMIO and CreativeMMIO. */
+ bpointer = (unsigned char *)MMIO;
+ for(i=0; i<sizeof(MMIO); i++)
+ {
+ *bpointer = 0;
+ bpointer++;
+ }
+ bpointer = (unsigned char *)CreativeMMIO;
+ for(i=0; i<sizeof(CreativeMMIO); i++)
+ {
+ *bpointer = 0;
+ bpointer++;
+ }
+
+ /* Set MMIO ranges in K8. */
+ /* Set MMIO TOM - 4G. */
+ SetMMIO(0x400<<12, 0x1000000, 0x80, &MMIO[0]);
+ /* Set MMIO for VGA Legacy FB. */
+ SetMMIO(0xa00, 0xc00, 0x80, &MMIO[0]);
+
+ /* Set MMIO for non prefetchable P2P. */
+ temp = pci_read_config32(dev0x14, 0x20);
+ Base32 = (temp & 0x0fff0) << 8;
+ Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
+ if(Base32 < Limit32)
+ {
+ Status = GetCreativeMMIO(&CreativeMMIO[0]);
+ if(Status != CIM_ERROR)
+ SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
+ }
+ /* Set MMIO for prefetchable P2P. */
+ if(Status != CIM_ERROR)
+ {
+ temp = pci_read_config32(dev0x14, 0x24);
+
+ Base32 = (temp & 0x0fff0) <<8;
+ Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
+ if(Base32 < Limit32)
+ SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
+ }
+
+ FinalizeMMIO(&MMIO[0]);
+
+ ProgramMMIO(&CreativeMMIO[0], 0, MMIO_ATTRIB_NP_ONLY);
+ ProgramMMIO(&MMIO[0], 0, MMIO_ATTRIB_NP_ONLY | MMIO_ATTRIB_BOTTOM_TO_TOP | MMIO_ATTRIB_SKIP_ZERO);
+#endif
+
+ pci_dev_init(dev);
+
+ /* clk ind */
+ clkind_write(dev, 0x08, 0x01);
+ clkind_write(dev, 0x0C, 0x22);
+ clkind_write(dev, 0x0F, 0x0);
+ clkind_write(dev, 0x11, 0x0);
+ clkind_write(dev, 0x12, 0x0);
+ clkind_write(dev, 0x14, 0x0);
+ clkind_write(dev, 0x15, 0x0);
+ clkind_write(dev, 0x16, 0x0);
+ clkind_write(dev, 0x17, 0x0);
+ clkind_write(dev, 0x18, 0x0);
+ clkind_write(dev, 0x19, 0x0);
+ clkind_write(dev, 0x1A, 0x0);
+ clkind_write(dev, 0x1B, 0x0);
+ clkind_write(dev, 0x1C, 0x0);
+ clkind_write(dev, 0x1D, 0x0);
+ clkind_write(dev, 0x1E, 0x0);
+ clkind_write(dev, 0x26, 0x0);
+ clkind_write(dev, 0x27, 0x0);
+ clkind_write(dev, 0x28, 0x0);
+ clkind_write(dev, 0x5C, 0x0);
+}
+
+
+/*
+* Set registers in RS780 and CPU to enable the internal GFX.
+* Please refer to CIM source code and BKDG.
+*/
+
+static void rs780_internal_gfx_enable(device_t dev)
+{
+ u32 l_dword;
+ int i;
+ device_t nb_dev = dev_find_slot(0, 0);
+ msr_t sysmem;
+
+#if (CONFIG_GFXUMA == 0)
+ u32 FB_Start, FB_End;
+#endif
+
+ printk(BIOS_DEBUG, "rs780_internal_gfx_enable dev = 0x%p, nb_dev = 0x%p.\n", dev, nb_dev);
+
+ sysmem = rdmsr(0xc001001a);
+ printk(BIOS_DEBUG, "sysmem = %x_%x\n", sysmem.hi, sysmem.lo);
+
+ /* The system top memory in 780. */
+ pci_write_config32(nb_dev, 0x90, sysmem.lo);
+ htiu_write_index(nb_dev, 0x30, 0);
+ htiu_write_index(nb_dev, 0x31, 0);
+
+ /* Disable external GFX and enable internal GFX. */
+ l_dword = pci_read_config32(nb_dev, 0x8c);
+ l_dword &= ~(1<<0);
+ l_dword |= 1<<1;
+ pci_write_config32(nb_dev, 0x8c, l_dword);
+
+ /* NB_SetDefaultIndexes */
+ pci_write_config32(nb_dev, 0x94, 0x7f);
+ pci_write_config32(nb_dev, 0x60, 0x7f);
+ pci_write_config32(nb_dev, 0xe0, 0);
+
+ /* NB_InitEarlyNB finished. */
+
+ /* LPC DMA Deadlock workaround? */
+ /* GFX_InitCommon*/
+ device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ l_dword = pci_read_config32(k8_f0, 0x68);
+ l_dword &= ~(3 << 21);
+ l_dword |= (1 << 21);
+ pci_write_config32(k8_f0, 0x68, l_dword);
+
+ /* GFX_InitCommon. */
+ nbmc_write_index(nb_dev, 0x23, 0x00c00010);
+ set_nbmc_enable_bits(nb_dev, 0x16, 1<<15, 1<<15);
+ set_nbmc_enable_bits(nb_dev, 0x25, 0xffffffff, 0x111f111f);
+ set_htiu_enable_bits(nb_dev, 0x37, 1<<24, 1<<24);
+
+#if (CONFIG_GFXUMA == 1)
+ /* GFX_InitUMA. */
+ /* Copy CPU DDR Controller to NB MC. */
+ device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
+ device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
+ device_t k8_f4 = dev_find_slot(0, PCI_DEVFN(0x18, 4));
+ for (i = 0; i < 12; i++)
+ {
+ l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
+ nbmc_write_index(nb_dev, 0x30 + i, l_dword);
+ }
+
+ l_dword = pci_read_config32(k8_f2, 0x80);
+ nbmc_write_index(nb_dev, 0x3c, l_dword);
+ l_dword = pci_read_config32(k8_f2, 0x94);
+ set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<22))<<16);
+ set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<< 8))<<17);
+ l_dword = pci_read_config32(k8_f2, 0x90);
+ set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<10))<<18);
+ if (is_family10h())
+ {
+ for (i = 0; i < 12; i++)
+ {
+ l_dword = pci_read_config32(k8_f2, 0x140 + i * 4);
+ nbmc_write_index(nb_dev, 0x3d + i, l_dword);
+ }
+
+ l_dword = pci_read_config32(k8_f2, 0x180);
+ nbmc_write_index(nb_dev, 0x49, l_dword);
+ l_dword = pci_read_config32(k8_f2, 0x194);
+ set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<22))<<16);
+ set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<< 8))<<17);
+ l_dword = pci_read_config32(k8_f2, 0x190);
+ set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<10))<<18);
+
+ l_dword = pci_read_config32(k8_f2, 0x110);
+ nbmc_write_index(nb_dev, 0x4a, l_dword);
+ l_dword = pci_read_config32(k8_f2, 0x114);
+ nbmc_write_index(nb_dev, 0x4b, l_dword);
+ l_dword = pci_read_config32(k8_f4, 0x44);
+ set_nbmc_enable_bits(nb_dev, 0x4a, 0, !!(l_dword & (1<<22))<<24);
+ l_dword = pci_read_config32(k8_f1, 0x40);
+ nbmc_write_index(nb_dev, 0x4c, l_dword);
+ l_dword = pci_read_config32(k8_f1, 0xf0);
+ nbmc_write_index(nb_dev, 0x4d, l_dword);
+ }
+
+
+ /* Set UMA in the 780 side. */
+ /* UMA start address, size. */
+ /* The UMA starts at 0xC0000000 of internal RS780 address space
+ [31:16] addr of last byte | [31:16] addr of first byte
+ */
+ nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000);
+ nbmc_write_index(nb_dev, 0x11, uma_memory_base);
+ nbmc_write_index(nb_dev, 0x12, 0);
+ nbmc_write_index(nb_dev, 0xf0, uma_memory_size >> 20);
+ /* GFX_InitUMA finished. */
+#else
+ /* GFX_InitSP. */
+ /* SP memory:Hynix HY5TQ1G631ZNFP. 128MB = 64M * 16. 667MHz. DDR3. */
+
+ /* Enable Async mode. */
+ set_nbmc_enable_bits(nb_dev, 0x06, 7<<8, 1<<8);
+ set_nbmc_enable_bits(nb_dev, 0x08, 1<<10, 0);
+ /* The last item in AsynchMclkTaskFileIndex. Why? */
+ /* MC_MPLL_CONTROL2. */
+ nbmc_write_index(nb_dev, 0x07, 0x40100028);
+ /* MC_MPLL_DIV_CONTROL. */
+ nbmc_write_index(nb_dev, 0x0b, 0x00000028);
+ /* MC_MPLL_FREQ_CONTROL. */
+ set_nbmc_enable_bits(nb_dev, 0x09, 3<<12|15<<16|15<<8, 1<<12|4<<16|0<<8);
+ /* MC_MPLL_CONTROL3. For PM. */
+ set_nbmc_enable_bits(nb_dev, 0x08, 0xff<<13, 1<<13|1<<18);
+ /* MPLL_CAL_TRIGGER. */
+ set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<0);
+ udelay(200); /* time is long enough? */
+ set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<1);
+ set_nbmc_enable_bits(nb_dev, 0x06, 1<<0, 0);
+ /* MCLK_SRC_USE_MPLL. */
+ set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<20);
+
+ /* Pre Init MC. */
+ nbmc_write_index(nb_dev, 0x01, 0x88108280);
+ set_nbmc_enable_bits(nb_dev, 0x02, ~(1<<20), 0x00030200);
+ nbmc_write_index(nb_dev, 0x04, 0x08881018);
+ nbmc_write_index(nb_dev, 0x05, 0x000000bb);
+ nbmc_write_index(nb_dev, 0x0c, 0x0f00001f);
+ nbmc_write_index(nb_dev, 0xa1, 0x01f10000);
+ /* MCA_INIT_DLL_PM. */
+ set_nbmc_enable_bits(nb_dev, 0xc9, 1<<24, 1<<24);
+ nbmc_write_index(nb_dev, 0xa2, 0x74f20000);
+ nbmc_write_index(nb_dev, 0xa3, 0x8af30000);
+ nbmc_write_index(nb_dev, 0xaf, 0x47d0a41c);
+ nbmc_write_index(nb_dev, 0xb0, 0x88800130);
+ nbmc_write_index(nb_dev, 0xb1, 0x00000040);
+ nbmc_write_index(nb_dev, 0xb4, 0x41247000);
+ nbmc_write_index(nb_dev, 0xb5, 0x00066664);
+ nbmc_write_index(nb_dev, 0xb6, 0x00000022);
+ nbmc_write_index(nb_dev, 0xb7, 0x00000044);
+ nbmc_write_index(nb_dev, 0xb8, 0xbbbbbbbb);
+ nbmc_write_index(nb_dev, 0xb9, 0xbbbbbbbb);
+ nbmc_write_index(nb_dev, 0xba, 0x55555555);
+ nbmc_write_index(nb_dev, 0xc1, 0x00000000);
+ nbmc_write_index(nb_dev, 0xc2, 0x00000000);
+ nbmc_write_index(nb_dev, 0xc3, 0x80006b00);
+ nbmc_write_index(nb_dev, 0xc4, 0x00066664);
+ nbmc_write_index(nb_dev, 0xc5, 0x00000000);
+ nbmc_write_index(nb_dev, 0xd2, 0x00000022);
+ nbmc_write_index(nb_dev, 0xd3, 0x00000044);
+ nbmc_write_index(nb_dev, 0xd6, 0x00050005);
+ nbmc_write_index(nb_dev, 0xd7, 0x00000000);
+ nbmc_write_index(nb_dev, 0xd8, 0x00700070);
+ nbmc_write_index(nb_dev, 0xd9, 0x00700070);
+ nbmc_write_index(nb_dev, 0xe0, 0x00200020);
+ nbmc_write_index(nb_dev, 0xe1, 0x00200020);
+ nbmc_write_index(nb_dev, 0xe8, 0x00200020);
+ nbmc_write_index(nb_dev, 0xe9, 0x00200020);
+ nbmc_write_index(nb_dev, 0xe0, 0x00180018);
+ nbmc_write_index(nb_dev, 0xe1, 0x00180018);
+ nbmc_write_index(nb_dev, 0xe8, 0x00180018);
+ nbmc_write_index(nb_dev, 0xe9, 0x00180018);
+
+ /* Misc options. */
+ /* Memory Termination. */
+ set_nbmc_enable_bits(nb_dev, 0xa1, 0x0ff, 0x044);
+ set_nbmc_enable_bits(nb_dev, 0xb4, 0xf00, 0xb00);
+#if 0
+ /* Controller Termation. */
+ set_nbmc_enable_bits(nb_dev, 0xb1, 0x77770000, 0x77770000);
+#endif
+
+ /* OEM Init MC. 667MHz. */
+ nbmc_write_index(nb_dev, 0xa8, 0x7a5aaa78);
+ nbmc_write_index(nb_dev, 0xa9, 0x514a2319);
+ nbmc_write_index(nb_dev, 0xaa, 0x54400520);
+ nbmc_write_index(nb_dev, 0xab, 0x441460ff);
+ nbmc_write_index(nb_dev, 0xa0, 0x20f00a48);
+ set_nbmc_enable_bits(nb_dev, 0xa2, ~(0xffffffc7), 0x10);
+ nbmc_write_index(nb_dev, 0xb2, 0x00000303);
+ set_nbmc_enable_bits(nb_dev, 0xb1, ~(0xffffff70), 0x45);
+ /* Do it later. */
+ /* set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b); */
+
+ /* Init PM timing. */
+ for(i=0; i<4; i++)
+ {
+ l_dword = nbmc_read_index(nb_dev, 0xa0+i);
+ nbmc_write_index(nb_dev, 0xc8+i, l_dword);
+ }
+ for(i=0; i<4; i++)
+ {
+ l_dword = nbmc_read_index(nb_dev, 0xa8+i);
+ nbmc_write_index(nb_dev, 0xcc+i, l_dword);
+ }
+ l_dword = nbmc_read_index(nb_dev, 0xb1);
+ set_nbmc_enable_bits(nb_dev, 0xc8, 0xff<<24, ((l_dword&0x0f)<<24)|((l_dword&0xf00)<<20));
+
+ /* Init MC FB. */
+ /* FB_Start = ; FB_End = ; iSpSize = 0x0080, 128MB. */
+ nbmc_write_index(nb_dev, 0x11, 0x40000000);
+ FB_Start = 0xc00 + 0x080;
+ FB_End = 0xc00 + 0x080;
+ nbmc_write_index(nb_dev, 0x10, (((FB_End&0xfff)<<20)-0x10000)|(((FB_Start&0xfff)-0x080)<<4));
+ set_nbmc_enable_bits(nb_dev, 0x0d, ~0x000ffff0, (FB_Start&0xfff)<<20);
+ nbmc_write_index(nb_dev, 0x0f, 0);
+ nbmc_write_index(nb_dev, 0x0e, (FB_Start&0xfff)|(0xaaaa<<12));
+#endif
+
+ /* GFX_InitSP finished. */
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = rs780_gfx_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = internal_gfx_pci_dev_init, /* The option ROM initializes the device. rs780_gfx_init, */
+ .scan_bus = 0,
+ .enable = rs780_internal_gfx_enable,
+ .ops_pci = &lops_pci,
+};
+
+/*
+ * We should list all of them here.
+ * */
+static const struct pci_driver pcie_driver_780 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS780_INT_GFX,
+};
+
+static const struct pci_driver pcie_driver_780c __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS780C_INT_GFX,
+};
+static const struct pci_driver pcie_driver_780m __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS780M_INT_GFX,
+};
+static const struct pci_driver pcie_driver_780mc __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS780MC_INT_GFX,
+};
+static const struct pci_driver pcie_driver_780e __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS780E_INT_GFX,
+};
+static const struct pci_driver pcie_driver_785g __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_RS785G_INT_GFX,
+};
+
+/* step 12 ~ step 14 from rpr */
+static void single_port_configuration(device_t nb_dev, device_t dev)
+{
+ u8 result, width;
+ u32 reg32;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration.\n");
+
+ /* step 12 training, releases hold training for GFX port 0 (device 2) */
+ PcieReleasePortTraining(nb_dev, dev, 2);
+ result = PcieTrainPort(nb_dev, dev, 2);
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step12.\n");
+
+ /* step 13 Power Down Control */
+ /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
+
+ /* step 13.a Link Training was NOT successful */
+ if (!result) {
+ set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
+ set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
+ if (cfg->gfx_tmds)
+ nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
+ else {
+ nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
+ set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
+ }
+ } else { /* step 13.b Link Training was successful */
+ set_pcie_enable_bits(dev, 0xA2, 0xFF, 0x1);
+ reg32 = nbpcie_p_read_index(dev, 0x29);
+ width = reg32 & 0xFF;
+ printk(BIOS_DEBUG, "GFX Inactive Lanes = 0x%x.\n", width);
+ switch (width) {
+ case 1:
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
+ break;
+ case 4:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
+ break;
+ case 8:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
+ break;
+ }
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step13.\n");
+
+ /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
+ set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
+ printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step14.\n");
+}
+
+static void dual_port_configuration(device_t nb_dev, device_t dev)
+{
+ u8 result, width;
+ u32 reg32, dev_ind = dev->path.pci.devfn >> 3;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ /* 5.4.1.2 Dual Port Configuration */
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+
+ /* 5.7. Training for Device 2 */
+ /* 5.7.1. Releases hold training for GFX port 0 (device 2) */
+ PcieReleasePortTraining(nb_dev, dev, dev_ind);
+ /* 5.7.2- 5.7.9. PCIE Link Training Sequence */
+ result = PcieTrainPort(nb_dev, dev, dev_ind);
+
+ /* Power Down Control for Device 2 */
+ /* Link Training was NOT successful */
+ if (!result) {
+ /* Powers down all lanes for port A */
+ /* nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f); */
+ /* Note: I have to disable the slot where there isnt a device,
+ * otherwise the system will hang. I dont know why. */
+ set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << dev_ind, 1 << dev_ind);
+
+ } else { /* step 16.b Link Training was successful */
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ width = (reg32 >> 4) & 0x7;
+ printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
+ switch (width) {
+ case 1:
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
+ break;
+ case 4:
+ nbpcie_ind_write_index(nb_dev, 0x65,
+ cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
+ break;
+ }
+ }
+}
+
+/* For single port GFX configuration Only
+* width:
+* 000 = x16
+* 001 = x1
+* 010 = x2
+* 011 = x4
+* 100 = x8
+* 101 = x12 (not supported)
+* 110 = x16
+*/
+static void dynamic_link_width_control(device_t nb_dev, device_t dev, u8 width)
+{
+ u32 reg32;
+ device_t sb_dev;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ /* step 5.9.1.1 */
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+
+ /* step 5.9.1.2 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
+ /* step 5.9.1.3 */
+ set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
+ /* step 5.9.1.4 */
+ set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
+ /* step 5.9.2.4 */
+ if (0 == cfg->gfx_reconfiguration)
+ set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
+
+ /* step 5.9.1.5 */
+ do {
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ }
+ while (reg32 & 0x100);
+
+ /* step 5.9.1.6 */
+ sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
+ do {
+ reg32 = pci_ext_read_config32(nb_dev, sb_dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ } while (reg32 & VC_NEGOTIATION_PENDING);
+
+ /* step 5.9.1.7 */
+ reg32 = nbpcie_p_read_index(dev, 0xa2);
+ if (((reg32 & 0x70) >> 4) != 0x6) {
+ /* the unused lanes should be powered off. */
+ }
+
+ /* step 5.9.1.8 */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
+}
+
+/*
+* GFX Core initialization, dev2, dev3
+*/
+void rs780_gfx_init(device_t nb_dev, device_t dev, u32 port)
+{
+ u32 reg32;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ printk(BIOS_DEBUG, "rs780_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
+ nb_dev, dev, port);
+
+ /* GFX Core Initialization */
+ //if (port == 2) return;
+
+ /* step 2, TMDS, (only need if CMOS option is enabled) */
+ if (cfg->gfx_tmds) {
+ }
+
+#if 1 /* external clock mode */
+ /* table 5-22, 5.9.1. REFCLK */
+ /* 5.9.1.1. Disables the GFX REFCLK transmitter so that the GFX
+ * REFCLK PAD can be driven by an external source. */
+ /* 5.9.1.2. Enables GFX REFCLK receiver to receive the REFCLK from an external source. */
+ set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28 | 1 << 26, 1 << 28);
+
+ /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
+ /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
+ /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
+ set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
+ 1 << 6 | 1 << 8 | 1 << 10);
+ reg32 = nbmisc_read_index(nb_dev, 0x28);
+ printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
+
+ /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
+ set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 1 << 31);
+#else /* internal clock mode */
+ /* table 5-23, 5.9.1. REFCLK */
+ /* 5.9.1.1. Enables the GFX REFCLK transmitter so that the GFX
+ * REFCLK PAD can be driven by the SB REFCLK. */
+ /* 5.9.1.2. Disables GFX REFCLK receiver from receiving the
+ * REFCLK from an external source.*/
+ set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28, 1 << 29 | 0 << 28);
+
+ /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
+ /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
+ /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
+ set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
+ 0);
+ reg32 = nbmisc_read_index(nb_dev, 0x28);
+ printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
+
+ /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
+ set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 0 << 31);
+#endif
+
+ /* step 5.9.3, GFX overclocking, (only need if CMOS option is enabled) */
+ /* 5.9.3.1. Increases PLL BW for 6G operation.*/
+ /* set_nbmisc_enable_bits(nb_dev, 0x36, 0x3FF << 4, 0xB5 << 4); */
+ /* skip */
+
+ /* step 5.9.4, reset the GFX link */
+ /* step 5.9.4.1 asserts both calibration reset and global reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
+
+ /* step 5.9.4.2 de-asserts calibration reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
+
+ /* step 5.9.4.3 wait for at least 200us */
+ udelay(300);
+
+ /* step 5.9.4.4 de-asserts global reset */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
+
+ /* 5.9.5 Reset PCIE_GFX Slot */
+ /* It is done in mainboard.c */
+ set_pcie_reset();
+ mdelay(1);
+ set_pcie_dereset();
+
+ /* step 5.9.8 program PCIE memory mapped configuration space */
+ /* done by enable_pci_bar3() before */
+
+ /* step 7 compliance state, (only need if CMOS option is enabled) */
+ /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
+ if (cfg->gfx_compliance) {
+ /* force compliance */
+ set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
+ /* release hold training for device 2. GFX initialization is done. */
+ set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
+ dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
+ printk(BIOS_DEBUG, "rs780_gfx_init step7.\n");
+ return;
+ }
+
+ /* 5.9.12 Core Initialization. */
+ /* 5.9.12.1 sets RCB timeout to be 25ms */
+ /* 5.9.12.2. RCB Cpl timeout on link down. */
+ set_pcie_enable_bits(dev, 0x70, 7 << 16 | 1 << 19, 4 << 16 | 1 << 19);
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.1.\n");
+
+ /* step 5.9.12.3 disables slave ordering logic */
+ set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.3.\n");
+
+ /* step 5.9.12.4 sets DMA payload size to 64 bytes */
+ set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
+ /* 5.9.12.5. Blocks DMA traffic during C3 state. */
+ set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
+
+ /* 5.9.12.6. Disables RC ordering logic */
+ set_pcie_enable_bits(nb_dev, 0x20, 1 << 9, 1 << 9);
+
+ /* Enabels TLP flushing. */
+ /* Note: It is got from RS690. The system will hang without this action. */
+ set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
+
+ /* 5.9.12.7. Ignores DLLPs during L1 so that txclk can be turned off */
+ set_pcie_enable_bits(nb_dev, 0x2, 1 << 0, 1 << 0);
+
+ /* 5.9.12.8 Prevents LC to go from L0 to Rcv_L0s if L1 is armed. */
+ set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
+
+ /* 5.9.12.9 CMGOOD_OVERRIDE for end point initiated lane degradation. */
+ set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
+ printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.9.\n");
+
+ /* 5.9.12.10 Sets the timer in Config state from 20us to */
+ /* 5.9.12.11 De-asserts RX_EN in L0s. */
+ /* 5.9.12.12 Enables de-assertion of PG2RX_CR_EN to lock clock
+ * recovery parameter when lane is in electrical idle in L0s.*/
+ set_pcie_enable_bits(dev, 0xB1, 1 << 23 | 1 << 19 | 1 << 28, 1 << 23 | 1 << 19 | 1 << 28);
+
+ /* 5.9.12.13. Turns off offset calibration. */
+ /* 5.9.12.14. Enables Rx Clock gating in CDR */
+ set_nbmisc_enable_bits(nb_dev, 0x34, 1 << 10/* | 1 << 22 */, 1 << 10/* | 1 << 22 */);
+
+ /* 5.9.12.15. Sets number of TX Clocks to drain TX Pipe to 3. */
+ set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 3 << 4);
+
+ /* 5.9.12.16. Lets PI use Electrical Idle from PHY when
+ * turning off PLL in L1 at Gen2 speed instead Inferred Electrical Idle. */
+ set_pcie_enable_bits(nb_dev, 0x40, 3 << 14, 2 << 14);
+
+ /* 5.9.12.17. Prevents the Electrical Idle from causing a transition from Rcv_L0 to Rcv_L0s. */
+ set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20);
+
+ /* 5.9.12.18. Prevents the LTSSM from going to Rcv_L0s if it has already
+ * acknowledged a request to go to L1. */
+ set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
+
+ /* 5.9.12.19. LDSK only taking deskew on deskewing error detect */
+ set_pcie_enable_bits(nb_dev, 0x40, 1 << 28, 0 << 28);
+
+ /* 5.9.12.20. Bypasses lane de-skew logic if in x1 */
+ set_pcie_enable_bits(nb_dev, 0xC2, 1 << 14, 1 << 14);
+
+ /* 5.9.12.21. Sets Electrical Idle Threshold. */
+ set_nbmisc_enable_bits(nb_dev, 0x35, 3 << 21, 2 << 21);
+
+ /* 5.9.12.22. Advertises -6 dB de-emphasis value in TS1 Data Rate Identifier
+ * Only if CMOS Option in section. skip */
+
+ /* 5.9.12.23. Disables GEN2 capability of the device. */
+ set_pcie_enable_bits(dev, 0xA4, 1 << 0, 0 << 0);
+
+ /* 5.9.12.24.Disables advertising Upconfigure Support. */
+ set_pcie_enable_bits(dev, 0xA2, 1 << 13, 1 << 13);
+
+ /* 5.9.12.25. No comment in RPR. */
+ set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 10, 0 << 10);
+
+ /* 5.9.12.26. This capacity is required since links wider than x1 and/or multiple link
+ * speed are supported */
+ set_pcie_enable_bits(nb_dev, 0xC1, 1 << 0, 1 << 0);
+
+ /* 5.9.12.27. Enables NVG86 ECO. A13 above only. */
+ if (get_nb_rev(nb_dev) == REV_RS780_A12) /* A12 */
+ set_pcie_enable_bits(dev, 0x02, 1 << 11, 1 << 11);
+
+ /* 5.9.12.28 Hides and disables the completion timeout method. */
+ set_pcie_enable_bits(nb_dev, 0xC1, 1 << 2, 0 << 2);
+
+ /* 5.9.12.29. Use the bif_core de-emphasis strength by default. */
+ /* set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 28, 1 << 28); */
+
+ /* 5.9.12.30. Set TX arbitration algorithm to round robin */
+ set_pcie_enable_bits(nb_dev, 0x1C,
+ 1 << 0 | 0x1F << 1 | 0x1F << 6,
+ 1 << 0 | 0x04 << 1 | 0x04 << 6);
+
+ /* Single-port/Dual-port configureation. */
+ switch (cfg->gfx_dual_slot) {
+ case 0:
+ /* step 1, lane reversal (only need if build config option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+
+ printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
+ if((dev->path.pci.devfn >> 3) == 2) {
+ single_port_configuration(nb_dev, dev);
+ } else {
+ set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
+ printk(BIOS_INFO, "Single port. Do nothing.\n"); // If dev3
+ }
+
+ break;
+ case 1:
+ /* step 1, lane reversal (only need if build config option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+ /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
+ /* AMD calls the configuration CrossFire */
+ set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
+ printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
+
+ printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
+ dual_port_configuration(nb_dev, dev);
+ break;
+
+ case 2:
+
+ if(is_dev3_present()){
+ /* step 1, lane reversal (only need if CMOS option is enabled) */
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+ /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
+ /* AMD calls the configuration CrossFire */
+ set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
+ printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
+
+
+ printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
+ dual_port_configuration(nb_dev, dev);
+
+ }else{
+ if (cfg->gfx_lane_reversal) {
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
+ }
+ printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
+
+ if((dev->path.pci.devfn >> 3) == 2)
+ single_port_configuration(nb_dev, dev);
+ else{
+ set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
+ printk(BIOS_DEBUG, "If dev3.., single port. Do nothing.\n");
+ }
+ }
+
+ default:
+ printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
+ break;
+ }
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "rs780.h"
+
+/* for UMA internal graphics */
+void avoid_lpc_dma_deadlock(device_t nb_dev, device_t sb_dev)
+{
+ device_t cpu_f0;
+ u8 reg;
+
+ cpu_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
+ set_nbcfg_enable_bits(cpu_f0, 0x68, 3 << 21, 1 << 21);
+
+ reg = nbpcie_p_read_index(sb_dev, 0x10);
+ reg |= 0x100; /* bit9=1 */
+ nbpcie_p_write_index(sb_dev, 0x10, reg);
+
+ reg = nbpcie_p_read_index(nb_dev, 0x10);
+ reg |= 0x100; /* bit9=1 */
+ nbpcie_p_write_index(nb_dev, 0x10, reg);
+
+ /* Enable NP protocol over PCIE for memory-mapped writes targeting LPC
+ * Set this bit to avoid a deadlock condition. */
+ reg = htiu_read_index(nb_dev, 0x6);
+ reg |= 0x1000000; /* bit26 */
+ htiu_write_index(nb_dev, 0x6, reg);
+}
+
+static void pcie_init(struct device *dev)
+{
+ /* Enable pci error detecting */
+ u32 dword;
+
+ printk(BIOS_INFO, "pcie_init in rs780_ht.c\n");
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* System error enable */
+ dword |= (1 << 30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+ /*
+ * 1 is APIC enable
+ * 18 is enable nb to accept A4 interrupt request from SB.
+ */
+ dword = pci_read_config32(dev, 0x4C);
+ dword |= 1 << 1 | 1 << 18; /* Clear possible errors */
+ pci_write_config32(dev, 0x4C, dword);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = pcie_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_AMD,
+ .device = PCI_DEVICE_ID_AMD_RS780_HT,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <delay.h>
+#include "rs780.h"
+
+/*------------------------------------------------
+* Global variable
+------------------------------------------------*/
+PCIE_CFG AtiPcieCfg = {
+ PCIE_ENABLE_STATIC_DEV_REMAP, /* Config */
+ 0, /* ResetReleaseDelay */
+ 0, /* Gfx0Width */
+ 0, /* Gfx1Width */
+ 0, /* GfxPayload */
+ 0, /* GppPayload */
+ 0, /* PortDetect, filled by GppSbInit */
+ 0, /* PortHp */
+ 0, /* DbgConfig */
+ 0, /* DbgConfig2 */
+ 0, /* GfxLx */
+ 0, /* GppLx */
+ 0, /* NBSBLx */
+ 0, /* PortSlotInit */
+ 0, /* Gfx0Pwr */
+ 0, /* Gfx1Pwr */
+ 0 /* GppPwr */
+};
+
+static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port);
+static void ValidatePortEn(device_t nb_dev);
+
+static void ValidatePortEn(device_t nb_dev)
+{
+}
+
+/*****************************************************************
+* Compliant with CIM_33's PCIEPowerOffGppPorts
+* Power off unused GPP lines
+*****************************************************************/
+static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
+{
+ u32 reg;
+ u16 state_save;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+ u8 state = cfg->port_enable;
+
+ if (!(AtiPcieCfg.Config & PCIE_DISABLE_HIDE_UNUSED_PORTS))
+ state &= AtiPcieCfg.PortDetect;
+ state = ~state;
+ state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7);
+ state_save = state << 17;
+ state &= !(AtiPcieCfg.PortHp);
+ reg = nbmisc_read_index(nb_dev, 0x0c);
+ reg |= state;
+ nbmisc_write_index(nb_dev, 0x0c, reg);
+
+ reg = nbmisc_read_index(nb_dev, 0x08);
+ reg |= state_save;
+ nbmisc_write_index(nb_dev, 0x08, reg);
+
+ if ((AtiPcieCfg.Config & PCIE_OFF_UNUSED_GPP_LANES)
+ && !(AtiPcieCfg.
+ Config & (PCIE_DISABLE_HIDE_UNUSED_PORTS +
+ PCIE_GFX_COMPLIANCE))) {
+ }
+ /* step 3 Power Down Control for Southbridge */
+ reg = nbpcie_p_read_index(dev, 0xa2);
+
+ switch ((reg >> 4) & 0x7) { /* get bit 4-6, LC_LINK_WIDTH_RD */
+ case 1:
+ nbpcie_ind_write_index(nb_dev, 0x65, 0x0e0e);
+ break;
+ case 2:
+ nbpcie_ind_write_index(nb_dev, 0x65, 0x0c0c);
+ break;
+ default:
+ break;
+ }
+}
+
+/**********************************************************************
+**********************************************************************/
+static void switching_gppsb_configurations(device_t nb_dev, device_t sb_dev)
+{
+ u32 reg;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ /* 5.5.7.1-3 enables GPP reconfiguration */
+ reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
+ reg |=
+ (RECONFIG_GPPSB_EN + RECONFIG_GPPSB_LINK_CONFIG +
+ RECONFIG_GPPSB_ATOMIC_RESET);
+ nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
+
+ /* 5.5.7.4a. De-asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
+ reg = nbmisc_read_index(nb_dev, 0x66);
+ reg |= 1 << 31;
+ nbmisc_write_index(nb_dev, 0x66, reg);
+ /* 5.5.7.4b. sets desired GPPSB configurations, bit4-7 */
+ reg = nbmisc_read_index(nb_dev, 0x67);
+ reg &= 0xFFFFff0f; /* clean */
+ reg |= cfg->gppsb_configuration << 4;
+ nbmisc_write_index(nb_dev, 0x67, reg);
+
+#if 1
+ /* NOTE:
+ * In CIMx 4.5.0 and RPR, 4c is done before 5 & 6. But in this way,
+ * a x4 device in port B (dev 4) of Configuration B can only be detected
+ * as x1, instead of x4. When the port B is being trained, the
+ * LC_CURRENT_STATE is 6 and the LC_LINK_WIDTH_RD is 1. We have
+ * to set the PCIEIND:0x65 as 0xE0E0 and reset the slot. Then the card
+ * seems to work in x1 mode.
+ * In the 2nd way below, we do the 5 & 6 before 4c. it conforms the
+ * CIMx 4.3.0. It conflicts with RPR. But based on the test result I've
+ * made so far, I haven't found any mistake.
+ */
+ /* 5.5.7.4c. Asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
+ reg = nbmisc_read_index(nb_dev, 0x66);
+ reg &= ~(1 << 31);
+ nbmisc_write_index(nb_dev, 0x66, reg);
+
+ /* 5.5.7.5-6. read bit14 and write back its inverst value */
+ reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
+ reg ^= RECONFIG_GPPSB_GPPSB;
+ nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
+#else
+ /* 5.5.7.5-6. read bit14 and write back its inverst value */
+ reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
+ reg ^= RECONFIG_GPPSB_GPPSB;
+ nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
+
+ /* 5.5.7.4c. Asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
+ reg = nbmisc_read_index(nb_dev, 0x66);
+ reg &= ~(1 << 31);
+ nbmisc_write_index(nb_dev, 0x66, reg);
+#endif
+ /* 5.5.7.7. delay 1ms */
+ mdelay(1);
+
+ /* 5.5.7.8. waits until SB has trained to L0, poll for bit0-5 = 0x10 */
+ do {
+ reg = nbpcie_p_read_index(sb_dev, PCIE_LC_STATE0);
+ reg &= 0x3f; /* remain LSB [5:0] bits */
+ } while (LC_STATE_RECONFIG_GPPSB != reg);
+
+ /* 5.5.7.9.ensures that virtual channel negotiation is completed. poll for bit1 = 0 */
+ do {
+ reg =
+ pci_ext_read_config32(nb_dev, sb_dev,
+ PCIE_VC0_RESOURCE_STATUS);
+ } while (reg & VC_NEGOTIATION_PENDING);
+}
+
+static void switching_gpp_configurations(device_t nb_dev, device_t sb_dev)
+{
+ u32 reg;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ /* 5.6.2.1. De-asserts STRAP_BIF_all_valid for PCIE-GPP core */
+ reg = nbmisc_read_index(nb_dev, 0x22);
+ reg |= 1 << 14;
+ nbmisc_write_index(nb_dev, 0x22, reg);
+ /* 5.6.2.2. sets desired GPPSB configurations, bit4-7 */
+ reg = nbmisc_read_index(nb_dev, 0x2D);
+ reg &= ~(0xF << 7); /* clean */
+ reg |= cfg->gpp_configuration << 7;
+ nbmisc_write_index(nb_dev, 0x2D, reg);
+ /* 5.6.2.3. Asserts STRAP_BIF_all_valid for PCIE-GPP core */
+ reg = nbmisc_read_index(nb_dev, 0x22);
+ reg &= ~(1 << 14);
+ nbmisc_write_index(nb_dev, 0x22, reg);
+}
+
+/*****************************************************************
+* The rs780 uses NBCONFIG:0x1c (BAR3) to map the PCIE Extended Configuration
+* Space to a 256MB range within the first 4GB of addressable memory.
+*****************************************************************/
+void enable_pcie_bar3(device_t nb_dev)
+{
+ printk(BIOS_DEBUG, "enable_pcie_bar3()\n");
+ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register. */
+ set_nbcfg_enable_bits(nb_dev, 0x84, 7 << 16, 0 << 16);
+
+ pci_write_config32(nb_dev, 0x1C, EXT_CONF_BASE_ADDRESS); /* PCIEMiscInit */
+ pci_write_config32(nb_dev, 0x20, 0x00000000);
+ set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
+ ProgK8TempMmioBase(1, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
+}
+
+/*****************************************************************
+* We should disable bar3 when we want to exit rs780_enable, because bar3 will be
+* remapped in set_resource later.
+*****************************************************************/
+void disable_pcie_bar3(device_t nb_dev)
+{
+ printk(BIOS_DEBUG, "disable_pcie_bar3()\n");
+ pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */
+ set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */
+ set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 0); /* disable bar3 decode */
+ ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
+}
+
+/*****************************************
+* Compliant with CIM_33's PCIEGPPInit
+* nb_dev:
+* root bridge struct
+* dev:
+* p2p bridge struct
+* port:
+* p2p bridge number, 4-10
+*****************************************/
+void rs780_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
+{
+ u32 gfx_gpp_sb_sel;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+ printk(BIOS_DEBUG, "gpp_sb_init nb_dev=0x%x, dev=0x%x, port=0x%x\n", nb_dev->path.pci.devfn, dev->path.pci.devfn, port);
+
+ gfx_gpp_sb_sel = port >= 4 && port <= 8 ?
+ PCIE_CORE_INDEX_GPPSB : /* 4,5,6,7,8 */
+ PCIE_CORE_INDEX_GPP; /* 9,10 */
+ /* init GPP core */
+ /* 5.10.8.3. Disable slave ordering logic */
+ set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 8,
+ 1 << 8);
+ /* 5.10.8.7. PCIE initialization 5.10.2: rpr 2.12*/
+ set_pcie_enable_bits(nb_dev, 0x02 | gfx_gpp_sb_sel, 1 << 0, 1 << 0); /* no description in datasheet. */
+
+ /* init GPPSB port. rpr 5.10.8 */
+ /* 5.10.8.1-5.10.8.2. Sets RCB timeout to be 100ms/4=25ms by setting bits[18:16] to 3 h4
+ * and shortens the enumeration timer by setting bit[19] to 1
+ */
+ set_pcie_enable_bits(dev, 0x70, 0xF << 16, 0x4 << 16 | 1 << 19);
+ /* 5.10.8.4. Sets DMA payload size to 64 bytes. */
+ set_pcie_enable_bits(nb_dev, 0x10 | gfx_gpp_sb_sel, 7 << 10, 4 << 10);
+ /* 5.10.8.6. Disable RC ordering logic */
+ set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 9, 1 << 9);
+ /* 5.10.8.7. Ignores DLLs druing L1 */
+ set_pcie_enable_bits(nb_dev, 0x02 | gfx_gpp_sb_sel, 1 << 0, 1 << 0);
+ /* 5.10.8.8. Prevents LCto go from L0 to Rcv_L0s if L1 is armed. */
+ set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
+ /* 5.10.8.9. Sets timer in Config state from 20us to 1us.
+ * 5.10.8.10. De-asserts RX_EN in L0s
+ * 5.10.8.11. Enables de-assertion of PG2RX_CR_EN to lock clock recovery parameter when .. */
+ set_pcie_enable_bits(dev, 0xB1, 1 << 23 | 1 << 19 | 1 << 28, 1 <<23 | 1 << 19 | 1 << 28);
+ /* 5.10.8.12. Turns off offset calibration */
+ /* 5.10.8.13. Enables Rx Clock gating in CDR */
+ if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
+ set_nbmisc_enable_bits(nb_dev, 0x67, 1 << 14 | 1 << 26, 1 << 14 | 1 << 26); /* 4,5,6,7 */
+ else
+ set_nbmisc_enable_bits(nb_dev, 0x24, 1 << 29 | 1 << 28, 1 << 29 | 1 << 28); /* 9,10 */
+ /* 5.10.8.14. Sets number of TX Clocks to drain TX Pipe to 3 */
+ set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 0x3 << 4);
+ /* 5.10.8.15. empty */
+ /* 5.10.8.16. P_ELEC_IDLE_MODE */
+ set_pcie_enable_bits(nb_dev, 0x40 | gfx_gpp_sb_sel, 0x3 << 14, 0x2 << 14);
+ /* 5.10.8.17. LC_BLOCK_EL_IDLE_IN_L0 */
+ set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20);
+ /* 5.10.8.18. LC_DONT_GO_TO_L0S_IFL1_ARMED */
+ set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
+ /* 5.10.8.19. RXP_REALIGN_ON_EACH_TSX_OR_SKP */
+ set_pcie_enable_bits(nb_dev, 0x40 | gfx_gpp_sb_sel, 1 << 28, 0 << 28);
+ /* 5.10.8.20. Bypass lane de-skew logic if in x1 */
+ set_pcie_enable_bits(nb_dev, 0xC2 | gfx_gpp_sb_sel, 1 << 14, 1 << 14);
+ /* 5.10.8.21. sets electrical idle threshold. */
+ if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
+ set_nbmisc_enable_bits(nb_dev, 0x6A, 3 << 22, 2 << 22);
+ else
+ set_nbmisc_enable_bits(nb_dev, 0x24, 3 << 16, 2 << 16);
+
+ /* 5.10.8.22. Disable GEN2 */
+ /* TODO: should be 2 seperated cases. */
+ set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 31, 0 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x22, 1 << 5, 0 << 5);
+ set_nbmisc_enable_bits(nb_dev, 0x34, 1 << 31, 0 << 31);
+ set_nbmisc_enable_bits(nb_dev, 0x37, 7 << 5, 0 << 5);
+ /* 5.10.8.23. Disables GEN2 capability of the device. RPR says enable? No! */
+ set_pcie_enable_bits(dev, 0xA4, 1 << 0, 0 << 0);
+ /* 5.10.8.24. Disable advertising upconfigure support. */
+ set_pcie_enable_bits(dev, 0xA2, 1 << 13, 1 << 13);
+ /* 5.10.8.25-26. STRAP_BIF_DSN_EN */
+ if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
+ set_nbmisc_enable_bits(nb_dev, 0x68, 1 << 19, 0 << 19);
+ else
+ set_nbmisc_enable_bits(nb_dev, 0x22, 1 << 3, 0 << 3);
+ /* 5.10.8.27-28. */
+ set_pcie_enable_bits(nb_dev, 0xC1 | gfx_gpp_sb_sel, 1 << 0 | 1 << 2, 1 << 0 | 0 << 2);
+ /* 5.10.8.29. Uses the bif_core de-emphasis strength by default. */
+ if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB) {
+ set_nbmisc_enable_bits(nb_dev, 0x67, 1 << 10, 1 << 10);
+ set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 29, 1 << 29);
+ }
+ else {
+ set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 30, 1 << 30);
+ }
+ /* 5.10.8.30. Set TX arbitration algorithm to round robin. */
+ set_pcie_enable_bits(nb_dev, 0x1C | gfx_gpp_sb_sel,
+ 1 << 0 | 0x1F << 1 | 0x1F << 6,
+ 1 << 0 | 0x04 << 1 | 0x04 << 6);
+
+ /* check compliance rpr step 2.1*/
+ if (AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE) {
+ u32 tmp;
+ tmp = nbmisc_read_index(nb_dev, 0x67);
+ tmp |= 1 << 3;
+ nbmisc_write_index(nb_dev, 0x67, tmp);
+ }
+
+ /* step 5: dynamic slave CPL buffer allocation. Disable it, otherwise linux hangs. Why? */
+ /* set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 11, 1 << 11); */
+
+ /* step 5a: Training for GPP devices */
+ /* init GPP */
+ switch (port) {
+ case 4: /* GPP */
+ case 5:
+ case 6:
+ case 7:
+ case 9:
+ case 10:
+ /* 5.10.8.5. Blocks DMA traffic during C3 state */
+ set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
+ /* Enabels TLP flushing */
+ set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
+
+ /* check port enable */
+ if (cfg->port_enable & (1 << port)) {
+ PcieReleasePortTraining(nb_dev, dev, port);
+ if (!(AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE)) {
+ u8 res = PcieTrainPort(nb_dev, dev, port);
+ printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res);
+ if (res) {
+ AtiPcieCfg.PortDetect |= 1 << port;
+ }
+ }
+ }
+ break;
+ case 8: /* SB */
+ break;
+ }
+ PciePowerOffGppPorts(nb_dev, dev, port);
+}
+
+/*****************************************
+* Compliant with CIM_33's PCIEConfigureGPPCore
+*****************************************/
+void config_gpp_core(device_t nb_dev, device_t sb_dev)
+{
+ u32 reg;
+ struct southbridge_amd_rs780_config *cfg =
+ (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
+
+ reg = nbmisc_read_index(nb_dev, 0x20);
+ if (AtiPcieCfg.Config & PCIE_ENABLE_STATIC_DEV_REMAP)
+ reg &= 0xfffffffd; /* set bit1 = 0 */
+ else
+ reg |= 0x2; /* set bit1 = 1 */
+ nbmisc_write_index(nb_dev, 0x20, reg);
+
+ reg = nbmisc_read_index(nb_dev, 0x67); /* get STRAP_BIF_LINK_CONFIG_GPPSB at bit 4-7 */
+ if (cfg->gppsb_configuration != ((reg >> 4) & 0xf))
+ switching_gppsb_configurations(nb_dev, sb_dev);
+ reg = nbmisc_read_index(nb_dev, 0x2D); /* get STRAP_BIF_LINK_CONFIG_GPP at bit 7-10 */
+ if (cfg->gpp_configuration != ((reg >> 7) & 0xf))
+ switching_gpp_configurations(nb_dev, sb_dev);
+ ValidatePortEn(nb_dev);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __RS780_REV_H__
+#define __RS780_REV_H__
+
+#define REV_RS780_A11 0
+#define REV_RS780_A12 1
+#define REV_RS780_A13 2
+
+#endif /* __RS780_REV_H__ */
#include <stdint.h>
#include <device/pci_ids.h>
#include "chip.h"
-#include "rs780_rev.h"
+#include "rev.h"
#define NBMISC_INDEX 0x60
#define NBHTIU_INDEX 0x94
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-
-#include <arch/io.h>
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-#include <boot/coreboot_tables.h>
-#include <delay.h>
-#include <cpu/cpu.h>
-#include "rs780.h"
-
-static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
-{
- pci_write_config32(dev, index_reg, index);
- return pci_read_config32(dev, index_reg + 0x4);
-}
-
-static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
-{
- pci_write_config32(dev, index_reg, index);
- pci_write_config32(dev, index_reg + 0x4, data);
-}
-
-/* extension registers */
-u32 pci_ext_read_config32(device_t nb_dev, device_t dev, u32 reg)
-{
- /*get BAR3 base address for nbcfg0x1c */
- u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
- printk(BIOS_DEBUG, "addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
- dev->path.pci.devfn);
- addr |= dev->bus->secondary << 20 | /* bus num */
- dev->path.pci.devfn << 12 | reg;
- return *((u32 *) addr);
-}
-
-void pci_ext_write_config32(device_t nb_dev, device_t dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
-
- /*get BAR3 base address for nbcfg0x1c */
- u32 addr = pci_read_config32(nb_dev, 0x1c) & ~0xF;
- /*printk(BIOS_DEBUG, "write: addr=%x,bus=%x,devfn=%x\n", addr, dev->bus->secondary,
- dev->path.pci.devfn);*/
- addr |= dev->bus->secondary << 20 | /* bus num */
- dev->path.pci.devfn << 12 | reg_pos;
-
- reg = reg_old = *((u32 *) addr);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- *((u32 *) addr) = reg;
- }
-}
-
-u32 nbmisc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMISC_INDEX, (index));
-}
-
-void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
-}
-
-u32 nbpcie_p_read_index(device_t dev, u32 index)
-{
- return nb_read_index((dev), NBPCIE_INDEX, (index));
-}
-
-void nbpcie_p_write_index(device_t dev, u32 index, u32 data)
-{
- nb_write_index((dev), NBPCIE_INDEX, (index), (data));
-}
-
-u32 nbpcie_ind_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBPCIE_INDEX, (index));
-}
-
-void nbpcie_ind_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBPCIE_INDEX, (index), (data));
-}
-
-u32 htiu_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
-}
-
-void htiu_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
-}
-
-u32 nbmc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMC_INDEX, (index));
-}
-
-void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
-}
-
-void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = pci_read_config32(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config32(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask, u8 val)
-{
- u8 reg_old, reg;
- reg = reg_old = pci_read_config8(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config8(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = htiu_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- htiu_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmisc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-void set_pcie_enable_bits(device_t dev, u32 reg_pos, u32 mask, u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nb_read_index(dev, NBPCIE_INDEX, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nb_write_index(dev, NBPCIE_INDEX, reg_pos, reg);
- }
-}
-
-/***********************************************************
-* To access bar3 we need to program PCI MMIO 7 in K8.
-* in_out:
-* 1: enable/enter k8 temp mmio base
-* 0: disable/restore
-***********************************************************/
-void ProgK8TempMmioBase(u8 in_out, u32 pcie_base_add, u32 mmio_base_add)
-{
- /* K8 Function1 is address map */
- device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
- device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
-
- if (in_out) {
- u32 dword, sblk;
-
- /* Get SBLink value (HyperTransport I/O Hub Link ID). */
- dword = pci_read_config32(k8_f0, 0x64);
- sblk = (dword >> 8) & 0x3;
-
- /* Fill MMIO limit/base pair. */
- pci_write_config32(k8_f1, 0xbc,
- (((pcie_base_add + 0x10000000 -
- 1) >> 8) & 0xffffff00) | 0x80 | (sblk << 4));
- pci_write_config32(k8_f1, 0xb8, (pcie_base_add >> 8) | 0x3);
- pci_write_config32(k8_f1, 0xb4,
- (((mmio_base_add + 0x10000000 -
- 1) >> 8) & 0xffffff00) | (sblk << 4));
- pci_write_config32(k8_f1, 0xb0, (mmio_base_add >> 8) | 0x3);
- } else {
- pci_write_config32(k8_f1, 0xb8, 0);
- pci_write_config32(k8_f1, 0xbc, 0);
- pci_write_config32(k8_f1, 0xb0, 0);
- pci_write_config32(k8_f1, 0xb4, 0);
- }
-}
-
-void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port)
-{
- switch (port) {
- case 2: /* GFX, bit4-5 */
- case 3:
- set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
- 1 << (port + 2), 0 << (port + 2));
- break;
- case 4: /* GPPSB, bit20-24 */
- case 5:
- case 6:
- case 7:
- set_nbmisc_enable_bits(nb_dev, PCIE_LINK_CFG,
- 1 << (port + 17), 0 << (port + 17));
- break;
- case 9: /* GPP, bit 4,5 of miscind 0x2D */
- case 10:
- set_nbmisc_enable_bits(nb_dev, 0x2D,
- 1 << (port - 5), 0 << (port - 5));
- break;
- }
-}
-
-/********************************************************************************************************
-* Output:
-* 0: no device is present.
-* 1: device is present and is trained.
-********************************************************************************************************/
-u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port)
-{
- u16 count = 5000;
- u32 lc_state, reg, current_link_width, lane_mask;
- int8_t current, res = 0;
- u32 gfx_gpp_sb_sel;
- void set_pcie_dereset(void);
- void set_pcie_reset(void);
-
- switch (port) {
- case 2 ... 3:
- gfx_gpp_sb_sel = PCIE_CORE_INDEX_GFX;
- break;
- case 4 ... 7:
- gfx_gpp_sb_sel = PCIE_CORE_INDEX_GPPSB;
- break;
- case 9 ... 10:
- gfx_gpp_sb_sel = PCIE_CORE_INDEX_GPP;
- break;
- default:
- gfx_gpp_sb_sel = -1;
- return 0;
- }
-
- while (count--) {
- mdelay(40);
- udelay(200);
- lc_state = nbpcie_p_read_index(dev, 0xa5); /* lc_state */
- printk(BIOS_DEBUG, "PcieLinkTraining port=%x:lc current state=%x\n",
- port, lc_state);
- current = lc_state & 0x3f; /* get LC_CURRENT_STATE, bit0-5 */
-
- switch (current) {
- case 0x00: /* 0x00-0x04 means no device is present */
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x04:
- res = 0;
- count = 0;
- break;
- case 0x06:
- /* read back current link width [6:4]. */
- current_link_width = (nbpcie_p_read_index(dev, 0xA2) >> 4) & 0x7;
- /* 4 means 7:4 and 15:12
- * 3 means 7:2 and 15:10
- * 2 means 7:1 and 15:9
- * egnoring the reversal case
- */
- lane_mask = (0xFF << (current_link_width - 2) * 2) & 0xFF;
- reg = nbpcie_ind_read_index(nb_dev, 0x65 | gfx_gpp_sb_sel);
- reg |= lane_mask << 8 | lane_mask;
- reg = 0xE0E0; /* TODO: See the comments in rs780_pcie.c, at about line 145. */
- nbpcie_ind_write_index(nb_dev, 0x65 | gfx_gpp_sb_sel, reg);
- printk(BIOS_DEBUG, "link_width=%x, lane_mask=%x",
- current_link_width, lane_mask);
- set_pcie_reset();
- mdelay(1);
- set_pcie_dereset();
- break;
- case 0x07: /* device is in compliance state (training sequence is done). Move to train the next device */
- res = 0;
- count = 0;
- break;
- case 0x10:
- reg =
- pci_ext_read_config32(nb_dev, dev,
- PCIE_VC0_RESOURCE_STATUS);
- printk(BIOS_DEBUG, "PcieTrainPort reg=0x%x\n", reg);
- /* check bit1 */
- if (reg & VC_NEGOTIATION_PENDING) { /* bit1=1 means the link needs to be re-trained. */
- /* set bit8=1, bit0-2=bit4-6 */
- u32 tmp;
- reg =
- nbpcie_p_read_index(dev,
- PCIE_LC_LINK_WIDTH);
- tmp = (reg >> 4) && 0x3; /* get bit4-6 */
- reg &= 0xfff8; /* clear bit0-2 */
- reg += tmp; /* merge */
- reg |= 1 << 8;
- count++; /* CIM said "keep in loop"? */
- } else {
- res = 1;
- count = 0;
- }
- break;
- default: /* reset pcie */
- res = 0;
- count = 0; /* break loop */
- break;
- }
- }
- return res;
-}
-
-/*
-* Compliant with CIM_33's ATINB_SetToms.
-* Set Top Of Memory below and above 4G.
-*/
-void rs780_set_tom(device_t nb_dev)
-{
- extern uint64_t uma_memory_base;
-
- /* set TOM */
- pci_write_config32(nb_dev, 0x90, uma_memory_base);
- //nbmc_write_index(nb_dev, 0x1e, uma_memory_base);
-}
-
-// extract single bit
-u32 extractbit(u32 data, int bit_number)
-{
- return (data >> bit_number) & 1;
-}
-
-// extract bit field
-u32 extractbits(u32 source, int lsb, int msb)
-{
- int field_width = msb - lsb + 1;
- u32 mask = 0xFFFFFFFF >> (32 - field_width);
- return (source >> lsb) & mask;
-}
-
-// return AMD cpuid family
-int cpuidFamily(void)
-{
- u32 baseFamily, extendedFamily, fms;
-
- fms = cpuid_eax (1);
- baseFamily = extractbits (fms, 8, 11);
- extendedFamily = extractbits (fms, 20, 27);
- return baseFamily + extendedFamily;
-}
-
-
-// return non-zero for AMD family 0Fh processor found
-int is_family0Fh(void)
-{
- return cpuidFamily() == 0x0F;
-}
-
-
-// return non-zero for AMD family 10h processor found
-int is_family10h(void)
-{
- return cpuidFamily() == 0x10;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef CONFIG_NORTHBRIDGE_AMD_AMDFAM10
-#define CONFIG_NORTHBRIDGE_AMD_AMDFAM10 0
-#endif
-
-#include "rs780_rev.h"
-
-#define NBHTIU_INDEX 0x94 /* Note: It is different with RS690, whose HTIU index is 0xA8 */
-#define NBMISC_INDEX 0x60
-#define NBMC_INDEX 0xE8
-
-static u32 nb_read_index(device_t dev, u32 index_reg, u32 index)
-{
- pci_write_config32(dev, index_reg, index);
- return pci_read_config32(dev, index_reg + 0x4);
-}
-
-static void nb_write_index(device_t dev, u32 index_reg, u32 index, u32 data)
-{
- pci_write_config32(dev, index_reg, index /* | 0x80 */ );
- pci_write_config32(dev, index_reg + 0x4, data);
-}
-
-static u32 nbmisc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMISC_INDEX, (index));
-}
-
-static void nbmisc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMISC_INDEX, ((index) | 0x80), (data));
-}
-
-static u32 htiu_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBHTIU_INDEX, (index));
-}
-
-static void htiu_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBHTIU_INDEX, ((index) | 0x100), (data));
-}
-
-static u32 nbmc_read_index(device_t nb_dev, u32 index)
-{
- return nb_read_index((nb_dev), NBMC_INDEX, (index));
-}
-
-static void nbmc_write_index(device_t nb_dev, u32 index, u32 data)
-{
- nb_write_index((nb_dev), NBMC_INDEX, ((index) | 1 << 9), (data));
-}
-
-static void set_htiu_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = htiu_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- htiu_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmisc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmisc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = pci_read_config32(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config32(nb_dev, reg_pos, reg);
- }
-}
-/* family 10 only, for reg > 0xFF */
-#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1
-static void set_fam10_ext_cfg_enable_bits(device_t fam10_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = Get_NB32(fam10_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- Set_NB32(fam10_dev, reg_pos, reg);
- }
-}
-#else
-#define set_fam10_ext_cfg_enable_bits(a, b, c, d) do {} while (0)
-#endif
-
-
-static void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask,
- u8 val)
-{
- u8 reg_old, reg;
- reg = reg_old = pci_read_config8(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- pci_write_config8(nb_dev, reg_pos, reg);
- }
-}
-
-static void set_nbmc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
- u32 val)
-{
- u32 reg_old, reg;
- reg = reg_old = nbmc_read_index(nb_dev, reg_pos);
- reg &= ~mask;
- reg |= val;
- if (reg != reg_old) {
- nbmc_write_index(nb_dev, reg_pos, reg);
- }
-}
-
-static void get_cpu_rev(void)
-{
- u32 eax;
-
- eax = cpuid_eax(1);
- printk(BIOS_INFO, "get_cpu_rev EAX=0x%x.\n", eax);
- if (eax <= 0xfff)
- printk(BIOS_INFO, "CPU Rev is K8_Cx.\n");
- else if (eax <= 0x10fff)
- printk(BIOS_INFO, "CPU Rev is K8_Dx.\n");
- else if (eax <= 0x20fff)
- printk(BIOS_INFO, "CPU Rev is K8_Ex.\n");
- else if (eax <= 0x40fff)
- printk(BIOS_INFO, "CPU Rev is K8_Fx.\n");
- else if (eax == 0x60fb1 || eax == 0x60f81) /*These two IDS are exception, they are G1. */
- printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
- else if (eax <= 0X60FF0)
- printk(BIOS_INFO, "CPU Rev is K8_G0.\n");
- else if (eax <= 0x100000)
- printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
- else if (eax <= 0x100f00)
- printk(BIOS_INFO, "CPU Rev is Fam 10.\n");
- else
- printk(BIOS_INFO, "CPU Rev is K8_10.\n");
-}
-
-static u8 is_famly10(void)
-{
- return (cpuid_eax(1) & 0xff00000) != 0;
-}
-
-#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
-static u8 l3_cache(void)
-{
- return (cpuid_edx(0x80000006) & (0x3FFF << 18)) != 0;
-}
-
-static u8 cpu_core_number(void)
-{
- return (cpuid_ecx(0x80000008) & 0xFF) + 1;
-}
-#endif
-
-static u8 get_nb_rev(device_t nb_dev)
-{
- u8 reg;
- reg = pci_read_config8(nb_dev, 0x89); /* copy from CIM, can't find in doc */
- switch(reg & 3)
- {
- case 0x01:
- reg = REV_RS780_A12;
- break;
- case 0x02:
- reg = REV_RS780_A13;
- break;
- default:
- reg = REV_RS780_A11;
- break;
- }
- return reg;
-}
-
-/*****************************************
- * Init HT link speed/width for rs780 -- k8 link
- * 1: Check CPU Family, Family10?
- * 2: Get CPU's HT speed and width
- * 3: Decide HT mode 1 or 3 by HT Speed. >1GHz: HT3, else HT1
- *****************************************/
-static const u8 rs780_ibias[] = {
- /* 1, 3 are reserved. */
- [0x0] = 0x4C, /* 200Mhz HyperTransport 1 only */
- [0x2] = 0x4C, /* 400Mhz HyperTransport 1 only */
- [0x4] = 0xB6, /* 600Mhz HyperTransport 1 only */
- [0x5] = 0x4C, /* 800Mhz HyperTransport 1 only */
- [0x6] = 0x9D, /* 1Ghz HyperTransport 1 only */
- /* HT3 for Family 10 */
- [0x7] = 0xB6, /* 1.2Ghz HyperTransport 3 only */
- [0x8] = 0x2B, /* 1.4Ghz HyperTransport 3 only */
- [0x9] = 0x4C, /* 1.6Ghz HyperTransport 3 only */
- [0xa] = 0x6C, /* 1.8Ghz HyperTransport 3 only */
- [0xb] = 0x9D, /* 2.0Ghz HyperTransport 3 only */
- [0xc] = 0xAD, /* 2.2Ghz HyperTransport 3 only */
- [0xd] = 0xB6, /* 2.4Ghz HyperTransport 3 only */
- [0xe] = 0xC6, /* 2.6Ghz HyperTransport 3 only */
-};
-
-static void rs780_htinit(void)
-{
- /*
- * About HT, it has been done in enumerate_ht_chain().
- */
- device_t cpu_f0, rs780_f0, clk_f1;
- u32 reg;
- u8 cpu_ht_freq, ibias;
-
- cpu_f0 = PCI_DEV(0, 0x18, 0);
- /************************
- * get cpu's ht freq, in cpu's function 0, offset 0x88
- * bit11-8, specifics the maximum operation frequency of the link's transmitter clock.
- * The link frequency field (Frq) is cleared by cold reset. SW can write a nonzero
- * value to this reg, and that value takes effect on the next warm reset or
- * LDTSTOP_L disconnect sequence.
- * please see the table rs780_ibias about the value and its corresponding frequency.
- ************************/
- reg = pci_read_config32(cpu_f0, 0x88);
- cpu_ht_freq = (reg & 0xf00) >> 8;
- printk(BIOS_INFO, "rs780_htinit cpu_ht_freq=%x.\n", cpu_ht_freq);
- rs780_f0 = PCI_DEV(0, 0, 0);
- //set_nbcfg_enable_bits(rs780_f0, 0xC8, 0x7<<24 | 0x7<<28, 1<<24 | 1<<28);
-
- clk_f1 = PCI_DEV(0, 0, 1); /* We need to make sure the F1 is accessible. */
-
- ibias = rs780_ibias[cpu_ht_freq];
-
- /* If HT freq>1GHz, we assume the CPU is fam10, else it is K8.
- * Is it appropriate?
- * Frequency is 1GHz, i.e. cpu_ht_freq is 6, in most cases.
- * So we check 6 only, it would be faster. */
- if ((cpu_ht_freq == 0x6) || (cpu_ht_freq == 0x5) || (cpu_ht_freq == 0x4) ||
- (cpu_ht_freq == 0x2) || (cpu_ht_freq == 0x0)) {
- printk(BIOS_INFO, "rs780_htinit: HT1 mode\n");
-
- /* HT1 mode, RPR 8.4.2 */
- /* set IBIAS code */
- set_nbcfg_enable_bits(clk_f1, 0xD8, 0x3FF, ibias);
- /* Optimizes chipset HT transmitter drive strength */
- set_htiu_enable_bits(rs780_f0, 0x2A, 0x3, 0x1);
- } else if ((cpu_ht_freq > 0x6) && (cpu_ht_freq < 0xf)) {
- printk(BIOS_INFO, "rs780_htinit: HT3 mode\n");
-
- #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
- /* HT3 mode, RPR 8.4.3 */
- set_nbcfg_enable_bits(rs780_f0, 0x9c, 0x3 << 16, 0);
-
- /* set IBIAS code */
- set_nbcfg_enable_bits(clk_f1, 0xD8, 0x3FF, ibias);
- /* Optimizes chipset HT transmitter drive strength */
- set_htiu_enable_bits(rs780_f0, 0x2A, 0x3, 0x1);
- /* Enables error-retry mode */
- set_nbcfg_enable_bits(rs780_f0, 0x44, 0x1, 0x1);
- /* Enables scrambling and Disalbes command throttling */
- set_nbcfg_enable_bits(rs780_f0, 0xac, (1 << 3) | (1 << 14), (1 << 3) | (1 << 14));
- /* Enables transmitter de-emphasis */
- set_nbcfg_enable_bits(rs780_f0, 0xa4, 1 << 31, 1 << 31);
- /* Enabels transmitter de-emphasis level */
- /* Sets training 0 time */
- set_nbcfg_enable_bits(rs780_f0, 0xa0, 0x3F, 0x14);
-
- /* Enables strict TM4 detection */
- set_htiu_enable_bits(rs780_f0, 0x15, 0x1 << 22, 0x1 << 22);
- /* Enables proprer DLL reset sequence */
- set_htiu_enable_bits(rs780_f0, 0x16, 0x1 << 10, 0x1 << 10);
-
- /* HyperTransport 3 Processor register settings to be done in northbridge */
- /* Enables error-retry mode */
- set_fam10_ext_cfg_enable_bits(cpu_f0, 0x130, 1 << 0, 1 << 0);
- /* Enables scrambling */
- set_fam10_ext_cfg_enable_bits(cpu_f0, 0x170, 1 << 3, 1 << 3);
- /* Enables transmitter de-emphasis
- * This depends on the PCB design and the trace */
- /* TODO: */
- /* Disables command throttling */
- set_fam10_ext_cfg_enable_bits(cpu_f0, 0x168, 1 << 10, 1 << 10);
- /* Sets Training 0 Time. See T0Time table for encodings */
- set_fam10_ext_cfg_enable_bits(cpu_f0, 0x16C, 0x3F, 0x20);
- /* TODO: */
- #endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 */
- }
-}
-
-#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1 /* save some spaces */
-/*******************************************************
-* Optimize k8 with UMA.
-* See BKDG_NPT_0F guide for details.
-* The processor node is addressed by its Node ID on the HT link and can be
-* accessed with a device number in the PCI configuration space on Bus0.
-* The Node ID 0 is mapped to Device 24 (0x18), the Node ID 1 is mapped
-* to Device 25, and so on.
-* The processor implements configuration registers in PCI configuration
-* space using the following four headers
-* Function0: HT technology configuration
-* Function1: Address map configuration
-* Function2: DRAM and HT technology Trace mode configuration
-* Function3: Miscellaneous configuration
-*******************************************************/
-static void k8_optimization(void)
-{
- device_t k8_f0, k8_f2, k8_f3;
- msr_t msr;
-
- printk(BIOS_INFO, "k8_optimization()\n");
- k8_f0 = PCI_DEV(0, 0x18, 0);
- k8_f2 = PCI_DEV(0, 0x18, 2);
- k8_f3 = PCI_DEV(0, 0x18, 3);
-
- /* 8.6.6 K8 Buffer Allocation Settings */
- pci_write_config32(k8_f0, 0x90, 0x01700169); /* CIM NPT_Optimization */
- set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 28, 0 << 28);
- set_nbcfg_enable_bits(k8_f0, 0x68, 3 << 26, 3 << 26);
- set_nbcfg_enable_bits(k8_f0, 0x68, 1 << 11, 1 << 11);
- /* set_nbcfg_enable_bits(k8_f0, 0x84, 1 << 11 | 1 << 13 | 1 << 15, 1 << 11 | 1 << 13 | 1 << 15); */ /* TODO */
-
- pci_write_config32(k8_f3, 0x70, 0x51220111);
- pci_write_config32(k8_f3, 0x74, 0x50404021);
- pci_write_config32(k8_f3, 0x78, 0x08002A00);
- if (pci_read_config32(k8_f3, 0xE8) & 0x3<<12)
- pci_write_config32(k8_f3, 0x7C, 0x0000211A); /* dual core */
- else
- pci_write_config32(k8_f3, 0x7C, 0x0000212B); /* single core */
- set_nbcfg_enable_bits_8(k8_f3, 0xDC, 0xFF, 0x25);
-
- set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
- set_nbcfg_enable_bits(k8_f2, 0x94, 0xF << 24, 7 << 24);
- set_nbcfg_enable_bits(k8_f2, 0x90, 1 << 10, 0 << 10);
- set_nbcfg_enable_bits(k8_f2, 0xA0, 3 << 2, 3 << 2);
- set_nbcfg_enable_bits(k8_f2, 0xA0, 1 << 5, 1 << 5);
-
- msr = rdmsr(0xC001001F);
- msr.lo &= ~(1 << 9);
- msr.hi &= ~(1 << 4);
- wrmsr(0xC001001F, msr);
-}
-#else
-#define k8_optimization() do{}while(0)
-#endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1 */
-
-#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 /* save some spaces */
-static void fam10_optimization(void)
-{
- device_t cpu_f0, cpu_f2, cpu_f3;
- u32 val;
-
- printk(BIOS_INFO, "fam10_optimization()\n");
-
- cpu_f0 = PCI_DEV(0, 0x18, 0);
- cpu_f2 = PCI_DEV(0, 0x18, 2);
- cpu_f3 = PCI_DEV(0, 0x18, 3);
-
- /* 8.6.4.1 */
- /* Table 8-13 */
- pci_write_config32(cpu_f0, 0x90, 0x808502D0);
- /* Table 8-14 */
- pci_write_config32(cpu_f0, 0x94, 0x00000000);
-
- /* Table 8-15 */
- val = pci_read_config32(cpu_f0, 0x68);
- val |= 1 << 24;
- pci_write_config32(cpu_f0, 0x68, val);
-
- /* Table 8-16 */
- val = pci_read_config32(cpu_f0, 0x84);
- val &= ~(1 << 12);
- pci_write_config32(cpu_f0, 0x84, val);
-
- /* Table 8-17 */
- val = pci_read_config32(cpu_f2, 0x90);
- val &= ~(1 << 10);
- pci_write_config32(cpu_f2, 0x90, val);
-
- /* Table 8-18 */
- pci_write_config32(cpu_f3, 0x6C, 0x60018051);
- /* Table 8-19 */
- pci_write_config32(cpu_f3, 0x70, 0x60321151);
- /* Table 8-20 */
- pci_write_config32(cpu_f3, 0x74, 0x00980101);
- /* Table 8-21 */
- pci_write_config32(cpu_f3, 0x78, 0x00200C14);
- /* Table 8-22 */
- pci_write_config32(cpu_f3, 0x7C, 0x00070811); /* TODO: Check if L3 Cache is enabled. */
-
- /* Table 8-23 */
- Set_NB32(cpu_f3, 0x140, 0x00D33656);
- /* Table 8-24 */
- Set_NB32(cpu_f3, 0x144, 0x00000036);
- /* Table 8-25 */
- Set_NB32(cpu_f3, 0x148, 0x8000832A);
- /* Table 8-26 */
- Set_NB32(cpu_f3, 0x158, 0);
- /* L3 Disabled: L3 Enabled: */
- /* cores: 2 3 4 2 3 4 */
- /* bit8:4 28 26 24 24 20 16 */
- if (!l3_cache()) {
- Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (24 + 2*(4-cpu_core_number())) << 4 | 2);
- } else {
- Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (16 + 4*(4-cpu_core_number())) << 4 | 4);
- }
-}
-#else
-#define fam10_optimization() do{}while(0)
-#endif /* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 */
-
-/*****************************************
-* rs780_por_pcicfg_init()
-*****************************************/
-static void rs780_por_pcicfg_init(device_t nb_dev)
-{
- /* enable PCI Memory Access */
- set_nbcfg_enable_bits_8(nb_dev, 0x04, (u8)(~0xFD), 0x02);
- /* Set RCRB Enable */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x1);
- /* allow decode of 640k-1MB */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xEF), 0x10);
- /* Enable PM2_CNTL(BAR2) IO mapped cfg write access to be broadcast to both NB and SB */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x4);
- /* Power Management Register Enable */
- set_nbcfg_enable_bits_8(nb_dev, 0x84, (u8)(~0xFF), 0x80);
-
- /* Reg4Ch[1]=1 (APIC_ENABLE) force cpu request with address 0xFECx_xxxx to south-bridge
- * Reg4Ch[6]=1 (BMMsgEn) enable BM_Set message generation
- * BMMsgEn */
- set_nbcfg_enable_bits_8(nb_dev, 0x4C, (u8)(~0x00), 0x42 | 1);
-
- /* Reg4Ch[16]=1 (WakeC2En) enable Wake_from_C2 message generation.
- * Reg4Ch[18]=1 (P4IntEnable) Enable north-bridge to accept MSI with address 0xFEEx_xxxx from south-bridge */
- set_nbcfg_enable_bits_8(nb_dev, 0x4E, (u8)(~0xFF), 0x05);
- /* Reg94h[4:0] = 0x0 P drive strength offset 0
- * Reg94h[6:5] = 0x2 P drive strength additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x94, (u8)(~0x80), 0x40);
-
- /* Reg94h[20:16] = 0x0 N drive strength offset 0
- * Reg94h[22:21] = 0x2 N drive strength additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x96, (u8)(~0x80), 0x40);
-
- /* Reg80h[4:0] = 0x0 Termination offset
- * Reg80h[6:5] = 0x2 Termination additive adjust */
- set_nbcfg_enable_bits_8(nb_dev, 0x80, (u8)(~0x80), 0x40);
-
- /* Reg80h[14] = 0x1 Enable receiver termination control */
- set_nbcfg_enable_bits_8(nb_dev, 0x81, (u8)(~0xFF), 0x40);
-
- /* Reg94h[15] = 0x1 Enables HT transmitter advanced features to be turned on
- * Reg94h[14] = 0x1 Enable drive strength control */
- set_nbcfg_enable_bits_8(nb_dev, 0x95, (u8)(~0x3F), 0xC4);
-
- /* Reg94h[31:29] = 0x7 Enables HT transmitter de-emphasis */
- set_nbcfg_enable_bits_8(nb_dev, 0x97, (u8)(~0x1F), 0xE0);
-
- /* Reg8Ch[9] enables Gfx Debug BAR programming
- * Reg8Ch[10] enables Gfx Debug BAR operation
- * Enable programming of the debug bar now, but enable
- * operation only after it has been programmed */
- set_nbcfg_enable_bits_8(nb_dev, 0x8D, (u8)(~0xFF), 0x02);
-}
-
-static void rs780_por_mc_index_init(device_t nb_dev)
-{
- set_nbmc_enable_bits(nb_dev, 0x7A, ~0xFFFFFF80, 0x0000005F);
- set_nbmc_enable_bits(nb_dev, 0xD8, ~0x00000000, 0x00600060);
- set_nbmc_enable_bits(nb_dev, 0xD9, ~0x00000000, 0x00600060);
- set_nbmc_enable_bits(nb_dev, 0xE0, ~0x00000000, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xE1, ~0x00000000, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xE8, ~0x00000000, 0x003E003E);
- set_nbmc_enable_bits(nb_dev, 0xE9, ~0x00000000, 0x003E003E);
-}
-
-static void rs780_por_misc_index_init(device_t nb_dev)
-{
- /* NB_MISC_IND_WR_EN + IOC_PCIE_CNTL
- * Block non-snoop DMA request if PMArbDis is set.
- * Set BMSetDis */
- set_nbmisc_enable_bits(nb_dev, 0x0B, ~0xFFFF0000, 0x00000180);
- set_nbmisc_enable_bits(nb_dev, 0x01, ~0xFFFFFFFF, 0x00000040);
-
- /* NBCFG (NBMISCIND 0x0): NB_CNTL -
- * HIDE_NB_AGP_CAP ([0], default=1)HIDE
- * HIDE_P2P_AGP_CAP ([1], default=1)HIDE
- * HIDE_NB_GART_BAR ([2], default=1)HIDE
- * AGPMODE30 ([4], default=0)DISABLE
- * AGP30ENCHANCED ([5], default=0)DISABLE
- * HIDE_AGP_CAP ([8], default=1)ENABLE */
- set_nbmisc_enable_bits(nb_dev, 0x00, ~0xFFFF0000, 0x00000506); /* set bit 10 for MSI */
-
- /* NBMISCIND:0x6A[16]= 1 SB link can get a full swing
- * set_nbmisc_enable_bits(nb_dev, 0x6A, 0ffffffffh, 000010000);
- * NBMISCIND:0x6A[17]=1 Set CMGOOD_OVERRIDE. */
- set_nbmisc_enable_bits(nb_dev, 0x6A, ~0xffffffff, 0x00020000);
-
- /* NBMISIND:0x40 Bit[8]=1 and Bit[10]=1 following bits are required to set in order to allow LVDS or PWM features to work. */
- set_nbmisc_enable_bits(nb_dev, 0x40, ~0xffffffff, 0x00000500);
-
- /* NBMISIND:0xC Bit[13]=1 Enable GSM mode for C1e or C3 with pop-up. */
- set_nbmisc_enable_bits(nb_dev, 0x0C, ~0xffffffff, 0x00002000);
-
- /* Set NBMISIND:0x1F[3] to map NB F2 interrupt pin to INTB# */
- set_nbmisc_enable_bits(nb_dev, 0x1F, ~0xffffffff, 0x00000008);
-
- /*
- * Enable access to DEV8
- * Enable setPower message for all ports
- */
- set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 6, 1 << 6);
- set_nbmisc_enable_bits(nb_dev, 0x0b, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x51, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x53, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x55, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x57, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x59, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x5B, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x5D, 1 << 20, 1 << 20);
- set_nbmisc_enable_bits(nb_dev, 0x5F, 1 << 20, 1 << 20);
-
- set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 7, 1 << 7);
- set_nbmisc_enable_bits(nb_dev, 0x07, 0x000000f0, 0x30);
-
- set_nbmisc_enable_bits(nb_dev, 0x01, 0xFFFFFFFF, 0x48);
- /* Disable bus-master trigger event from SB and Enable set_slot_power message to SB */
- set_nbmisc_enable_bits(nb_dev, 0x0B, 0xffffffff, 0x500180);
-}
-
-/*****************************************
-* Some setting is from rpr. Some is from CIMx.
-*****************************************/
-static void rs780_por_htiu_index_init(device_t nb_dev)
-{
-#if 0 /* get from rpr. */
- set_htiu_enable_bits(nb_dev, 0x1C, 0x1<<17, 0x1<<17);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<0, 0x0<<0);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<1, 0x1<<1);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<9, 0x1<<9);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<13, 0x1<<13);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<17, 0x1<<17);
- set_htiu_enable_bits(nb_dev, 0x06, 0x3<<15, 0x3<<15);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<25, 0x1<<25);
- set_htiu_enable_bits(nb_dev, 0x06, 0x1<<30, 0x1<<30);
-
- set_htiu_enable_bits(nb_dev, 0x07, 0x1<<0, 0x1<<0);
- set_htiu_enable_bits(nb_dev, 0x07, 0x1<<1, 0x0<<1);
- set_htiu_enable_bits(nb_dev, 0x07, 0x1<<2, 0x0<<2);
- set_htiu_enable_bits(nb_dev, 0x07, 0x1<<15, 0x1<<15);
-
- set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<0, 0x1<<0);
- set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<2, 0x2<<2);
- set_htiu_enable_bits(nb_dev, 0x0C, 0x3<<4, 0x0<<4);
-
- /* A12 only */
- set_htiu_enable_bits(nb_dev, 0x2D, 0x1<<4, 0x1<<4);
- set_htiu_enable_bits(nb_dev, 0x2D, 0x1<<6, 0x1<<6);
- set_htiu_enable_bits(nb_dev, 0x05, 0x1<<2, 0x1<<2);
-
- set_htiu_enable_bits(nb_dev, 0x1E, 0xFFFFFFFF, 0xFFFFFFFF);
-#else /* get from CIM. It is more reliable than above. */
- set_htiu_enable_bits(nb_dev, 0x05, (1<<10|1<<9), 1<<10 | 1<<9);
- set_htiu_enable_bits(nb_dev, 0x06, ~0xFFFFFFFE, 0x04203A202);
-
- set_htiu_enable_bits(nb_dev, 0x07, ~0xFFFFFFF9, 0x8001/* | 7 << 8 */); /* fam 10 */
-
- set_htiu_enable_bits(nb_dev, 0x15, ~0xFFFFFFFF, 1<<31| 1<<30 | 1<<27);
- set_htiu_enable_bits(nb_dev, 0x1C, ~0xFFFFFFFF, 0xFFFE0000);
-
- set_htiu_enable_bits(nb_dev, 0x4B, (1<<11), 1<<11);
-
- set_htiu_enable_bits(nb_dev, 0x0C, ~0xFFFFFFC0, 1<<0|1<<3);
-
- set_htiu_enable_bits(nb_dev, 0x17, (1<<27|1<<1), 0x1<<1);
- set_htiu_enable_bits(nb_dev, 0x17, 0x1 << 30, 0x1<<30);
-
- set_htiu_enable_bits(nb_dev, 0x19, (0xFFFFF+(1<<31)), 0x186A0+(1<<31));
-
- set_htiu_enable_bits(nb_dev, 0x16, (0x3F<<10), 0x7<<10);
-
- set_htiu_enable_bits(nb_dev, 0x23, 0xFFFFFFF, 1<<28);
-
- set_htiu_enable_bits(nb_dev, 0x1E, 0xFFFFFFFF, 0xFFFFFFFF);
-#endif
-}
-
-/*****************************************
-* Configure RS780 registers to power-on default RPR.
-* POR: Power On Reset
-* RPR: Register Programming Requirements
-*****************************************/
-static void rs780_por_init(device_t nb_dev)
-{
- printk(BIOS_INFO, "rs780_por_init\n");
- /* ATINB_PCICFG_POR_TABLE, initialize the values for rs780 PCI Config registers */
- rs780_por_pcicfg_init(nb_dev);
-
- /* ATINB_MCIND_POR_TABLE */
- rs780_por_mc_index_init(nb_dev);
-
- /* ATINB_MISCIND_POR_TABLE */
- rs780_por_misc_index_init(nb_dev);
-
- /* ATINB_HTIUNBIND_POR_TABLE */
- rs780_por_htiu_index_init(nb_dev);
-
- /* ATINB_CLKCFG_PORT_TABLE */
- /* rs780 A11 SB Link full swing? */
-}
-
-/* enable CFG access to Dev8, which is the SB P2P Bridge */
-static void enable_rs780_dev8(void)
-{
- set_nbmisc_enable_bits(PCI_DEV(0, 0, 0), 0x00, 1 << 6, 1 << 6);
-}
-
-static void rs780_before_pci_init(void)
-{
-}
-
-static void rs780_early_setup(void)
-{
- device_t nb_dev = PCI_DEV(0, 0, 0);
- printk(BIOS_INFO, "rs780_early_setup()\n");
-
- get_cpu_rev();
-
- /* The printk(BIOS_INFO, s) below cause the system unstable. */
- switch (get_nb_rev(nb_dev)) {
- case REV_RS780_A11:
- /* printk(BIOS_INFO, "NB Revision is A11.\n"); */
- break;
- case REV_RS780_A12:
- /* printk(BIOS_INFO, "NB Revision is A12.\n"); */
- break;
- case REV_RS780_A13:
- /* printk(BIOS_INFO, "NB Revision is A13.\n"); */
- break;
- }
-
- if (is_famly10())
- fam10_optimization();
- else
- k8_optimization();
-
- rs780_por_init(nb_dev);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * for rs780 internal graphics device
- * device id of internal grphics:
- * RS780: 0x9610
- * RS780C: 0x9611
- * RS780M: 0x9612
- * RS780MC:0x9613
- * RS780E: 0x9615
- * RS785G: 0x9710 - just works, not much tested
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <delay.h>
-#include <cpu/x86/msr.h>
-#include "rs780.h"
-extern int is_dev3_present(void);
-void set_pcie_reset(void);
-void set_pcie_dereset(void);
-
-extern uint64_t uma_memory_base, uma_memory_size;
-
-/* Trust the original resource allocation. Don't do it again. */
-#undef DONT_TRUST_RESOURCE_ALLOCATION
-//#define DONT_TRUST_RESOURCE_ALLOCATION
-
-#define CLK_CNTL_INDEX 0x8
-#define CLK_CNTL_DATA 0xC
-
-/* The Integrated Info Table. */
-ATOM_INTEGRATED_SYSTEM_INFO_V2 vgainfo;
-
-#ifdef UNUSED_CODE
-static u32 clkind_read(device_t dev, u32 index)
-{
- u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
-
- *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
- return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
-}
-#endif
-
-static void clkind_write(device_t dev, u32 index, u32 data)
-{
- u32 gfx_bar2 = pci_read_config32(dev, 0x18) & ~0xF;
- /* printk(BIOS_DEBUG, "gfx bar 2 %02x\n", gfx_bar2); */
-
- *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
- *(u32*)(gfx_bar2+CLK_CNTL_DATA) = data;
-}
-
-/*
-* pci_dev_read_resources thinks it is a IO type.
-* We have to force it to mem type.
-*/
-static void rs780_gfx_read_resources(device_t dev)
-{
- printk(BIOS_DEBUG, "rs780_gfx_read_resources.\n");
-
- /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
- Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
- which tells us it is a memory address base.
- */
- pci_write_config32(dev, 0x24, 0x00000000);
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
- compact_resources(dev);
-}
-
-typedef struct _MMIORANGE
-{
- u32 Base;
- u32 Limit;
- u8 Attribute;
-} MMIORANGE;
-
-MMIORANGE MMIO[8], CreativeMMIO[8];
-
-#define CIM_STATUS u32
-#define CIM_SUCCESS 0x00000000
-#define CIM_ERROR 0x80000000
-#define CIM_UNSUPPORTED 0x80000001
-#define CIM_DISABLEPORT 0x80000002
-
-#define MMIO_ATTRIB_NP_ONLY 1
-#define MMIO_ATTRIB_BOTTOM_TO_TOP 1<<1
-#define MMIO_ATTRIB_SKIP_ZERO 1<<2
-
-#ifdef DONT_TRUST_RESOURCE_ALLOCATION
-static MMIORANGE* AllocMMIO(MMIORANGE* pMMIO)
-{
- int i;
- for (i=0; i<8; i++) {
- if (pMMIO[i].Limit == 0)
- return &pMMIO[i];
- }
- return 0;
-}
-
-static void FreeMMIO(MMIORANGE* pMMIO)
-{
- pMMIO->Base = 0;
- pMMIO->Limit = 0;
-}
-
-static u32 SetMMIO(u32 Base, u32 Limit, u8 Attribute, MMIORANGE *pMMIO)
-{
- int i;
- MMIORANGE * TempRange;
- for(i=0; i<8; i++)
- {
- if(pMMIO[i].Attribute != Attribute && Base >= pMMIO[i].Base && Limit <= pMMIO[i].Limit)
- {
- TempRange = AllocMMIO(pMMIO);
- if(TempRange == 0) return 0x80000000;
- TempRange->Base = Limit;
- TempRange->Limit = pMMIO[i].Limit;
- TempRange->Attribute = pMMIO[i].Attribute;
- pMMIO[i].Limit = Base;
- }
- }
- TempRange = AllocMMIO(pMMIO);
- if(TempRange == 0) return 0x80000000;
- TempRange->Base = Base;
- TempRange->Limit = Limit;
- TempRange->Attribute = Attribute;
- return 0;
-}
-
-static u8 FinalizeMMIO(MMIORANGE *pMMIO)
-{
- int i, j, n = 0;
- for(i=0; i<8; i++)
- {
- if (pMMIO[i].Base == pMMIO[i].Limit)
- {
- FreeMMIO(&pMMIO[i]);
- continue;
- }
- for(j=0; j<i; j++)
- {
- if (i!=j && pMMIO[i].Attribute == pMMIO[j].Attribute)
- {
- if (pMMIO[i].Base == pMMIO[j].Limit)
- {
- pMMIO[j].Limit = pMMIO[i].Limit;
- FreeMMIO(&pMMIO[i]);
- }
- if (pMMIO[i].Limit == pMMIO[j].Base)
- {
- pMMIO[j].Base = pMMIO[i].Base;
- FreeMMIO(&pMMIO[i]);
- }
- }
- }
- }
- for (i=0; i<8; i++)
- {
- if (pMMIO[i].Limit != 0) n++;
- }
- return n;
-}
-
-static CIM_STATUS GetCreativeMMIO(MMIORANGE *pMMIO)
-{
- CIM_STATUS Status = CIM_UNSUPPORTED;
- u8 Bus, Dev, Reg, BusStart, BusEnd;
- u32 Value;
- device_t dev0x14 = dev_find_slot(0, PCI_DEVFN(0x14, 4));
- device_t tempdev;
- Value = pci_read_config32(dev0x14, 0x18);
- BusStart = (Value >> 8) & 0xFF;
- BusEnd = (Value >> 16) & 0xFF;
- for(Bus = BusStart; Bus <= BusEnd; Bus++)
- {
- for(Dev = 0; Dev <= 0x1f; Dev++)
- {
- tempdev = dev_find_slot(Bus, Dev << 3);
- Value = pci_read_config32(tempdev, 0);
- printk(BIOS_DEBUG, "Dev ID %x \n", Value);
- if((Value & 0xffff) == 0x1102)
- {//Creative
- //Found Creative SB
- u32 MMIOStart = 0xffffffff;
- u32 MMIOLimit = 0;
- for(Reg = 0x10; Reg < 0x20; Reg+=4)
- {
- u32 BaseA, LimitA;
- BaseA = pci_read_config32(tempdev, Reg);
- Value = BaseA;
- if(!(Value & 0x01))
- {
- Value = Value & 0xffffff00;
- if(Value != 0)
- {
- if(MMIOStart > Value)
- MMIOStart = Value;
- LimitA = 0xffffffff;
- //WritePCI(PciAddress,AccWidthUint32,&LimitA);
- pci_write_config32(tempdev, Reg, LimitA);
- //ReadPCI(PciAddress,AccWidthUint32,&LimitA);
- LimitA = pci_read_config32(tempdev, Reg);
- LimitA = Value + (~LimitA + 1);
- //WritePCI(PciAddress,AccWidthUint32,&BaseA);
- pci_write_config32(tempdev, Reg, BaseA);
- if (LimitA > MMIOLimit)
- MMIOLimit = LimitA;
- }
- }
- }
- printk(BIOS_DEBUG, " MMIOStart %x MMIOLimit %x \n", MMIOStart, MMIOLimit);
- if (MMIOStart < MMIOLimit)
- {
- Status = SetMMIO(MMIOStart>>8, MMIOLimit>>8, 0x80, pMMIO);
- if(Status == CIM_ERROR) return Status;
- }
- }
- }
- }
- if(Status == CIM_SUCCESS)
- {
- //Lets optimize MMIO
- if(FinalizeMMIO(pMMIO) > 4)
- {
- Status = CIM_ERROR;
- }
- }
-
- return Status;
-}
-
-static void ProgramMMIO(MMIORANGE *pMMIO, u8 LinkID, u8 Attribute)
-{
- int i, j, n = 7;
- device_t k8_f1;
-
- k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
-
- for(i = 0; i < 8; i++)
- {
- int k = 0, MmioReg;
- u32 Base = 0;
- u32 Limit = 0;
- for(j = 0; j < 8; j++)
- {
- if (Base < pMMIO[j].Base)
- {
- Base = pMMIO[j].Base;
- k = j;
- }
- }
- if(pMMIO[k].Limit != 0)
- {
- if(Attribute & MMIO_ATTRIB_NP_ONLY && pMMIO[k].Attribute == 0 )
- {
- Base = 0;
- }
- else
- {
- Base = pMMIO[k].Base | 0x3;
- Limit= ((pMMIO[k].Limit - 1) & 0xffffff00) | pMMIO[k].Attribute | (LinkID << 4);
- }
- FreeMMIO(&pMMIO[k]);
- }
- if (Attribute & MMIO_ATTRIB_SKIP_ZERO && Base == 0 && Limit == 0) continue;
- MmioReg = (Attribute & MMIO_ATTRIB_BOTTOM_TO_TOP)?n:(7-n);
- n--;
- //RWPCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,0x0,0x0);
- pci_write_config32(k8_f1, 0x80+MmioReg*8, 0);
-
- //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x84+MmioReg*8),AccWidthUint32 |S3_SAVE,&Limit);
- pci_write_config32(k8_f1, 0x84+MmioReg*8, Limit);
-
- //WritePCI(PCI_ADDRESS(0,CPU_DEV,CPU_F1,0x80+MmioReg*8),AccWidthUint32 |S3_SAVE,&Base);
- pci_write_config32(k8_f1, 0x80+MmioReg*8, Base);
- }
-}
-#endif
-
-static void internal_gfx_pci_dev_init(struct device *dev)
-{
- unsigned char * bpointer;
- volatile u32 * GpuF0MMReg;
- volatile u32 * pointer;
- int i;
- u16 command;
- u32 value;
- u16 deviceid, vendorid;
- device_t nb_dev = dev_find_slot(0, 0);
- device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
- device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- static const u8 ht_freq_lookup [] = {2, 0, 4, 0, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 0, 0, 28, 30, 32};
- static const u8 ht_width_lookup [] = {8, 16, 0, 0, 2, 4, 0, 0};
- static const u16 memclk_lookup_fam0F [] = {100, 0, 133, 0, 0, 166, 0, 200};
- static const u16 memclk_lookup_fam10 [] = {200, 266, 333, 400, 533, 667, 800, 800};
-
- /* We definetely will use this in future. Just leave it here. */
- /*struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)dev->chip_info;*/
-
- deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
- vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
- printk(BIOS_DEBUG, "internal_gfx_pci_dev_init device=%x, vendor=%x.\n",
- deviceid, vendorid);
-
- command = pci_read_config16(dev, 0x04);
- command |= 0x7;
- pci_write_config16(dev, 0x04, command);
-
- /* Clear vgainfo. */
- bpointer = (unsigned char *) &vgainfo;
- for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i++)
- {
- *bpointer = 0;
- bpointer++;
- }
-
- GpuF0MMReg = (u32 *)pci_read_config32(dev, 0x18);
-
- /* GFX_InitFBAccess. */
- value = nbmc_read_index(nb_dev, 0x10);
- *(GpuF0MMReg + 0x2000/4) = 0x11;
- *(GpuF0MMReg + 0x2180/4) = ((value&0xff00)>>8)|((value&0xff000000)>>8);
- *(GpuF0MMReg + 0x2c04/4) = ((value&0xff00)<<8);
- *(GpuF0MMReg + 0x5428/4) = ((value&0xffff0000)+0x10000)-((value&0xffff)<<16);
- *(GpuF0MMReg + 0xF774/4) = 0xffffffff;
- *(GpuF0MMReg + 0xF770/4) = 0x00000001;
- *(GpuF0MMReg + 0x2000/4) = 0x00000011;
- *(GpuF0MMReg + 0x200c/4) = 0x00000020;
- *(GpuF0MMReg + 0x2010/4) = 0x10204810;
- *(GpuF0MMReg + 0x2010/4) = 0x00204810;
- *(GpuF0MMReg + 0x2014/4) = 0x10408810;
- *(GpuF0MMReg + 0x2014/4) = 0x00408810;
- *(GpuF0MMReg + 0x2414/4) = 0x00000080;
- *(GpuF0MMReg + 0x2418/4) = 0x84422415;
- *(GpuF0MMReg + 0x2418/4) = 0x04422415;
- *(GpuF0MMReg + 0x5490/4) = 0x00000001;
- *(GpuF0MMReg + 0x7de4/4) |= (1<<3) | (1<<4);
- /* Force allow LDT_STOP Cool'n'Quiet workaround. */
- *(GpuF0MMReg + 0x655c/4) |= 1<<4;
-
- // disable write combining, needed for stability
- // reference bios does this only for RS780 rev A11
- // need to figure out why we need it for all revs
- *(GpuF0MMReg + 0x2000/4) = 0x00000010;
- *(GpuF0MMReg + 0x2408/4) = 1 << 9;
- *(GpuF0MMReg + 0x2000/4) = 0x00000011;
-
- /* GFX_InitFBAccess finished. */
-
-#if (CONFIG_GFXUMA == 1) /* for UMA mode. */
- /* GFX_StartMC. */
- set_nbmc_enable_bits(nb_dev, 0x02, 0x00000000, 0x80000000);
- set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000001);
- set_nbmc_enable_bits(nb_dev, 0x01, 0x00000000, 0x00000004);
- set_nbmc_enable_bits(nb_dev, 0x01, 0x00040000, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xB1, 0xFFFF0000, 0x00000040);
- set_nbmc_enable_bits(nb_dev, 0xC3, 0x00000000, 0x00000001);
- set_nbmc_enable_bits(nb_dev, 0x07, 0xFFFFFFFF, 0x00000018);
- set_nbmc_enable_bits(nb_dev, 0x06, 0xFFFFFFFF, 0x00000102);
- set_nbmc_enable_bits(nb_dev, 0x09, 0xFFFFFFFF, 0x40000008);
- set_nbmc_enable_bits(nb_dev, 0x06, 0x00000000, 0x80000000);
- /* GFX_StartMC finished. */
-#else
- /* for SP mode. */
- set_nbmc_enable_bits(nb_dev, 0xaa, 0xf0, 0x30);
- set_nbmc_enable_bits(nb_dev, 0xce, 0xf0, 0x30);
- set_nbmc_enable_bits(nb_dev, 0xca, 0xff000000, 0x47000000);
- set_nbmc_enable_bits(nb_dev, 0xcb, 0x3f000000, 0x01000000);
- set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<0);
- set_nbmc_enable_bits(nb_dev, 0x04, 0, 1<<31);
- set_nbmc_enable_bits(nb_dev, 0xb4, 0x3f, 0x3f);
- set_nbmc_enable_bits(nb_dev, 0xb4, 0, 1<<6);
- set_nbmc_enable_bits(nb_dev, 0xc3, 1<<11, 0);
- set_nbmc_enable_bits(nb_dev, 0xa0, 1<<29, 0);
- nbmc_write_index(nb_dev, 0xa4, 0x3484576f);
- nbmc_write_index(nb_dev, 0xa5, 0x222222df);
- nbmc_write_index(nb_dev, 0xa6, 0x00000000);
- nbmc_write_index(nb_dev, 0xa7, 0x00000000);
- set_nbmc_enable_bits(nb_dev, 0xc3, 1<<8, 0);
- udelay(10);
- set_nbmc_enable_bits(nb_dev, 0xc3, 1<<9, 0);
- udelay(10);
- set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<2);
- udelay(200);
- set_nbmc_enable_bits(nb_dev, 0x01, 0, 1<<3);
- set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<31);
- udelay(500);
- set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<31);
- set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<30);
- set_nbmc_enable_bits(nb_dev, 0xa0, 1<<31, 0);
- set_nbmc_enable_bits(nb_dev, 0xa0, 0, 1<<29);
- nbmc_write_index(nb_dev, 0xa4, 0x23484576);
- nbmc_write_index(nb_dev, 0xa5, 0x00000000);
- nbmc_write_index(nb_dev, 0xa6, 0x00000000);
- nbmc_write_index(nb_dev, 0xa7, 0x00000000);
- /* GFX_StartMC finished. */
-
- /* GFX_SPPowerManagment, don't care for new. */
- /* Post MC Init table programming. */
- set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b);
-
- /* Do we need Write and Read Calibration? */
- /* GFX_Init finished. */
-#endif
-
- /* GFX_InitIntegratedInfo. */
- /* fill the Integrated Info Table. */
- vgainfo.sHeader.usStructureSize = sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2);
- vgainfo.sHeader.ucTableFormatRevision = 1;
- vgainfo.sHeader.ucTableContentRevision = 2;
-
-#if (CONFIG_GFXUMA == 0) /* SP mode. */
- // Side port support is incomplete, do not use it
- // These parameters must match the motherboard
- vgainfo.ulBootUpSidePortClock = 667*100;
- vgainfo.ucMemoryType = 3; // 3=ddr3 sp mem, 2=ddr2 sp mem
- vgainfo.ulMinSidePortClock = 333*100;
-#endif
-
- vgainfo.ulBootUpEngineClock = 500 * 100; // setup option on reference BIOS, 500 is default
-
- // find the DDR memory frequency
- if (is_family10h()) {
- value = pci_read_config32(k8_f2, 0x94); // read channel 0 DRAM Configuration High Register
- if (extractbit(value, 14)) // if channel 0 disabled, channel 1 must have memory
- value = pci_read_config32(k8_f2, 0x194);// read channel 1 DRAM Configuration High Register
- vgainfo.ulBootUpUMAClock = memclk_lookup_fam10 [extractbits (value, 0, 2)] * 100;
- }
- if (is_family0Fh()) {
- value = pci_read_config32(k8_f2, 0x94);
- vgainfo.ulBootUpUMAClock = memclk_lookup_fam0F [extractbits (value, 20, 22)] * 100;
- }
-
- /* UMA Channel Number: 1 or 2. */
- vgainfo.ucUMAChannelNumber = 1;
- if (is_family0Fh()) {
- value = pci_read_config32(k8_f2, 0x90);
- if (extractbit(value, 11)) // 128-bit mode
- vgainfo.ucUMAChannelNumber = 2;
- }
- if (is_family10h()) {
- u32 dch0 = pci_read_config32(k8_f2, 0x94);
- u32 dch1 = pci_read_config32(k8_f2, 0x194);
- if (extractbit(dch0, 14) == 0 && extractbit(dch1, 14) == 0) { // both channels enabled
- value = pci_read_config32(k8_f2, 0x110);
- if (extractbit(value, 4)) // ganged mode
- vgainfo.ucUMAChannelNumber = 2;
- }
- }
-
- // processor type
- if (is_family0Fh())
- vgainfo.ulCPUCapInfo = 3;
- if (is_family10h())
- vgainfo.ulCPUCapInfo = 2;
-
- /* HT speed */
- value = pci_read_config8(nb_dev, 0xd1);
- value = ht_freq_lookup [value] * 100; // HT link frequency in MHz
- vgainfo.ulHTLinkFreq = value * 100; // HT frequency in units of 100 MHz
- vgainfo.ulHighVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
- vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
-
- if (value <= 1800)
- vgainfo.ulLowVoltageHTLinkFreq = vgainfo.ulHTLinkFreq;
- else {
- int sblink, cpuLnkFreqCap, nbLnkFreqCap;
- value = pci_read_config32(k8_f0, 0x64);
- sblink = extractbits(value, 8, 10);
- cpuLnkFreqCap = pci_read_config16(k8_f0, 0x8a + sblink * 0x20);
- nbLnkFreqCap = pci_read_config16(nb_dev, 0xd2);
- if (cpuLnkFreqCap & nbLnkFreqCap & (1 << 10)) // if both 1800 MHz capable
- vgainfo.ulLowVoltageHTLinkFreq = 1800*100;
- }
-
- /* HT width. */
- value = pci_read_config8(nb_dev, 0xcb);
- vgainfo.usMinDownStreamHTLinkWidth =
- vgainfo.usMaxDownStreamHTLinkWidth =
- vgainfo.usMinUpStreamHTLinkWidth =
- vgainfo.usMaxUpStreamHTLinkWidth =
- vgainfo.usMinHTLinkWidth =
- vgainfo.usMaxHTLinkWidth = ht_width_lookup [extractbits(value, 0, 2)];
-
- if (is_family0Fh()) {
- vgainfo.usUMASyncStartDelay = 322;
- vgainfo.usUMADataReturnTime = 286;
- }
-
- if (is_family10h()) {
- static u16 t0mult_lookup [] = {10, 50, 200, 2000};
- int t0time, t0scale;
- value = pci_read_config32(k8_f0, 0x16c);
- t0time = extractbits(value, 0, 3);
- t0scale = extractbits(value, 4, 5);
- vgainfo.usLinkStatusZeroTime = t0mult_lookup [t0scale] * t0time;
- vgainfo.usUMASyncStartDelay = 100;
- if (vgainfo.ulHTLinkFreq < 1000 * 100) { // less than 1000 MHz
- vgainfo.usUMADataReturnTime = 300;
- vgainfo.usLinkStatusZeroTime = 6 * 100; // 6us for GH in HT1 mode
- }
- else {
- int lssel;
- value = pci_read_config32(nb_dev, 0xac);
- lssel = extractbits (value, 7, 8);
- vgainfo.usUMADataReturnTime = 1300;
- if (lssel == 0) vgainfo.usUMADataReturnTime = 150;
- }
- }
-
- /* Transfer the Table to VBIOS. */
- pointer = (u32 *)&vgainfo;
- for(i=0; i<sizeof(ATOM_INTEGRATED_SYSTEM_INFO_V2); i+=4)
- {
-#if (CONFIG_GFXUMA == 1)
- *GpuF0MMReg = 0x80000000 + uma_memory_size - 512 + i;
-#else
- *GpuF0MMReg = 0x80000000 + 0x8000000 - 512 + i;
-#endif
- *(GpuF0MMReg+1) = *pointer++;
- }
-
- /* GFX_InitLate. */
- {
- u32 temp;
- temp = pci_read_config8(dev, 0x4);
- //temp &= ~1; /* CIM clears this bit. Strangely, I can'd. */
- temp |= 1<<1|1<<2;
- pci_write_config8(dev, 0x4, temp);
-
- // if the GFX debug bar is writable, then it has
- // been programmed and can be safely enabled now
- temp = pci_read_config32(nb_dev, 0x8c);
-
- // if bits 1 (intgfx_enable) and 9 (gfx_debug_bar_enable)
- // then enable gfx debug bar (set gxf_debug_decode_enable)
- if (temp & 0x202)
- temp |= (1 << 10);
- pci_write_config32(nb_dev, 0x8c, temp);
-
- }
-
-#ifdef DONT_TRUST_RESOURCE_ALLOCATION
- /* NB_SetupMGMMIO. */
-
- /* clear MMIO and CreativeMMIO. */
- bpointer = (unsigned char *)MMIO;
- for(i=0; i<sizeof(MMIO); i++)
- {
- *bpointer = 0;
- bpointer++;
- }
- bpointer = (unsigned char *)CreativeMMIO;
- for(i=0; i<sizeof(CreativeMMIO); i++)
- {
- *bpointer = 0;
- bpointer++;
- }
-
- /* Set MMIO ranges in K8. */
- /* Set MMIO TOM - 4G. */
- SetMMIO(0x400<<12, 0x1000000, 0x80, &MMIO[0]);
- /* Set MMIO for VGA Legacy FB. */
- SetMMIO(0xa00, 0xc00, 0x80, &MMIO[0]);
-
- /* Set MMIO for non prefetchable P2P. */
- temp = pci_read_config32(dev0x14, 0x20);
- Base32 = (temp & 0x0fff0) << 8;
- Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
- if(Base32 < Limit32)
- {
- Status = GetCreativeMMIO(&CreativeMMIO[0]);
- if(Status != CIM_ERROR)
- SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
- }
- /* Set MMIO for prefetchable P2P. */
- if(Status != CIM_ERROR)
- {
- temp = pci_read_config32(dev0x14, 0x24);
-
- Base32 = (temp & 0x0fff0) <<8;
- Limit32 = ((temp & 0x0fff00000) + 0x100000) >> 8;
- if(Base32 < Limit32)
- SetMMIO(Base32, Limit32, 0x0, &MMIO[0]);
- }
-
- FinalizeMMIO(&MMIO[0]);
-
- ProgramMMIO(&CreativeMMIO[0], 0, MMIO_ATTRIB_NP_ONLY);
- ProgramMMIO(&MMIO[0], 0, MMIO_ATTRIB_NP_ONLY | MMIO_ATTRIB_BOTTOM_TO_TOP | MMIO_ATTRIB_SKIP_ZERO);
-#endif
-
- pci_dev_init(dev);
-
- /* clk ind */
- clkind_write(dev, 0x08, 0x01);
- clkind_write(dev, 0x0C, 0x22);
- clkind_write(dev, 0x0F, 0x0);
- clkind_write(dev, 0x11, 0x0);
- clkind_write(dev, 0x12, 0x0);
- clkind_write(dev, 0x14, 0x0);
- clkind_write(dev, 0x15, 0x0);
- clkind_write(dev, 0x16, 0x0);
- clkind_write(dev, 0x17, 0x0);
- clkind_write(dev, 0x18, 0x0);
- clkind_write(dev, 0x19, 0x0);
- clkind_write(dev, 0x1A, 0x0);
- clkind_write(dev, 0x1B, 0x0);
- clkind_write(dev, 0x1C, 0x0);
- clkind_write(dev, 0x1D, 0x0);
- clkind_write(dev, 0x1E, 0x0);
- clkind_write(dev, 0x26, 0x0);
- clkind_write(dev, 0x27, 0x0);
- clkind_write(dev, 0x28, 0x0);
- clkind_write(dev, 0x5C, 0x0);
-}
-
-
-/*
-* Set registers in RS780 and CPU to enable the internal GFX.
-* Please refer to CIM source code and BKDG.
-*/
-
-static void rs780_internal_gfx_enable(device_t dev)
-{
- u32 l_dword;
- int i;
- device_t nb_dev = dev_find_slot(0, 0);
- msr_t sysmem;
-
-#if (CONFIG_GFXUMA == 0)
- u32 FB_Start, FB_End;
-#endif
-
- printk(BIOS_DEBUG, "rs780_internal_gfx_enable dev = 0x%p, nb_dev = 0x%p.\n", dev, nb_dev);
-
- sysmem = rdmsr(0xc001001a);
- printk(BIOS_DEBUG, "sysmem = %x_%x\n", sysmem.hi, sysmem.lo);
-
- /* The system top memory in 780. */
- pci_write_config32(nb_dev, 0x90, sysmem.lo);
- htiu_write_index(nb_dev, 0x30, 0);
- htiu_write_index(nb_dev, 0x31, 0);
-
- /* Disable external GFX and enable internal GFX. */
- l_dword = pci_read_config32(nb_dev, 0x8c);
- l_dword &= ~(1<<0);
- l_dword |= 1<<1;
- pci_write_config32(nb_dev, 0x8c, l_dword);
-
- /* NB_SetDefaultIndexes */
- pci_write_config32(nb_dev, 0x94, 0x7f);
- pci_write_config32(nb_dev, 0x60, 0x7f);
- pci_write_config32(nb_dev, 0xe0, 0);
-
- /* NB_InitEarlyNB finished. */
-
- /* LPC DMA Deadlock workaround? */
- /* GFX_InitCommon*/
- device_t k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- l_dword = pci_read_config32(k8_f0, 0x68);
- l_dword &= ~(3 << 21);
- l_dword |= (1 << 21);
- pci_write_config32(k8_f0, 0x68, l_dword);
-
- /* GFX_InitCommon. */
- nbmc_write_index(nb_dev, 0x23, 0x00c00010);
- set_nbmc_enable_bits(nb_dev, 0x16, 1<<15, 1<<15);
- set_nbmc_enable_bits(nb_dev, 0x25, 0xffffffff, 0x111f111f);
- set_htiu_enable_bits(nb_dev, 0x37, 1<<24, 1<<24);
-
-#if (CONFIG_GFXUMA == 1)
- /* GFX_InitUMA. */
- /* Copy CPU DDR Controller to NB MC. */
- device_t k8_f1 = dev_find_slot(0, PCI_DEVFN(0x18, 1));
- device_t k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
- device_t k8_f4 = dev_find_slot(0, PCI_DEVFN(0x18, 4));
- for (i = 0; i < 12; i++)
- {
- l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
- nbmc_write_index(nb_dev, 0x30 + i, l_dword);
- }
-
- l_dword = pci_read_config32(k8_f2, 0x80);
- nbmc_write_index(nb_dev, 0x3c, l_dword);
- l_dword = pci_read_config32(k8_f2, 0x94);
- set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<22))<<16);
- set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<< 8))<<17);
- l_dword = pci_read_config32(k8_f2, 0x90);
- set_nbmc_enable_bits(nb_dev, 0x3c, 0, !!(l_dword & (1<<10))<<18);
- if (is_family10h())
- {
- for (i = 0; i < 12; i++)
- {
- l_dword = pci_read_config32(k8_f2, 0x140 + i * 4);
- nbmc_write_index(nb_dev, 0x3d + i, l_dword);
- }
-
- l_dword = pci_read_config32(k8_f2, 0x180);
- nbmc_write_index(nb_dev, 0x49, l_dword);
- l_dword = pci_read_config32(k8_f2, 0x194);
- set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<22))<<16);
- set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<< 8))<<17);
- l_dword = pci_read_config32(k8_f2, 0x190);
- set_nbmc_enable_bits(nb_dev, 0x49, 0, !!(l_dword & (1<<10))<<18);
-
- l_dword = pci_read_config32(k8_f2, 0x110);
- nbmc_write_index(nb_dev, 0x4a, l_dword);
- l_dword = pci_read_config32(k8_f2, 0x114);
- nbmc_write_index(nb_dev, 0x4b, l_dword);
- l_dword = pci_read_config32(k8_f4, 0x44);
- set_nbmc_enable_bits(nb_dev, 0x4a, 0, !!(l_dword & (1<<22))<<24);
- l_dword = pci_read_config32(k8_f1, 0x40);
- nbmc_write_index(nb_dev, 0x4c, l_dword);
- l_dword = pci_read_config32(k8_f1, 0xf0);
- nbmc_write_index(nb_dev, 0x4d, l_dword);
- }
-
-
- /* Set UMA in the 780 side. */
- /* UMA start address, size. */
- /* The UMA starts at 0xC0000000 of internal RS780 address space
- [31:16] addr of last byte | [31:16] addr of first byte
- */
- nbmc_write_index(nb_dev, 0x10, ((uma_memory_size - 1 + 0xC0000000) & (~0xffff)) | 0xc000);
- nbmc_write_index(nb_dev, 0x11, uma_memory_base);
- nbmc_write_index(nb_dev, 0x12, 0);
- nbmc_write_index(nb_dev, 0xf0, uma_memory_size >> 20);
- /* GFX_InitUMA finished. */
-#else
- /* GFX_InitSP. */
- /* SP memory:Hynix HY5TQ1G631ZNFP. 128MB = 64M * 16. 667MHz. DDR3. */
-
- /* Enable Async mode. */
- set_nbmc_enable_bits(nb_dev, 0x06, 7<<8, 1<<8);
- set_nbmc_enable_bits(nb_dev, 0x08, 1<<10, 0);
- /* The last item in AsynchMclkTaskFileIndex. Why? */
- /* MC_MPLL_CONTROL2. */
- nbmc_write_index(nb_dev, 0x07, 0x40100028);
- /* MC_MPLL_DIV_CONTROL. */
- nbmc_write_index(nb_dev, 0x0b, 0x00000028);
- /* MC_MPLL_FREQ_CONTROL. */
- set_nbmc_enable_bits(nb_dev, 0x09, 3<<12|15<<16|15<<8, 1<<12|4<<16|0<<8);
- /* MC_MPLL_CONTROL3. For PM. */
- set_nbmc_enable_bits(nb_dev, 0x08, 0xff<<13, 1<<13|1<<18);
- /* MPLL_CAL_TRIGGER. */
- set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<0);
- udelay(200); /* time is long enough? */
- set_nbmc_enable_bits(nb_dev, 0x06, 0, 1<<1);
- set_nbmc_enable_bits(nb_dev, 0x06, 1<<0, 0);
- /* MCLK_SRC_USE_MPLL. */
- set_nbmc_enable_bits(nb_dev, 0x02, 0, 1<<20);
-
- /* Pre Init MC. */
- nbmc_write_index(nb_dev, 0x01, 0x88108280);
- set_nbmc_enable_bits(nb_dev, 0x02, ~(1<<20), 0x00030200);
- nbmc_write_index(nb_dev, 0x04, 0x08881018);
- nbmc_write_index(nb_dev, 0x05, 0x000000bb);
- nbmc_write_index(nb_dev, 0x0c, 0x0f00001f);
- nbmc_write_index(nb_dev, 0xa1, 0x01f10000);
- /* MCA_INIT_DLL_PM. */
- set_nbmc_enable_bits(nb_dev, 0xc9, 1<<24, 1<<24);
- nbmc_write_index(nb_dev, 0xa2, 0x74f20000);
- nbmc_write_index(nb_dev, 0xa3, 0x8af30000);
- nbmc_write_index(nb_dev, 0xaf, 0x47d0a41c);
- nbmc_write_index(nb_dev, 0xb0, 0x88800130);
- nbmc_write_index(nb_dev, 0xb1, 0x00000040);
- nbmc_write_index(nb_dev, 0xb4, 0x41247000);
- nbmc_write_index(nb_dev, 0xb5, 0x00066664);
- nbmc_write_index(nb_dev, 0xb6, 0x00000022);
- nbmc_write_index(nb_dev, 0xb7, 0x00000044);
- nbmc_write_index(nb_dev, 0xb8, 0xbbbbbbbb);
- nbmc_write_index(nb_dev, 0xb9, 0xbbbbbbbb);
- nbmc_write_index(nb_dev, 0xba, 0x55555555);
- nbmc_write_index(nb_dev, 0xc1, 0x00000000);
- nbmc_write_index(nb_dev, 0xc2, 0x00000000);
- nbmc_write_index(nb_dev, 0xc3, 0x80006b00);
- nbmc_write_index(nb_dev, 0xc4, 0x00066664);
- nbmc_write_index(nb_dev, 0xc5, 0x00000000);
- nbmc_write_index(nb_dev, 0xd2, 0x00000022);
- nbmc_write_index(nb_dev, 0xd3, 0x00000044);
- nbmc_write_index(nb_dev, 0xd6, 0x00050005);
- nbmc_write_index(nb_dev, 0xd7, 0x00000000);
- nbmc_write_index(nb_dev, 0xd8, 0x00700070);
- nbmc_write_index(nb_dev, 0xd9, 0x00700070);
- nbmc_write_index(nb_dev, 0xe0, 0x00200020);
- nbmc_write_index(nb_dev, 0xe1, 0x00200020);
- nbmc_write_index(nb_dev, 0xe8, 0x00200020);
- nbmc_write_index(nb_dev, 0xe9, 0x00200020);
- nbmc_write_index(nb_dev, 0xe0, 0x00180018);
- nbmc_write_index(nb_dev, 0xe1, 0x00180018);
- nbmc_write_index(nb_dev, 0xe8, 0x00180018);
- nbmc_write_index(nb_dev, 0xe9, 0x00180018);
-
- /* Misc options. */
- /* Memory Termination. */
- set_nbmc_enable_bits(nb_dev, 0xa1, 0x0ff, 0x044);
- set_nbmc_enable_bits(nb_dev, 0xb4, 0xf00, 0xb00);
-#if 0
- /* Controller Termation. */
- set_nbmc_enable_bits(nb_dev, 0xb1, 0x77770000, 0x77770000);
-#endif
-
- /* OEM Init MC. 667MHz. */
- nbmc_write_index(nb_dev, 0xa8, 0x7a5aaa78);
- nbmc_write_index(nb_dev, 0xa9, 0x514a2319);
- nbmc_write_index(nb_dev, 0xaa, 0x54400520);
- nbmc_write_index(nb_dev, 0xab, 0x441460ff);
- nbmc_write_index(nb_dev, 0xa0, 0x20f00a48);
- set_nbmc_enable_bits(nb_dev, 0xa2, ~(0xffffffc7), 0x10);
- nbmc_write_index(nb_dev, 0xb2, 0x00000303);
- set_nbmc_enable_bits(nb_dev, 0xb1, ~(0xffffff70), 0x45);
- /* Do it later. */
- /* set_nbmc_enable_bits(nb_dev, 0xac, ~(0xfffffff0), 0x0b); */
-
- /* Init PM timing. */
- for(i=0; i<4; i++)
- {
- l_dword = nbmc_read_index(nb_dev, 0xa0+i);
- nbmc_write_index(nb_dev, 0xc8+i, l_dword);
- }
- for(i=0; i<4; i++)
- {
- l_dword = nbmc_read_index(nb_dev, 0xa8+i);
- nbmc_write_index(nb_dev, 0xcc+i, l_dword);
- }
- l_dword = nbmc_read_index(nb_dev, 0xb1);
- set_nbmc_enable_bits(nb_dev, 0xc8, 0xff<<24, ((l_dword&0x0f)<<24)|((l_dword&0xf00)<<20));
-
- /* Init MC FB. */
- /* FB_Start = ; FB_End = ; iSpSize = 0x0080, 128MB. */
- nbmc_write_index(nb_dev, 0x11, 0x40000000);
- FB_Start = 0xc00 + 0x080;
- FB_End = 0xc00 + 0x080;
- nbmc_write_index(nb_dev, 0x10, (((FB_End&0xfff)<<20)-0x10000)|(((FB_Start&0xfff)-0x080)<<4));
- set_nbmc_enable_bits(nb_dev, 0x0d, ~0x000ffff0, (FB_Start&0xfff)<<20);
- nbmc_write_index(nb_dev, 0x0f, 0);
- nbmc_write_index(nb_dev, 0x0e, (FB_Start&0xfff)|(0xaaaa<<12));
-#endif
-
- /* GFX_InitSP finished. */
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations pcie_ops = {
- .read_resources = rs780_gfx_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = internal_gfx_pci_dev_init, /* The option ROM initializes the device. rs780_gfx_init, */
- .scan_bus = 0,
- .enable = rs780_internal_gfx_enable,
- .ops_pci = &lops_pci,
-};
-
-/*
- * We should list all of them here.
- * */
-static const struct pci_driver pcie_driver_780 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS780_INT_GFX,
-};
-
-static const struct pci_driver pcie_driver_780c __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS780C_INT_GFX,
-};
-static const struct pci_driver pcie_driver_780m __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS780M_INT_GFX,
-};
-static const struct pci_driver pcie_driver_780mc __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS780MC_INT_GFX,
-};
-static const struct pci_driver pcie_driver_780e __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS780E_INT_GFX,
-};
-static const struct pci_driver pcie_driver_785g __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_RS785G_INT_GFX,
-};
-
-/* step 12 ~ step 14 from rpr */
-static void single_port_configuration(device_t nb_dev, device_t dev)
-{
- u8 result, width;
- u32 reg32;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration.\n");
-
- /* step 12 training, releases hold training for GFX port 0 (device 2) */
- PcieReleasePortTraining(nb_dev, dev, 2);
- result = PcieTrainPort(nb_dev, dev, 2);
- printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step12.\n");
-
- /* step 13 Power Down Control */
- /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
-
- /* step 13.a Link Training was NOT successful */
- if (!result) {
- set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
- set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
- if (cfg->gfx_tmds)
- nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
- else {
- nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
- set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
- }
- } else { /* step 13.b Link Training was successful */
- set_pcie_enable_bits(dev, 0xA2, 0xFF, 0x1);
- reg32 = nbpcie_p_read_index(dev, 0x29);
- width = reg32 & 0xFF;
- printk(BIOS_DEBUG, "GFX Inactive Lanes = 0x%x.\n", width);
- switch (width) {
- case 1:
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
- break;
- case 4:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
- break;
- case 8:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
- break;
- }
- }
- printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step13.\n");
-
- /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
- set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
- printk(BIOS_DEBUG, "rs780_gfx_init single_port_configuration step14.\n");
-}
-
-static void dual_port_configuration(device_t nb_dev, device_t dev)
-{
- u8 result, width;
- u32 reg32, dev_ind = dev->path.pci.devfn >> 3;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- /* 5.4.1.2 Dual Port Configuration */
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x08, 0xF << 8, 0x5 << 8);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
-
- /* 5.7. Training for Device 2 */
- /* 5.7.1. Releases hold training for GFX port 0 (device 2) */
- PcieReleasePortTraining(nb_dev, dev, dev_ind);
- /* 5.7.2- 5.7.9. PCIE Link Training Sequence */
- result = PcieTrainPort(nb_dev, dev, dev_ind);
-
- /* Power Down Control for Device 2 */
- /* Link Training was NOT successful */
- if (!result) {
- /* Powers down all lanes for port A */
- /* nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f); */
- /* Note: I have to disable the slot where there isnt a device,
- * otherwise the system will hang. I dont know why. */
- set_nbmisc_enable_bits(nb_dev, 0x0c, 1 << dev_ind, 1 << dev_ind);
-
- } else { /* step 16.b Link Training was successful */
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- width = (reg32 >> 4) & 0x7;
- printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
- switch (width) {
- case 1:
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
- break;
- case 4:
- nbpcie_ind_write_index(nb_dev, 0x65,
- cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
- break;
- }
- }
-}
-
-/* For single port GFX configuration Only
-* width:
-* 000 = x16
-* 001 = x1
-* 010 = x2
-* 011 = x4
-* 100 = x8
-* 101 = x12 (not supported)
-* 110 = x16
-*/
-static void dynamic_link_width_control(device_t nb_dev, device_t dev, u8 width)
-{
- u32 reg32;
- device_t sb_dev;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- /* step 5.9.1.1 */
- reg32 = nbpcie_p_read_index(dev, 0xa2);
-
- /* step 5.9.1.2 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
- /* step 5.9.1.3 */
- set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
- /* step 5.9.1.4 */
- set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
- /* step 5.9.2.4 */
- if (0 == cfg->gfx_reconfiguration)
- set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
-
- /* step 5.9.1.5 */
- do {
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- }
- while (reg32 & 0x100);
-
- /* step 5.9.1.6 */
- sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
- do {
- reg32 = pci_ext_read_config32(nb_dev, sb_dev,
- PCIE_VC0_RESOURCE_STATUS);
- } while (reg32 & VC_NEGOTIATION_PENDING);
-
- /* step 5.9.1.7 */
- reg32 = nbpcie_p_read_index(dev, 0xa2);
- if (((reg32 & 0x70) >> 4) != 0x6) {
- /* the unused lanes should be powered off. */
- }
-
- /* step 5.9.1.8 */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
-}
-
-/*
-* GFX Core initialization, dev2, dev3
-*/
-void rs780_gfx_init(device_t nb_dev, device_t dev, u32 port)
-{
- u32 reg32;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- printk(BIOS_DEBUG, "rs780_gfx_init, nb_dev=0x%p, dev=0x%p, port=0x%x.\n",
- nb_dev, dev, port);
-
- /* GFX Core Initialization */
- //if (port == 2) return;
-
- /* step 2, TMDS, (only need if CMOS option is enabled) */
- if (cfg->gfx_tmds) {
- }
-
-#if 1 /* external clock mode */
- /* table 5-22, 5.9.1. REFCLK */
- /* 5.9.1.1. Disables the GFX REFCLK transmitter so that the GFX
- * REFCLK PAD can be driven by an external source. */
- /* 5.9.1.2. Enables GFX REFCLK receiver to receive the REFCLK from an external source. */
- set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28 | 1 << 26, 1 << 28);
-
- /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
- /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
- /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
- set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
- 1 << 6 | 1 << 8 | 1 << 10);
- reg32 = nbmisc_read_index(nb_dev, 0x28);
- printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
-
- /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
- set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 1 << 31);
-#else /* internal clock mode */
- /* table 5-23, 5.9.1. REFCLK */
- /* 5.9.1.1. Enables the GFX REFCLK transmitter so that the GFX
- * REFCLK PAD can be driven by the SB REFCLK. */
- /* 5.9.1.2. Disables GFX REFCLK receiver from receiving the
- * REFCLK from an external source.*/
- set_nbmisc_enable_bits(nb_dev, 0x38, 1 << 29 | 1 << 28, 1 << 29 | 0 << 28);
-
- /* 5.9.1.3 Selects the GFX REFCLK to be the source for PLL A. */
- /* 5.9.1.4 Selects the GFX REFCLK to be the source for PLL B. */
- /* 5.9.1.5 Selects the GFX REFCLK to be the source for PLL C. */
- set_nbmisc_enable_bits(nb_dev, 0x28, 3 << 6 | 3 << 8 | 3 << 10,
- 0);
- reg32 = nbmisc_read_index(nb_dev, 0x28);
- printk(BIOS_DEBUG, "misc 28 = %x\n", reg32);
-
- /* 5.9.1.6.Selects the single ended GFX REFCLK to be the source for core logic. */
- set_nbmisc_enable_bits(nb_dev, 0x6C, 1 << 31, 0 << 31);
-#endif
-
- /* step 5.9.3, GFX overclocking, (only need if CMOS option is enabled) */
- /* 5.9.3.1. Increases PLL BW for 6G operation.*/
- /* set_nbmisc_enable_bits(nb_dev, 0x36, 0x3FF << 4, 0xB5 << 4); */
- /* skip */
-
- /* step 5.9.4, reset the GFX link */
- /* step 5.9.4.1 asserts both calibration reset and global reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
-
- /* step 5.9.4.2 de-asserts calibration reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
-
- /* step 5.9.4.3 wait for at least 200us */
- udelay(300);
-
- /* step 5.9.4.4 de-asserts global reset */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
-
- /* 5.9.5 Reset PCIE_GFX Slot */
- /* It is done in mainboard.c */
- set_pcie_reset();
- mdelay(1);
- set_pcie_dereset();
-
- /* step 5.9.8 program PCIE memory mapped configuration space */
- /* done by enable_pci_bar3() before */
-
- /* step 7 compliance state, (only need if CMOS option is enabled) */
- /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
- if (cfg->gfx_compliance) {
- /* force compliance */
- set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
- /* release hold training for device 2. GFX initialization is done. */
- set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
- dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
- printk(BIOS_DEBUG, "rs780_gfx_init step7.\n");
- return;
- }
-
- /* 5.9.12 Core Initialization. */
- /* 5.9.12.1 sets RCB timeout to be 25ms */
- /* 5.9.12.2. RCB Cpl timeout on link down. */
- set_pcie_enable_bits(dev, 0x70, 7 << 16 | 1 << 19, 4 << 16 | 1 << 19);
- printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.1.\n");
-
- /* step 5.9.12.3 disables slave ordering logic */
- set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
- printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.3.\n");
-
- /* step 5.9.12.4 sets DMA payload size to 64 bytes */
- set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
- /* 5.9.12.5. Blocks DMA traffic during C3 state. */
- set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
-
- /* 5.9.12.6. Disables RC ordering logic */
- set_pcie_enable_bits(nb_dev, 0x20, 1 << 9, 1 << 9);
-
- /* Enabels TLP flushing. */
- /* Note: It is got from RS690. The system will hang without this action. */
- set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
-
- /* 5.9.12.7. Ignores DLLPs during L1 so that txclk can be turned off */
- set_pcie_enable_bits(nb_dev, 0x2, 1 << 0, 1 << 0);
-
- /* 5.9.12.8 Prevents LC to go from L0 to Rcv_L0s if L1 is armed. */
- set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
-
- /* 5.9.12.9 CMGOOD_OVERRIDE for end point initiated lane degradation. */
- set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
- printk(BIOS_DEBUG, "rs780_gfx_init step5.9.12.9.\n");
-
- /* 5.9.12.10 Sets the timer in Config state from 20us to */
- /* 5.9.12.11 De-asserts RX_EN in L0s. */
- /* 5.9.12.12 Enables de-assertion of PG2RX_CR_EN to lock clock
- * recovery parameter when lane is in electrical idle in L0s.*/
- set_pcie_enable_bits(dev, 0xB1, 1 << 23 | 1 << 19 | 1 << 28, 1 << 23 | 1 << 19 | 1 << 28);
-
- /* 5.9.12.13. Turns off offset calibration. */
- /* 5.9.12.14. Enables Rx Clock gating in CDR */
- set_nbmisc_enable_bits(nb_dev, 0x34, 1 << 10/* | 1 << 22 */, 1 << 10/* | 1 << 22 */);
-
- /* 5.9.12.15. Sets number of TX Clocks to drain TX Pipe to 3. */
- set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 3 << 4);
-
- /* 5.9.12.16. Lets PI use Electrical Idle from PHY when
- * turning off PLL in L1 at Gen2 speed instead Inferred Electrical Idle. */
- set_pcie_enable_bits(nb_dev, 0x40, 3 << 14, 2 << 14);
-
- /* 5.9.12.17. Prevents the Electrical Idle from causing a transition from Rcv_L0 to Rcv_L0s. */
- set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20);
-
- /* 5.9.12.18. Prevents the LTSSM from going to Rcv_L0s if it has already
- * acknowledged a request to go to L1. */
- set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
-
- /* 5.9.12.19. LDSK only taking deskew on deskewing error detect */
- set_pcie_enable_bits(nb_dev, 0x40, 1 << 28, 0 << 28);
-
- /* 5.9.12.20. Bypasses lane de-skew logic if in x1 */
- set_pcie_enable_bits(nb_dev, 0xC2, 1 << 14, 1 << 14);
-
- /* 5.9.12.21. Sets Electrical Idle Threshold. */
- set_nbmisc_enable_bits(nb_dev, 0x35, 3 << 21, 2 << 21);
-
- /* 5.9.12.22. Advertises -6 dB de-emphasis value in TS1 Data Rate Identifier
- * Only if CMOS Option in section. skip */
-
- /* 5.9.12.23. Disables GEN2 capability of the device. */
- set_pcie_enable_bits(dev, 0xA4, 1 << 0, 0 << 0);
-
- /* 5.9.12.24.Disables advertising Upconfigure Support. */
- set_pcie_enable_bits(dev, 0xA2, 1 << 13, 1 << 13);
-
- /* 5.9.12.25. No comment in RPR. */
- set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 10, 0 << 10);
-
- /* 5.9.12.26. This capacity is required since links wider than x1 and/or multiple link
- * speed are supported */
- set_pcie_enable_bits(nb_dev, 0xC1, 1 << 0, 1 << 0);
-
- /* 5.9.12.27. Enables NVG86 ECO. A13 above only. */
- if (get_nb_rev(nb_dev) == REV_RS780_A12) /* A12 */
- set_pcie_enable_bits(dev, 0x02, 1 << 11, 1 << 11);
-
- /* 5.9.12.28 Hides and disables the completion timeout method. */
- set_pcie_enable_bits(nb_dev, 0xC1, 1 << 2, 0 << 2);
-
- /* 5.9.12.29. Use the bif_core de-emphasis strength by default. */
- /* set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 28, 1 << 28); */
-
- /* 5.9.12.30. Set TX arbitration algorithm to round robin */
- set_pcie_enable_bits(nb_dev, 0x1C,
- 1 << 0 | 0x1F << 1 | 0x1F << 6,
- 1 << 0 | 0x04 << 1 | 0x04 << 6);
-
- /* Single-port/Dual-port configureation. */
- switch (cfg->gfx_dual_slot) {
- case 0:
- /* step 1, lane reversal (only need if build config option is enabled) */
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
- }
- printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
-
- printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
- if((dev->path.pci.devfn >> 3) == 2) {
- single_port_configuration(nb_dev, dev);
- } else {
- set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
- printk(BIOS_INFO, "Single port. Do nothing.\n"); // If dev3
- }
-
- break;
- case 1:
- /* step 1, lane reversal (only need if build config option is enabled) */
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
- }
- printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
- /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
- /* AMD calls the configuration CrossFire */
- set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
- printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
-
- printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
- dual_port_configuration(nb_dev, dev);
- break;
-
- case 2:
-
- if(is_dev3_present()){
- /* step 1, lane reversal (only need if CMOS option is enabled) */
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
- }
- printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
- /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
- /* AMD calls the configuration CrossFire */
- set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
- printk(BIOS_DEBUG, "rs780_gfx_init step2.\n");
-
-
- printk(BIOS_DEBUG, "device = %x\n", dev->path.pci.devfn >> 3);
- dual_port_configuration(nb_dev, dev);
-
- }else{
- if (cfg->gfx_lane_reversal) {
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 1 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 31, 0 << 31);
- }
- printk(BIOS_DEBUG, "rs780_gfx_init step1.\n");
-
- if((dev->path.pci.devfn >> 3) == 2)
- single_port_configuration(nb_dev, dev);
- else{
- set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x2 << 2); /* hide the GFX bridge. */
- printk(BIOS_DEBUG, "If dev3.., single port. Do nothing.\n");
- }
- }
-
- default:
- printk(BIOS_INFO, "Incorrect configuration of external GFX slot.\n");
- break;
- }
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "rs780.h"
-
-/* for UMA internal graphics */
-void avoid_lpc_dma_deadlock(device_t nb_dev, device_t sb_dev)
-{
- device_t cpu_f0;
- u8 reg;
-
- cpu_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
- set_nbcfg_enable_bits(cpu_f0, 0x68, 3 << 21, 1 << 21);
-
- reg = nbpcie_p_read_index(sb_dev, 0x10);
- reg |= 0x100; /* bit9=1 */
- nbpcie_p_write_index(sb_dev, 0x10, reg);
-
- reg = nbpcie_p_read_index(nb_dev, 0x10);
- reg |= 0x100; /* bit9=1 */
- nbpcie_p_write_index(nb_dev, 0x10, reg);
-
- /* Enable NP protocol over PCIE for memory-mapped writes targeting LPC
- * Set this bit to avoid a deadlock condition. */
- reg = htiu_read_index(nb_dev, 0x6);
- reg |= 0x1000000; /* bit26 */
- htiu_write_index(nb_dev, 0x6, reg);
-}
-
-static void pcie_init(struct device *dev)
-{
- /* Enable pci error detecting */
- u32 dword;
-
- printk(BIOS_INFO, "pcie_init in rs780_ht.c\n");
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* System error enable */
- dword |= (1 << 30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
- /*
- * 1 is APIC enable
- * 18 is enable nb to accept A4 interrupt request from SB.
- */
- dword = pci_read_config32(dev, 0x4C);
- dword |= 1 << 1 | 1 << 18; /* Clear possible errors */
- pci_write_config32(dev, 0x4C, dword);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations ht_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = pcie_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ht_driver __pci_driver = {
- .ops = &ht_ops,
- .vendor = PCI_VENDOR_ID_AMD,
- .device = PCI_DEVICE_ID_AMD_RS780_HT,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <delay.h>
-#include "rs780.h"
-
-/*------------------------------------------------
-* Global variable
-------------------------------------------------*/
-PCIE_CFG AtiPcieCfg = {
- PCIE_ENABLE_STATIC_DEV_REMAP, /* Config */
- 0, /* ResetReleaseDelay */
- 0, /* Gfx0Width */
- 0, /* Gfx1Width */
- 0, /* GfxPayload */
- 0, /* GppPayload */
- 0, /* PortDetect, filled by GppSbInit */
- 0, /* PortHp */
- 0, /* DbgConfig */
- 0, /* DbgConfig2 */
- 0, /* GfxLx */
- 0, /* GppLx */
- 0, /* NBSBLx */
- 0, /* PortSlotInit */
- 0, /* Gfx0Pwr */
- 0, /* Gfx1Pwr */
- 0 /* GppPwr */
-};
-
-static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port);
-static void ValidatePortEn(device_t nb_dev);
-
-static void ValidatePortEn(device_t nb_dev)
-{
-}
-
-/*****************************************************************
-* Compliant with CIM_33's PCIEPowerOffGppPorts
-* Power off unused GPP lines
-*****************************************************************/
-static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port)
-{
- u32 reg;
- u16 state_save;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
- u8 state = cfg->port_enable;
-
- if (!(AtiPcieCfg.Config & PCIE_DISABLE_HIDE_UNUSED_PORTS))
- state &= AtiPcieCfg.PortDetect;
- state = ~state;
- state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7);
- state_save = state << 17;
- state &= !(AtiPcieCfg.PortHp);
- reg = nbmisc_read_index(nb_dev, 0x0c);
- reg |= state;
- nbmisc_write_index(nb_dev, 0x0c, reg);
-
- reg = nbmisc_read_index(nb_dev, 0x08);
- reg |= state_save;
- nbmisc_write_index(nb_dev, 0x08, reg);
-
- if ((AtiPcieCfg.Config & PCIE_OFF_UNUSED_GPP_LANES)
- && !(AtiPcieCfg.
- Config & (PCIE_DISABLE_HIDE_UNUSED_PORTS +
- PCIE_GFX_COMPLIANCE))) {
- }
- /* step 3 Power Down Control for Southbridge */
- reg = nbpcie_p_read_index(dev, 0xa2);
-
- switch ((reg >> 4) & 0x7) { /* get bit 4-6, LC_LINK_WIDTH_RD */
- case 1:
- nbpcie_ind_write_index(nb_dev, 0x65, 0x0e0e);
- break;
- case 2:
- nbpcie_ind_write_index(nb_dev, 0x65, 0x0c0c);
- break;
- default:
- break;
- }
-}
-
-/**********************************************************************
-**********************************************************************/
-static void switching_gppsb_configurations(device_t nb_dev, device_t sb_dev)
-{
- u32 reg;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- /* 5.5.7.1-3 enables GPP reconfiguration */
- reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
- reg |=
- (RECONFIG_GPPSB_EN + RECONFIG_GPPSB_LINK_CONFIG +
- RECONFIG_GPPSB_ATOMIC_RESET);
- nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
-
- /* 5.5.7.4a. De-asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
- reg = nbmisc_read_index(nb_dev, 0x66);
- reg |= 1 << 31;
- nbmisc_write_index(nb_dev, 0x66, reg);
- /* 5.5.7.4b. sets desired GPPSB configurations, bit4-7 */
- reg = nbmisc_read_index(nb_dev, 0x67);
- reg &= 0xFFFFff0f; /* clean */
- reg |= cfg->gppsb_configuration << 4;
- nbmisc_write_index(nb_dev, 0x67, reg);
-
-#if 1
- /* NOTE:
- * In CIMx 4.5.0 and RPR, 4c is done before 5 & 6. But in this way,
- * a x4 device in port B (dev 4) of Configuration B can only be detected
- * as x1, instead of x4. When the port B is being trained, the
- * LC_CURRENT_STATE is 6 and the LC_LINK_WIDTH_RD is 1. We have
- * to set the PCIEIND:0x65 as 0xE0E0 and reset the slot. Then the card
- * seems to work in x1 mode.
- * In the 2nd way below, we do the 5 & 6 before 4c. it conforms the
- * CIMx 4.3.0. It conflicts with RPR. But based on the test result I've
- * made so far, I haven't found any mistake.
- */
- /* 5.5.7.4c. Asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
- reg = nbmisc_read_index(nb_dev, 0x66);
- reg &= ~(1 << 31);
- nbmisc_write_index(nb_dev, 0x66, reg);
-
- /* 5.5.7.5-6. read bit14 and write back its inverst value */
- reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
- reg ^= RECONFIG_GPPSB_GPPSB;
- nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
-#else
- /* 5.5.7.5-6. read bit14 and write back its inverst value */
- reg = nbmisc_read_index(nb_dev, PCIE_NBCFG_REG7);
- reg ^= RECONFIG_GPPSB_GPPSB;
- nbmisc_write_index(nb_dev, PCIE_NBCFG_REG7, reg);
-
- /* 5.5.7.4c. Asserts STRAP_BIF_all_valid for PCIE-GPPSB core */
- reg = nbmisc_read_index(nb_dev, 0x66);
- reg &= ~(1 << 31);
- nbmisc_write_index(nb_dev, 0x66, reg);
-#endif
- /* 5.5.7.7. delay 1ms */
- mdelay(1);
-
- /* 5.5.7.8. waits until SB has trained to L0, poll for bit0-5 = 0x10 */
- do {
- reg = nbpcie_p_read_index(sb_dev, PCIE_LC_STATE0);
- reg &= 0x3f; /* remain LSB [5:0] bits */
- } while (LC_STATE_RECONFIG_GPPSB != reg);
-
- /* 5.5.7.9.ensures that virtual channel negotiation is completed. poll for bit1 = 0 */
- do {
- reg =
- pci_ext_read_config32(nb_dev, sb_dev,
- PCIE_VC0_RESOURCE_STATUS);
- } while (reg & VC_NEGOTIATION_PENDING);
-}
-
-static void switching_gpp_configurations(device_t nb_dev, device_t sb_dev)
-{
- u32 reg;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- /* 5.6.2.1. De-asserts STRAP_BIF_all_valid for PCIE-GPP core */
- reg = nbmisc_read_index(nb_dev, 0x22);
- reg |= 1 << 14;
- nbmisc_write_index(nb_dev, 0x22, reg);
- /* 5.6.2.2. sets desired GPPSB configurations, bit4-7 */
- reg = nbmisc_read_index(nb_dev, 0x2D);
- reg &= ~(0xF << 7); /* clean */
- reg |= cfg->gpp_configuration << 7;
- nbmisc_write_index(nb_dev, 0x2D, reg);
- /* 5.6.2.3. Asserts STRAP_BIF_all_valid for PCIE-GPP core */
- reg = nbmisc_read_index(nb_dev, 0x22);
- reg &= ~(1 << 14);
- nbmisc_write_index(nb_dev, 0x22, reg);
-}
-
-/*****************************************************************
-* The rs780 uses NBCONFIG:0x1c (BAR3) to map the PCIE Extended Configuration
-* Space to a 256MB range within the first 4GB of addressable memory.
-*****************************************************************/
-void enable_pcie_bar3(device_t nb_dev)
-{
- printk(BIOS_DEBUG, "enable_pcie_bar3()\n");
- set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register. */
- set_nbcfg_enable_bits(nb_dev, 0x84, 7 << 16, 0 << 16);
-
- pci_write_config32(nb_dev, 0x1C, EXT_CONF_BASE_ADDRESS); /* PCIEMiscInit */
- pci_write_config32(nb_dev, 0x20, 0x00000000);
- set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */
- ProgK8TempMmioBase(1, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
-}
-
-/*****************************************************************
-* We should disable bar3 when we want to exit rs780_enable, because bar3 will be
-* remapped in set_resource later.
-*****************************************************************/
-void disable_pcie_bar3(device_t nb_dev)
-{
- printk(BIOS_DEBUG, "disable_pcie_bar3()\n");
- pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */
- set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */
- set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 0); /* disable bar3 decode */
- ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
-}
-
-/*****************************************
-* Compliant with CIM_33's PCIEGPPInit
-* nb_dev:
-* root bridge struct
-* dev:
-* p2p bridge struct
-* port:
-* p2p bridge number, 4-10
-*****************************************/
-void rs780_gpp_sb_init(device_t nb_dev, device_t dev, u32 port)
-{
- u32 gfx_gpp_sb_sel;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
- printk(BIOS_DEBUG, "gpp_sb_init nb_dev=0x%x, dev=0x%x, port=0x%x\n", nb_dev->path.pci.devfn, dev->path.pci.devfn, port);
-
- gfx_gpp_sb_sel = port >= 4 && port <= 8 ?
- PCIE_CORE_INDEX_GPPSB : /* 4,5,6,7,8 */
- PCIE_CORE_INDEX_GPP; /* 9,10 */
- /* init GPP core */
- /* 5.10.8.3. Disable slave ordering logic */
- set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 8,
- 1 << 8);
- /* 5.10.8.7. PCIE initialization 5.10.2: rpr 2.12*/
- set_pcie_enable_bits(nb_dev, 0x02 | gfx_gpp_sb_sel, 1 << 0, 1 << 0); /* no description in datasheet. */
-
- /* init GPPSB port. rpr 5.10.8 */
- /* 5.10.8.1-5.10.8.2. Sets RCB timeout to be 100ms/4=25ms by setting bits[18:16] to 3 h4
- * and shortens the enumeration timer by setting bit[19] to 1
- */
- set_pcie_enable_bits(dev, 0x70, 0xF << 16, 0x4 << 16 | 1 << 19);
- /* 5.10.8.4. Sets DMA payload size to 64 bytes. */
- set_pcie_enable_bits(nb_dev, 0x10 | gfx_gpp_sb_sel, 7 << 10, 4 << 10);
- /* 5.10.8.6. Disable RC ordering logic */
- set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 9, 1 << 9);
- /* 5.10.8.7. Ignores DLLs druing L1 */
- set_pcie_enable_bits(nb_dev, 0x02 | gfx_gpp_sb_sel, 1 << 0, 1 << 0);
- /* 5.10.8.8. Prevents LCto go from L0 to Rcv_L0s if L1 is armed. */
- set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
- /* 5.10.8.9. Sets timer in Config state from 20us to 1us.
- * 5.10.8.10. De-asserts RX_EN in L0s
- * 5.10.8.11. Enables de-assertion of PG2RX_CR_EN to lock clock recovery parameter when .. */
- set_pcie_enable_bits(dev, 0xB1, 1 << 23 | 1 << 19 | 1 << 28, 1 <<23 | 1 << 19 | 1 << 28);
- /* 5.10.8.12. Turns off offset calibration */
- /* 5.10.8.13. Enables Rx Clock gating in CDR */
- if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
- set_nbmisc_enable_bits(nb_dev, 0x67, 1 << 14 | 1 << 26, 1 << 14 | 1 << 26); /* 4,5,6,7 */
- else
- set_nbmisc_enable_bits(nb_dev, 0x24, 1 << 29 | 1 << 28, 1 << 29 | 1 << 28); /* 9,10 */
- /* 5.10.8.14. Sets number of TX Clocks to drain TX Pipe to 3 */
- set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 0x3 << 4);
- /* 5.10.8.15. empty */
- /* 5.10.8.16. P_ELEC_IDLE_MODE */
- set_pcie_enable_bits(nb_dev, 0x40 | gfx_gpp_sb_sel, 0x3 << 14, 0x2 << 14);
- /* 5.10.8.17. LC_BLOCK_EL_IDLE_IN_L0 */
- set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20);
- /* 5.10.8.18. LC_DONT_GO_TO_L0S_IFL1_ARMED */
- set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11);
- /* 5.10.8.19. RXP_REALIGN_ON_EACH_TSX_OR_SKP */
- set_pcie_enable_bits(nb_dev, 0x40 | gfx_gpp_sb_sel, 1 << 28, 0 << 28);
- /* 5.10.8.20. Bypass lane de-skew logic if in x1 */
- set_pcie_enable_bits(nb_dev, 0xC2 | gfx_gpp_sb_sel, 1 << 14, 1 << 14);
- /* 5.10.8.21. sets electrical idle threshold. */
- if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
- set_nbmisc_enable_bits(nb_dev, 0x6A, 3 << 22, 2 << 22);
- else
- set_nbmisc_enable_bits(nb_dev, 0x24, 3 << 16, 2 << 16);
-
- /* 5.10.8.22. Disable GEN2 */
- /* TODO: should be 2 seperated cases. */
- set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 31, 0 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x22, 1 << 5, 0 << 5);
- set_nbmisc_enable_bits(nb_dev, 0x34, 1 << 31, 0 << 31);
- set_nbmisc_enable_bits(nb_dev, 0x37, 7 << 5, 0 << 5);
- /* 5.10.8.23. Disables GEN2 capability of the device. RPR says enable? No! */
- set_pcie_enable_bits(dev, 0xA4, 1 << 0, 0 << 0);
- /* 5.10.8.24. Disable advertising upconfigure support. */
- set_pcie_enable_bits(dev, 0xA2, 1 << 13, 1 << 13);
- /* 5.10.8.25-26. STRAP_BIF_DSN_EN */
- if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB)
- set_nbmisc_enable_bits(nb_dev, 0x68, 1 << 19, 0 << 19);
- else
- set_nbmisc_enable_bits(nb_dev, 0x22, 1 << 3, 0 << 3);
- /* 5.10.8.27-28. */
- set_pcie_enable_bits(nb_dev, 0xC1 | gfx_gpp_sb_sel, 1 << 0 | 1 << 2, 1 << 0 | 0 << 2);
- /* 5.10.8.29. Uses the bif_core de-emphasis strength by default. */
- if (gfx_gpp_sb_sel == PCIE_CORE_INDEX_GPPSB) {
- set_nbmisc_enable_bits(nb_dev, 0x67, 1 << 10, 1 << 10);
- set_nbmisc_enable_bits(nb_dev, 0x36, 1 << 29, 1 << 29);
- }
- else {
- set_nbmisc_enable_bits(nb_dev, 0x39, 1 << 30, 1 << 30);
- }
- /* 5.10.8.30. Set TX arbitration algorithm to round robin. */
- set_pcie_enable_bits(nb_dev, 0x1C | gfx_gpp_sb_sel,
- 1 << 0 | 0x1F << 1 | 0x1F << 6,
- 1 << 0 | 0x04 << 1 | 0x04 << 6);
-
- /* check compliance rpr step 2.1*/
- if (AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE) {
- u32 tmp;
- tmp = nbmisc_read_index(nb_dev, 0x67);
- tmp |= 1 << 3;
- nbmisc_write_index(nb_dev, 0x67, tmp);
- }
-
- /* step 5: dynamic slave CPL buffer allocation. Disable it, otherwise linux hangs. Why? */
- /* set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 11, 1 << 11); */
-
- /* step 5a: Training for GPP devices */
- /* init GPP */
- switch (port) {
- case 4: /* GPP */
- case 5:
- case 6:
- case 7:
- case 9:
- case 10:
- /* 5.10.8.5. Blocks DMA traffic during C3 state */
- set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
- /* Enabels TLP flushing */
- set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19);
-
- /* check port enable */
- if (cfg->port_enable & (1 << port)) {
- PcieReleasePortTraining(nb_dev, dev, port);
- if (!(AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE)) {
- u8 res = PcieTrainPort(nb_dev, dev, port);
- printk(BIOS_DEBUG, "PcieTrainPort port=0x%x result=%d\n", port, res);
- if (res) {
- AtiPcieCfg.PortDetect |= 1 << port;
- }
- }
- }
- break;
- case 8: /* SB */
- break;
- }
- PciePowerOffGppPorts(nb_dev, dev, port);
-}
-
-/*****************************************
-* Compliant with CIM_33's PCIEConfigureGPPCore
-*****************************************/
-void config_gpp_core(device_t nb_dev, device_t sb_dev)
-{
- u32 reg;
- struct southbridge_amd_rs780_config *cfg =
- (struct southbridge_amd_rs780_config *)nb_dev->chip_info;
-
- reg = nbmisc_read_index(nb_dev, 0x20);
- if (AtiPcieCfg.Config & PCIE_ENABLE_STATIC_DEV_REMAP)
- reg &= 0xfffffffd; /* set bit1 = 0 */
- else
- reg |= 0x2; /* set bit1 = 1 */
- nbmisc_write_index(nb_dev, 0x20, reg);
-
- reg = nbmisc_read_index(nb_dev, 0x67); /* get STRAP_BIF_LINK_CONFIG_GPPSB at bit 4-7 */
- if (cfg->gppsb_configuration != ((reg >> 4) & 0xf))
- switching_gppsb_configurations(nb_dev, sb_dev);
- reg = nbmisc_read_index(nb_dev, 0x2D); /* get STRAP_BIF_LINK_CONFIG_GPP at bit 7-10 */
- if (cfg->gpp_configuration != ((reg >> 7) & 0xf))
- switching_gpp_configurations(nb_dev, sb_dev);
- ValidatePortEn(nb_dev);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef __RS780_REV_H__
-#define __RS780_REV_H__
-
-#define REV_RS780_A11 0
-#define REV_RS780_A12 1
-#define REV_RS780_A13 2
-
-#endif /* __RS780_REV_H__ */
driver-y += sb600.c
-driver-y += sb600_usb.c
-driver-y += sb600_lpc.c
-driver-y += sb600_sm.c
-driver-y += sb600_ide.c
-driver-y += sb600_sata.c
-driver-y += sb600_hda.c
-driver-y += sb600_ac97.c
-driver-y += sb600_pci.c
-ramstage-y += sb600_reset.c
-romstage-y += sb600_enable_usbdebug.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += sm.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += hda.c
+driver-y += ac97.c
+driver-y += pci.c
+ramstage-y += reset.c
+romstage-y += enable_usbdebug.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sb600.h"
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ac97audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+/* .enable = sb600_enable, */
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_ACI,
+};
+
+static struct device_operations ac97modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+/* .enable = sb600_enable, */
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_MCI,
+};
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "southbridge/amd/sb600/sb600_enable_rom.c"
+#include "southbridge/amd/sb600/enable_rom.c"
static void bootblock_southbridge_init(void)
{
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+#include <arch/cpu.h>
+#include "sb600.h"
+#include "smbus.c"
+
+#define SMBUS_IO_BASE 0x1000 /* Is it a temporary SMBus I/O base address? */
+ /*SIZE 0x40 */
+
+static void pmio_write(u8 reg, u8 value)
+{
+ outb(reg, PM_INDEX);
+ outb(value, PM_INDEX + 1);
+}
+
+static u8 pmio_read(u8 reg)
+{
+ outb(reg, PM_INDEX);
+ return inb(PM_INDEX + 1);
+}
+
+/* RPR 2.1: Get SB ASIC Revision. */
+static u8 get_sb600_revision(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ /* NOT REACHED */
+ }
+ return pci_read_config8(dev, 0x08);
+}
+
+
+/***************************************
+* Legacy devices are mapped to LPC space.
+* Serial port 0
+* KBC Port
+* ACPI Micro-controller port
+* This function does not change port 0x80 decoding.
+* Console output through any port besides 0x3f8 is unsupported.
+* If you use FWH ROMs, you have to setup IDSEL.
+* Reviewed-by: Carl-Daniel Hailfinger
+* Reviewed against AMD SB600 Register Reference Manual rev. 3.03, section 3.1
+* (LPC ISA Bridge)
+***************************************/
+static void sb600_lpc_init(void)
+{
+ u8 reg8;
+ u32 reg32;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); /* SMBUS controller */
+ /* NOTE: Set BootTimerDisable, otherwise it would keep rebooting!!
+ * This bit has no meaning if debug strap is not enabled. So if the
+ * board keeps rebooting and the code fails to reach here, we could
+ * disable the debug strap first. */
+ reg32 = pci_read_config32(dev, 0x4C);
+ reg32 |= 1 << 31;
+ pci_write_config32(dev, 0x4C, reg32);
+
+ /* Enable lpc controller */
+ reg32 = pci_read_config32(dev, 0x64);
+ reg32 |= 1 << 20;
+ pci_write_config32(dev, 0x64, reg32);
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438d), 0); /* LPC Controller */
+ /* Decode port 0x3f8-0x3ff (Serial 0) */
+ // XXX Serial port decode on LPC is hardcoded to 0x3f8
+ reg8 = pci_read_config8(dev, 0x44);
+ reg8 |= 1 << 6;
+ pci_write_config8(dev, 0x44, reg8);
+
+ /* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
+ reg8 = pci_read_config8(dev, 0x47);
+ reg8 |= (1 << 5) | (1 << 6);
+ pci_write_config8(dev, 0x47, reg8);
+
+ /* Super I/O, RTC */
+ reg8 = pci_read_config8(dev, 0x48);
+ /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
+ reg8 |= (1 << 1) | (1 << 0);
+ /* Decode port 0x70-0x73 (RTC) */
+ reg8 |= (1 << 6);
+ pci_write_config8(dev, 0x48, reg8);
+}
+
+/* what is its usage? */
+static u32 get_sbdn(u32 bus)
+{
+ device_t dev;
+
+ /* Find the device. */
+ dev = pci_locate_device_on_bus(PCI_ID(0x1002, 0x4385), bus);
+ return (dev >> 15) & 0x1f;
+}
+
+static u8 dual_core(void)
+{
+ return (pci_read_config32(PCI_DEV(0, 0x18, 3), 0xE8) & (0x3<<12)) != 0;
+}
+
+/*
+ * SB600 VFSMAF (VID/FID System Management Action Field) is 010b by default.
+ * RPR 2.3.3 C-state and VID/FID change for the K8 platform.
+*/
+static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
+{
+ u8 byte;
+ byte = pmio_read(0x9a);
+ byte &= ~0x34;
+ if (dual_core())
+ byte |= 0x34;
+ else
+ byte |= 0x04;
+ pmio_write(0x9a, byte);
+
+ byte = pmio_read(0x8f);
+ byte &= ~0x30;
+ byte |= 0x20;
+ pmio_write(0x8f, byte);
+
+ pmio_write(0x8b, 0x01);
+ pmio_write(0x8a, 0x90);
+
+ if(get_sb600_revision() > 0x13)
+ pmio_write(0x88, 0x10);
+ else
+ pmio_write(0x88, 0x06);
+
+ byte = pmio_read(0x7c);
+ byte &= ~0x01;
+ byte |= 0x01;
+ pmio_write(0x7c, byte);
+
+ /* Must be 0 for K8 platform. */
+ byte = pmio_read(0x68);
+ byte &= ~0x01;
+ pmio_write(0x68, byte);
+ /* Must be 0 for K8 platform. */
+ byte = pmio_read(0x8d);
+ byte &= ~(1<<6);
+ pmio_write(0x8d, byte);
+
+ byte = pmio_read(0x61);
+ byte &= ~0x04;
+ pmio_write(0x61, byte);
+
+ byte = pmio_read(0x42);
+ byte &= ~0x04;
+ pmio_write(0x42, byte);
+
+ if (get_sb600_revision() == 0x14) {
+ pmio_write(0x89, 0x10);
+
+ byte = pmio_read(0x52);
+ byte |= 0x80;
+ pmio_write(0x52, byte);
+ }
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+ /* link reset */
+ outb(0x06, 0x0cf9);
+}
+
+void sb600_pci_port80(void)
+{
+ u8 byte;
+ device_t dev;
+
+ /* P2P Bridge */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
+
+ /* Chip Control: Enable subtractive decoding */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 5;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 7;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* The same IO Base and IO Limit here is meaningful because we set the
+ * bridge to be subtractive. During early setup stage, we have to make
+ * sure that data can go through port 0x80.
+ */
+ /* IO Base: 0xf000 */
+ byte = pci_read_config8(dev, 0x1C);
+ byte |= 0xF << 4;
+ pci_write_config8(dev, 0x1C, byte);
+
+ /* IO Limit: 0xf000 */
+ byte = pci_read_config8(dev, 0x1D);
+ byte |= 0xF << 4;
+ pci_write_config8(dev, 0x1D, byte);
+
+ /* PCI Command: Enable IO response */
+ byte = pci_read_config8(dev, 0x04);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x04, byte);
+
+ /* LPC controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
+
+ byte = pci_read_config8(dev, 0x4A);
+ byte &= ~(1 << 5); /* disable lpc port 80 */
+ pci_write_config8(dev, 0x4A, byte);
+}
+
+void sb600_lpc_port80(void)
+{
+ u8 byte;
+ device_t dev;
+ u32 reg32;
+
+ /* Enable LPC controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+ reg32 = pci_read_config32(dev, 0x64);
+ reg32 |= 0x00100000; /* lpcEnable */
+ pci_write_config32(dev, 0x64, reg32);
+
+ /* Enable port 80 LPC decode in pci function 3 configuration space. */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438d), 0);
+ byte = pci_read_config8(dev, 0x4a);
+ byte |= 1 << 5; /* enable port 80 */
+ pci_write_config8(dev, 0x4a, byte);
+}
+
+/* sbDevicesPorInitTable */
+static void sb600_devices_por_init(void)
+{
+ device_t dev;
+ u8 byte;
+
+ printk(BIOS_INFO, "sb600_devices_por_init()\n");
+ /* SMBus Device, BDF:0-20-0 */
+ printk(BIOS_INFO, "sb600_devices_por_init(): SMBus Device, BDF:0-20-0\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ /* NOT REACHED */
+ }
+ printk(BIOS_INFO, "SMBus controller enabled, sb revision is 0x%x\n",
+ get_sb600_revision());
+
+ /* sbPorAtStartOfTblCfg */
+ /* Set A-Link bridge access address. This address is set at device 14h, function 0, register 0xf0.
+ * This is an I/O address. The I/O address must be on 16-byte boundry. */
+ pci_write_config32(dev, 0xf0, AB_INDX);
+
+ /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */
+ /*Enables the SB600 to send transactions upstream over A-Link Express interface. */
+ axcfg_reg(0x04, 1 << 2, 1 << 2);
+ axindxc_reg(0x21, 0xff, 0);
+
+ /* 2.3.5:Enabling Non-Posted Memory Write for the K8 Platform */
+ axindxc_reg(0x10, 1 << 9, 1 << 9);
+ /* END of sbPorAtStartOfTblCfg */
+
+ /* sbDevicesPorInitTables */
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x10, SMBUS_IO_BASE | 1);
+
+ /* enable smbus controller interface */
+ byte = pci_read_config8(dev, 0xd2);
+ byte |= (1 << 0);
+ pci_write_config8(dev, 0xd2, byte);
+
+ /* set smbus 1, ASF 2.0 (Alert Standard Format), iobase */
+ pci_write_config16(dev, 0x58, SMBUS_IO_BASE | 0x11);
+
+ /* TODO: I don't know the useage of followed two lines. I copied them from CIM. */
+ pci_write_config8(dev, 0x0a, 0x1);
+ pci_write_config8(dev, 0x0b, 0x6);
+
+ /* KB2RstEnable */
+ pci_write_config8(dev, 0x40, 0xd4);
+
+ /* Enable ISA Address 0-960K decoding */
+ pci_write_config8(dev, 0x48, 0x0f);
+
+ /* Enable ISA Address 0xC0000-0xDFFFF decode */
+ pci_write_config8(dev, 0x49, 0xff);
+
+ /* Enable decode cycles to IO C50, C51, C52 GPM controls. */
+ byte = pci_read_config8(dev, 0x41);
+ byte &= 0x80;
+ byte |= 0x33;
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Legacy DMA Prefetch Enhancement, CIM masked it. */
+ /* pci_write_config8(dev, 0x43, 0x1); */
+
+ /* Disabling Legacy USB Fast SMI# */
+ byte = pci_read_config8(dev, 0x62);
+ byte |= 0x24;
+ pci_write_config8(dev, 0x62, byte);
+
+ /* Features Enable */
+ pci_write_config32(dev, 0x64, 0x829E7DBF); /* bit10: Enables the HPET interrupt. */
+
+ /* SerialIrq Control */
+ pci_write_config8(dev, 0x69, 0x90);
+
+ /* Test Mode, PCIB_SReset_En Mask is set. */
+ pci_write_config8(dev, 0x6c, 0x20);
+
+ /* IO Address Enable, CIM set 0x78 only and masked 0x79. */
+ /*pci_write_config8(dev, 0x79, 0x4F); */
+ pci_write_config8(dev, 0x78, 0xFF);
+
+ /* This register is not used on sb600. It came from older chipset. */
+ /*pci_write_config8(dev, 0x95, 0xFF); */
+
+ /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */
+ pci_write_config16(dev, 0x4, 0x0407);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* IDE Device, BDF:0-20-1 */
+ printk(BIOS_INFO, "sb600_devices_por_init(): IDE Device, BDF:0-20-1\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438C), 0);
+ /* Disable prefetch */
+ byte = pci_read_config8(dev, 0x63);
+ byte |= 0x1;
+ pci_write_config8(dev, 0x63, byte);
+
+ /* LPC Device, BDF:0-20-3 */
+ printk(BIOS_INFO, "sb600_devices_por_init(): LPC Device, BDF:0-20-3\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
+ /* DMA enable */
+ pci_write_config8(dev, 0x40, 0x04);
+
+ /* IO Port Decode Enable */
+ pci_write_config8(dev, 0x44, 0xFF);
+ pci_write_config8(dev, 0x45, 0xFF);
+ pci_write_config8(dev, 0x46, 0xC3);
+ pci_write_config8(dev, 0x47, 0xFF);
+
+ // TODO: This has already been done(?)
+ /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
+ * Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
+ * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65). */
+ byte = pci_read_config8(dev, 0x48);
+ byte |= (1 << 1) | (1 << 0); /* enable Super IO config port 2e-2h, 4e-4f */
+ byte |= 1 << 6; /* enable for RTC I/O range */
+ pci_write_config8(dev, 0x48, byte);
+ pci_write_config8(dev, 0x49, 0xFF);
+ /* Enable 0x480-0x4bf, 0x4700-0x470B */
+ byte = pci_read_config8(dev, 0x4A);
+ byte |= ((1 << 1) + (1 << 6)); /*0x42, save the configuraion for port 0x80. */
+ pci_write_config8(dev, 0x4A, byte);
+
+ /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
+ pci_write_config8(dev, 0x7C, 0x05);
+
+ /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
+ * TODO: I don't know what are their mean? */
+ printk(BIOS_INFO, "sb600_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
+ /* I don't know why CIM tried to write into a read-only reg! */
+ /*pci_write_config8(dev, 0x0c, 0x20) */ ;
+
+ /* Arbiter enable. */
+ pci_write_config8(dev, 0x43, 0xff);
+
+ /* Set PCDMA request into hight priority list. */
+ /* pci_write_config8(dev, 0x49, 0x1) */ ;
+
+ pci_write_config8(dev, 0x40, 0x26);
+
+ /* I don't know why CIM set reg0x1c as 0x11.
+ * System will block at sdram_initialize() if I set it before call sdram_initialize().
+ * If it is necessary to set reg0x1c as 0x11, please call this function after sdram_initialize().
+ * pci_write_config8(dev, 0x1c, 0x11);
+ * pci_write_config8(dev, 0x1d, 0x11);*/
+
+ /*CIM set this register; but I didn't find its description in RPR.
+ On DBM690T platform, I didn't find different between set and skip this register.
+ But on Filbert platform, the DEBUG message from serial port on Peanut board can't be displayed
+ after the bit0 of this register is set.
+ pci_write_config8(dev, 0x04, 0x21);
+ */
+ pci_write_config8(dev, 0x0d, 0x40);
+ pci_write_config8(dev, 0x1b, 0x40);
+ /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
+ pci_write_config8(dev, 0x50, 0x01);
+
+ /* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
+ printk(BIOS_INFO, "sb600_devices_por_init(): SATA Device, BDF:0-18-0\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
+
+ /*PHY Global Control, we are using A14.
+ * default: 0x2c40 for ASIC revision A12 and below
+ * 0x2c00 for ASIC revision A13 and above.*/
+ pci_write_config16(dev, 0x86, 0x2C00);
+
+ /* PHY Port0-3 Control */
+ pci_write_config32(dev, 0x88, 0xB400DA);
+ pci_write_config32(dev, 0x8c, 0xB400DA);
+ pci_write_config32(dev, 0x90, 0xB400DA);
+ pci_write_config32(dev, 0x94, 0xB400DA);
+
+ /* Port0-3 BIST Control/Status */
+ pci_write_config8(dev, 0xa5, 0xB8);
+ pci_write_config8(dev, 0xad, 0xB8);
+ pci_write_config8(dev, 0xb5, 0xB8);
+ pci_write_config8(dev, 0xbd, 0xB8);
+}
+
+/* sbPmioPorInitTable, Pre-initializing PMIO register space
+* The power management (PM) block is resident in the PCI/LPC/ISA bridge.
+* The PM regs are accessed via IO mapped regs 0xcd6 and 0xcd7.
+* The index address is first programmed into IO reg 0xcd6.
+* Read or write values are accessed through IO reg 0xcd7.
+*/
+static void sb600_pmio_por_init(void)
+{
+ u8 byte;
+
+ printk(BIOS_INFO, "sb600_pmio_por_init()\n");
+ /* K8KbRstEn, KB_RST# control for K8 system. */
+ byte = pmio_read(0x66);
+ byte |= 0x20;
+ pmio_write(0x66, byte);
+
+ /* RPR2.3.4 S3/S4/S5 Function for the K8 Platform. */
+ byte = pmio_read(0x52);
+ byte &= 0xc0;
+ byte |= 0x08;
+ pmio_write(0x52, byte);
+
+ /* C state enable and SLP enable in C states. */
+ byte = pmio_read(0x67);
+ byte |= 0x6;
+ pmio_write(0x67, byte);
+
+ /* CIM sets 0x0e, but bit2 is for P4 system. */
+ byte = pmio_read(0x68);
+ byte &= 0xf0;
+ byte |= 0x0c;
+ pmio_write(0x68, byte);
+
+ /* Watch Dog Timer Control
+ * Set watchdog time base to 0xfec000f0 to avoid SCSI card boot failure.
+ * But I don't find WDT is enabled in SMBUS 0x41 bit3 in CIM.
+ */
+ pmio_write(0x6c, 0xf0);
+ pmio_write(0x6d, 0x00);
+ pmio_write(0x6e, 0xc0);
+ pmio_write(0x6f, 0xfe);
+
+ /* rpr2.14: Enables HPET periodical mode */
+ byte = pmio_read(0x9a);
+ byte |= 1 << 7;
+ pmio_write(0x9a, byte);
+ byte = pmio_read(0x9f);
+ byte |= 1 << 5;
+ pmio_write(0x9f, byte);
+ byte = pmio_read(0x9e);
+ byte |= (1 << 6) | (1 << 7);
+ pmio_write(0x9e, byte);
+
+ /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
+ /* We have to clear this bit here, otherwise the kernel hangs. */
+ byte = pmio_read(0x55);
+ byte |= 1 << 7;
+ byte |= 1 << 1;
+ pmio_write(0x55, byte);
+
+ /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */
+ byte = pmio_read(0x52);
+ byte |= 1 << 6;
+ pmio_write(0x52, byte);
+
+ /* rpr2.22: PLL Reset */
+ byte = pmio_read(0x86);
+ byte |= 1 << 7;
+ pmio_write(0x86, byte);
+
+ /* rpr2.3.3 */
+ /* This provides 16us delay before the assertion of LDTSTP# when C3 is entered.
+ * The delay will allow USB DMA to go on in a continuous manner
+ */
+ pmio_write(0x89, 0x10);
+ /* Set this bit to allow pop-up request being latched during the minimum LDTSTP# assertion time */
+ byte = pmio_read(0x52);
+ byte |= 1 << 7;
+ pmio_write(0x52, byte);
+
+ /* rpr2.15: ASF Remote Control Action */
+ byte = pmio_read(0x9f);
+ byte |= 1 << 6;
+ pmio_write(0x9f, byte);
+
+ /* rpr2.19: Enabling Spread Spectrum */
+ byte = pmio_read(0x42);
+ byte |= 1 << 7;
+ pmio_write(0x42, byte);
+}
+
+/*
+* Compliant with CIM_48's sbPciCfg.
+* Add any south bridge setting.
+*/
+static void sb600_pci_cfg(void)
+{
+ device_t dev;
+ u8 byte;
+
+ /* SMBus Device, BDF:0-20-0 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+ /* Eable the hidden revision ID, available after A13. */
+ byte = pci_read_config8(dev, 0x70);
+ byte |= (1 << 8);
+ pci_write_config8(dev, 0x70, byte);
+ /* rpr2.20 Disable Timer IRQ Enhancement for proper operation of the 8254 timer, 0xae[5]. */
+ byte = pci_read_config8(dev, 0xae);
+ byte |= (1 << 5);
+ pci_write_config8(dev, 0xae, byte);
+
+ /* Enable watchdog decode timer */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1 << 3);
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
+ * generated PCIRST#. */
+ byte = pmio_read(0x65);
+ byte |= (1 << 4);
+ pmio_write(0x65, byte);
+ /*For A13 and above. */
+ if (get_sb600_revision() > 0x12) {
+ /* rpr2.16 C-State Reset, PMIO 0x9f[7]. */
+ byte = pmio_read(0x9f);
+ byte |= (1 << 7);
+ pmio_write(0x9f, byte);
+ /* rpr2.17 PCI Clock Period will increase to 30.8ns. 0x53[7]. */
+ byte = pmio_read(0x53);
+ byte |= (1 << 7);
+ pmio_write(0x53, byte);
+ }
+
+ /* IDE Device, BDF:0-20-1 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438C), 0);
+ /* Enable IDE Explicit prefetch, 0x63[0] clear */
+ byte = pci_read_config8(dev, 0x63);
+ byte &= 0xfe;
+ pci_write_config8(dev, 0x63, byte);
+
+ /* LPC Device, BDF:0-20-3 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
+ /* rpr7.2 Enabling LPC DMA function. */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+ /* rpr7.3 Disabling LPC TimeOut. 0x48[7] clear. */
+ byte = pci_read_config8(dev, 0x48);
+ byte &= 0x7f;
+ pci_write_config8(dev, 0x48, byte);
+ /* rpr7.5 Disabling LPC MSI Capability, 0x78[1] clear. */
+ byte = pci_read_config8(dev, 0x78);
+ byte &= 0xfd;
+ pci_write_config8(dev, 0x78, byte);
+
+ /* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
+ /* rpr6.8 Disabling SATA MSI Capability, for A13 and above, 0x42[7]. */
+ if (0x12 < get_sb600_revision()) {
+ u32 reg32;
+ reg32 = pci_read_config32(dev, 0x40);
+ reg32 |= (1 << 23);
+ pci_write_config32(dev, 0x40, reg32);
+ }
+
+ /* EHCI Device, BDF:0-19-5, ehci usb controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4386), 0);
+ /* rpr5.10 Disabling USB EHCI MSI Capability. 0x50[6]. */
+ byte = pci_read_config8(dev, 0x50);
+ byte |= (1 << 6);
+ pci_write_config8(dev, 0x50, byte);
+
+ /* OHCI0 Device, BDF:0-19-0, ohci usb controller #0 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4387), 0);
+ /* rpr5.11 Disabling USB OHCI MSI Capability. 0x40[12:8]=0x1f. */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= 0x1f;
+ pci_write_config8(dev, 0x41, byte);
+
+}
+
+/*
+* Compliant with CIM_48's ATSBPowerOnResetInitJSP
+*/
+static void sb600_por_init(void)
+{
+ /* sbDevicesPorInitTable + sbK8PorInitTable */
+ sb600_devices_por_init();
+
+ /* sbPmioPorInitTable + sbK8PmioPorInitTable */
+ sb600_pmio_por_init();
+}
+
+/*
+* Compliant with CIM_48's AtiSbBeforePciInit
+* It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
+*/
+static void sb600_before_pci_init(void)
+{
+ sb600_pci_cfg();
+}
+
+/*
+* This function should be called after enable_sb600_smbus().
+*/
+static void sb600_early_setup(void)
+{
+ printk(BIOS_INFO, "sb600_early_setup()\n");
+ sb600_por_init();
+}
+
+static int smbus_read_byte(u32 device, u32 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+
+/*
+ * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
+ *
+ * Hardware should enable LPC ROM by pin straps. This function does not
+ * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
+ *
+ * The SB600 power-on default is to map 256K ROM space.
+ *
+ * Details: AMD SB600 BIOS Developer's Guide (BDG), page 15.
+ */
+static void sb600_enable_rom(void)
+{
+ u8 reg8;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_ATI,
+ PCI_DEVICE_ID_ATI_SB600_LPC), 0);
+
+ /* Decode variable LPC ROM address ranges 1 and 2. */
+ reg8 = pci_read_config8(dev, 0x48);
+ reg8 |= (1 << 3) | (1 << 4);
+ pci_write_config8(dev, 0x48, reg8);
+
+ /* LPC ROM address range 1: */
+ /* Enable LPC ROM range mirroring start at 0x000e(0000). */
+ pci_write_config16(dev, 0x68, 0x000e);
+ /* Enable LPC ROM range mirroring end at 0x000f(ffff). */
+ pci_write_config16(dev, 0x6a, 0x000f);
+
+ /* LPC ROM address range 2: */
+ /*
+ * Enable LPC ROM range start at:
+ * 0xfff8(0000): 512KB
+ * 0xfff0(0000): 1MB
+ * 0xffe0(0000): 2MB
+ * 0xffc0(0000): 4MB
+ */
+ pci_write_config16(dev, 0x6c, 0xffc0); /* 4 MB */
+ /* Enable LPC ROM range end at 0xffff(ffff). */
+ pci_write_config16(dev, 0x6e, 0xffff);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "sb600.h"
+
+/* Required for successful build, but currently empty. */
+void set_debug_port(unsigned int port)
+{
+ /* TODO: Allow changing the physical USB port used as Debug Port. */
+}
+
+void sb600_enable_usbdebug(unsigned int port)
+{
+ device_t dev = PCI_DEV(0, 0x13, 5); /* USB EHCI, D19:F5 */
+
+ /* Select the requested physical USB port (1-15) as the Debug Port. */
+ set_debug_port(port);
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "sb600.h"
+
+#define HDA_ICII_REG 0x68
+#define HDA_ICII_BUSY (1 << 0)
+#define HDA_ICII_VALID (1 << 1)
+
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 dword;
+ int count;
+
+ /* Write (val & ~mask) to port */
+ val &= mask;
+ dword = read32(port);
+ dword &= ~mask;
+ dword |= val;
+ write32(port, dword);
+
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
+ count = 50;
+ do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
+ dword = read32(port);
+ dword &= mask;
+ } while ((dword != val) && --count);
+
+ /* Timeout occurred */
+ if (!count)
+ return -1;
+ return 0;
+}
+
+static u32 codec_detect(u32 base)
+{
+ u32 dword;
+
+ /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 0) == -1)
+ goto no_codec;
+
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 1) == -1)
+ goto no_codec;
+
+ /* Delay for 1 ms since the BKDG does */
+ mdelay(1);
+
+ /* Read in Codec location (BAR + 0xe)[3..0]*/
+ dword = read32(base + 0xe);
+ dword &= 0x0F;
+ if (!dword)
+ goto no_codec;
+
+ return dword;
+
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + 0x08, 1, 0);
+ printk(BIOS_DEBUG, "No codec!\n");
+ return 0;
+}
+
+static u32 cim_verb_data[] = {
+ 0x01471c10,
+ 0x01471d40,
+ 0x01471e01,
+ 0x01471f01,
+/* 1 */
+ 0x01571c12,
+ 0x01571d10,
+ 0x01571e01,
+ 0x01571f01,
+/* 2 */
+ 0x01671c11,
+ 0x01671d60,
+ 0x01671e01,
+ 0x01671f01,
+/* 3 */
+ 0x01771c14,
+ 0x01771d20,
+ 0x01771e01,
+ 0x01771f01,
+/* 4 */
+ 0x01871c30,
+ 0x01871d90,
+ 0x01871ea1,
+ 0x01871f01,
+/* 5 */
+ 0x01971cf0,
+ 0x01971d11,
+ 0x01971e11,
+ 0x01971f41,
+/* 6 */
+ 0x01a71c80,
+ 0x01a71d30,
+ 0x01a71e81,
+ 0x01a71f01,
+/* 7 */
+ 0x01b71cf0,
+ 0x01b71d11,
+ 0x01b71e11,
+ 0x01b71f41,
+/* 8 */
+ 0x01c71cf0,
+ 0x01c71d11,
+ 0x01c71e11,
+ 0x01c71f41,
+/* 9 */
+ 0x01d71cf0,
+ 0x01d71d11,
+ 0x01d71e11,
+ 0x01d71f41,
+/* 10 */
+ 0x01e71c50,
+ 0x01e71d11,
+ 0x01e71e44,
+ 0x01e71f01,
+/* 11 */
+ 0x01f71c60,
+ 0x01f71d61,
+ 0x01f71ec4,
+ 0x01f71f01,
+};
+
+static u32 find_verb(u32 viddid, u32 ** verb)
+{
+ device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
+ struct southbridge_amd_sb600_config *cfg =
+ (struct southbridge_amd_sb600_config *)azalia_dev->chip_info;
+ printk(BIOS_DEBUG, "Dev=%s\n", dev_path(azalia_dev));
+ printk(BIOS_DEBUG, "Default viddid=%x\n", cfg->hda_viddid);
+ printk(BIOS_DEBUG, "Reading viddid=%x\n", viddid);
+ if (!cfg)
+ return 0;
+ if (viddid != cfg->hda_viddid)
+ return 0;
+ *verb = (u32 *) cim_verb_data;
+ return sizeof(cim_verb_data) / sizeof(u32);
+}
+
+/**
+ * Wait 50usec for the codec to indicate it is ready
+ * no response would imply that the codec is non-operative
+ */
+static int wait_for_ready(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+
+ while(timeout--) {
+ u32 dword=read32(base + HDA_ICII_REG);
+ if (!(dword & HDA_ICII_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Wait 50usec for the codec to indicate that it accepted
+ * the previous command. No response would imply that the code
+ * is non-operative
+ */
+static int wait_for_valid(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+ while(timeout--) {
+ u32 dword = read32(base + HDA_ICII_REG);
+ if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
+ HDA_ICII_VALID)
+ return 0;
+ udelay(1);
+ }
+
+ return 1;
+}
+
+static void codec_init(u32 base, int addr)
+{
+ u32 dword;
+ u32 *verb;
+ u32 verb_size;
+ int i;
+
+ /* 1 */
+ if (wait_for_ready(base) == -1)
+ return;
+
+ dword = (addr << 28) | 0x000f0000;
+ write32(base + 0x60, dword);
+
+ if (wait_for_valid(base) == -1)
+ return;
+
+ dword = read32(base + 0x64);
+
+ /* 2 */
+ printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
+ verb_size = find_verb(dword, &verb);
+
+ if (!verb_size) {
+ printk(BIOS_DEBUG, "No verb!\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
+ /* 3 */
+ for (i = 0; i < verb_size; i++) {
+ if (wait_for_ready(base) == -1)
+ return;
+
+ write32(base + 0x60, verb[i]);
+
+ if (wait_for_valid(base) == -1)
+ return;
+ }
+ printk(BIOS_DEBUG, "verb loaded!\n");
+}
+
+static void codecs_init(u32 base, u32 codec_mask)
+{
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (codec_mask & (1 << i))
+ codec_init(base, i);
+ }
+}
+
+static void hda_init(struct device *dev)
+{
+ u8 byte;
+ u32 dword;
+ u32 base;
+ struct resource *res;
+ u32 codec_mask;
+ device_t sm_dev;
+
+ /* Enable azalia - PM_io 0x59[4], disable ac97 - PM_io 0x59[1..0] */
+ pm_iowrite(0x59, 0xB);
+
+ /* Find the SMBus */
+ /* FIXME: Need to find out why the call below crashes. */
+ /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB600_SM, 0);*/
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+
+ /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
+ pci_write_config32(sm_dev, 0xf8, 0x00);
+ pci_write_config8(sm_dev, 0xfc, 0xAA);
+ /* Set INTA - SMBus 0x63 [2..0] */
+ byte = pci_read_config8(sm_dev, 0x63);
+ byte &= ~0x7;
+ byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
+ pci_write_config8(sm_dev, 0x63, byte);
+
+ /* Program the 2C to 0x437b1002 */
+ dword = 0x437b1002;
+ pci_write_config32(dev, 0x2c, dword);
+
+ /* Read in BAR */
+ /* Is this right? HDA allows for a 64-bit BAR
+ * but this is only setup for a 32-bit one
+ */
+ res = find_resource(dev, 0x10);
+ if (!res)
+ return;
+
+ base = (u32)res->base;
+ printk(BIOS_DEBUG, "base = 0x%x\n", base);
+ codec_mask = codec_detect(base);
+
+ if (codec_mask) {
+ printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
+ codecs_init(base, codec_mask);
+ }
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations hda_audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ /*.enable = sb600_enable, */
+ .init = hda_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver hdaaudio_driver __pci_driver = {
+ .ops = &hda_audio_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_HDA,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sb600.h"
+
+static void ide_init(struct device *dev)
+{
+ /* Enable ide devices so the linux ide driver will work */
+ u32 dword;
+ u8 byte;
+
+ /* RPR10.1 disable MSI */
+ dword = pci_read_config32(dev, 0x70);
+ dword &= ~(1 << 16);
+ pci_write_config32(dev, 0x70, dword);
+
+ /* Enable UDMA on all devices, it will become UDMA0 (default PIO is PIO0) */
+ byte = pci_read_config8(dev, 0x54);
+ byte |= 0xf;
+ pci_write_config8(dev, 0x54, byte);
+
+ /* Enable I/O Access&& Bus Master */
+ dword = pci_read_config16(dev, 0x4);
+ dword |= 1 << 2;
+ pci_write_config16(dev, 0x4, dword);
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ /* .enable = sb600_enable, */
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "sb600.h"
+
+static void lpc_init(device_t dev)
+{
+ u8 byte;
+ u32 dword;
+ device_t sm_dev;
+
+ /* Enable the LPC Controller */
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ dword = pci_read_config32(sm_dev, 0x64);
+ dword |= 1 << 20;
+ pci_write_config32(sm_dev, 0x64, dword);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ /* RPR 7.2 Enable DMA transaction on the LPC bus */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR 7.3 Disable the timeout mechanism on LPC */
+ byte = pci_read_config8(dev, 0x48);
+ byte &= ~(1 << 7);
+ pci_write_config8(dev, 0x48, byte);
+
+ /* RPR 7.5 Disable LPC MSI Capability */
+ byte = pci_read_config8(dev, 0x78);
+ byte &= ~(1 << 1);
+ pci_write_config8(dev, 0x78, byte);
+
+}
+
+static void sb600_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
+
+ pci_get_resource(dev, 0xA0); /* SPI ROM base address */
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ compact_resources(dev);
+}
+
+/**
+ * @brief Enable resources for children devices
+ *
+ * @param dev the device whos children's resources are to be enabled
+ *
+ */
+static void sb600_lpc_enable_childrens_resources(device_t dev)
+{
+ struct bus *link;
+ u32 reg, reg_x;
+ int var_num = 0;
+ u16 reg_var[3];
+
+ reg = pci_read_config32(dev, 0x44);
+ reg_x = pci_read_config32(dev, 0x48);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child;
+ child = child->sibling) {
+ if (child->enabled
+ && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for (res = child->resource_list; res; res = res->next) {
+ u32 base, end; /* don't need long long */
+ if (!(res->flags & IORESOURCE_IO))
+ continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "sb600 lpc decode:%s, base=0x%08x, end=0x%08x\n",
+ dev_path(child), base, end);
+ switch (base) {
+ case 0x60: /* KB */
+ case 0x64: /* MS */
+ reg |= (1 << 29);
+ break;
+ case 0x3f8: /* COM1 */
+ reg |= (1 << 6);
+ break;
+ case 0x2f8: /* COM2 */
+ reg |= (1 << 7);
+ break;
+ case 0x378: /* Parallal 1 */
+ reg |= (1 << 0);
+ break;
+ case 0x3f0: /* FD0 */
+ reg |= (1 << 26);
+ break;
+ case 0x220: /* Aduio 0 */
+ reg |= (1 << 8);
+ break;
+ case 0x300: /* Midi 0 */
+ reg |= (1 << 18);
+ break;
+ case 0x400:
+ reg_x |= (1 << 16);
+ break;
+ case 0x480:
+ reg_x |= (1 << 17);
+ break;
+ case 0x500:
+ reg_x |= (1 << 18);
+ break;
+ case 0x580:
+ reg_x |= (1 << 19);
+ break;
+ case 0x4700:
+ reg_x |= (1 << 22);
+ break;
+ case 0xfd60:
+ reg_x |= (1 << 23);
+ break;
+ default:
+ if (var_num >= 3)
+ continue; /* only 3 var ; compact them ? */
+ switch (var_num) {
+ case 0:
+ reg_x |= (1 << 2);
+ break;
+ case 1:
+ reg_x |= (1 << 24);
+ break;
+ case 2:
+ reg_x |= (1 << 25);
+ break;
+ }
+ reg_var[var_num++] =
+ base & 0xffff;
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0x44, reg);
+ pci_write_config32(dev, 0x48, reg_x);
+ /* Set WideIO for as many IOs found (fall through is on purpose) */
+ switch (var_num) {
+ case 2:
+ pci_write_config16(dev, 0x90, reg_var[2]);
+ case 1:
+ pci_write_config16(dev, 0x66, reg_var[1]);
+ case 0:
+ pci_write_config16(dev, 0x64, reg_var[0]);
+ break;
+ }
+}
+
+static void sb600_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ sb600_lpc_enable_childrens_resources(dev);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = sb600_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = sb600_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ /* .enable = sb600_enable, */
+ .ops_pci = &lops_pci,
+};
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sb600.h"
+
+static void pci_init(struct device *dev)
+{
+ u32 dword;
+ u16 word;
+ u8 byte;
+
+ /* RPR 4.1 Enables the PCI-bridge subtractive decode */
+ /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 7;
+ pci_write_config8(dev, 0x4B, byte);
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 5;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR4.2 PCI-bridge upstream dual address window */
+ /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */
+ byte = pci_read_config8(dev, 0x50);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x50, byte);
+
+ /* RPR 4.3 PCI bus 64-byte DMA read access */
+ /* Enhance the PCI bus DMA performance */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 4;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 4.4 Enables the PCIB writes to be cacheline aligned. */
+ /* The size of the writes will be set in the Cacheline Register */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 1;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR 4.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */
+ pci_write_config8(dev, 0x0D, 0x40);
+ pci_write_config8(dev, 0x1B, 0x40);
+
+ /* RPR 4.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 6;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 4.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 4.8 Adjusts the GNT# de-assertion time */
+ word = pci_read_config16(dev, 0x64);
+ word |= 1 << 12;
+ pci_write_config16(dev, 0x64, word);
+
+ /* RPR 4.9 Fast Back to Back transactions support */
+ byte = pci_read_config8(dev, 0x48);
+ byte |= 1 << 2;
+ pci_write_config8(dev, 0x48, byte);
+
+ /* RPR 4.10 Enable Lock Operation */
+ byte = pci_read_config8(dev, 0x48);
+ byte |= 1 << 3;
+ pci_write_config8(dev, 0x48, byte);
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR 4.11 Enable additional optional PCI clock */
+ word = pci_read_config16(dev, 0x64);
+ word |= 1 << 8;
+ pci_write_config16(dev, 0x64, word);
+
+ /* rpr4.12 Disable Fewer-Retry Mode for A11-A13 only. 0x64[5:4] clear */
+ byte = pci_read_config8(dev, 0x64);
+ byte &= 0xcf;
+ pci_write_config8(dev, 0x64, byte);
+
+ /* rpr4.14 Disabling Downstream Flush, for A12 only, 0x64[18]. */
+ dword = pci_read_config32(dev, 0x64);
+ dword |= (1 << 18);
+ pci_write_config32(dev, 0x64, dword);
+
+ /* RPR 4.13 Enable One-Prefetch-Channel Mode */
+ dword = pci_read_config32(dev, 0x64);
+ dword |= 1 << 20;
+ pci_write_config32(dev, 0x64, dword);
+
+ /* RPR 4.15 Disable PCIB MSI Capability */
+ byte = pci_read_config8(dev, 0x40);
+ byte &= ~(1 << 3);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* rpr4.16 Adjusting CLKRUN# */
+ dword = pci_read_config32(dev, 0x64);
+ dword |= (1 << 15);
+ pci_write_config32(dev, 0x64, dword);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ /* .enable = sb600_enable, */
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_PCI,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <reset.h>
+
+#include "northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
+ outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008 Carl-Daniel Hailfinger
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "sb600.h"
+
+static int sata_drive_detect(int portnum, u16 iobar)
+{
+ u8 byte, byte2;
+ int i = 0;
+ outb(0xA0 + 0x10 * (portnum % 2), iobar + 0x6);
+ while (byte = inb(iobar + 0x6), byte2 = inb(iobar + 0x7),
+ (byte != (0xA0 + 0x10 * (portnum % 2))) ||
+ ((byte2 & 0x88) != 0)) {
+ printk(BIOS_SPEW, "0x6=%x, 0x7=%x\n", byte, byte2);
+ if (byte != (0xA0 + 0x10 * (portnum % 2))) {
+ /* This will happen at the first iteration of this loop
+ * if the first SATA port is unpopulated and the
+ * second SATA port is populated.
+ */
+ printk(BIOS_DEBUG, "drive no longer selected after %i ms, "
+ "retrying init\n", i * 10);
+ return 1;
+ } else
+ printk(BIOS_SPEW, "drive detection not yet completed, "
+ "waiting...\n");
+ mdelay(10);
+ i++;
+ }
+ printk(BIOS_SPEW, "drive detection done after %i ms\n", i * 10);
+ return 0;
+}
+
+static void sata_init(struct device *dev)
+{
+ u8 byte;
+ u16 word;
+ u32 dword;
+ u32 sata_bar5;
+ u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
+ int i, j;
+
+ struct southbridge_ati_sb600_config *conf;
+ conf = dev->chip_info;
+
+ device_t sm_dev;
+ /* SATA SMBus Disable */
+ /* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); */
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ /* Disable SATA SMBUS */
+ byte = pci_read_config8(sm_dev, 0xad);
+ byte |= (1 << 1);
+ /* Enable SATA and power saving */
+ byte = pci_read_config8(sm_dev, 0xad);
+ byte |= (1 << 0);
+ byte |= (1 << 5);
+ pci_write_config8(sm_dev, 0xad, byte);
+ /* Set the interrupt Mapping to INTG# */
+ byte = pci_read_config8(sm_dev, 0xaf);
+ byte = 0x6 << 2;
+ pci_write_config8(sm_dev, 0xaf, byte);
+
+ /* get base address */
+ sata_bar5 = pci_read_config32(dev, 0x24) & ~0x3FF;
+ sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7;
+ sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3;
+ sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7;
+ sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3;
+ sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf;
+
+ printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */
+ printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */
+ printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */
+ printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */
+ printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */
+ printk(BIOS_SPEW, "sata_bar5=%x\n", sata_bar5); /* e0309000 */
+
+ /* Program the 2C to 0x43801002 */
+ dword = 0x43801002;
+ pci_write_config32(dev, 0x2c, dword);
+
+ /* SERR-Enable */
+ word = pci_read_config16(dev, 0x04);
+ word |= (1 << 8);
+ pci_write_config16(dev, 0x04, word);
+
+ /* Dynamic power saving */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Set SATA Operation Mode, Set to IDE mode */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 0);
+ byte |= (1 << 4);
+ pci_write_config8(dev, 0x40, byte);
+
+ dword = 0x01018f00;
+ pci_write_config32(dev, 0x8, dword);
+
+ byte = pci_read_config8(dev, 0x40);
+ byte &= ~(1 << 0);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Enable the SATA watchdog counter */
+ byte = pci_read_config8(dev, 0x44);
+ byte |= (1 << 0);
+ pci_write_config8(dev, 0x44, byte);
+
+ /* Program the watchdog counter to 0x10 */
+ byte = 0x10;
+ pci_write_config8(dev, 0x46, byte);
+
+ /* RPR6.5 Program the PHY Global Control to 0x2C00 for A13 */
+ word = 0x2c00;
+ pci_write_config16(dev, 0x86, word);
+
+ /* RPR6.5 Program the Phy Tuning4Ports */
+ dword = 0x00B401D6;
+ pci_write_config32(dev, 0x88, dword);
+ pci_write_config32(dev, 0x8c, dword);
+ pci_write_config32(dev, 0x90, dword);
+ pci_write_config32(dev, 0x94, dword);
+
+ byte = 0xB8;
+ pci_write_config8(dev, 0xA5, byte);
+ pci_write_config8(dev, 0xAD, byte);
+ pci_write_config8(dev, 0xB5, byte);
+ pci_write_config8(dev, 0xBD, byte);
+
+ /* RPR 6.8 */
+ word = pci_read_config16(dev, 0x42);
+ word |= 1 << 7;
+ pci_write_config16(dev, 0x42, word);
+ /* RPR 6.9 */
+ dword = pci_read_config32(dev, 0x40);
+ dword |= 1 << 25;
+ pci_write_config32(dev, 0x40, dword);
+
+ /* Enable the I/O, MM, BusMaster access for SATA */
+ byte = pci_read_config8(dev, 0x4);
+ byte |= 7 << 0;
+ pci_write_config8(dev, 0x4, byte);
+
+ /* RPR6.6 SATA drive detection. */
+ /* Use BAR5+0x128,BAR0 for Primary Slave */
+ /* Use BAR5+0x1A8,BAR0 for Primary Slave */
+ /* Use BAR5+0x228,BAR2 for Secondary Master */
+ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */
+
+ for (i = 0; i < 4; i++) {
+ byte = read8(sata_bar5 + 0x128 + 0x80 * i);
+ printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
+ byte &= 0xF;
+
+ if( byte == 0x1 ) {
+ /* If the drive status is 0x1 then we see it but we aren't talking to it. */
+ /* Try to do something about it. */
+ printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n");
+
+ /* Read in Port-N Serial ATA Control Register */
+ byte = read8(sata_bar5 + 0x12C + 0x80 * i);
+
+ /* Set Reset Bit and 1.5g bit */
+ byte |= 0x11;
+ write8((sata_bar5 + 0x12C + 0x80 * i), byte);
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Clear Reset Bit */
+ byte &= ~0x01;
+ write8((sata_bar5 + 0x12C + 0x80 * i), byte);
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Reread status */
+ byte = read8(sata_bar5 + 0x128 + 0x80 * i);
+ printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
+ byte &= 0xF;
+ }
+
+ if (byte == 0x3) {
+ for (j = 0; j < 10; j++) {
+ if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))
+ break;
+ }
+ printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n",
+ (i / 2) ? "Secondary" : "Primary",
+ (i % 2 ) ? "Slave" : "Master",
+ (j == 10) ? "not " : "",
+ (j == 10) ? j : j + 1);
+ } else {
+ printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n",
+ (i / 2) ? "Secondary" : "Primary",
+ (i % 2 ) ? "Slave" : "Master", i);
+ }
+ }
+
+ /* Below is CIM InitSataLateFar */
+ /* Enable interrupts from the HBA */
+ byte = read8(sata_bar5 + 0x4);
+ byte |= 1 << 1;
+ write8((sata_bar5 + 0x4), byte);
+
+ /* Clear error status */
+ write32((sata_bar5 + 0x130), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x230), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
+
+ /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */
+ /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */
+
+ /* word = 0x0000; */
+ /* word = pm_ioread(0x28); */
+ /* byte = pm_ioread(0x29); */
+ /* word |= byte<<8; */
+ /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */
+ /* write32(word, 0x80000000); */
+}
+
+static struct pci_operations lops_pci = {
+ /* .set_subsystem = pci_dev_set_subsystem, */
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ /* .enable = sb600_enable, */
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_SATA,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sb600.h"
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations ac97audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-/* .enable = sb600_enable, */
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97audio_driver __pci_driver = {
- .ops = &ac97audio_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_ACI,
-};
-
-static struct device_operations ac97modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-/* .enable = sb600_enable, */
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97modem_driver __pci_driver = {
- .ops = &ac97modem_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_MCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-#include <arch/cpu.h>
-#include "sb600.h"
-#include "sb600_smbus.c"
-
-#define SMBUS_IO_BASE 0x1000 /* Is it a temporary SMBus I/O base address? */
- /*SIZE 0x40 */
-
-static void pmio_write(u8 reg, u8 value)
-{
- outb(reg, PM_INDEX);
- outb(value, PM_INDEX + 1);
-}
-
-static u8 pmio_read(u8 reg)
-{
- outb(reg, PM_INDEX);
- return inb(PM_INDEX + 1);
-}
-
-/* RPR 2.1: Get SB ASIC Revision. */
-static u8 get_sb600_revision(void)
-{
- device_t dev;
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- /* NOT REACHED */
- }
- return pci_read_config8(dev, 0x08);
-}
-
-
-/***************************************
-* Legacy devices are mapped to LPC space.
-* Serial port 0
-* KBC Port
-* ACPI Micro-controller port
-* This function does not change port 0x80 decoding.
-* Console output through any port besides 0x3f8 is unsupported.
-* If you use FWH ROMs, you have to setup IDSEL.
-* Reviewed-by: Carl-Daniel Hailfinger
-* Reviewed against AMD SB600 Register Reference Manual rev. 3.03, section 3.1
-* (LPC ISA Bridge)
-***************************************/
-static void sb600_lpc_init(void)
-{
- u8 reg8;
- u32 reg32;
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); /* SMBUS controller */
- /* NOTE: Set BootTimerDisable, otherwise it would keep rebooting!!
- * This bit has no meaning if debug strap is not enabled. So if the
- * board keeps rebooting and the code fails to reach here, we could
- * disable the debug strap first. */
- reg32 = pci_read_config32(dev, 0x4C);
- reg32 |= 1 << 31;
- pci_write_config32(dev, 0x4C, reg32);
-
- /* Enable lpc controller */
- reg32 = pci_read_config32(dev, 0x64);
- reg32 |= 1 << 20;
- pci_write_config32(dev, 0x64, reg32);
-
- dev = pci_locate_device(PCI_ID(0x1002, 0x438d), 0); /* LPC Controller */
- /* Decode port 0x3f8-0x3ff (Serial 0) */
- // XXX Serial port decode on LPC is hardcoded to 0x3f8
- reg8 = pci_read_config8(dev, 0x44);
- reg8 |= 1 << 6;
- pci_write_config8(dev, 0x44, reg8);
-
- /* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
- reg8 = pci_read_config8(dev, 0x47);
- reg8 |= (1 << 5) | (1 << 6);
- pci_write_config8(dev, 0x47, reg8);
-
- /* Super I/O, RTC */
- reg8 = pci_read_config8(dev, 0x48);
- /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
- reg8 |= (1 << 1) | (1 << 0);
- /* Decode port 0x70-0x73 (RTC) */
- reg8 |= (1 << 6);
- pci_write_config8(dev, 0x48, reg8);
-}
-
-/* what is its usage? */
-static u32 get_sbdn(u32 bus)
-{
- device_t dev;
-
- /* Find the device. */
- dev = pci_locate_device_on_bus(PCI_ID(0x1002, 0x4385), bus);
- return (dev >> 15) & 0x1f;
-}
-
-static u8 dual_core(void)
-{
- return (pci_read_config32(PCI_DEV(0, 0x18, 3), 0xE8) & (0x3<<12)) != 0;
-}
-
-/*
- * SB600 VFSMAF (VID/FID System Management Action Field) is 010b by default.
- * RPR 2.3.3 C-state and VID/FID change for the K8 platform.
-*/
-static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
-{
- u8 byte;
- byte = pmio_read(0x9a);
- byte &= ~0x34;
- if (dual_core())
- byte |= 0x34;
- else
- byte |= 0x04;
- pmio_write(0x9a, byte);
-
- byte = pmio_read(0x8f);
- byte &= ~0x30;
- byte |= 0x20;
- pmio_write(0x8f, byte);
-
- pmio_write(0x8b, 0x01);
- pmio_write(0x8a, 0x90);
-
- if(get_sb600_revision() > 0x13)
- pmio_write(0x88, 0x10);
- else
- pmio_write(0x88, 0x06);
-
- byte = pmio_read(0x7c);
- byte &= ~0x01;
- byte |= 0x01;
- pmio_write(0x7c, byte);
-
- /* Must be 0 for K8 platform. */
- byte = pmio_read(0x68);
- byte &= ~0x01;
- pmio_write(0x68, byte);
- /* Must be 0 for K8 platform. */
- byte = pmio_read(0x8d);
- byte &= ~(1<<6);
- pmio_write(0x8d, byte);
-
- byte = pmio_read(0x61);
- byte &= ~0x04;
- pmio_write(0x61, byte);
-
- byte = pmio_read(0x42);
- byte &= ~0x04;
- pmio_write(0x42, byte);
-
- if (get_sb600_revision() == 0x14) {
- pmio_write(0x89, 0x10);
-
- byte = pmio_read(0x52);
- byte |= 0x80;
- pmio_write(0x52, byte);
- }
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
- /* link reset */
- outb(0x06, 0x0cf9);
-}
-
-void sb600_pci_port80(void)
-{
- u8 byte;
- device_t dev;
-
- /* P2P Bridge */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
-
- /* Chip Control: Enable subtractive decoding */
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 5;
- pci_write_config8(dev, 0x40, byte);
-
- /* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 7;
- pci_write_config8(dev, 0x4B, byte);
-
- /* The same IO Base and IO Limit here is meaningful because we set the
- * bridge to be subtractive. During early setup stage, we have to make
- * sure that data can go through port 0x80.
- */
- /* IO Base: 0xf000 */
- byte = pci_read_config8(dev, 0x1C);
- byte |= 0xF << 4;
- pci_write_config8(dev, 0x1C, byte);
-
- /* IO Limit: 0xf000 */
- byte = pci_read_config8(dev, 0x1D);
- byte |= 0xF << 4;
- pci_write_config8(dev, 0x1D, byte);
-
- /* PCI Command: Enable IO response */
- byte = pci_read_config8(dev, 0x04);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x04, byte);
-
- /* LPC controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
-
- byte = pci_read_config8(dev, 0x4A);
- byte &= ~(1 << 5); /* disable lpc port 80 */
- pci_write_config8(dev, 0x4A, byte);
-}
-
-void sb600_lpc_port80(void)
-{
- u8 byte;
- device_t dev;
- u32 reg32;
-
- /* Enable LPC controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
- reg32 = pci_read_config32(dev, 0x64);
- reg32 |= 0x00100000; /* lpcEnable */
- pci_write_config32(dev, 0x64, reg32);
-
- /* Enable port 80 LPC decode in pci function 3 configuration space. */
- dev = pci_locate_device(PCI_ID(0x1002, 0x438d), 0);
- byte = pci_read_config8(dev, 0x4a);
- byte |= 1 << 5; /* enable port 80 */
- pci_write_config8(dev, 0x4a, byte);
-}
-
-/* sbDevicesPorInitTable */
-static void sb600_devices_por_init(void)
-{
- device_t dev;
- u8 byte;
-
- printk(BIOS_INFO, "sb600_devices_por_init()\n");
- /* SMBus Device, BDF:0-20-0 */
- printk(BIOS_INFO, "sb600_devices_por_init(): SMBus Device, BDF:0-20-0\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- /* NOT REACHED */
- }
- printk(BIOS_INFO, "SMBus controller enabled, sb revision is 0x%x\n",
- get_sb600_revision());
-
- /* sbPorAtStartOfTblCfg */
- /* Set A-Link bridge access address. This address is set at device 14h, function 0, register 0xf0.
- * This is an I/O address. The I/O address must be on 16-byte boundry. */
- pci_write_config32(dev, 0xf0, AB_INDX);
-
- /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */
- /*Enables the SB600 to send transactions upstream over A-Link Express interface. */
- axcfg_reg(0x04, 1 << 2, 1 << 2);
- axindxc_reg(0x21, 0xff, 0);
-
- /* 2.3.5:Enabling Non-Posted Memory Write for the K8 Platform */
- axindxc_reg(0x10, 1 << 9, 1 << 9);
- /* END of sbPorAtStartOfTblCfg */
-
- /* sbDevicesPorInitTables */
- /* set smbus iobase */
- pci_write_config32(dev, 0x10, SMBUS_IO_BASE | 1);
-
- /* enable smbus controller interface */
- byte = pci_read_config8(dev, 0xd2);
- byte |= (1 << 0);
- pci_write_config8(dev, 0xd2, byte);
-
- /* set smbus 1, ASF 2.0 (Alert Standard Format), iobase */
- pci_write_config16(dev, 0x58, SMBUS_IO_BASE | 0x11);
-
- /* TODO: I don't know the useage of followed two lines. I copied them from CIM. */
- pci_write_config8(dev, 0x0a, 0x1);
- pci_write_config8(dev, 0x0b, 0x6);
-
- /* KB2RstEnable */
- pci_write_config8(dev, 0x40, 0xd4);
-
- /* Enable ISA Address 0-960K decoding */
- pci_write_config8(dev, 0x48, 0x0f);
-
- /* Enable ISA Address 0xC0000-0xDFFFF decode */
- pci_write_config8(dev, 0x49, 0xff);
-
- /* Enable decode cycles to IO C50, C51, C52 GPM controls. */
- byte = pci_read_config8(dev, 0x41);
- byte &= 0x80;
- byte |= 0x33;
- pci_write_config8(dev, 0x41, byte);
-
- /* Legacy DMA Prefetch Enhancement, CIM masked it. */
- /* pci_write_config8(dev, 0x43, 0x1); */
-
- /* Disabling Legacy USB Fast SMI# */
- byte = pci_read_config8(dev, 0x62);
- byte |= 0x24;
- pci_write_config8(dev, 0x62, byte);
-
- /* Features Enable */
- pci_write_config32(dev, 0x64, 0x829E7DBF); /* bit10: Enables the HPET interrupt. */
-
- /* SerialIrq Control */
- pci_write_config8(dev, 0x69, 0x90);
-
- /* Test Mode, PCIB_SReset_En Mask is set. */
- pci_write_config8(dev, 0x6c, 0x20);
-
- /* IO Address Enable, CIM set 0x78 only and masked 0x79. */
- /*pci_write_config8(dev, 0x79, 0x4F); */
- pci_write_config8(dev, 0x78, 0xFF);
-
- /* This register is not used on sb600. It came from older chipset. */
- /*pci_write_config8(dev, 0x95, 0xFF); */
-
- /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */
- pci_write_config16(dev, 0x4, 0x0407);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* IDE Device, BDF:0-20-1 */
- printk(BIOS_INFO, "sb600_devices_por_init(): IDE Device, BDF:0-20-1\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x438C), 0);
- /* Disable prefetch */
- byte = pci_read_config8(dev, 0x63);
- byte |= 0x1;
- pci_write_config8(dev, 0x63, byte);
-
- /* LPC Device, BDF:0-20-3 */
- printk(BIOS_INFO, "sb600_devices_por_init(): LPC Device, BDF:0-20-3\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
- /* DMA enable */
- pci_write_config8(dev, 0x40, 0x04);
-
- /* IO Port Decode Enable */
- pci_write_config8(dev, 0x44, 0xFF);
- pci_write_config8(dev, 0x45, 0xFF);
- pci_write_config8(dev, 0x46, 0xC3);
- pci_write_config8(dev, 0x47, 0xFF);
-
- // TODO: This has already been done(?)
- /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
- * Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
- * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65). */
- byte = pci_read_config8(dev, 0x48);
- byte |= (1 << 1) | (1 << 0); /* enable Super IO config port 2e-2h, 4e-4f */
- byte |= 1 << 6; /* enable for RTC I/O range */
- pci_write_config8(dev, 0x48, byte);
- pci_write_config8(dev, 0x49, 0xFF);
- /* Enable 0x480-0x4bf, 0x4700-0x470B */
- byte = pci_read_config8(dev, 0x4A);
- byte |= ((1 << 1) + (1 << 6)); /*0x42, save the configuraion for port 0x80. */
- pci_write_config8(dev, 0x4A, byte);
-
- /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
- pci_write_config8(dev, 0x7C, 0x05);
-
- /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
- * TODO: I don't know what are their mean? */
- printk(BIOS_INFO, "sb600_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
- /* I don't know why CIM tried to write into a read-only reg! */
- /*pci_write_config8(dev, 0x0c, 0x20) */ ;
-
- /* Arbiter enable. */
- pci_write_config8(dev, 0x43, 0xff);
-
- /* Set PCDMA request into hight priority list. */
- /* pci_write_config8(dev, 0x49, 0x1) */ ;
-
- pci_write_config8(dev, 0x40, 0x26);
-
- /* I don't know why CIM set reg0x1c as 0x11.
- * System will block at sdram_initialize() if I set it before call sdram_initialize().
- * If it is necessary to set reg0x1c as 0x11, please call this function after sdram_initialize().
- * pci_write_config8(dev, 0x1c, 0x11);
- * pci_write_config8(dev, 0x1d, 0x11);*/
-
- /*CIM set this register; but I didn't find its description in RPR.
- On DBM690T platform, I didn't find different between set and skip this register.
- But on Filbert platform, the DEBUG message from serial port on Peanut board can't be displayed
- after the bit0 of this register is set.
- pci_write_config8(dev, 0x04, 0x21);
- */
- pci_write_config8(dev, 0x0d, 0x40);
- pci_write_config8(dev, 0x1b, 0x40);
- /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
- pci_write_config8(dev, 0x50, 0x01);
-
- /* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
- printk(BIOS_INFO, "sb600_devices_por_init(): SATA Device, BDF:0-18-0\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
-
- /*PHY Global Control, we are using A14.
- * default: 0x2c40 for ASIC revision A12 and below
- * 0x2c00 for ASIC revision A13 and above.*/
- pci_write_config16(dev, 0x86, 0x2C00);
-
- /* PHY Port0-3 Control */
- pci_write_config32(dev, 0x88, 0xB400DA);
- pci_write_config32(dev, 0x8c, 0xB400DA);
- pci_write_config32(dev, 0x90, 0xB400DA);
- pci_write_config32(dev, 0x94, 0xB400DA);
-
- /* Port0-3 BIST Control/Status */
- pci_write_config8(dev, 0xa5, 0xB8);
- pci_write_config8(dev, 0xad, 0xB8);
- pci_write_config8(dev, 0xb5, 0xB8);
- pci_write_config8(dev, 0xbd, 0xB8);
-}
-
-/* sbPmioPorInitTable, Pre-initializing PMIO register space
-* The power management (PM) block is resident in the PCI/LPC/ISA bridge.
-* The PM regs are accessed via IO mapped regs 0xcd6 and 0xcd7.
-* The index address is first programmed into IO reg 0xcd6.
-* Read or write values are accessed through IO reg 0xcd7.
-*/
-static void sb600_pmio_por_init(void)
-{
- u8 byte;
-
- printk(BIOS_INFO, "sb600_pmio_por_init()\n");
- /* K8KbRstEn, KB_RST# control for K8 system. */
- byte = pmio_read(0x66);
- byte |= 0x20;
- pmio_write(0x66, byte);
-
- /* RPR2.3.4 S3/S4/S5 Function for the K8 Platform. */
- byte = pmio_read(0x52);
- byte &= 0xc0;
- byte |= 0x08;
- pmio_write(0x52, byte);
-
- /* C state enable and SLP enable in C states. */
- byte = pmio_read(0x67);
- byte |= 0x6;
- pmio_write(0x67, byte);
-
- /* CIM sets 0x0e, but bit2 is for P4 system. */
- byte = pmio_read(0x68);
- byte &= 0xf0;
- byte |= 0x0c;
- pmio_write(0x68, byte);
-
- /* Watch Dog Timer Control
- * Set watchdog time base to 0xfec000f0 to avoid SCSI card boot failure.
- * But I don't find WDT is enabled in SMBUS 0x41 bit3 in CIM.
- */
- pmio_write(0x6c, 0xf0);
- pmio_write(0x6d, 0x00);
- pmio_write(0x6e, 0xc0);
- pmio_write(0x6f, 0xfe);
-
- /* rpr2.14: Enables HPET periodical mode */
- byte = pmio_read(0x9a);
- byte |= 1 << 7;
- pmio_write(0x9a, byte);
- byte = pmio_read(0x9f);
- byte |= 1 << 5;
- pmio_write(0x9f, byte);
- byte = pmio_read(0x9e);
- byte |= (1 << 6) | (1 << 7);
- pmio_write(0x9e, byte);
-
- /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
- /* We have to clear this bit here, otherwise the kernel hangs. */
- byte = pmio_read(0x55);
- byte |= 1 << 7;
- byte |= 1 << 1;
- pmio_write(0x55, byte);
-
- /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridage */
- byte = pmio_read(0x52);
- byte |= 1 << 6;
- pmio_write(0x52, byte);
-
- /* rpr2.22: PLL Reset */
- byte = pmio_read(0x86);
- byte |= 1 << 7;
- pmio_write(0x86, byte);
-
- /* rpr2.3.3 */
- /* This provides 16us delay before the assertion of LDTSTP# when C3 is entered.
- * The delay will allow USB DMA to go on in a continuous manner
- */
- pmio_write(0x89, 0x10);
- /* Set this bit to allow pop-up request being latched during the minimum LDTSTP# assertion time */
- byte = pmio_read(0x52);
- byte |= 1 << 7;
- pmio_write(0x52, byte);
-
- /* rpr2.15: ASF Remote Control Action */
- byte = pmio_read(0x9f);
- byte |= 1 << 6;
- pmio_write(0x9f, byte);
-
- /* rpr2.19: Enabling Spread Spectrum */
- byte = pmio_read(0x42);
- byte |= 1 << 7;
- pmio_write(0x42, byte);
-}
-
-/*
-* Compliant with CIM_48's sbPciCfg.
-* Add any south bridge setting.
-*/
-static void sb600_pci_cfg(void)
-{
- device_t dev;
- u8 byte;
-
- /* SMBus Device, BDF:0-20-0 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
- /* Eable the hidden revision ID, available after A13. */
- byte = pci_read_config8(dev, 0x70);
- byte |= (1 << 8);
- pci_write_config8(dev, 0x70, byte);
- /* rpr2.20 Disable Timer IRQ Enhancement for proper operation of the 8254 timer, 0xae[5]. */
- byte = pci_read_config8(dev, 0xae);
- byte |= (1 << 5);
- pci_write_config8(dev, 0xae, byte);
-
- /* Enable watchdog decode timer */
- byte = pci_read_config8(dev, 0x41);
- byte |= (1 << 3);
- pci_write_config8(dev, 0x41, byte);
-
- /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
- * generated PCIRST#. */
- byte = pmio_read(0x65);
- byte |= (1 << 4);
- pmio_write(0x65, byte);
- /*For A13 and above. */
- if (get_sb600_revision() > 0x12) {
- /* rpr2.16 C-State Reset, PMIO 0x9f[7]. */
- byte = pmio_read(0x9f);
- byte |= (1 << 7);
- pmio_write(0x9f, byte);
- /* rpr2.17 PCI Clock Period will increase to 30.8ns. 0x53[7]. */
- byte = pmio_read(0x53);
- byte |= (1 << 7);
- pmio_write(0x53, byte);
- }
-
- /* IDE Device, BDF:0-20-1 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x438C), 0);
- /* Enable IDE Explicit prefetch, 0x63[0] clear */
- byte = pci_read_config8(dev, 0x63);
- byte &= 0xfe;
- pci_write_config8(dev, 0x63, byte);
-
- /* LPC Device, BDF:0-20-3 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x438D), 0);
- /* rpr7.2 Enabling LPC DMA function. */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
- /* rpr7.3 Disabling LPC TimeOut. 0x48[7] clear. */
- byte = pci_read_config8(dev, 0x48);
- byte &= 0x7f;
- pci_write_config8(dev, 0x48, byte);
- /* rpr7.5 Disabling LPC MSI Capability, 0x78[1] clear. */
- byte = pci_read_config8(dev, 0x78);
- byte &= 0xfd;
- pci_write_config8(dev, 0x78, byte);
-
- /* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
- /* rpr6.8 Disabling SATA MSI Capability, for A13 and above, 0x42[7]. */
- if (0x12 < get_sb600_revision()) {
- u32 reg32;
- reg32 = pci_read_config32(dev, 0x40);
- reg32 |= (1 << 23);
- pci_write_config32(dev, 0x40, reg32);
- }
-
- /* EHCI Device, BDF:0-19-5, ehci usb controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4386), 0);
- /* rpr5.10 Disabling USB EHCI MSI Capability. 0x50[6]. */
- byte = pci_read_config8(dev, 0x50);
- byte |= (1 << 6);
- pci_write_config8(dev, 0x50, byte);
-
- /* OHCI0 Device, BDF:0-19-0, ohci usb controller #0 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4387), 0);
- /* rpr5.11 Disabling USB OHCI MSI Capability. 0x40[12:8]=0x1f. */
- byte = pci_read_config8(dev, 0x41);
- byte |= 0x1f;
- pci_write_config8(dev, 0x41, byte);
-
-}
-
-/*
-* Compliant with CIM_48's ATSBPowerOnResetInitJSP
-*/
-static void sb600_por_init(void)
-{
- /* sbDevicesPorInitTable + sbK8PorInitTable */
- sb600_devices_por_init();
-
- /* sbPmioPorInitTable + sbK8PmioPorInitTable */
- sb600_pmio_por_init();
-}
-
-/*
-* Compliant with CIM_48's AtiSbBeforePciInit
-* It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
-*/
-static void sb600_before_pci_init(void)
-{
- sb600_pci_cfg();
-}
-
-/*
-* This function should be called after enable_sb600_smbus().
-*/
-static void sb600_early_setup(void)
-{
- printk(BIOS_INFO, "sb600_early_setup()\n");
- sb600_por_init();
-}
-
-static int smbus_read_byte(u32 device, u32 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-
-/*
- * Enable 4MB (LPC) ROM access at 0xFFC00000 - 0xFFFFFFFF.
- *
- * Hardware should enable LPC ROM by pin straps. This function does not
- * handle the theoretically possible PCI ROM, FWH, or SPI ROM configurations.
- *
- * The SB600 power-on default is to map 256K ROM space.
- *
- * Details: AMD SB600 BIOS Developer's Guide (BDG), page 15.
- */
-static void sb600_enable_rom(void)
-{
- u8 reg8;
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_ATI,
- PCI_DEVICE_ID_ATI_SB600_LPC), 0);
-
- /* Decode variable LPC ROM address ranges 1 and 2. */
- reg8 = pci_read_config8(dev, 0x48);
- reg8 |= (1 << 3) | (1 << 4);
- pci_write_config8(dev, 0x48, reg8);
-
- /* LPC ROM address range 1: */
- /* Enable LPC ROM range mirroring start at 0x000e(0000). */
- pci_write_config16(dev, 0x68, 0x000e);
- /* Enable LPC ROM range mirroring end at 0x000f(ffff). */
- pci_write_config16(dev, 0x6a, 0x000f);
-
- /* LPC ROM address range 2: */
- /*
- * Enable LPC ROM range start at:
- * 0xfff8(0000): 512KB
- * 0xfff0(0000): 1MB
- * 0xffe0(0000): 2MB
- * 0xffc0(0000): 4MB
- */
- pci_write_config16(dev, 0x6c, 0xffc0); /* 4 MB */
- /* Enable LPC ROM range end at 0xffff(ffff). */
- pci_write_config16(dev, 0x6e, 0xffff);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "sb600.h"
-
-/* Required for successful build, but currently empty. */
-void set_debug_port(unsigned int port)
-{
- /* TODO: Allow changing the physical USB port used as Debug Port. */
-}
-
-void sb600_enable_usbdebug(unsigned int port)
-{
- device_t dev = PCI_DEV(0, 0x13, 5); /* USB EHCI, D19:F5 */
-
- /* Select the requested physical USB port (1-15) as the Debug Port. */
- set_debug_port(port);
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "sb600.h"
-
-#define HDA_ICII_REG 0x68
-#define HDA_ICII_BUSY (1 << 0)
-#define HDA_ICII_VALID (1 << 1)
-
-static int set_bits(u32 port, u32 mask, u32 val)
-{
- u32 dword;
- int count;
-
- /* Write (val & ~mask) to port */
- val &= mask;
- dword = read32(port);
- dword &= ~mask;
- dword |= val;
- write32(port, dword);
-
- /* Wait for readback of register to
- * match what was just written to it
- */
- count = 50;
- do {
- /* Wait 1ms based on BKDG wait time */
- mdelay(1);
- dword = read32(port);
- dword &= mask;
- } while ((dword != val) && --count);
-
- /* Timeout occurred */
- if (!count)
- return -1;
- return 0;
-}
-
-static u32 codec_detect(u32 base)
-{
- u32 dword;
-
- /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 0) == -1)
- goto no_codec;
-
- /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 1) == -1)
- goto no_codec;
-
- /* Delay for 1 ms since the BKDG does */
- mdelay(1);
-
- /* Read in Codec location (BAR + 0xe)[3..0]*/
- dword = read32(base + 0xe);
- dword &= 0x0F;
- if (!dword)
- goto no_codec;
-
- return dword;
-
-no_codec:
- /* Codec Not found */
- /* Put HDA back in reset (BAR + 0x8) [0] */
- set_bits(base + 0x08, 1, 0);
- printk(BIOS_DEBUG, "No codec!\n");
- return 0;
-}
-
-static u32 cim_verb_data[] = {
- 0x01471c10,
- 0x01471d40,
- 0x01471e01,
- 0x01471f01,
-/* 1 */
- 0x01571c12,
- 0x01571d10,
- 0x01571e01,
- 0x01571f01,
-/* 2 */
- 0x01671c11,
- 0x01671d60,
- 0x01671e01,
- 0x01671f01,
-/* 3 */
- 0x01771c14,
- 0x01771d20,
- 0x01771e01,
- 0x01771f01,
-/* 4 */
- 0x01871c30,
- 0x01871d90,
- 0x01871ea1,
- 0x01871f01,
-/* 5 */
- 0x01971cf0,
- 0x01971d11,
- 0x01971e11,
- 0x01971f41,
-/* 6 */
- 0x01a71c80,
- 0x01a71d30,
- 0x01a71e81,
- 0x01a71f01,
-/* 7 */
- 0x01b71cf0,
- 0x01b71d11,
- 0x01b71e11,
- 0x01b71f41,
-/* 8 */
- 0x01c71cf0,
- 0x01c71d11,
- 0x01c71e11,
- 0x01c71f41,
-/* 9 */
- 0x01d71cf0,
- 0x01d71d11,
- 0x01d71e11,
- 0x01d71f41,
-/* 10 */
- 0x01e71c50,
- 0x01e71d11,
- 0x01e71e44,
- 0x01e71f01,
-/* 11 */
- 0x01f71c60,
- 0x01f71d61,
- 0x01f71ec4,
- 0x01f71f01,
-};
-
-static u32 find_verb(u32 viddid, u32 ** verb)
-{
- device_t azalia_dev = dev_find_slot(0, PCI_DEVFN(0x14, 2));
- struct southbridge_amd_sb600_config *cfg =
- (struct southbridge_amd_sb600_config *)azalia_dev->chip_info;
- printk(BIOS_DEBUG, "Dev=%s\n", dev_path(azalia_dev));
- printk(BIOS_DEBUG, "Default viddid=%x\n", cfg->hda_viddid);
- printk(BIOS_DEBUG, "Reading viddid=%x\n", viddid);
- if (!cfg)
- return 0;
- if (viddid != cfg->hda_viddid)
- return 0;
- *verb = (u32 *) cim_verb_data;
- return sizeof(cim_verb_data) / sizeof(u32);
-}
-
-/**
- * Wait 50usec for the codec to indicate it is ready
- * no response would imply that the codec is non-operative
- */
-static int wait_for_ready(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
-
- while(timeout--) {
- u32 dword=read32(base + HDA_ICII_REG);
- if (!(dword & HDA_ICII_BUSY))
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-/**
- * Wait 50usec for the codec to indicate that it accepted
- * the previous command. No response would imply that the code
- * is non-operative
- */
-static int wait_for_valid(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
- while(timeout--) {
- u32 dword = read32(base + HDA_ICII_REG);
- if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
- HDA_ICII_VALID)
- return 0;
- udelay(1);
- }
-
- return 1;
-}
-
-static void codec_init(u32 base, int addr)
-{
- u32 dword;
- u32 *verb;
- u32 verb_size;
- int i;
-
- /* 1 */
- if (wait_for_ready(base) == -1)
- return;
-
- dword = (addr << 28) | 0x000f0000;
- write32(base + 0x60, dword);
-
- if (wait_for_valid(base) == -1)
- return;
-
- dword = read32(base + 0x64);
-
- /* 2 */
- printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
- verb_size = find_verb(dword, &verb);
-
- if (!verb_size) {
- printk(BIOS_DEBUG, "No verb!\n");
- return;
- }
-
- printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
- /* 3 */
- for (i = 0; i < verb_size; i++) {
- if (wait_for_ready(base) == -1)
- return;
-
- write32(base + 0x60, verb[i]);
-
- if (wait_for_valid(base) == -1)
- return;
- }
- printk(BIOS_DEBUG, "verb loaded!\n");
-}
-
-static void codecs_init(u32 base, u32 codec_mask)
-{
- int i;
- for (i = 2; i >= 0; i--) {
- if (codec_mask & (1 << i))
- codec_init(base, i);
- }
-}
-
-static void hda_init(struct device *dev)
-{
- u8 byte;
- u32 dword;
- u32 base;
- struct resource *res;
- u32 codec_mask;
- device_t sm_dev;
-
- /* Enable azalia - PM_io 0x59[4], disable ac97 - PM_io 0x59[1..0] */
- pm_iowrite(0x59, 0xB);
-
- /* Find the SMBus */
- /* FIXME: Need to find out why the call below crashes. */
- /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB600_SM, 0);*/
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
-
- /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
- pci_write_config32(sm_dev, 0xf8, 0x00);
- pci_write_config8(sm_dev, 0xfc, 0xAA);
- /* Set INTA - SMBus 0x63 [2..0] */
- byte = pci_read_config8(sm_dev, 0x63);
- byte &= ~0x7;
- byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
- pci_write_config8(sm_dev, 0x63, byte);
-
- /* Program the 2C to 0x437b1002 */
- dword = 0x437b1002;
- pci_write_config32(dev, 0x2c, dword);
-
- /* Read in BAR */
- /* Is this right? HDA allows for a 64-bit BAR
- * but this is only setup for a 32-bit one
- */
- res = find_resource(dev, 0x10);
- if (!res)
- return;
-
- base = (u32)res->base;
- printk(BIOS_DEBUG, "base = 0x%x\n", base);
- codec_mask = codec_detect(base);
-
- if (codec_mask) {
- printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
- codecs_init(base, codec_mask);
- }
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations hda_audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- /*.enable = sb600_enable, */
- .init = hda_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver hdaaudio_driver __pci_driver = {
- .ops = &hda_audio_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_HDA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sb600.h"
-
-static void ide_init(struct device *dev)
-{
- /* Enable ide devices so the linux ide driver will work */
- u32 dword;
- u8 byte;
-
- /* RPR10.1 disable MSI */
- dword = pci_read_config32(dev, 0x70);
- dword &= ~(1 << 16);
- pci_write_config32(dev, 0x70, dword);
-
- /* Enable UDMA on all devices, it will become UDMA0 (default PIO is PIO0) */
- byte = pci_read_config8(dev, 0x54);
- byte |= 0xf;
- pci_write_config8(dev, 0x54, byte);
-
- /* Enable I/O Access&& Bus Master */
- dword = pci_read_config16(dev, 0x4);
- dword |= 1 << 2;
- pci_write_config16(dev, 0x4, dword);
-
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);
-#endif
-
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- /* .enable = sb600_enable, */
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "sb600.h"
-
-static void lpc_init(device_t dev)
-{
- u8 byte;
- u32 dword;
- device_t sm_dev;
-
- /* Enable the LPC Controller */
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- dword = pci_read_config32(sm_dev, 0x64);
- dword |= 1 << 20;
- pci_write_config32(sm_dev, 0x64, dword);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- /* RPR 7.2 Enable DMA transaction on the LPC bus */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR 7.3 Disable the timeout mechanism on LPC */
- byte = pci_read_config8(dev, 0x48);
- byte &= ~(1 << 7);
- pci_write_config8(dev, 0x48, byte);
-
- /* RPR 7.5 Disable LPC MSI Capability */
- byte = pci_read_config8(dev, 0x78);
- byte &= ~(1 << 1);
- pci_write_config8(dev, 0x78, byte);
-
-}
-
-static void sb600_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
-
- pci_get_resource(dev, 0xA0); /* SPI ROM base address */
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- compact_resources(dev);
-}
-
-/**
- * @brief Enable resources for children devices
- *
- * @param dev the device whos children's resources are to be enabled
- *
- */
-static void sb600_lpc_enable_childrens_resources(device_t dev)
-{
- struct bus *link;
- u32 reg, reg_x;
- int var_num = 0;
- u16 reg_var[3];
-
- reg = pci_read_config32(dev, 0x44);
- reg_x = pci_read_config32(dev, 0x48);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child;
- child = child->sibling) {
- if (child->enabled
- && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for (res = child->resource_list; res; res = res->next) {
- u32 base, end; /* don't need long long */
- if (!(res->flags & IORESOURCE_IO))
- continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "sb600 lpc decode:%s, base=0x%08x, end=0x%08x\n",
- dev_path(child), base, end);
- switch (base) {
- case 0x60: /* KB */
- case 0x64: /* MS */
- reg |= (1 << 29);
- break;
- case 0x3f8: /* COM1 */
- reg |= (1 << 6);
- break;
- case 0x2f8: /* COM2 */
- reg |= (1 << 7);
- break;
- case 0x378: /* Parallal 1 */
- reg |= (1 << 0);
- break;
- case 0x3f0: /* FD0 */
- reg |= (1 << 26);
- break;
- case 0x220: /* Aduio 0 */
- reg |= (1 << 8);
- break;
- case 0x300: /* Midi 0 */
- reg |= (1 << 18);
- break;
- case 0x400:
- reg_x |= (1 << 16);
- break;
- case 0x480:
- reg_x |= (1 << 17);
- break;
- case 0x500:
- reg_x |= (1 << 18);
- break;
- case 0x580:
- reg_x |= (1 << 19);
- break;
- case 0x4700:
- reg_x |= (1 << 22);
- break;
- case 0xfd60:
- reg_x |= (1 << 23);
- break;
- default:
- if (var_num >= 3)
- continue; /* only 3 var ; compact them ? */
- switch (var_num) {
- case 0:
- reg_x |= (1 << 2);
- break;
- case 1:
- reg_x |= (1 << 24);
- break;
- case 2:
- reg_x |= (1 << 25);
- break;
- }
- reg_var[var_num++] =
- base & 0xffff;
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0x44, reg);
- pci_write_config32(dev, 0x48, reg_x);
- /* Set WideIO for as many IOs found (fall through is on purpose) */
- switch (var_num) {
- case 2:
- pci_write_config16(dev, 0x90, reg_var[2]);
- case 1:
- pci_write_config16(dev, 0x66, reg_var[1]);
- case 0:
- pci_write_config16(dev, 0x64, reg_var[0]);
- break;
- }
-}
-
-static void sb600_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- sb600_lpc_enable_childrens_resources(dev);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = sb600_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = sb600_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- /* .enable = sb600_enable, */
- .ops_pci = &lops_pci,
-};
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sb600.h"
-
-static void pci_init(struct device *dev)
-{
- u32 dword;
- u16 word;
- u8 byte;
-
- /* RPR 4.1 Enables the PCI-bridge subtractive decode */
- /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 7;
- pci_write_config8(dev, 0x4B, byte);
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 5;
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR4.2 PCI-bridge upstream dual address window */
- /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */
- byte = pci_read_config8(dev, 0x50);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x50, byte);
-
- /* RPR 4.3 PCI bus 64-byte DMA read access */
- /* Enhance the PCI bus DMA performance */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 4;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 4.4 Enables the PCIB writes to be cacheline aligned. */
- /* The size of the writes will be set in the Cacheline Register */
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 1;
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR 4.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */
- pci_write_config8(dev, 0x0D, 0x40);
- pci_write_config8(dev, 0x1B, 0x40);
-
- /* RPR 4.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 6;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 4.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 4.8 Adjusts the GNT# de-assertion time */
- word = pci_read_config16(dev, 0x64);
- word |= 1 << 12;
- pci_write_config16(dev, 0x64, word);
-
- /* RPR 4.9 Fast Back to Back transactions support */
- byte = pci_read_config8(dev, 0x48);
- byte |= 1 << 2;
- pci_write_config8(dev, 0x48, byte);
-
- /* RPR 4.10 Enable Lock Operation */
- byte = pci_read_config8(dev, 0x48);
- byte |= 1 << 3;
- pci_write_config8(dev, 0x48, byte);
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR 4.11 Enable additional optional PCI clock */
- word = pci_read_config16(dev, 0x64);
- word |= 1 << 8;
- pci_write_config16(dev, 0x64, word);
-
- /* rpr4.12 Disable Fewer-Retry Mode for A11-A13 only. 0x64[5:4] clear */
- byte = pci_read_config8(dev, 0x64);
- byte &= 0xcf;
- pci_write_config8(dev, 0x64, byte);
-
- /* rpr4.14 Disabling Downstream Flush, for A12 only, 0x64[18]. */
- dword = pci_read_config32(dev, 0x64);
- dword |= (1 << 18);
- pci_write_config32(dev, 0x64, dword);
-
- /* RPR 4.13 Enable One-Prefetch-Channel Mode */
- dword = pci_read_config32(dev, 0x64);
- dword |= 1 << 20;
- pci_write_config32(dev, 0x64, dword);
-
- /* RPR 4.15 Disable PCIB MSI Capability */
- byte = pci_read_config8(dev, 0x40);
- byte &= ~(1 << 3);
- pci_write_config8(dev, 0x40, byte);
-
- /* rpr4.16 Adjusting CLKRUN# */
- dword = pci_read_config32(dev, 0x64);
- dword |= (1 << 15);
- pci_write_config32(dev, 0x64, dword);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- /* .enable = sb600_enable, */
- .reset_bus = pci_bus_reset,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_PCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <reset.h>
-
-#include "northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
- outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
- outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2008 Carl-Daniel Hailfinger
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "sb600.h"
-
-static int sata_drive_detect(int portnum, u16 iobar)
-{
- u8 byte, byte2;
- int i = 0;
- outb(0xA0 + 0x10 * (portnum % 2), iobar + 0x6);
- while (byte = inb(iobar + 0x6), byte2 = inb(iobar + 0x7),
- (byte != (0xA0 + 0x10 * (portnum % 2))) ||
- ((byte2 & 0x88) != 0)) {
- printk(BIOS_SPEW, "0x6=%x, 0x7=%x\n", byte, byte2);
- if (byte != (0xA0 + 0x10 * (portnum % 2))) {
- /* This will happen at the first iteration of this loop
- * if the first SATA port is unpopulated and the
- * second SATA port is populated.
- */
- printk(BIOS_DEBUG, "drive no longer selected after %i ms, "
- "retrying init\n", i * 10);
- return 1;
- } else
- printk(BIOS_SPEW, "drive detection not yet completed, "
- "waiting...\n");
- mdelay(10);
- i++;
- }
- printk(BIOS_SPEW, "drive detection done after %i ms\n", i * 10);
- return 0;
-}
-
-static void sata_init(struct device *dev)
-{
- u8 byte;
- u16 word;
- u32 dword;
- u32 sata_bar5;
- u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
- int i, j;
-
- struct southbridge_ati_sb600_config *conf;
- conf = dev->chip_info;
-
- device_t sm_dev;
- /* SATA SMBus Disable */
- /* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); */
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- /* Disable SATA SMBUS */
- byte = pci_read_config8(sm_dev, 0xad);
- byte |= (1 << 1);
- /* Enable SATA and power saving */
- byte = pci_read_config8(sm_dev, 0xad);
- byte |= (1 << 0);
- byte |= (1 << 5);
- pci_write_config8(sm_dev, 0xad, byte);
- /* Set the interrupt Mapping to INTG# */
- byte = pci_read_config8(sm_dev, 0xaf);
- byte = 0x6 << 2;
- pci_write_config8(sm_dev, 0xaf, byte);
-
- /* get base address */
- sata_bar5 = pci_read_config32(dev, 0x24) & ~0x3FF;
- sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7;
- sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3;
- sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7;
- sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3;
- sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf;
-
- printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */
- printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */
- printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */
- printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */
- printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */
- printk(BIOS_SPEW, "sata_bar5=%x\n", sata_bar5); /* e0309000 */
-
- /* Program the 2C to 0x43801002 */
- dword = 0x43801002;
- pci_write_config32(dev, 0x2c, dword);
-
- /* SERR-Enable */
- word = pci_read_config16(dev, 0x04);
- word |= (1 << 8);
- pci_write_config16(dev, 0x04, word);
-
- /* Dynamic power saving */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
-
- /* Set SATA Operation Mode, Set to IDE mode */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 0);
- byte |= (1 << 4);
- pci_write_config8(dev, 0x40, byte);
-
- dword = 0x01018f00;
- pci_write_config32(dev, 0x8, dword);
-
- byte = pci_read_config8(dev, 0x40);
- byte &= ~(1 << 0);
- pci_write_config8(dev, 0x40, byte);
-
- /* Enable the SATA watchdog counter */
- byte = pci_read_config8(dev, 0x44);
- byte |= (1 << 0);
- pci_write_config8(dev, 0x44, byte);
-
- /* Program the watchdog counter to 0x10 */
- byte = 0x10;
- pci_write_config8(dev, 0x46, byte);
-
- /* RPR6.5 Program the PHY Global Control to 0x2C00 for A13 */
- word = 0x2c00;
- pci_write_config16(dev, 0x86, word);
-
- /* RPR6.5 Program the Phy Tuning4Ports */
- dword = 0x00B401D6;
- pci_write_config32(dev, 0x88, dword);
- pci_write_config32(dev, 0x8c, dword);
- pci_write_config32(dev, 0x90, dword);
- pci_write_config32(dev, 0x94, dword);
-
- byte = 0xB8;
- pci_write_config8(dev, 0xA5, byte);
- pci_write_config8(dev, 0xAD, byte);
- pci_write_config8(dev, 0xB5, byte);
- pci_write_config8(dev, 0xBD, byte);
-
- /* RPR 6.8 */
- word = pci_read_config16(dev, 0x42);
- word |= 1 << 7;
- pci_write_config16(dev, 0x42, word);
- /* RPR 6.9 */
- dword = pci_read_config32(dev, 0x40);
- dword |= 1 << 25;
- pci_write_config32(dev, 0x40, dword);
-
- /* Enable the I/O, MM, BusMaster access for SATA */
- byte = pci_read_config8(dev, 0x4);
- byte |= 7 << 0;
- pci_write_config8(dev, 0x4, byte);
-
- /* RPR6.6 SATA drive detection. */
- /* Use BAR5+0x128,BAR0 for Primary Slave */
- /* Use BAR5+0x1A8,BAR0 for Primary Slave */
- /* Use BAR5+0x228,BAR2 for Secondary Master */
- /* Use BAR5+0x2A8,BAR2 for Secondary Slave */
-
- for (i = 0; i < 4; i++) {
- byte = read8(sata_bar5 + 0x128 + 0x80 * i);
- printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
- byte &= 0xF;
-
- if( byte == 0x1 ) {
- /* If the drive status is 0x1 then we see it but we aren't talking to it. */
- /* Try to do something about it. */
- printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n");
-
- /* Read in Port-N Serial ATA Control Register */
- byte = read8(sata_bar5 + 0x12C + 0x80 * i);
-
- /* Set Reset Bit and 1.5g bit */
- byte |= 0x11;
- write8((sata_bar5 + 0x12C + 0x80 * i), byte);
-
- /* Wait 1ms */
- mdelay(1);
-
- /* Clear Reset Bit */
- byte &= ~0x01;
- write8((sata_bar5 + 0x12C + 0x80 * i), byte);
-
- /* Wait 1ms */
- mdelay(1);
-
- /* Reread status */
- byte = read8(sata_bar5 + 0x128 + 0x80 * i);
- printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
- byte &= 0xF;
- }
-
- if (byte == 0x3) {
- for (j = 0; j < 10; j++) {
- if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))
- break;
- }
- printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n",
- (i / 2) ? "Secondary" : "Primary",
- (i % 2 ) ? "Slave" : "Master",
- (j == 10) ? "not " : "",
- (j == 10) ? j : j + 1);
- } else {
- printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n",
- (i / 2) ? "Secondary" : "Primary",
- (i % 2 ) ? "Slave" : "Master", i);
- }
- }
-
- /* Below is CIM InitSataLateFar */
- /* Enable interrupts from the HBA */
- byte = read8(sata_bar5 + 0x4);
- byte |= 1 << 1;
- write8((sata_bar5 + 0x4), byte);
-
- /* Clear error status */
- write32((sata_bar5 + 0x130), 0xFFFFFFFF);
- write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
- write32((sata_bar5 + 0x230), 0xFFFFFFFF);
- write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
-
- /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */
- /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */
-
- /* word = 0x0000; */
- /* word = pm_ioread(0x28); */
- /* byte = pm_ioread(0x29); */
- /* word |= byte<<8; */
- /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */
- /* write32(word, 0x80000000); */
-}
-
-static struct pci_operations lops_pci = {
- /* .set_subsystem = pci_dev_set_subsystem, */
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- /* .enable = sb600_enable, */
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_SATA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <pc80/mc146818rtc.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <cpu/x86/lapic.h>
-#include <arch/ioapic.h>
-#include <stdlib.h>
-#include "sb600.h"
-#include "sb600_smbus.c"
-
-#define NMI_OFF 0
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-/*
-* SB600 enables all USB controllers by default in SMBUS Control.
-* SB600 enables SATA by default in SMBUS Control.
-*/
-static void sm_init(device_t dev)
-{
- u8 byte;
- u8 byte_old;
- u32 dword;
- u32 ioapic_base;
- u32 on;
- u32 nmi_option;
-
- printk(BIOS_INFO, "sm_init().\n");
-
- ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */
- /* Don't rename APIC ID */
- clear_ioapic(ioapic_base);
-
- dword = pci_read_config8(dev, 0x62);
- dword |= 1 << 2;
- pci_write_config8(dev, 0x62, dword);
-
- dword = pci_read_config32(dev, 0x78);
- dword |= 1 << 9;
- pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */
-
- /* bit 10: MultiMediaTimerIrqEn */
- dword = pci_read_config8(dev, 0x64);
- dword |= 1 << 10;
- pci_write_config8(dev, 0x64, dword);
- /* enable serial irq */
- byte = pci_read_config8(dev, 0x69);
- byte |= 1 << 7; /* enable serial irq function */
- byte &= ~(0xF << 2);
- byte |= 4 << 2; /* set NumSerIrqBits=4 */
- pci_write_config8(dev, 0x69, byte);
-
- byte = pm_ioread(0x61);
- byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */
- pm_iowrite(0x61, byte);
-
- /* disable SMI */
- byte = pm_ioread(0x53);
- byte |= 1 << 3;
- pm_iowrite(0x53, byte);
-
- /* power after power fail */
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pm_ioread(0x74);
- byte &= ~0x03;
- if (on) {
- byte |= 2;
- }
- byte |= 1 << 2;
- pm_iowrite(0x74, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
-
- /* sb600 rpr:2.3.3: */
- byte = pm_ioread(0x9A);
- byte |= 1 << 5 | 1 << 4 | 1 << 2;
- pm_iowrite(0x9A, byte);
-
- byte = pm_ioread(0x8F);
- byte |= 1 << 5;
- byte &= ~(1 << 4);
- pm_iowrite(0x8F, byte);
-
- pm_iowrite(0x8B, 0x01);
- pm_iowrite(0x8A, 0x90);
- pm_iowrite(0x88, 0x10); /* A21 */
-
- byte = pm_ioread(0x7C);
- byte |= 1 << 0;
- pm_iowrite(0x7C, byte);
-
- byte = pm_ioread(0x68);
- byte &= ~(1 << 1);
- /* 2.6 */
- byte |= 1 << 2;
- pm_iowrite(0x68, byte);
-
- /* 2.6 */
- byte = pm_ioread(0x65);
- byte &= ~(1 << 7);
- pm_iowrite(0x65, byte);
-
- /* 2.3.4 */
- byte = pm_ioread(0x52);
- byte &= ~0x2F;
- byte |= 0x8;
- pm_iowrite(0x52, byte);
-
- byte = pm_ioread(0x8D);
- byte &= ~(1 << 6);
- pm_iowrite(0x8D, byte);
-
- byte = pm_ioread(0x61);
- byte &= ~(1 << 2);
- pm_iowrite(0x61, byte);
-
- byte = pm_ioread(0x42);
- byte &= ~(1 << 2);
- pm_iowrite(0x42, byte);
-
- /* Set up NMI on errors */
- byte = inb(0x70); /* RTC70 */
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- printk(BIOS_INFO, "++++++++++set NMI+++++\n");
- } else {
- byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */
- printk(BIOS_INFO, "++++++++++no set NMI+++++\n");
- }
- byte &= ~(1 << 7);
- if (byte != byte_old) {
- outb(byte, 0x70);
- }
-
- /* 2.10 IO Trap Settings */
- abcfg_reg(0x10090, 1 << 16, 1 << 16);
-
- /* ab index */
- pci_write_config32(dev, 0xF0, AB_INDX);
- /* Initialize the real time clock */
- rtc_init(0);
-
- /*3.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */
- abcfg_reg(0x10060, 9 << 17, 9 << 17);
- abcfg_reg(0x10064, 9 << 17, 9 << 17);
-
- /* 3.5 Enabling OHCI Prefetch for Performance Enhancement */
- abcfg_reg(0x80, 1 << 0, 1<< 0);
-
- /* 3.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */
- /* 3.7 Enabling Additional Address Bits Checking in Downstream */
- abcfg_reg(0x9c, 3 << 0, 3 << 0);
-
- /* 3.8 Set B-Link Prefetch Mode */
- abcfg_reg(0x80, 3 << 17, 3 << 17);
-
- /* 3.9 Enabling Detection of Upstream Interrupts */
- abcfg_reg(0x94, 1 << 20,1 << 20);
-
- /* 3.10: Enabling Downstream Posted Transactions to Pass Non-Posted
- * Transactions for the K8 Platform (for All Revisions) */
- abcfg_reg(0x10090, 1 << 8, 1 << 8);
-
- /* 3.11:Programming Cycle Delay for AB and BIF Clock Gating */
- /* 3.12: Enabling AB and BIF Clock Gating */
- abcfg_reg(0x10054, 0xFFFF0000, 0x1040000);
- abcfg_reg(0x54, 0xFF << 16, 4 << 16);
- printk(BIOS_INFO, "3.11, ABCFG:0x54\n");
- abcfg_reg(0x54, 1 << 24, 1 << 24);
- printk(BIOS_INFO, "3.12, ABCFG:0x54\n");
- abcfg_reg(0x98, 0x0000FF00, 0x00004700);
-
- /* 3.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */
- abcfg_reg(0x10054, 0x0000FFFF, 0x07FF);
-
- /* 3.14:Enabling L1 on A-link Express */
- axcfg_reg(0x68, 0x00000003, 0x2);
- axindxp_reg(0xa0, 0x0000F000, 0x6000);
-
- abcfg_reg(0x10098, 0xFFFFFFFF, 0x4000);
- abcfg_reg(0x04, 0xFFFFFFFF, 0x6);
- printk(BIOS_INFO, "sm_init() end\n");
-
- /* Enable NbSb virtual channel */
- axcfg_reg(0x114, 0x3f << 1, 0 << 1);
- axcfg_reg(0x120, 0x7f << 1, 0x7f << 1);
- axcfg_reg(0x120, 7 << 24, 1 << 24);
- axcfg_reg(0x120, 1 << 31, 1 << 31);
- abcfg_reg(0x50, 1 << 3, 1 << 3);
-}
-
-static int lsmbus_recv_byte(device_t dev)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x10);
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, u8 val)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x10);
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x10);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x10);
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-static void sb600_sm_read_resources(device_t dev)
-{
- struct resource *res;
- u8 byte;
-
- /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
- byte = pm_ioread(0x55);
- byte |= 1 << 7;
- pm_iowrite(0x55, byte);
-
- /* Get the normal pci resources of this device */
- /* pci_dev_read_resources(dev); */
-
- byte = pm_ioread(0x55);
- byte &= ~(1 << 7);
- pm_iowrite(0x55, byte);
-
- /* apic */
- res = new_resource(dev, 0x74);
- res->base = IO_APIC_ADDR;
- res->size = 256 * 0x10;
- res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
-
- res = new_resource(dev, 0x14); /* hpet */
- res->base = 0xfed00000; /* reset hpet to widely accepted address */
- res->size = 0x400;
- res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
- /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
-
- /* smbus */
- res = new_resource(dev, 0x10);
- res->base = 0xB00;
- res->size = 0x10;
- res->limit = 0xFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
-
- compact_resources(dev);
-
-}
-
-static void sb600_sm_set_resources(struct device *dev)
-{
- struct resource *res;
- u8 byte;
-
- pci_dev_set_resources(dev);
-
- /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */
- byte = pm_ioread(0x52);
- byte |= 1 << 6;
- pm_iowrite(0x52, byte);
-
- res = find_resource(dev, 0x74);
- pci_write_config32(dev, 0x74, res->base | 1 << 3);
-
- res = find_resource(dev, 0x14);
- pci_write_config32(dev, 0x14, res->base);
-
- res = find_resource(dev, 0x10);
- pci_write_config32(dev, 0x10, res->base | 1);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = sb600_sm_read_resources,
- .set_resources = sb600_sm_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sm_init,
- .scan_bus = scan_static_bus,
- /* .enable = sb600_enable, */
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_SM,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "sb600_smbus.h"
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(u32 smbus_io_base)
-{
- u32 loops;
- loops = SMBUS_TIMEOUT;
- do {
- u8 val;
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f;
- if (val == 0) { /* ready now */
- return 0;
- }
- outb(val, smbus_io_base + SMBHSTSTAT);
- } while (--loops);
- return -2; /* time out */
-}
-
-static int smbus_wait_until_done(u32 smbus_io_base)
-{
- u32 loops;
- loops = SMBUS_TIMEOUT;
- do {
- u8 val;
-
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f; /* mask off reserved bits */
- if (val & 0x1c) {
- return -5; /* error */
- }
- if (val == 0x02) {
- outb(val, smbus_io_base + SMBHSTSTAT); /* clear status */
- return 0;
- }
- } while (--loops);
- return -3; /* timeout */
-}
-
-int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTCMD);
-
- return byte;
-}
-
-int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command... */
- outb(val, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- return 0;
-}
-
-int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- return byte;
-}
-
-int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
-
- /* output value */
- outb(val, smbus_io_base + SMBHSTDAT0);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- return 0;
-}
-
-static void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
-{
- u32 tmp;
-
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
- tmp = inl(AB_DATA);
-
- tmp &= ~mask;
- tmp |= val;
-
- /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
- outl(tmp, AB_DATA);
-}
-
-/* space = 0: AX_INDXC, AX_DATAC
-* space = 1: AX_INDXP, AX_DATAP
- */
-static void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
- u32 mask, u32 val)
-{
- u32 tmp;
-
- /* read axindc to tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- tmp = inl(AB_DATA);
-
- tmp &= ~mask;
- tmp |= val;
-
- /* write tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- outl(tmp, AB_DATA);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef SB600_SMBUS_H
-#define SB600_SMBUS_H
-
-#define SMBHSTSTAT 0x0
-#define SMBSLVSTAT 0x1
-#define SMBHSTCTRL 0x2
-#define SMBHSTCMD 0x3
-#define SMBHSTADDR 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBHSTBLKDAT 0x7
-
-#define SMBSLVCTRL 0x8
-#define SMBSLVCMD_SHADOW 0x9
-#define SMBSLVEVT 0xa
-#define SMBSLVDAT 0xc
-
-#define AX_INDXC 0
-#define AX_INDXP 1
-#define AXCFG 2
-#define ABCFG 3
-
-#define AB_INDX 0xCD8
-#define AB_DATA (AB_INDX+4)
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100*1000*10)
-
-#define abcfg_reg(reg, mask, val) \
- alink_ab_indx((ABCFG), (reg), (mask), (val))
-#define axcfg_reg(reg, mask, val) \
- alink_ab_indx((AXCFG), (reg), (mask), (val))
-#define axindxc_reg(reg, mask, val) \
- alink_ax_indx(0, (reg), (mask), (val))
-#define axindxp_reg(reg, mask, val) \
- alink_ax_indx(1, (reg), (mask), (val))
-
-int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
-int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
-int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
-int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
-
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <usbdebug.h>
-#include <arch/io.h>
-#include "sb600.h"
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static void usb_init(struct device *dev)
-{
- u8 byte;
- u16 word;
- u32 dword;
-
- /* Enable OHCI0-4 and EHCI Controllers */
- device_t sm_dev;
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- byte = pci_read_config8(sm_dev, 0x68);
- byte |= 0x3F;
- pci_write_config8(sm_dev, 0x68, byte);
-
- /* RPR 5.2 Enables the USB PME Event,Enable USB resume support */
- byte = pm_ioread(0x61);
- byte |= 1 << 6;
- pm_iowrite(0x61, byte);
- byte = pm_ioread(0x65);
- byte |= 1 << 2;
- pm_iowrite(0x65, byte);
-
- /* RPR 5.3 Support USB device wakeup from the S4/S5 state */
- byte = pm_ioread(0x65);
- byte &= ~(1 << 0);
- pm_iowrite(0x65, byte);
-
- /* RPR 5.6 Enable the USB controller to get reset by any software that generate a PCIRst# condition */
- byte = pm_ioread(0x65);
- byte |= (1 << 4);
- pm_iowrite(0x65, byte);
-
- /* RPR 5.11 Disable OHCI MSI Capability */
- word = pci_read_config16(dev, 0x40);
- word |= (0x1F << 8);
- pci_write_config16(dev, 0x40, word);
-
- /* RPR 5.8 Disable the OHCI Dynamic Power Saving feature */
- dword = pci_read_config32(dev, 0x50);
- dword &= ~(1 << 16);
- pci_write_config32(dev, 0x50, dword);
-
- /* RPR 5.12 Enable prevention of OHCI accessing the invalid system memory address range */
- word = pci_read_config16(dev, 0x50);
- word |= 1 << 15;
- pci_write_config16(dev, 0x50, word);
-
- /* RPR 5.15 Disable SMI handshake in between USB and ACPI for USB legacy support. */
- /* The BIOS should always set this bit to prevent the malfunction on USB legacy keyboard/mouse support */
- word = pci_read_config16(dev, 0x50);
- word |= 1 << 12;
- pci_write_config16(dev, 0x50, word);
-}
-
-static void usb_init2(struct device *dev)
-{
- u8 byte;
- u16 word;
- u32 dword;
- u32 usb2_bar0;
- /* dword = pci_read_config32(dev, 0xf8); */
- /* dword |= 40; */
- /* pci_write_config32(dev, 0xf8, dword); */
-
- usb2_bar0 = pci_read_config32(dev, 0x10) & ~0xFF;
- printk(BIOS_INFO, "usb2_bar0=0x%x\n", usb2_bar0);
-
- /* RPR5.4 Enables the USB PHY auto calibration resister to match 45ohm resistance */
- dword = 0x00020F00;
- write32(usb2_bar0 + 0xC0, dword);
-
- /* RPR5.5 Sets In/OUT FIFO threshold for best performance */
- dword = 0x00200040;
- write32(usb2_bar0 + 0xA4, dword);
-
- /* RPR5.9 Disable the EHCI Dynamic Power Saving feature */
- word = read16(usb2_bar0 + 0xBC);
- word &= ~(1 << 12);
- write16(usb2_bar0 + 0xBC, word);
-
- /* RPR5.10 Disable EHCI MSI support */
- byte = pci_read_config8(dev, 0x50);
- byte |= (1 << 6);
- pci_write_config8(dev, 0x50, byte);
-
- /* RPR5.13 Disable C3 time enhancement feature */
- dword = pci_read_config32(dev, 0x50);
- dword &= ~(1 << 28);
- pci_write_config32(dev, 0x50, dword);
-
- /* RPR5.14 Disable USB PHY PLL Reset signal to come from ACPI */
- byte = pci_read_config8(dev, 0x54);
- byte &= ~(1 << 0);
- pci_write_config8(dev, 0x54, byte);
-}
-
-static void usb_set_resources(struct device *dev)
-{
-#if CONFIG_USBDEBUG
- struct resource *res;
- u32 base;
- u32 old_debug;
-
- old_debug = get_ehci_debug();
- set_ehci_debug(0);
-#endif
- pci_dev_set_resources(dev);
-
-#if CONFIG_USBDEBUG
- res = find_resource(dev, 0x10);
- set_ehci_debug(old_debug);
- if (!res)
- return;
- base = res->base;
- set_ehci_base(base);
- report_resource_stored(dev, res, "");
-#endif
-
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb_set_resources, /* pci_dev_set_resources, */
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- /*.enable = sb600_enable, */
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_0_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB_0,
-};
-static const struct pci_driver usb_1_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB_1,
-};
-static const struct pci_driver usb_2_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB_2,
-};
-static const struct pci_driver usb_3_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB_3,
-};
-static const struct pci_driver usb_4_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB_4,
-};
-
-static struct device_operations usb_ops2 = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb_set_resources, /* pci_dev_set_resources, */
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init2,
- /*.enable = sb600_enable, */
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_5_driver __pci_driver = {
- .ops = &usb_ops2,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB600_USB2,
-};
-
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <pc80/mc146818rtc.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <cpu/x86/lapic.h>
+#include <arch/ioapic.h>
+#include <stdlib.h>
+#include "sb600.h"
+#include "smbus.c"
+
+#define NMI_OFF 0
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+/*
+* SB600 enables all USB controllers by default in SMBUS Control.
+* SB600 enables SATA by default in SMBUS Control.
+*/
+static void sm_init(device_t dev)
+{
+ u8 byte;
+ u8 byte_old;
+ u32 dword;
+ u32 ioapic_base;
+ u32 on;
+ u32 nmi_option;
+
+ printk(BIOS_INFO, "sm_init().\n");
+
+ ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */
+ /* Don't rename APIC ID */
+ clear_ioapic(ioapic_base);
+
+ dword = pci_read_config8(dev, 0x62);
+ dword |= 1 << 2;
+ pci_write_config8(dev, 0x62, dword);
+
+ dword = pci_read_config32(dev, 0x78);
+ dword |= 1 << 9;
+ pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */
+
+ /* bit 10: MultiMediaTimerIrqEn */
+ dword = pci_read_config8(dev, 0x64);
+ dword |= 1 << 10;
+ pci_write_config8(dev, 0x64, dword);
+ /* enable serial irq */
+ byte = pci_read_config8(dev, 0x69);
+ byte |= 1 << 7; /* enable serial irq function */
+ byte &= ~(0xF << 2);
+ byte |= 4 << 2; /* set NumSerIrqBits=4 */
+ pci_write_config8(dev, 0x69, byte);
+
+ byte = pm_ioread(0x61);
+ byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */
+ pm_iowrite(0x61, byte);
+
+ /* disable SMI */
+ byte = pm_ioread(0x53);
+ byte |= 1 << 3;
+ pm_iowrite(0x53, byte);
+
+ /* power after power fail */
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pm_ioread(0x74);
+ byte &= ~0x03;
+ if (on) {
+ byte |= 2;
+ }
+ byte |= 1 << 2;
+ pm_iowrite(0x74, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
+
+ /* sb600 rpr:2.3.3: */
+ byte = pm_ioread(0x9A);
+ byte |= 1 << 5 | 1 << 4 | 1 << 2;
+ pm_iowrite(0x9A, byte);
+
+ byte = pm_ioread(0x8F);
+ byte |= 1 << 5;
+ byte &= ~(1 << 4);
+ pm_iowrite(0x8F, byte);
+
+ pm_iowrite(0x8B, 0x01);
+ pm_iowrite(0x8A, 0x90);
+ pm_iowrite(0x88, 0x10); /* A21 */
+
+ byte = pm_ioread(0x7C);
+ byte |= 1 << 0;
+ pm_iowrite(0x7C, byte);
+
+ byte = pm_ioread(0x68);
+ byte &= ~(1 << 1);
+ /* 2.6 */
+ byte |= 1 << 2;
+ pm_iowrite(0x68, byte);
+
+ /* 2.6 */
+ byte = pm_ioread(0x65);
+ byte &= ~(1 << 7);
+ pm_iowrite(0x65, byte);
+
+ /* 2.3.4 */
+ byte = pm_ioread(0x52);
+ byte &= ~0x2F;
+ byte |= 0x8;
+ pm_iowrite(0x52, byte);
+
+ byte = pm_ioread(0x8D);
+ byte &= ~(1 << 6);
+ pm_iowrite(0x8D, byte);
+
+ byte = pm_ioread(0x61);
+ byte &= ~(1 << 2);
+ pm_iowrite(0x61, byte);
+
+ byte = pm_ioread(0x42);
+ byte &= ~(1 << 2);
+ pm_iowrite(0x42, byte);
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); /* RTC70 */
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ printk(BIOS_INFO, "++++++++++set NMI+++++\n");
+ } else {
+ byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */
+ printk(BIOS_INFO, "++++++++++no set NMI+++++\n");
+ }
+ byte &= ~(1 << 7);
+ if (byte != byte_old) {
+ outb(byte, 0x70);
+ }
+
+ /* 2.10 IO Trap Settings */
+ abcfg_reg(0x10090, 1 << 16, 1 << 16);
+
+ /* ab index */
+ pci_write_config32(dev, 0xF0, AB_INDX);
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /*3.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */
+ abcfg_reg(0x10060, 9 << 17, 9 << 17);
+ abcfg_reg(0x10064, 9 << 17, 9 << 17);
+
+ /* 3.5 Enabling OHCI Prefetch for Performance Enhancement */
+ abcfg_reg(0x80, 1 << 0, 1<< 0);
+
+ /* 3.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */
+ /* 3.7 Enabling Additional Address Bits Checking in Downstream */
+ abcfg_reg(0x9c, 3 << 0, 3 << 0);
+
+ /* 3.8 Set B-Link Prefetch Mode */
+ abcfg_reg(0x80, 3 << 17, 3 << 17);
+
+ /* 3.9 Enabling Detection of Upstream Interrupts */
+ abcfg_reg(0x94, 1 << 20,1 << 20);
+
+ /* 3.10: Enabling Downstream Posted Transactions to Pass Non-Posted
+ * Transactions for the K8 Platform (for All Revisions) */
+ abcfg_reg(0x10090, 1 << 8, 1 << 8);
+
+ /* 3.11:Programming Cycle Delay for AB and BIF Clock Gating */
+ /* 3.12: Enabling AB and BIF Clock Gating */
+ abcfg_reg(0x10054, 0xFFFF0000, 0x1040000);
+ abcfg_reg(0x54, 0xFF << 16, 4 << 16);
+ printk(BIOS_INFO, "3.11, ABCFG:0x54\n");
+ abcfg_reg(0x54, 1 << 24, 1 << 24);
+ printk(BIOS_INFO, "3.12, ABCFG:0x54\n");
+ abcfg_reg(0x98, 0x0000FF00, 0x00004700);
+
+ /* 3.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */
+ abcfg_reg(0x10054, 0x0000FFFF, 0x07FF);
+
+ /* 3.14:Enabling L1 on A-link Express */
+ axcfg_reg(0x68, 0x00000003, 0x2);
+ axindxp_reg(0xa0, 0x0000F000, 0x6000);
+
+ abcfg_reg(0x10098, 0xFFFFFFFF, 0x4000);
+ abcfg_reg(0x04, 0xFFFFFFFF, 0x6);
+ printk(BIOS_INFO, "sm_init() end\n");
+
+ /* Enable NbSb virtual channel */
+ axcfg_reg(0x114, 0x3f << 1, 0 << 1);
+ axcfg_reg(0x120, 0x7f << 1, 0x7f << 1);
+ axcfg_reg(0x120, 7 << 24, 1 << 24);
+ axcfg_reg(0x120, 1 << 31, 1 << 31);
+ abcfg_reg(0x50, 1 << 3, 1 << 3);
+}
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x10);
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, u8 val)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x10);
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x10);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x10);
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static void sb600_sm_read_resources(device_t dev)
+{
+ struct resource *res;
+ u8 byte;
+
+ /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
+ byte = pm_ioread(0x55);
+ byte |= 1 << 7;
+ pm_iowrite(0x55, byte);
+
+ /* Get the normal pci resources of this device */
+ /* pci_dev_read_resources(dev); */
+
+ byte = pm_ioread(0x55);
+ byte &= ~(1 << 7);
+ pm_iowrite(0x55, byte);
+
+ /* apic */
+ res = new_resource(dev, 0x74);
+ res->base = IO_APIC_ADDR;
+ res->size = 256 * 0x10;
+ res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 0x14); /* hpet */
+ res->base = 0xfed00000; /* reset hpet to widely accepted address */
+ res->size = 0x400;
+ res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+ /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
+
+ /* smbus */
+ res = new_resource(dev, 0x10);
+ res->base = 0xB00;
+ res->size = 0x10;
+ res->limit = 0xFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
+
+ compact_resources(dev);
+
+}
+
+static void sb600_sm_set_resources(struct device *dev)
+{
+ struct resource *res;
+ u8 byte;
+
+ pci_dev_set_resources(dev);
+
+ /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */
+ byte = pm_ioread(0x52);
+ byte |= 1 << 6;
+ pm_iowrite(0x52, byte);
+
+ res = find_resource(dev, 0x74);
+ pci_write_config32(dev, 0x74, res->base | 1 << 3);
+
+ res = find_resource(dev, 0x14);
+ pci_write_config32(dev, 0x14, res->base);
+
+ res = find_resource(dev, 0x10);
+ pci_write_config32(dev, 0x10, res->base | 1);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = sb600_sm_read_resources,
+ .set_resources = sb600_sm_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sm_init,
+ .scan_bus = scan_static_bus,
+ /* .enable = sb600_enable, */
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_SM,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "smbus.h"
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(u32 smbus_io_base)
+{
+ u32 loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ u8 val;
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0) { /* ready now */
+ return 0;
+ }
+ outb(val, smbus_io_base + SMBHSTSTAT);
+ } while (--loops);
+ return -2; /* time out */
+}
+
+static int smbus_wait_until_done(u32 smbus_io_base)
+{
+ u32 loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ u8 val;
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f; /* mask off reserved bits */
+ if (val & 0x1c) {
+ return -5; /* error */
+ }
+ if (val == 0x02) {
+ outb(val, smbus_io_base + SMBHSTSTAT); /* clear status */
+ return 0;
+ }
+ } while (--loops);
+ return -3; /* timeout */
+}
+
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ return byte;
+}
+
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ return 0;
+}
+
+int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ return byte;
+}
+
+int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+ /* output value */
+ outb(val, smbus_io_base + SMBHSTDAT0);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ return 0;
+}
+
+static void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
+ tmp = inl(AB_DATA);
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
+ outl(tmp, AB_DATA);
+}
+
+/* space = 0: AX_INDXC, AX_DATAC
+* space = 1: AX_INDXP, AX_DATAP
+ */
+static void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
+ u32 mask, u32 val)
+{
+ u32 tmp;
+
+ /* read axindc to tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ tmp = inl(AB_DATA);
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* write tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ outl(tmp, AB_DATA);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SB600_SMBUS_H
+#define SB600_SMBUS_H
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTRL 0x2
+#define SMBHSTCMD 0x3
+#define SMBHSTADDR 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBHSTBLKDAT 0x7
+
+#define SMBSLVCTRL 0x8
+#define SMBSLVCMD_SHADOW 0x9
+#define SMBSLVEVT 0xa
+#define SMBSLVDAT 0xc
+
+#define AX_INDXC 0
+#define AX_INDXP 1
+#define AXCFG 2
+#define ABCFG 3
+
+#define AB_INDX 0xCD8
+#define AB_DATA (AB_INDX+4)
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+#define abcfg_reg(reg, mask, val) \
+ alink_ab_indx((ABCFG), (reg), (mask), (val))
+#define axcfg_reg(reg, mask, val) \
+ alink_ab_indx((AXCFG), (reg), (mask), (val))
+#define axindxc_reg(reg, mask, val) \
+ alink_ax_indx(0, (reg), (mask), (val))
+#define axindxp_reg(reg, mask, val) \
+ alink_ax_indx(1, (reg), (mask), (val))
+
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
+int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
+int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
+
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <usbdebug.h>
+#include <arch/io.h>
+#include "sb600.h"
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static void usb_init(struct device *dev)
+{
+ u8 byte;
+ u16 word;
+ u32 dword;
+
+ /* Enable OHCI0-4 and EHCI Controllers */
+ device_t sm_dev;
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ byte = pci_read_config8(sm_dev, 0x68);
+ byte |= 0x3F;
+ pci_write_config8(sm_dev, 0x68, byte);
+
+ /* RPR 5.2 Enables the USB PME Event,Enable USB resume support */
+ byte = pm_ioread(0x61);
+ byte |= 1 << 6;
+ pm_iowrite(0x61, byte);
+ byte = pm_ioread(0x65);
+ byte |= 1 << 2;
+ pm_iowrite(0x65, byte);
+
+ /* RPR 5.3 Support USB device wakeup from the S4/S5 state */
+ byte = pm_ioread(0x65);
+ byte &= ~(1 << 0);
+ pm_iowrite(0x65, byte);
+
+ /* RPR 5.6 Enable the USB controller to get reset by any software that generate a PCIRst# condition */
+ byte = pm_ioread(0x65);
+ byte |= (1 << 4);
+ pm_iowrite(0x65, byte);
+
+ /* RPR 5.11 Disable OHCI MSI Capability */
+ word = pci_read_config16(dev, 0x40);
+ word |= (0x1F << 8);
+ pci_write_config16(dev, 0x40, word);
+
+ /* RPR 5.8 Disable the OHCI Dynamic Power Saving feature */
+ dword = pci_read_config32(dev, 0x50);
+ dword &= ~(1 << 16);
+ pci_write_config32(dev, 0x50, dword);
+
+ /* RPR 5.12 Enable prevention of OHCI accessing the invalid system memory address range */
+ word = pci_read_config16(dev, 0x50);
+ word |= 1 << 15;
+ pci_write_config16(dev, 0x50, word);
+
+ /* RPR 5.15 Disable SMI handshake in between USB and ACPI for USB legacy support. */
+ /* The BIOS should always set this bit to prevent the malfunction on USB legacy keyboard/mouse support */
+ word = pci_read_config16(dev, 0x50);
+ word |= 1 << 12;
+ pci_write_config16(dev, 0x50, word);
+}
+
+static void usb_init2(struct device *dev)
+{
+ u8 byte;
+ u16 word;
+ u32 dword;
+ u32 usb2_bar0;
+ /* dword = pci_read_config32(dev, 0xf8); */
+ /* dword |= 40; */
+ /* pci_write_config32(dev, 0xf8, dword); */
+
+ usb2_bar0 = pci_read_config32(dev, 0x10) & ~0xFF;
+ printk(BIOS_INFO, "usb2_bar0=0x%x\n", usb2_bar0);
+
+ /* RPR5.4 Enables the USB PHY auto calibration resister to match 45ohm resistance */
+ dword = 0x00020F00;
+ write32(usb2_bar0 + 0xC0, dword);
+
+ /* RPR5.5 Sets In/OUT FIFO threshold for best performance */
+ dword = 0x00200040;
+ write32(usb2_bar0 + 0xA4, dword);
+
+ /* RPR5.9 Disable the EHCI Dynamic Power Saving feature */
+ word = read16(usb2_bar0 + 0xBC);
+ word &= ~(1 << 12);
+ write16(usb2_bar0 + 0xBC, word);
+
+ /* RPR5.10 Disable EHCI MSI support */
+ byte = pci_read_config8(dev, 0x50);
+ byte |= (1 << 6);
+ pci_write_config8(dev, 0x50, byte);
+
+ /* RPR5.13 Disable C3 time enhancement feature */
+ dword = pci_read_config32(dev, 0x50);
+ dword &= ~(1 << 28);
+ pci_write_config32(dev, 0x50, dword);
+
+ /* RPR5.14 Disable USB PHY PLL Reset signal to come from ACPI */
+ byte = pci_read_config8(dev, 0x54);
+ byte &= ~(1 << 0);
+ pci_write_config8(dev, 0x54, byte);
+}
+
+static void usb_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+ struct resource *res;
+ u32 base;
+ u32 old_debug;
+
+ old_debug = get_ehci_debug();
+ set_ehci_debug(0);
+#endif
+ pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+ res = find_resource(dev, 0x10);
+ set_ehci_debug(old_debug);
+ if (!res)
+ return;
+ base = res->base;
+ set_ehci_base(base);
+ report_resource_stored(dev, res, "");
+#endif
+
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb_set_resources, /* pci_dev_set_resources, */
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ /*.enable = sb600_enable, */
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_0_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB_0,
+};
+static const struct pci_driver usb_1_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB_1,
+};
+static const struct pci_driver usb_2_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB_2,
+};
+static const struct pci_driver usb_3_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB_3,
+};
+static const struct pci_driver usb_4_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB_4,
+};
+
+static struct device_operations usb_ops2 = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb_set_resources, /* pci_dev_set_resources, */
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init2,
+ /*.enable = sb600_enable, */
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_5_driver __pci_driver = {
+ .ops = &usb_ops2,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB600_USB2,
+};
+
driver-y += sb700.c
-driver-y += sb700_usb.c
-driver-y += sb700_lpc.c
-driver-y += sb700_sm.c
-driver-y += sb700_ide.c
-driver-y += sb700_sata.c
-driver-y += sb700_hda.c
-driver-y += sb700_pci.c
-ramstage-y += sb700_reset.c
-romstage-y += sb700_enable_usbdebug.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += sm.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += hda.c
+driver-y += pci.c
+ramstage-y += reset.c
+romstage-y += enable_usbdebug.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SB700_EARLY_SETUP_C_
+#define _SB700_EARLY_SETUP_C_
+
+#include <reset.h>
+#include <arch/cpu.h>
+#include "sb700.h"
+#include "smbus.c"
+
+#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */
+ /*SIZE 0x40 */
+
+static void pmio_write(u8 reg, u8 value)
+{
+ outb(reg, PM_INDEX);
+ outb(value, PM_INDEX + 1);
+}
+
+static u8 pmio_read(u8 reg)
+{
+ outb(reg, PM_INDEX);
+ return inb(PM_INDEX + 1);
+}
+
+/* RPR 2.28: Get SB ASIC Revision. */
+static u8 set_sb700_revision(void)
+{
+ device_t dev;
+ u8 rev_id, enable_14Mhz, byte;
+ u8 rev = 0;
+
+ /* if (rev != 0) return rev; */
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ /* NOT REACHED */
+ }
+ rev_id = pci_read_config8(dev, 0x08);
+
+ if (rev_id == 0x39) {
+ enable_14Mhz = (pmio_read(0x53) >> 6) & 1;
+ if (enable_14Mhz == 0x0)
+ rev = 0x11; /* A11 */
+ else if (enable_14Mhz == 0x1) {
+ /* This happens, if does, only once. So later if we need to get
+ * the revision ID, we don't have to make such a big function.
+ * We just get reg 0x8 in smbus dev. 0x39 is A11, 0x3A is A12. */
+ rev = 0x12;
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x40, byte);
+
+ pci_write_config8(dev, 0x08, 0x3A); /* Change 0x39 to 0x3A. */
+
+ byte &= ~(1 << 0);
+ pci_write_config8(dev, 0x40, byte);
+ }
+ } else if (rev_id == 0x3A) { /* A12 will be 0x3A after BIOS is initialized */
+ rev = 0x12;
+ } else if (rev_id == 0x3C) {
+ rev = 0x14;
+ } else if (rev_id == 0x3D) {
+ rev = 0x15;
+ } else
+ die("It is not SB700 or SB710\n");
+
+ return rev;
+}
+
+/***************************************
+* Legacy devices are mapped to LPC space.
+* Serial port 0
+* KBC Port
+* ACPI Micro-controller port
+* LPC ROM size
+* This function does not change port 0x80 decoding.
+* Console output through any port besides 0x3f8 is unsupported.
+* If you use FWH ROMs, you have to setup IDSEL.
+***************************************/
+static void sb700_lpc_init(void)
+{
+ u8 reg8;
+ u32 reg32;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); /* SMBUS controller */
+ /* NOTE: Set BootTimerDisable, otherwise it would keep rebooting!!
+ * This bit has no meaning if debug strap is not enabled. So if the
+ * board keeps rebooting and the code fails to reach here, we could
+ * disable the debug strap first. */
+ reg32 = pci_read_config32(dev, 0x4C);
+ reg32 |= 1 << 31;
+ pci_write_config32(dev, 0x4C, reg32);
+
+ /* Enable lpc controller */
+ reg32 = pci_read_config32(dev, 0x64);
+ reg32 |= 1 << 20;
+ pci_write_config32(dev, 0x64, reg32);
+
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
+ /* Decode port 0x3f8-0x3ff (Serial 0) */
+ // XXX Serial port decode on LPC is hardcoded to 0x3f8
+ reg8 = pci_read_config8(dev, 0x44);
+ reg8 |= 1 << 6;
+ pci_write_config8(dev, 0x44, reg8);
+
+ /* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
+ reg8 = pci_read_config8(dev, 0x47);
+ reg8 |= (1 << 5) | (1 << 6);
+ pci_write_config8(dev, 0x47, reg8);
+
+ /* Enable PrefetchEnSPIFromHost to speed up SPI flash read (does not affect LPC) */
+ reg8 = pci_read_config8(dev, 0xbb);
+ reg8 |= 1 << 0;
+ pci_write_config8(dev, 0xbb, reg8);
+
+ /* SuperIO, LPC ROM */
+ reg8 = pci_read_config8(dev, 0x48);
+ /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
+ reg8 |= (1 << 1) | (1 << 0);
+ /* Decode variable LPC ROM address ranges 1&2 (see register 0x68-0x6b, 0x6c-0x6f) */
+ reg8 |= (1 << 3) | (1 << 4);
+ /* Decode port 0x70-0x73 (RTC) */
+ reg8 |= 1 << 6;
+ pci_write_config8(dev, 0x48, reg8);
+
+ /* hardware should enable LPC ROM by pin straps */
+ /* ROM access at 0xFFF80000/0xFFF00000 - 0xFFFFFFFF */
+ /* See detail in 43366_sb700_bdg_nda_1.01.pdf page 17. */
+ /* enable LPC ROM range mirroring start 0x000e(0000) */
+ pci_write_config16(dev, 0x68, 0x000e);
+ /* enable LPC ROM range mirroring end 0x000f(ffff) */
+ pci_write_config16(dev, 0x6a, 0x000f);
+ /* enable LPC ROM range start, 0xfff8(0000): 512KB, 0xfff0(0000): 1MB */
+ pci_write_config16(dev, 0x6c, 0xfff0);
+ /* enable LPC ROM range end at 0xffff(ffff) */
+ pci_write_config16(dev, 0x6e, 0xffff);
+}
+
+/* what is its usage? */
+static u32 get_sbdn(u32 bus)
+{
+ device_t dev;
+
+ /* Find the device. */
+ dev = pci_locate_device_on_bus(PCI_ID(0x1002, 0x4385), bus);
+ return (dev >> 15) & 0x1f;
+}
+
+static u8 dual_core(void)
+{
+ return (pci_read_config32(PCI_DEV(0, 0x18, 3), 0xE8) & (0x3<<12)) != 0;
+}
+
+/*
+ * RPR 2.4 C-state and VID/FID change for the K8 platform.
+ */
+static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
+{
+ u8 byte;
+ byte = pmio_read(0x9a);
+ byte &= ~0x34;
+ if (dual_core())
+ byte |= 0x34;
+ else
+ byte |= 0x04;
+ pmio_write(0x9a, byte);
+
+ byte = pmio_read(0x8f);
+ byte &= ~0x30;
+ byte |= 0x20;
+ pmio_write(0x8f, byte);
+
+ pmio_write(0x8b, 0x01); /* TODO: if the HT Link is 200 MHz, it is 0x0A. It doesnt often happen. */
+ pmio_write(0x8a, 0x90);
+
+ pmio_write(0x88, 0x10);
+
+ byte = pmio_read(0x7c);
+ byte |= 0x03;
+ pmio_write(0x7c, byte);
+
+ /* Must be 0 for K8 platform. */
+ byte = pmio_read(0x68);
+ byte &= ~0x01;
+ pmio_write(0x68, byte);
+ /* Must be 0 for K8 platform. */
+ byte = pmio_read(0x8d);
+ byte &= ~(1<<6);
+ pmio_write(0x8d, byte);
+
+ byte = pmio_read(0x61);
+ byte &= ~0x04;
+ pmio_write(0x61, byte);
+
+ byte = pmio_read(0x42);
+ byte &= ~0x04;
+ pmio_write(0x42, byte);
+
+ pmio_write(0x89, 0x10);
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+ /* link reset */
+ outb(0x06, 0x0cf9);
+}
+
+void sb700_pci_port80(void)
+{
+ u8 byte;
+ device_t dev;
+
+ /* P2P Bridge */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
+
+ /* Chip Control: Enable subtractive decoding */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 5;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 7;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* The same IO Base and IO Limit here is meaningful because we set the
+ * bridge to be subtractive. During early setup stage, we have to make
+ * sure that data can go through port 0x80.
+ */
+ /* IO Base: 0xf000 */
+ byte = pci_read_config8(dev, 0x1C);
+ byte |= 0xF << 4;
+ pci_write_config8(dev, 0x1C, byte);
+
+ /* IO Limit: 0xf000 */
+ byte = pci_read_config8(dev, 0x1D);
+ byte |= 0xF << 4;
+ pci_write_config8(dev, 0x1D, byte);
+
+ /* PCI Command: Enable IO response */
+ byte = pci_read_config8(dev, 0x04);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x04, byte);
+
+ /* LPC controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
+
+ byte = pci_read_config8(dev, 0x4A);
+ byte &= ~(1 << 5); /* disable lpc port 80 */
+ pci_write_config8(dev, 0x4A, byte);
+}
+
+void sb700_lpc_port80(void)
+{
+ u8 byte;
+ device_t dev;
+ u32 reg32;
+
+ /* Enable LPC controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+ reg32 = pci_read_config32(dev, 0x64);
+ reg32 |= 0x00100000; /* lpcEnable */
+ pci_write_config32(dev, 0x64, reg32);
+
+ /* Enable port 80 LPC decode in pci function 3 configuration space. */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0);
+ byte = pci_read_config8(dev, 0x4a);
+ byte |= 1 << 5; /* enable port 80 */
+ pci_write_config8(dev, 0x4a, byte);
+}
+
+/* sbDevicesPorInitTable */
+static void sb700_devices_por_init(void)
+{
+ device_t dev;
+ u8 byte;
+
+ printk(BIOS_INFO, "sb700_devices_por_init()\n");
+ /* SMBus Device, BDF:0-20-0 */
+ printk(BIOS_INFO, "sb700_devices_por_init(): SMBus Device, BDF:0-20-0\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ /* NOT REACHED */
+ }
+ printk(BIOS_INFO, "SMBus controller enabled, sb revision is A%x\n",
+ set_sb700_revision());
+
+ /* sbPorAtStartOfTblCfg */
+ /* Set A-Link bridge access address. This address is set at device 14h, function 0, register 0xf0.
+ * This is an I/O address. The I/O address must be on 16-byte boundry. */
+ pci_write_config32(dev, 0xf0, AB_INDX);
+
+ /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */
+ /* 4.3:Enables the SB700 to send transactions upstream over A-Link Express interface. */
+ axcfg_reg(0x04, 1 << 2, 1 << 2);
+ axindxc_reg(0x21, 0xff, 0);
+
+ /* 2.5:Enabling Non-Posted Memory Write for the K8 Platform */
+ axindxc_reg(0x10, 1 << 9, 1 << 9);
+ /* END of sbPorAtStartOfTblCfg */
+
+ /* sbDevicesPorInitTables */
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
+
+ /* enable smbus controller interface */
+ byte = pci_read_config8(dev, 0xd2);
+ byte |= (1 << 0);
+ pci_write_config8(dev, 0xd2, byte);
+
+ /* KB2RstEnable */
+ pci_write_config8(dev, 0x40, 0x44);
+
+ /* Enable ISA Address 0-960K decoding */
+ pci_write_config8(dev, 0x48, 0x0f);
+
+ /* Enable ISA Address 0xC0000-0xDFFFF decode */
+ pci_write_config8(dev, 0x49, 0xff);
+
+ /* Enable decode cycles to IO C50, C51, C52 GPM controls. */
+ byte = pci_read_config8(dev, 0x41);
+ byte &= 0x80;
+ byte |= 0x33;
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Legacy DMA Prefetch Enhancement, CIM masked it. */
+ /* pci_write_config8(dev, 0x43, 0x1); */
+
+ /* Disabling Legacy USB Fast SMI# */
+ byte = pci_read_config8(dev, 0x62);
+ byte |= 0x24;
+ pci_write_config8(dev, 0x62, byte);
+
+ /* Features Enable */
+ pci_write_config32(dev, 0x64, 0x829E79BF); /* bit10: Enables the HPET interrupt. */
+
+ /* SerialIrq Control */
+ pci_write_config8(dev, 0x69, 0x90);
+
+ /* Test Mode, PCIB_SReset_En Mask is set. */
+ pci_write_config8(dev, 0x6c, 0x20);
+
+ /* IO Address Enable, CIM set 0x78 only and masked 0x79. */
+ /*pci_write_config8(dev, 0x79, 0x4F); */
+ pci_write_config8(dev, 0x78, 0xFF);
+
+ /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */
+ pci_write_config16(dev, 0x4, 0x0407);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* IDE Device, BDF:0-20-1 */
+ printk(BIOS_INFO, "sb700_devices_por_init(): IDE Device, BDF:0-20-1\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
+ /* Disable prefetch */
+ byte = pci_read_config8(dev, 0x63);
+ byte |= 0x1;
+ pci_write_config8(dev, 0x63, byte);
+
+ /* LPC Device, BDF:0-20-3 */
+ printk(BIOS_INFO, "sb700_devices_por_init(): LPC Device, BDF:0-20-3\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
+ /* DMA enable */
+ pci_write_config8(dev, 0x40, 0x04);
+
+ /* IO Port Decode Enable */
+ pci_write_config8(dev, 0x44, 0xFF);
+ pci_write_config8(dev, 0x45, 0xFF);
+ pci_write_config8(dev, 0x46, 0xC3);
+ pci_write_config8(dev, 0x47, 0xFF);
+
+ /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
+ * Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
+ * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65).
+ * Enable bits for LPC ROM memory address range 1&2 for 1M ROM setting.*/
+ byte = pci_read_config8(dev, 0x48);
+ byte |= (1 << 1) | (1 << 0); /* enable Super IO config port 2e-2h, 4e-4f */
+ byte |= (1 << 3) | (1 << 4); /* enable for LPC ROM address range1&2, Enable 512KB rom access at 0xFFF80000 - 0xFFFFFFFF */
+ byte |= 1 << 6; /* enable for RTC I/O range */
+ pci_write_config8(dev, 0x48, byte);
+ pci_write_config8(dev, 0x49, 0xFF);
+ /* Enable 0x480-0x4bf, 0x4700-0x470B */
+ byte = pci_read_config8(dev, 0x4A);
+ byte |= ((1 << 1) + (1 << 6)); /*0x42, save the configuraion for port 0x80. */
+ pci_write_config8(dev, 0x4A, byte);
+
+ /* Set LPC ROM size, it has been done in sb700_lpc_init().
+ * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB;
+ * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB
+ * pci_write_config16(dev, 0x68, 0x000e)
+ * pci_write_config16(dev, 0x6c, 0xfff0);*/
+
+ /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
+ pci_write_config8(dev, 0x7C, 0x05);
+
+ /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
+ */
+ printk(BIOS_INFO, "sb700_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
+
+ /* Arbiter enable. */
+ pci_write_config8(dev, 0x43, 0xff);
+
+ /* Set PCDMA request into hight priority list. */
+ /* pci_write_config8(dev, 0x49, 0x1) */ ;
+
+ pci_write_config8(dev, 0x40, 0x26);
+
+ pci_write_config8(dev, 0x0d, 0x40);
+ pci_write_config8(dev, 0x1b, 0x40);
+ /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
+ pci_write_config8(dev, 0x50, 0x01);
+
+ /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
+ printk(BIOS_INFO, "sb700_devices_por_init(): SATA Device, BDF:0-18-0\n");
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
+
+ /*PHY Global Control*/
+ pci_write_config16(dev, 0x86, 0x2C00);
+}
+
+/* sbPmioPorInitTable, Pre-initializing PMIO register space
+* The power management (PM) block is resident in the PCI/LPC/ISA bridge.
+* The PM regs are accessed via IO mapped regs 0xcd6 and 0xcd7.
+* The index address is first programmed into IO reg 0xcd6.
+* Read or write values are accessed through IO reg 0xcd7.
+*/
+static void sb700_pmio_por_init(void)
+{
+ u8 byte;
+
+ printk(BIOS_INFO, "sb700_pmio_por_init()\n");
+ /* K8KbRstEn, KB_RST# control for K8 system. */
+ byte = pmio_read(0x66);
+ byte |= 0x20;
+ pmio_write(0x66, byte);
+
+ /* RPR2.31 PM_TURN_OFF_MSG during ASF Shutdown. */
+ if (get_sb700_revision(pci_locate_device(PCI_ID(0x1002, 0x4385), 0)) <= 0x12) {
+ byte = pmio_read(0x65);
+ byte &= ~(1 << 7);
+ pmio_write(0x65, byte);
+
+ byte = pmio_read(0x75);
+ byte &= 0xc0;
+ byte |= 0x05;
+ pmio_write(0x75, byte);
+
+ byte = pmio_read(0x52);
+ byte &= 0xc0;
+ byte |= 0x08;
+ pmio_write(0x52, byte);
+ } else {
+ byte = pmio_read(0xD7);
+ byte |= 1 << 0;
+ pmio_write(0xD7, byte);
+
+ byte = pmio_read(0x65);
+ byte |= 1 << 7;
+ pmio_write(0x65, byte);
+
+ byte = pmio_read(0x75);
+ byte &= 0xc0;
+ byte |= 0x01;
+ pmio_write(0x75, byte);
+
+ byte = pmio_read(0x52);
+ byte &= 0xc0;
+ byte |= 0x02;
+ pmio_write(0x52, byte);
+
+ }
+
+ /* Watch Dog Timer Control
+ * Set watchdog time base to 0xfec000f0 to avoid SCSI card boot failure.
+ * But I don't find WDT is enabled in SMBUS 0x41 bit3 in CIM.
+ */
+ pmio_write(0x6c, 0xf0);
+ pmio_write(0x6d, 0x00);
+ pmio_write(0x6e, 0xc0);
+ pmio_write(0x6f, 0xfe);
+
+ /* rpr2.15: Enabling Spread Spectrum */
+ byte = pmio_read(0x42);
+ byte |= 1 << 7;
+ pmio_write(0x42, byte);
+ /* TODO: Check if it is necessary. IDE reset */
+ byte = pmio_read(0xB2);
+ byte |= 1 << 0;
+ pmio_write(0xB2, byte);
+}
+
+/*
+* Add any south bridge setting.
+*/
+static void sb700_pci_cfg(void)
+{
+ device_t dev;
+ u8 byte;
+
+ /* SMBus Device, BDF:0-20-0 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
+ /* Enable watchdog decode timer */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= (1 << 3);
+ pci_write_config8(dev, 0x41, byte);
+
+ /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
+ * generated PCIRST#. */
+ byte = pmio_read(0x65);
+ byte |= (1 << 4);
+ pmio_write(0x65, byte);
+
+ /* IDE Device, BDF:0-20-1 */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
+ /* Enable IDE Explicit prefetch, 0x63[0] clear */
+ byte = pci_read_config8(dev, 0x63);
+ byte &= 0xfe;
+ pci_write_config8(dev, 0x63, byte);
+
+ /* LPC Device, BDF:0-20-3 */
+ /* The code below is ported from old chipset. It is not
+ * mentioned in RPR. But I keep them. The registers and the
+ * comments are compatible. */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
+ /* Enabling LPC DMA function. */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+ /* Disabling LPC TimeOut. 0x48[7] clear. */
+ byte = pci_read_config8(dev, 0x48);
+ byte &= 0x7f;
+ pci_write_config8(dev, 0x48, byte);
+ /* Disabling LPC MSI Capability, 0x78[1] clear. */
+ byte = pci_read_config8(dev, 0x78);
+ byte &= 0xfd;
+ pci_write_config8(dev, 0x78, byte);
+
+ /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
+ dev = pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
+ /* rpr7.12 SATA MSI and D3 Power State Capability. */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x40, byte);
+ if (get_sb700_revision(pci_locate_device(PCI_ID(0x1002, 0x4385), 0)) <= 0x12)
+ pci_write_config8(dev, 0x34, 0x70); /* set 0x61 to 0x70 if S1 is not supported. */
+ else
+ pci_write_config8(dev, 0x34, 0x50); /* set 0x61 to 0x50 if S1 is not supported. */
+ byte &= ~(1 << 0);
+ pci_write_config8(dev, 0x40, byte);
+}
+
+/*
+*/
+static void sb700_por_init(void)
+{
+ /* sbDevicesPorInitTable + sbK8PorInitTable */
+ sb700_devices_por_init();
+
+ /* sbPmioPorInitTable + sbK8PmioPorInitTable */
+ sb700_pmio_por_init();
+}
+
+/*
+* It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
+*/
+static void sb700_before_pci_init(void)
+{
+ sb700_pci_cfg();
+}
+
+/*
+* This function should be called after enable_sb700_smbus().
+*/
+static void sb700_early_setup(void)
+{
+ printk(BIOS_INFO, "sb700_early_setup()\n");
+ sb700_por_init();
+}
+
+static int smbus_read_byte(u32 device, u32 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "sb700.h"
+
+#define EHCI_EOR (CONFIG_EHCI_BAR + 0x20)
+#define DEBUGPORT_MISC_CONTROL (EHCI_EOR + 0x80)
+
+void set_debug_port(unsigned int port)
+{
+ u32 reg32;
+
+ /* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
+ reg32 = read32(DEBUGPORT_MISC_CONTROL);
+ reg32 &= ~(0xf << 28);
+ reg32 |= (port << 28);
+ reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
+ write32(DEBUGPORT_MISC_CONTROL, reg32);
+}
+
+/*
+ * Note: The SB700 has two EHCI devices, D18:F2 and D19:F2.
+ * This code currently only supports the first one, i.e., USB Debug devices
+ * attached to physical USB ports belonging to the first EHCI device.
+ */
+void sb700_enable_usbdebug(unsigned int port)
+{
+ device_t dev = PCI_DEV(0, 0x12, 2); /* USB EHCI, D18:F2 */
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+
+ /*
+ * Select the requested physical USB port (1-15) as the Debug Port.
+ * Must be called after the EHCI BAR has been set up (see above).
+ */
+ set_debug_port(port);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "sb700.h"
+
+#define HDA_ICII_REG 0x68
+#define HDA_ICII_BUSY (1 << 0)
+#define HDA_ICII_VALID (1 << 1)
+
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 dword;
+ int count;
+
+ /* Write (val & ~mask) to port */
+ val &= mask;
+ dword = read32(port);
+ dword &= ~mask;
+ dword |= val;
+ write32(port, dword);
+
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
+ count = 50;
+ do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
+ dword = read32(port);
+ dword &= mask;
+ } while ((dword != val) && --count);
+
+ /* Timeout occured */
+ if (!count)
+ return -1;
+ return 0;
+}
+
+static u32 codec_detect(u32 base)
+{
+ u32 dword;
+
+ /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 0) == -1)
+ goto no_codec;
+
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 1) == -1)
+ goto no_codec;
+
+ /* Delay for 1 ms since the BKDG does */
+ mdelay(1);
+
+ /* Read in Codec location (BAR + 0xe)[3..0]*/
+ dword = read32(base + 0xe);
+ dword &= 0x0F;
+ if (!dword)
+ goto no_codec;
+
+ return dword;
+
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + 0x08, 1, 0);
+ printk(BIOS_DEBUG, "No codec!\n");
+ return 0;
+}
+
+/**
+ * Wait 50usec for the codec to indicate it is ready
+ * no response would imply that the codec is non-operative
+ */
+static int wait_for_ready(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+
+ while(timeout--) {
+ u32 dword=read32(base + HDA_ICII_REG);
+ if (!(dword & HDA_ICII_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Wait 50usec for the codec to indicate that it accepted
+ * the previous command. No response would imply that the code
+ * is non-operative
+ */
+static int wait_for_valid(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+ while(timeout--) {
+ u32 dword = read32(base + HDA_ICII_REG);
+ if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
+ HDA_ICII_VALID)
+ return 0;
+ udelay(1);
+ }
+
+ return 1;
+}
+
+static void codec_init(u32 base, int addr)
+{
+ u32 dword;
+
+ /* 1 */
+ if (wait_for_ready(base) == -1)
+ return;
+
+ dword = (addr << 28) | 0x000f0000;
+ write32(base + 0x60, dword);
+
+ if (wait_for_valid(base) == -1)
+ return;
+
+ dword = read32(base + 0x64);
+
+ /* 2 */
+ printk(BIOS_DEBUG, "%x(th) codec viddid: %08x\n", addr, dword);
+}
+
+static void codecs_init(u32 base, u32 codec_mask)
+{
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (codec_mask & (1 << i))
+ codec_init(base, i);
+ }
+}
+
+static void hda_init(struct device *dev)
+{
+ u8 byte;
+ u32 dword;
+ u32 base;
+ struct resource *res;
+ u32 codec_mask;
+ device_t sm_dev;
+
+ /* Enable azalia - PM_io 0x59[3], no ac97 in sb700. */
+ byte = pm_ioread(0x59);
+ byte |= 1 << 3;
+ pm_iowrite(0x59, byte);
+
+ /* Find the SMBus */
+ /* FIXME: Need to find out why the call below crashes. */
+ /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB700_SM, 0);*/
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+
+ /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
+ pci_write_config32(sm_dev, 0xf8, 0x00);
+ pci_write_config8(sm_dev, 0xfc, 0xAA);
+ /* Set INTA - SMBus 0x63 [2..0] */
+ byte = pci_read_config8(sm_dev, 0x63);
+ byte &= ~0x7;
+ byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
+ pci_write_config8(sm_dev, 0x63, byte);
+
+ /* Program the 2C to 0x437b1002 */
+ dword = 0x437b1002;
+ pci_write_config32(dev, 0x2c, dword);
+
+ /* Read in BAR */
+ /* Is this right? HDA allows for a 64-bit BAR
+ * but this is only setup for a 32-bit one
+ */
+ res = find_resource(dev, 0x10);
+ if (!res)
+ return;
+
+ base = (u32)res->base;
+ printk(BIOS_DEBUG, "base = 0x%x\n", base);
+ codec_mask = codec_detect(base);
+
+ if (codec_mask) {
+ printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
+ codecs_init(base, codec_mask);
+ }
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations hda_audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = hda_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver hdaaudio_driver __pci_driver = {
+ .ops = &hda_audio_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_HDA,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sb700.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_amd_sb700_config *conf;
+ /* Enable ide devices so the linux ide driver will work */
+ u32 dword;
+ u8 byte;
+
+ conf = dev->chip_info;
+
+ /* RPR9.1 disable MSI */
+ /* TODO: For A14, it should set as 1. I doubt it. */
+ dword = pci_read_config32(dev, 0x70);
+ dword &= ~(1 << 16);
+ pci_write_config32(dev, 0x70, dword);
+
+ /* Enable UDMA on all devices, it will become UDMA0 (default PIO is PIO0) */
+ byte = pci_read_config8(dev, 0x54);
+ byte |= 0xf;
+ pci_write_config8(dev, 0x54, byte);
+
+ /* Enable I/O Access&& Bus Master */
+ dword = pci_read_config16(dev, 0x4);
+ dword |= 1 << 2;
+ pci_write_config16(dev, 0x4, dword);
+
+ /* set ide as primary, if you want to boot from IDE, you'd better set it
+ * in $vendor/$mainboard/devicetree.cb */
+
+
+ if (conf->boot_switch_sata_ide == 1) {
+ struct device *sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ byte = pci_read_config8(sm_dev, 0xAD);
+ byte |= 1 << 4;
+ pci_write_config8(sm_dev, 0xAD, byte);
+ }
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "sb700.h"
+
+static void lpc_init(device_t dev)
+{
+ u8 byte;
+ u32 dword;
+ device_t sm_dev;
+
+ /* Enable the LPC Controller */
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ dword = pci_read_config32(sm_dev, 0x64);
+ dword |= 1 << 20;
+ pci_write_config32(sm_dev, 0x64, dword);
+
+ /* Initialize isa dma */
+#if CONFIG_SOUTHBRIDGE_AMD_SB700_SKIP_ISA_DMA_INIT
+ printk(BIOS_DEBUG, "Skipping isa_dma_init() to avoid getting stuck.\n");
+#else
+ isa_dma_init();
+#endif
+
+ /* Enable DMA transaction on the LPC bus */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Disable the timeout mechanism on LPC */
+ byte = pci_read_config8(dev, 0x48);
+ byte &= ~(1 << 7);
+ pci_write_config8(dev, 0x48, byte);
+
+ /* Disable LPC MSI Capability */
+ byte = pci_read_config8(dev, 0x78);
+ byte &= ~(1 << 1);
+ pci_write_config8(dev, 0x78, byte);
+}
+
+static void sb700_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
+
+ pci_get_resource(dev, 0xA0); /* SPI ROM base address */
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ compact_resources(dev);
+}
+
+static void sb700_lpc_set_resources(struct device *dev)
+{
+ struct resource *res;
+
+ pci_dev_set_resources(dev);
+
+ /* Specical case. SPI Base Address. The SpiRomEnable should be set. */
+ res = find_resource(dev, 0xA0);
+ pci_write_config32(dev, 0xA0, res->base | 1 << 1);
+}
+
+/**
+ * @brief Enable resources for children devices
+ *
+ * @param dev the device whose children's resources are to be enabled
+ *
+ */
+static void sb700_lpc_enable_childrens_resources(device_t dev)
+{
+ struct bus *link;
+ u32 reg, reg_x;
+ int var_num = 0;
+ u16 reg_var[3];
+
+ reg = pci_read_config32(dev, 0x44);
+ reg_x = pci_read_config32(dev, 0x48);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child;
+ child = child->sibling) {
+ if (child->enabled
+ && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for (res = child->resource_list; res; res = res->next) {
+ u32 base, end; /* don't need long long */
+ if (!(res->flags & IORESOURCE_IO))
+ continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "sb700 lpc decode:%s, base=0x%08x, end=0x%08x\n",
+ dev_path(child), base, end);
+ switch (base) {
+ case 0x60: /* KB */
+ case 0x64: /* MS */
+ reg |= (1 << 29);
+ break;
+ case 0x3f8: /* COM1 */
+ reg |= (1 << 6);
+ break;
+ case 0x2f8: /* COM2 */
+ reg |= (1 << 7);
+ break;
+ case 0x378: /* Parallal 1 */
+ reg |= (1 << 0);
+ break;
+ case 0x3f0: /* FD0 */
+ reg |= (1 << 26);
+ break;
+ case 0x220: /* Aduio 0 */
+ reg |= (1 << 8);
+ break;
+ case 0x300: /* Midi 0 */
+ reg |= (1 << 18);
+ break;
+ case 0x400:
+ reg_x |= (1 << 16);
+ break;
+ case 0x480:
+ reg_x |= (1 << 17);
+ break;
+ case 0x500:
+ reg_x |= (1 << 18);
+ break;
+ case 0x580:
+ reg_x |= (1 << 19);
+ break;
+ case 0x4700:
+ reg_x |= (1 << 22);
+ break;
+ case 0xfd60:
+ reg_x |= (1 << 23);
+ break;
+ default:
+ if (var_num >= 3)
+ continue; /* only 3 var ; compact them ? */
+ switch (var_num) {
+ case 0:
+ reg_x |= (1 << 2);
+ break;
+ case 1:
+ reg_x |= (1 << 24);
+ break;
+ case 2:
+ reg_x |= (1 << 25);
+ break;
+ }
+ reg_var[var_num++] =
+ base & 0xffff;
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0x44, reg);
+ pci_write_config32(dev, 0x48, reg_x);
+ /* Set WideIO for as many IOs found (fall through is on purpose) */
+ switch (var_num) {
+ case 2:
+ pci_write_config16(dev, 0x90, reg_var[2]);
+ case 1:
+ pci_write_config16(dev, 0x66, reg_var[1]);
+ case 0:
+ pci_write_config16(dev, 0x64, reg_var[0]);
+ break;
+ }
+}
+
+static void sb700_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ sb700_lpc_enable_childrens_resources(dev);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = sb700_lpc_read_resources,
+ .set_resources = sb700_lpc_set_resources,
+ .enable_resources = sb700_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .ops_pci = &lops_pci,
+};
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sb700.h"
+
+static void pci_init(struct device *dev)
+{
+ u32 dword;
+ u16 word;
+ u8 byte;
+
+ /* RPR 5.1 Enables the PCI-bridge subtractive decode */
+ /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 7;
+ pci_write_config8(dev, 0x4B, byte);
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 5;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR5.2 PCI-bridge upstream dual address window */
+ /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */
+ byte = pci_read_config8(dev, 0x50);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x50, byte);
+
+ /* RPR 5.3 PCI bus 64-byte DMA read access */
+ /* Enhance the PCI bus DMA performance */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 4;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 5.4 Enables the PCIB writes to be cacheline aligned. */
+ /* The size of the writes will be set in the Cacheline Register */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= 1 << 1;
+ pci_write_config8(dev, 0x40, byte);
+
+ /* RPR 5.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */
+ pci_write_config8(dev, 0x0D, 0x40);
+ pci_write_config8(dev, 0x1B, 0x40);
+
+ /* RPR 5.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 6;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 5.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */
+ byte = pci_read_config8(dev, 0x4B);
+ byte |= 1 << 0;
+ pci_write_config8(dev, 0x4B, byte);
+
+ /* RPR 5.8 Adjusts the GNT# de-assertion time */
+ word = pci_read_config16(dev, 0x64);
+ word |= 1 << 12;
+ pci_write_config16(dev, 0x64, word);
+
+ /* RPR 5.9 Fast Back to Back transactions support */
+ byte = pci_read_config8(dev, 0x48);
+ byte |= 1 << 2;
+ /* pci_write_config8(dev, 0x48, byte); */
+
+ /* RPR 5.10 Enable Lock Operation */
+ /* byte = pci_read_config8(dev, 0x48); */
+ byte |= 1 << 3;
+ pci_write_config8(dev, 0x48, byte);
+
+ /* RPR 5.11 Enable additional optional PCI clock */
+ word = pci_read_config16(dev, 0x64);
+ word |= 1 << 8;
+ pci_write_config16(dev, 0x64, word);
+
+ /* RPR 5.12 Enable One-Prefetch-Channel Mode */
+ dword = pci_read_config32(dev, 0x64);
+ dword |= 1 << 20;
+ pci_write_config32(dev, 0x64, dword);
+
+ /* RPR 5.13 Disable PCIB MSI Capability */
+ byte = pci_read_config8(dev, 0x40);
+ byte &= ~(1 << 3);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* rpr5.14 Adjusting CLKRUN# */
+ dword = pci_read_config32(dev, 0x64);
+ dword |= (1 << 15);
+ pci_write_config32(dev, 0x64, dword);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_PCI,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
+ outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "sb700.h"
+
+static int sata_drive_detect(int portnum, u16 iobar)
+{
+ u8 byte, byte2;
+ int i = 0;
+ outb(0xA0 + 0x10 * (portnum % 2), iobar + 0x6);
+ while (byte = inb(iobar + 0x6), byte2 = inb(iobar + 0x7),
+ (byte != (0xA0 + 0x10 * (portnum % 2))) ||
+ ((byte2 & 0x88) != 0)) {
+ printk(BIOS_SPEW, "0x6=%x, 0x7=%x\n", byte, byte2);
+ if (byte != (0xA0 + 0x10 * (portnum % 2))) {
+ /* This will happen at the first iteration of this loop
+ * if the first SATA port is unpopulated and the
+ * second SATA port is poulated.
+ */
+ printk(BIOS_DEBUG, "drive no longer selected after %i ms, "
+ "retrying init\n", i * 10);
+ return 1;
+ } else
+ printk(BIOS_SPEW, "drive detection not yet completed, "
+ "waiting...\n");
+ mdelay(10);
+ i++;
+ }
+ printk(BIOS_SPEW, "drive detection done after %i ms\n", i * 10);
+ return 0;
+}
+
+ /* This function can be overloaded in mainboard.c */
+
+void __attribute__((weak)) sb700_setup_sata_phys(struct device *dev) {
+ /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */
+ pci_write_config16(dev, 0x86, 0x2c00);
+
+ /* RPR7.6.2 SATA GENI PHY ports setting */
+ pci_write_config32(dev, 0x88, 0x01B48017);
+ pci_write_config32(dev, 0x8c, 0x01B48019);
+ pci_write_config32(dev, 0x90, 0x01B48016);
+ pci_write_config32(dev, 0x94, 0x01B48016);
+ pci_write_config32(dev, 0x98, 0x01B48016);
+ pci_write_config32(dev, 0x9C, 0x01B48016);
+
+ /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */
+ pci_write_config16(dev, 0xA0, 0xA09A);
+ pci_write_config16(dev, 0xA2, 0xA09F);
+ pci_write_config16(dev, 0xA4, 0xA07A);
+ pci_write_config16(dev, 0xA6, 0xA07A);
+ pci_write_config16(dev, 0xA8, 0xA07A);
+ pci_write_config16(dev, 0xAA, 0xA07A);
+}
+
+static void sata_init(struct device *dev)
+{
+ u8 byte;
+ u16 word;
+ u32 dword;
+ u8 rev_id;
+ u32 sata_bar5;
+ u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
+ int i, j;
+
+ struct southbridge_ati_sb700_config *conf;
+ conf = dev->chip_info;
+
+ device_t sm_dev;
+ /* SATA SMBus Disable */
+ /* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); */
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ /* Disable SATA SMBUS */
+ byte = pci_read_config8(sm_dev, 0xad);
+ byte |= (1 << 1);
+ /* Enable SATA and power saving */
+ byte = pci_read_config8(sm_dev, 0xad);
+ byte |= (1 << 0);
+ byte |= (1 << 5);
+ pci_write_config8(sm_dev, 0xad, byte);
+
+ /* RPR 7.2 SATA Initialization */
+ /* Set the interrupt Mapping to INTG# */
+ byte = pci_read_config8(sm_dev, 0xaf);
+ byte = 0x6 << 2;
+ pci_write_config8(sm_dev, 0xaf, byte);
+
+ /* get rev_id */
+ rev_id = pci_read_config8(sm_dev, 0x08) - 0x28;
+
+ /* get base address */
+ sata_bar5 = pci_read_config32(dev, 0x24) & ~0x3FF;
+ sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7;
+ sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3;
+ sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7;
+ sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3;
+ sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf;
+
+ printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */
+ printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */
+ printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */
+ printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */
+ printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */
+ printk(BIOS_SPEW, "sata_bar5=%x\n", sata_bar5); /* e0309000 */
+
+ /* disable combined mode */
+ byte = pci_read_config8(sm_dev, 0xAD);
+ byte &= ~(1 << 3);
+ pci_write_config8(sm_dev, 0xAD, byte);
+ /* Program the 2C to 0x43801002 */
+ dword = 0x43801002;
+ pci_write_config32(dev, 0x2c, dword);
+
+ /* SERR-Enable */
+ word = pci_read_config16(dev, 0x04);
+ word |= (1 << 8);
+ pci_write_config16(dev, 0x04, word);
+
+ /* Dynamic power saving */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 2);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Set SATA Operation Mode, Set to IDE mode */
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1 << 0);
+ byte |= (1 << 4);
+ pci_write_config8(dev, 0x40, byte);
+
+ dword = 0x01018f00;
+ pci_write_config32(dev, 0x8, dword);
+
+ byte = pci_read_config8(dev, 0x40);
+ byte &= ~(1 << 0);
+ pci_write_config8(dev, 0x40, byte);
+
+ /* Enable the SATA watchdog counter */
+ byte = pci_read_config8(dev, 0x44);
+ byte |= (1 << 0);
+ pci_write_config8(dev, 0x44, byte);
+
+ /* Set bit 29 and 24 for A12 */
+ dword = pci_read_config32(dev, 0x40);
+ if (rev_id < 0x14) /* before A12 */
+ dword |= (1 << 29);
+ else
+ dword &= ~(1 << 29); /* A14 and above */
+ pci_write_config32(dev, 0x40, dword);
+
+ /* set bit 21 for A12 */
+ dword = pci_read_config32(dev, 0x48);
+ if (rev_id < 0x14) /* before A12 */
+ dword |= 1 << 24 | 1 << 21;
+ else {
+ dword &= ~(1 << 24 | 1 << 21); /* A14 and above */
+ dword &= ~0xFF80; /* 15:7 */
+ dword |= 1 << 15 | 0x7F << 7;
+ }
+ pci_write_config32(dev, 0x48, dword);
+
+ /* Program the watchdog counter to 0x10 */
+ byte = 0x10;
+ pci_write_config8(dev, 0x46, byte);
+ sb700_setup_sata_phys(dev);
+ /* Enable the I/O, MM, BusMaster access for SATA */
+ byte = pci_read_config8(dev, 0x4);
+ byte |= 7 << 0;
+ pci_write_config8(dev, 0x4, byte);
+
+ /* RPR7.7 SATA drive detection. */
+ /* Use BAR5+0x128,BAR0 for Primary Slave */
+ /* Use BAR5+0x1A8,BAR0 for Primary Slave */
+ /* Use BAR5+0x228,BAR2 for Secondary Master */
+ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */
+ /* Use BAR5+0x328,PATA_BAR0/2 for Primary/Secondary master emulation */
+ /* Use BAR5+0x3A8,PATA_BAR0/2 for Primary/Secondary Slave emulation */
+
+ /* TODO: port 4,5, which are PATA emulations. What are PATA_BARs? */
+
+ for (i = 0; i < 4; i++) {
+ byte = read8(sata_bar5 + 0x128 + 0x80 * i);
+ printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
+ byte &= 0xF;
+ if( byte == 0x1 ) {
+ /* If the drive status is 0x1 then we see it but we aren't talking to it. */
+ /* Try to do something about it. */
+ printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n");
+
+ /* Read in Port-N Serial ATA Control Register */
+ byte = read8(sata_bar5 + 0x12C + 0x80 * i);
+
+ /* Set Reset Bit and 1.5g bit */
+ byte |= 0x11;
+ write8((sata_bar5 + 0x12C + 0x80 * i), byte);
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Clear Reset Bit */
+ byte &= ~0x01;
+ write8((sata_bar5 + 0x12C + 0x80 * i), byte);
+
+ /* Wait 1ms */
+ mdelay(1);
+
+ /* Reread status */
+ byte = read8(sata_bar5 + 0x128 + 0x80 * i);
+ printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
+ byte &= 0xF;
+ }
+
+ if (byte == 0x3) {
+ for (j = 0; j < 10; j++) {
+ if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))
+ break;
+ }
+ printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n",
+ (i / 2) ? "Secondary" : "Primary",
+ (i % 2 ) ? "Slave" : "Master",
+ (j == 10) ? "not " : "",
+ (j == 10) ? j : j + 1);
+ } else {
+ printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n",
+ (i / 2) ? "Secondary" : "Primary",
+ (i % 2 ) ? "Slave" : "Master", i);
+ }
+ }
+
+ /* Below is CIM InitSataLateFar */
+ /* Enable interrupts from the HBA */
+ byte = read8(sata_bar5 + 0x4);
+ byte |= 1 << 1;
+ write8((sata_bar5 + 0x4), byte);
+
+ /* Clear error status */
+ write32((sata_bar5 + 0x130), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x230), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x330), 0xFFFFFFFF);
+ write32((sata_bar5 + 0x3b0), 0xFFFFFFFF);
+
+ /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */
+ /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */
+
+ /* word = 0x0000; */
+ /* word = pm_ioread(0x28); */
+ /* byte = pm_ioread(0x29); */
+ /* word |= byte<<8; */
+ /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */
+ /* write32(word, 0x80000000); */
+}
+
+static struct pci_operations lops_pci = {
+ /* .set_subsystem = pci_dev_set_subsystem, */
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_SATA,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _SB700_EARLY_SETUP_C_
-#define _SB700_EARLY_SETUP_C_
-
-#include <reset.h>
-#include <arch/cpu.h>
-#include "sb700.h"
-#include "sb700_smbus.c"
-
-#define SMBUS_IO_BASE 0x6000 /* Is it a temporary SMBus I/O base address? */
- /*SIZE 0x40 */
-
-static void pmio_write(u8 reg, u8 value)
-{
- outb(reg, PM_INDEX);
- outb(value, PM_INDEX + 1);
-}
-
-static u8 pmio_read(u8 reg)
-{
- outb(reg, PM_INDEX);
- return inb(PM_INDEX + 1);
-}
-
-/* RPR 2.28: Get SB ASIC Revision. */
-static u8 set_sb700_revision(void)
-{
- device_t dev;
- u8 rev_id, enable_14Mhz, byte;
- u8 rev = 0;
-
- /* if (rev != 0) return rev; */
-
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- /* NOT REACHED */
- }
- rev_id = pci_read_config8(dev, 0x08);
-
- if (rev_id == 0x39) {
- enable_14Mhz = (pmio_read(0x53) >> 6) & 1;
- if (enable_14Mhz == 0x0)
- rev = 0x11; /* A11 */
- else if (enable_14Mhz == 0x1) {
- /* This happens, if does, only once. So later if we need to get
- * the revision ID, we don't have to make such a big function.
- * We just get reg 0x8 in smbus dev. 0x39 is A11, 0x3A is A12. */
- rev = 0x12;
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x40, byte);
-
- pci_write_config8(dev, 0x08, 0x3A); /* Change 0x39 to 0x3A. */
-
- byte &= ~(1 << 0);
- pci_write_config8(dev, 0x40, byte);
- }
- } else if (rev_id == 0x3A) { /* A12 will be 0x3A after BIOS is initialized */
- rev = 0x12;
- } else if (rev_id == 0x3C) {
- rev = 0x14;
- } else if (rev_id == 0x3D) {
- rev = 0x15;
- } else
- die("It is not SB700 or SB710\n");
-
- return rev;
-}
-
-/***************************************
-* Legacy devices are mapped to LPC space.
-* Serial port 0
-* KBC Port
-* ACPI Micro-controller port
-* LPC ROM size
-* This function does not change port 0x80 decoding.
-* Console output through any port besides 0x3f8 is unsupported.
-* If you use FWH ROMs, you have to setup IDSEL.
-***************************************/
-static void sb700_lpc_init(void)
-{
- u8 reg8;
- u32 reg32;
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); /* SMBUS controller */
- /* NOTE: Set BootTimerDisable, otherwise it would keep rebooting!!
- * This bit has no meaning if debug strap is not enabled. So if the
- * board keeps rebooting and the code fails to reach here, we could
- * disable the debug strap first. */
- reg32 = pci_read_config32(dev, 0x4C);
- reg32 |= 1 << 31;
- pci_write_config32(dev, 0x4C, reg32);
-
- /* Enable lpc controller */
- reg32 = pci_read_config32(dev, 0x64);
- reg32 |= 1 << 20;
- pci_write_config32(dev, 0x64, reg32);
-
- dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0); /* LPC Controller */
- /* Decode port 0x3f8-0x3ff (Serial 0) */
- // XXX Serial port decode on LPC is hardcoded to 0x3f8
- reg8 = pci_read_config8(dev, 0x44);
- reg8 |= 1 << 6;
- pci_write_config8(dev, 0x44, reg8);
-
- /* Decode port 0x60 & 0x64 (PS/2 keyboard) and port 0x62 & 0x66 (ACPI)*/
- reg8 = pci_read_config8(dev, 0x47);
- reg8 |= (1 << 5) | (1 << 6);
- pci_write_config8(dev, 0x47, reg8);
-
- /* Enable PrefetchEnSPIFromHost to speed up SPI flash read (does not affect LPC) */
- reg8 = pci_read_config8(dev, 0xbb);
- reg8 |= 1 << 0;
- pci_write_config8(dev, 0xbb, reg8);
-
- /* SuperIO, LPC ROM */
- reg8 = pci_read_config8(dev, 0x48);
- /* Decode ports 0x2e-0x2f, 0x4e-0x4f (SuperI/O configuration) */
- reg8 |= (1 << 1) | (1 << 0);
- /* Decode variable LPC ROM address ranges 1&2 (see register 0x68-0x6b, 0x6c-0x6f) */
- reg8 |= (1 << 3) | (1 << 4);
- /* Decode port 0x70-0x73 (RTC) */
- reg8 |= 1 << 6;
- pci_write_config8(dev, 0x48, reg8);
-
- /* hardware should enable LPC ROM by pin straps */
- /* ROM access at 0xFFF80000/0xFFF00000 - 0xFFFFFFFF */
- /* See detail in 43366_sb700_bdg_nda_1.01.pdf page 17. */
- /* enable LPC ROM range mirroring start 0x000e(0000) */
- pci_write_config16(dev, 0x68, 0x000e);
- /* enable LPC ROM range mirroring end 0x000f(ffff) */
- pci_write_config16(dev, 0x6a, 0x000f);
- /* enable LPC ROM range start, 0xfff8(0000): 512KB, 0xfff0(0000): 1MB */
- pci_write_config16(dev, 0x6c, 0xfff0);
- /* enable LPC ROM range end at 0xffff(ffff) */
- pci_write_config16(dev, 0x6e, 0xffff);
-}
-
-/* what is its usage? */
-static u32 get_sbdn(u32 bus)
-{
- device_t dev;
-
- /* Find the device. */
- dev = pci_locate_device_on_bus(PCI_ID(0x1002, 0x4385), bus);
- return (dev >> 15) & 0x1f;
-}
-
-static u8 dual_core(void)
-{
- return (pci_read_config32(PCI_DEV(0, 0x18, 3), 0xE8) & (0x3<<12)) != 0;
-}
-
-/*
- * RPR 2.4 C-state and VID/FID change for the K8 platform.
- */
-static void enable_fid_change_on_sb(u32 sbbusn, u32 sbdn)
-{
- u8 byte;
- byte = pmio_read(0x9a);
- byte &= ~0x34;
- if (dual_core())
- byte |= 0x34;
- else
- byte |= 0x04;
- pmio_write(0x9a, byte);
-
- byte = pmio_read(0x8f);
- byte &= ~0x30;
- byte |= 0x20;
- pmio_write(0x8f, byte);
-
- pmio_write(0x8b, 0x01); /* TODO: if the HT Link is 200 MHz, it is 0x0A. It doesnt often happen. */
- pmio_write(0x8a, 0x90);
-
- pmio_write(0x88, 0x10);
-
- byte = pmio_read(0x7c);
- byte |= 0x03;
- pmio_write(0x7c, byte);
-
- /* Must be 0 for K8 platform. */
- byte = pmio_read(0x68);
- byte &= ~0x01;
- pmio_write(0x68, byte);
- /* Must be 0 for K8 platform. */
- byte = pmio_read(0x8d);
- byte &= ~(1<<6);
- pmio_write(0x8d, byte);
-
- byte = pmio_read(0x61);
- byte &= ~0x04;
- pmio_write(0x61, byte);
-
- byte = pmio_read(0x42);
- byte &= ~0x04;
- pmio_write(0x42, byte);
-
- pmio_write(0x89, 0x10);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
- /* link reset */
- outb(0x06, 0x0cf9);
-}
-
-void sb700_pci_port80(void)
-{
- u8 byte;
- device_t dev;
-
- /* P2P Bridge */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
-
- /* Chip Control: Enable subtractive decoding */
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 5;
- pci_write_config8(dev, 0x40, byte);
-
- /* Misc Control: Enable subtractive decoding if 0x40 bit 5 is set */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 7;
- pci_write_config8(dev, 0x4B, byte);
-
- /* The same IO Base and IO Limit here is meaningful because we set the
- * bridge to be subtractive. During early setup stage, we have to make
- * sure that data can go through port 0x80.
- */
- /* IO Base: 0xf000 */
- byte = pci_read_config8(dev, 0x1C);
- byte |= 0xF << 4;
- pci_write_config8(dev, 0x1C, byte);
-
- /* IO Limit: 0xf000 */
- byte = pci_read_config8(dev, 0x1D);
- byte |= 0xF << 4;
- pci_write_config8(dev, 0x1D, byte);
-
- /* PCI Command: Enable IO response */
- byte = pci_read_config8(dev, 0x04);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x04, byte);
-
- /* LPC controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
-
- byte = pci_read_config8(dev, 0x4A);
- byte &= ~(1 << 5); /* disable lpc port 80 */
- pci_write_config8(dev, 0x4A, byte);
-}
-
-void sb700_lpc_port80(void)
-{
- u8 byte;
- device_t dev;
- u32 reg32;
-
- /* Enable LPC controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
- reg32 = pci_read_config32(dev, 0x64);
- reg32 |= 0x00100000; /* lpcEnable */
- pci_write_config32(dev, 0x64, reg32);
-
- /* Enable port 80 LPC decode in pci function 3 configuration space. */
- dev = pci_locate_device(PCI_ID(0x1002, 0x439d), 0);
- byte = pci_read_config8(dev, 0x4a);
- byte |= 1 << 5; /* enable port 80 */
- pci_write_config8(dev, 0x4a, byte);
-}
-
-/* sbDevicesPorInitTable */
-static void sb700_devices_por_init(void)
-{
- device_t dev;
- u8 byte;
-
- printk(BIOS_INFO, "sb700_devices_por_init()\n");
- /* SMBus Device, BDF:0-20-0 */
- printk(BIOS_INFO, "sb700_devices_por_init(): SMBus Device, BDF:0-20-0\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- /* NOT REACHED */
- }
- printk(BIOS_INFO, "SMBus controller enabled, sb revision is A%x\n",
- set_sb700_revision());
-
- /* sbPorAtStartOfTblCfg */
- /* Set A-Link bridge access address. This address is set at device 14h, function 0, register 0xf0.
- * This is an I/O address. The I/O address must be on 16-byte boundry. */
- pci_write_config32(dev, 0xf0, AB_INDX);
-
- /* To enable AB/BIF DMA access, a specific register inside the BIF register space needs to be configured first. */
- /* 4.3:Enables the SB700 to send transactions upstream over A-Link Express interface. */
- axcfg_reg(0x04, 1 << 2, 1 << 2);
- axindxc_reg(0x21, 0xff, 0);
-
- /* 2.5:Enabling Non-Posted Memory Write for the K8 Platform */
- axindxc_reg(0x10, 1 << 9, 1 << 9);
- /* END of sbPorAtStartOfTblCfg */
-
- /* sbDevicesPorInitTables */
- /* set smbus iobase */
- pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
-
- /* enable smbus controller interface */
- byte = pci_read_config8(dev, 0xd2);
- byte |= (1 << 0);
- pci_write_config8(dev, 0xd2, byte);
-
- /* KB2RstEnable */
- pci_write_config8(dev, 0x40, 0x44);
-
- /* Enable ISA Address 0-960K decoding */
- pci_write_config8(dev, 0x48, 0x0f);
-
- /* Enable ISA Address 0xC0000-0xDFFFF decode */
- pci_write_config8(dev, 0x49, 0xff);
-
- /* Enable decode cycles to IO C50, C51, C52 GPM controls. */
- byte = pci_read_config8(dev, 0x41);
- byte &= 0x80;
- byte |= 0x33;
- pci_write_config8(dev, 0x41, byte);
-
- /* Legacy DMA Prefetch Enhancement, CIM masked it. */
- /* pci_write_config8(dev, 0x43, 0x1); */
-
- /* Disabling Legacy USB Fast SMI# */
- byte = pci_read_config8(dev, 0x62);
- byte |= 0x24;
- pci_write_config8(dev, 0x62, byte);
-
- /* Features Enable */
- pci_write_config32(dev, 0x64, 0x829E79BF); /* bit10: Enables the HPET interrupt. */
-
- /* SerialIrq Control */
- pci_write_config8(dev, 0x69, 0x90);
-
- /* Test Mode, PCIB_SReset_En Mask is set. */
- pci_write_config8(dev, 0x6c, 0x20);
-
- /* IO Address Enable, CIM set 0x78 only and masked 0x79. */
- /*pci_write_config8(dev, 0x79, 0x4F); */
- pci_write_config8(dev, 0x78, 0xFF);
-
- /* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */
- pci_write_config16(dev, 0x4, 0x0407);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* IDE Device, BDF:0-20-1 */
- printk(BIOS_INFO, "sb700_devices_por_init(): IDE Device, BDF:0-20-1\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
- /* Disable prefetch */
- byte = pci_read_config8(dev, 0x63);
- byte |= 0x1;
- pci_write_config8(dev, 0x63, byte);
-
- /* LPC Device, BDF:0-20-3 */
- printk(BIOS_INFO, "sb700_devices_por_init(): LPC Device, BDF:0-20-3\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
- /* DMA enable */
- pci_write_config8(dev, 0x40, 0x04);
-
- /* IO Port Decode Enable */
- pci_write_config8(dev, 0x44, 0xFF);
- pci_write_config8(dev, 0x45, 0xFF);
- pci_write_config8(dev, 0x46, 0xC3);
- pci_write_config8(dev, 0x47, 0xFF);
-
- /* IO/Mem Port Decode Enable, I don't know why CIM disable some ports.
- * Disable LPC TimeOut counter, enable SuperIO Configuration Port (2e/2f),
- * Alternate SuperIO Configuration Port (4e/4f), Wide Generic IO Port (64/65).
- * Enable bits for LPC ROM memory address range 1&2 for 1M ROM setting.*/
- byte = pci_read_config8(dev, 0x48);
- byte |= (1 << 1) | (1 << 0); /* enable Super IO config port 2e-2h, 4e-4f */
- byte |= (1 << 3) | (1 << 4); /* enable for LPC ROM address range1&2, Enable 512KB rom access at 0xFFF80000 - 0xFFFFFFFF */
- byte |= 1 << 6; /* enable for RTC I/O range */
- pci_write_config8(dev, 0x48, byte);
- pci_write_config8(dev, 0x49, 0xFF);
- /* Enable 0x480-0x4bf, 0x4700-0x470B */
- byte = pci_read_config8(dev, 0x4A);
- byte |= ((1 << 1) + (1 << 6)); /*0x42, save the configuraion for port 0x80. */
- pci_write_config8(dev, 0x4A, byte);
-
- /* Set LPC ROM size, it has been done in sb700_lpc_init().
- * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB;
- * enable LPC ROM range, 0xfff8: 512KB, 0xfff0: 1MB
- * pci_write_config16(dev, 0x68, 0x000e)
- * pci_write_config16(dev, 0x6c, 0xfff0);*/
-
- /* Enable Tpm12_en and Tpm_legacy. I don't know what is its usage and copied from CIM. */
- pci_write_config8(dev, 0x7C, 0x05);
-
- /* P2P Bridge, BDF:0-20-4, the configuration of the registers in this dev are copied from CIM,
- */
- printk(BIOS_INFO, "sb700_devices_por_init(): P2P Bridge, BDF:0-20-4\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4384), 0);
-
- /* Arbiter enable. */
- pci_write_config8(dev, 0x43, 0xff);
-
- /* Set PCDMA request into hight priority list. */
- /* pci_write_config8(dev, 0x49, 0x1) */ ;
-
- pci_write_config8(dev, 0x40, 0x26);
-
- pci_write_config8(dev, 0x0d, 0x40);
- pci_write_config8(dev, 0x1b, 0x40);
- /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
- pci_write_config8(dev, 0x50, 0x01);
-
- /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
- printk(BIOS_INFO, "sb700_devices_por_init(): SATA Device, BDF:0-18-0\n");
- dev = pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
-
- /*PHY Global Control*/
- pci_write_config16(dev, 0x86, 0x2C00);
-}
-
-/* sbPmioPorInitTable, Pre-initializing PMIO register space
-* The power management (PM) block is resident in the PCI/LPC/ISA bridge.
-* The PM regs are accessed via IO mapped regs 0xcd6 and 0xcd7.
-* The index address is first programmed into IO reg 0xcd6.
-* Read or write values are accessed through IO reg 0xcd7.
-*/
-static void sb700_pmio_por_init(void)
-{
- u8 byte;
-
- printk(BIOS_INFO, "sb700_pmio_por_init()\n");
- /* K8KbRstEn, KB_RST# control for K8 system. */
- byte = pmio_read(0x66);
- byte |= 0x20;
- pmio_write(0x66, byte);
-
- /* RPR2.31 PM_TURN_OFF_MSG during ASF Shutdown. */
- if (get_sb700_revision(pci_locate_device(PCI_ID(0x1002, 0x4385), 0)) <= 0x12) {
- byte = pmio_read(0x65);
- byte &= ~(1 << 7);
- pmio_write(0x65, byte);
-
- byte = pmio_read(0x75);
- byte &= 0xc0;
- byte |= 0x05;
- pmio_write(0x75, byte);
-
- byte = pmio_read(0x52);
- byte &= 0xc0;
- byte |= 0x08;
- pmio_write(0x52, byte);
- } else {
- byte = pmio_read(0xD7);
- byte |= 1 << 0;
- pmio_write(0xD7, byte);
-
- byte = pmio_read(0x65);
- byte |= 1 << 7;
- pmio_write(0x65, byte);
-
- byte = pmio_read(0x75);
- byte &= 0xc0;
- byte |= 0x01;
- pmio_write(0x75, byte);
-
- byte = pmio_read(0x52);
- byte &= 0xc0;
- byte |= 0x02;
- pmio_write(0x52, byte);
-
- }
-
- /* Watch Dog Timer Control
- * Set watchdog time base to 0xfec000f0 to avoid SCSI card boot failure.
- * But I don't find WDT is enabled in SMBUS 0x41 bit3 in CIM.
- */
- pmio_write(0x6c, 0xf0);
- pmio_write(0x6d, 0x00);
- pmio_write(0x6e, 0xc0);
- pmio_write(0x6f, 0xfe);
-
- /* rpr2.15: Enabling Spread Spectrum */
- byte = pmio_read(0x42);
- byte |= 1 << 7;
- pmio_write(0x42, byte);
- /* TODO: Check if it is necessary. IDE reset */
- byte = pmio_read(0xB2);
- byte |= 1 << 0;
- pmio_write(0xB2, byte);
-}
-
-/*
-* Add any south bridge setting.
-*/
-static void sb700_pci_cfg(void)
-{
- device_t dev;
- u8 byte;
-
- /* SMBus Device, BDF:0-20-0 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0);
- /* Enable watchdog decode timer */
- byte = pci_read_config8(dev, 0x41);
- byte |= (1 << 3);
- pci_write_config8(dev, 0x41, byte);
-
- /* Set to 1 to reset USB on the software (such as IO-64 or IO-CF9 cycles)
- * generated PCIRST#. */
- byte = pmio_read(0x65);
- byte |= (1 << 4);
- pmio_write(0x65, byte);
-
- /* IDE Device, BDF:0-20-1 */
- dev = pci_locate_device(PCI_ID(0x1002, 0x439C), 0);
- /* Enable IDE Explicit prefetch, 0x63[0] clear */
- byte = pci_read_config8(dev, 0x63);
- byte &= 0xfe;
- pci_write_config8(dev, 0x63, byte);
-
- /* LPC Device, BDF:0-20-3 */
- /* The code below is ported from old chipset. It is not
- * mentioned in RPR. But I keep them. The registers and the
- * comments are compatible. */
- dev = pci_locate_device(PCI_ID(0x1002, 0x439D), 0);
- /* Enabling LPC DMA function. */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
- /* Disabling LPC TimeOut. 0x48[7] clear. */
- byte = pci_read_config8(dev, 0x48);
- byte &= 0x7f;
- pci_write_config8(dev, 0x48, byte);
- /* Disabling LPC MSI Capability, 0x78[1] clear. */
- byte = pci_read_config8(dev, 0x78);
- byte &= 0xfd;
- pci_write_config8(dev, 0x78, byte);
-
- /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
- dev = pci_locate_device(PCI_ID(0x1002, 0x4390), 0);
- /* rpr7.12 SATA MSI and D3 Power State Capability. */
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x40, byte);
- if (get_sb700_revision(pci_locate_device(PCI_ID(0x1002, 0x4385), 0)) <= 0x12)
- pci_write_config8(dev, 0x34, 0x70); /* set 0x61 to 0x70 if S1 is not supported. */
- else
- pci_write_config8(dev, 0x34, 0x50); /* set 0x61 to 0x50 if S1 is not supported. */
- byte &= ~(1 << 0);
- pci_write_config8(dev, 0x40, byte);
-}
-
-/*
-*/
-static void sb700_por_init(void)
-{
- /* sbDevicesPorInitTable + sbK8PorInitTable */
- sb700_devices_por_init();
-
- /* sbPmioPorInitTable + sbK8PmioPorInitTable */
- sb700_pmio_por_init();
-}
-
-/*
-* It should be called during early POST after memory detection and BIOS shadowing but before PCI bus enumeration.
-*/
-static void sb700_before_pci_init(void)
-{
- sb700_pci_cfg();
-}
-
-/*
-* This function should be called after enable_sb700_smbus().
-*/
-static void sb700_early_setup(void)
-{
- printk(BIOS_INFO, "sb700_early_setup()\n");
- sb700_por_init();
-}
-
-static int smbus_read_byte(u32 device, u32 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "sb700.h"
-
-#define EHCI_EOR (CONFIG_EHCI_BAR + 0x20)
-#define DEBUGPORT_MISC_CONTROL (EHCI_EOR + 0x80)
-
-void set_debug_port(unsigned int port)
-{
- u32 reg32;
-
- /* Write the port number to DEBUGPORT_MISC_CONTROL[31:28]. */
- reg32 = read32(DEBUGPORT_MISC_CONTROL);
- reg32 &= ~(0xf << 28);
- reg32 |= (port << 28);
- reg32 |= (1 << 27); /* Enable Debug Port port number remapping. */
- write32(DEBUGPORT_MISC_CONTROL, reg32);
-}
-
-/*
- * Note: The SB700 has two EHCI devices, D18:F2 and D19:F2.
- * This code currently only supports the first one, i.e., USB Debug devices
- * attached to physical USB ports belonging to the first EHCI device.
- */
-void sb700_enable_usbdebug(unsigned int port)
-{
- device_t dev = PCI_DEV(0, 0x12, 2); /* USB EHCI, D18:F2 */
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-
- /*
- * Select the requested physical USB port (1-15) as the Debug Port.
- * Must be called after the EHCI BAR has been set up (see above).
- */
- set_debug_port(port);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "sb700.h"
-
-#define HDA_ICII_REG 0x68
-#define HDA_ICII_BUSY (1 << 0)
-#define HDA_ICII_VALID (1 << 1)
-
-static int set_bits(u32 port, u32 mask, u32 val)
-{
- u32 dword;
- int count;
-
- /* Write (val & ~mask) to port */
- val &= mask;
- dword = read32(port);
- dword &= ~mask;
- dword |= val;
- write32(port, dword);
-
- /* Wait for readback of register to
- * match what was just written to it
- */
- count = 50;
- do {
- /* Wait 1ms based on BKDG wait time */
- mdelay(1);
- dword = read32(port);
- dword &= mask;
- } while ((dword != val) && --count);
-
- /* Timeout occured */
- if (!count)
- return -1;
- return 0;
-}
-
-static u32 codec_detect(u32 base)
-{
- u32 dword;
-
- /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 0) == -1)
- goto no_codec;
-
- /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 1) == -1)
- goto no_codec;
-
- /* Delay for 1 ms since the BKDG does */
- mdelay(1);
-
- /* Read in Codec location (BAR + 0xe)[3..0]*/
- dword = read32(base + 0xe);
- dword &= 0x0F;
- if (!dword)
- goto no_codec;
-
- return dword;
-
-no_codec:
- /* Codec Not found */
- /* Put HDA back in reset (BAR + 0x8) [0] */
- set_bits(base + 0x08, 1, 0);
- printk(BIOS_DEBUG, "No codec!\n");
- return 0;
-}
-
-/**
- * Wait 50usec for the codec to indicate it is ready
- * no response would imply that the codec is non-operative
- */
-static int wait_for_ready(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
-
- while(timeout--) {
- u32 dword=read32(base + HDA_ICII_REG);
- if (!(dword & HDA_ICII_BUSY))
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-/**
- * Wait 50usec for the codec to indicate that it accepted
- * the previous command. No response would imply that the code
- * is non-operative
- */
-static int wait_for_valid(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
- while(timeout--) {
- u32 dword = read32(base + HDA_ICII_REG);
- if ((dword & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
- HDA_ICII_VALID)
- return 0;
- udelay(1);
- }
-
- return 1;
-}
-
-static void codec_init(u32 base, int addr)
-{
- u32 dword;
-
- /* 1 */
- if (wait_for_ready(base) == -1)
- return;
-
- dword = (addr << 28) | 0x000f0000;
- write32(base + 0x60, dword);
-
- if (wait_for_valid(base) == -1)
- return;
-
- dword = read32(base + 0x64);
-
- /* 2 */
- printk(BIOS_DEBUG, "%x(th) codec viddid: %08x\n", addr, dword);
-}
-
-static void codecs_init(u32 base, u32 codec_mask)
-{
- int i;
- for (i = 2; i >= 0; i--) {
- if (codec_mask & (1 << i))
- codec_init(base, i);
- }
-}
-
-static void hda_init(struct device *dev)
-{
- u8 byte;
- u32 dword;
- u32 base;
- struct resource *res;
- u32 codec_mask;
- device_t sm_dev;
-
- /* Enable azalia - PM_io 0x59[3], no ac97 in sb700. */
- byte = pm_ioread(0x59);
- byte |= 1 << 3;
- pm_iowrite(0x59, byte);
-
- /* Find the SMBus */
- /* FIXME: Need to find out why the call below crashes. */
- /*sm_dev = dev_find_device(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_ATI_SB700_SM, 0);*/
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
-
- /* Set routing pin - SMBus ExtFunc (0xf8/0xfc) */
- pci_write_config32(sm_dev, 0xf8, 0x00);
- pci_write_config8(sm_dev, 0xfc, 0xAA);
- /* Set INTA - SMBus 0x63 [2..0] */
- byte = pci_read_config8(sm_dev, 0x63);
- byte &= ~0x7;
- byte |= 0x0; /* INTA:0x0 - INTH:0x7 */
- pci_write_config8(sm_dev, 0x63, byte);
-
- /* Program the 2C to 0x437b1002 */
- dword = 0x437b1002;
- pci_write_config32(dev, 0x2c, dword);
-
- /* Read in BAR */
- /* Is this right? HDA allows for a 64-bit BAR
- * but this is only setup for a 32-bit one
- */
- res = find_resource(dev, 0x10);
- if (!res)
- return;
-
- base = (u32)res->base;
- printk(BIOS_DEBUG, "base = 0x%x\n", base);
- codec_mask = codec_detect(base);
-
- if (codec_mask) {
- printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
- codecs_init(base, codec_mask);
- }
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations hda_audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = hda_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver hdaaudio_driver __pci_driver = {
- .ops = &hda_audio_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_HDA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sb700.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_amd_sb700_config *conf;
- /* Enable ide devices so the linux ide driver will work */
- u32 dword;
- u8 byte;
-
- conf = dev->chip_info;
-
- /* RPR9.1 disable MSI */
- /* TODO: For A14, it should set as 1. I doubt it. */
- dword = pci_read_config32(dev, 0x70);
- dword &= ~(1 << 16);
- pci_write_config32(dev, 0x70, dword);
-
- /* Enable UDMA on all devices, it will become UDMA0 (default PIO is PIO0) */
- byte = pci_read_config8(dev, 0x54);
- byte |= 0xf;
- pci_write_config8(dev, 0x54, byte);
-
- /* Enable I/O Access&& Bus Master */
- dword = pci_read_config16(dev, 0x4);
- dword |= 1 << 2;
- pci_write_config16(dev, 0x4, dword);
-
- /* set ide as primary, if you want to boot from IDE, you'd better set it
- * in $vendor/$mainboard/devicetree.cb */
-
-
- if (conf->boot_switch_sata_ide == 1) {
- struct device *sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- byte = pci_read_config8(sm_dev, 0xAD);
- byte |= 1 << 4;
- pci_write_config8(sm_dev, 0xAD, byte);
- }
-
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);
-#endif
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "sb700.h"
-
-static void lpc_init(device_t dev)
-{
- u8 byte;
- u32 dword;
- device_t sm_dev;
-
- /* Enable the LPC Controller */
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- dword = pci_read_config32(sm_dev, 0x64);
- dword |= 1 << 20;
- pci_write_config32(sm_dev, 0x64, dword);
-
- /* Initialize isa dma */
-#if CONFIG_SOUTHBRIDGE_AMD_SB700_SKIP_ISA_DMA_INIT
- printk(BIOS_DEBUG, "Skipping isa_dma_init() to avoid getting stuck.\n");
-#else
- isa_dma_init();
-#endif
-
- /* Enable DMA transaction on the LPC bus */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
-
- /* Disable the timeout mechanism on LPC */
- byte = pci_read_config8(dev, 0x48);
- byte &= ~(1 << 7);
- pci_write_config8(dev, 0x48, byte);
-
- /* Disable LPC MSI Capability */
- byte = pci_read_config8(dev, 0x78);
- byte &= ~(1 << 1);
- pci_write_config8(dev, 0x78, byte);
-}
-
-static void sb700_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev); /* We got one for APIC, or one more for TRAP */
-
- pci_get_resource(dev, 0xA0); /* SPI ROM base address */
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- compact_resources(dev);
-}
-
-static void sb700_lpc_set_resources(struct device *dev)
-{
- struct resource *res;
-
- pci_dev_set_resources(dev);
-
- /* Specical case. SPI Base Address. The SpiRomEnable should be set. */
- res = find_resource(dev, 0xA0);
- pci_write_config32(dev, 0xA0, res->base | 1 << 1);
-}
-
-/**
- * @brief Enable resources for children devices
- *
- * @param dev the device whose children's resources are to be enabled
- *
- */
-static void sb700_lpc_enable_childrens_resources(device_t dev)
-{
- struct bus *link;
- u32 reg, reg_x;
- int var_num = 0;
- u16 reg_var[3];
-
- reg = pci_read_config32(dev, 0x44);
- reg_x = pci_read_config32(dev, 0x48);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child;
- child = child->sibling) {
- if (child->enabled
- && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for (res = child->resource_list; res; res = res->next) {
- u32 base, end; /* don't need long long */
- if (!(res->flags & IORESOURCE_IO))
- continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "sb700 lpc decode:%s, base=0x%08x, end=0x%08x\n",
- dev_path(child), base, end);
- switch (base) {
- case 0x60: /* KB */
- case 0x64: /* MS */
- reg |= (1 << 29);
- break;
- case 0x3f8: /* COM1 */
- reg |= (1 << 6);
- break;
- case 0x2f8: /* COM2 */
- reg |= (1 << 7);
- break;
- case 0x378: /* Parallal 1 */
- reg |= (1 << 0);
- break;
- case 0x3f0: /* FD0 */
- reg |= (1 << 26);
- break;
- case 0x220: /* Aduio 0 */
- reg |= (1 << 8);
- break;
- case 0x300: /* Midi 0 */
- reg |= (1 << 18);
- break;
- case 0x400:
- reg_x |= (1 << 16);
- break;
- case 0x480:
- reg_x |= (1 << 17);
- break;
- case 0x500:
- reg_x |= (1 << 18);
- break;
- case 0x580:
- reg_x |= (1 << 19);
- break;
- case 0x4700:
- reg_x |= (1 << 22);
- break;
- case 0xfd60:
- reg_x |= (1 << 23);
- break;
- default:
- if (var_num >= 3)
- continue; /* only 3 var ; compact them ? */
- switch (var_num) {
- case 0:
- reg_x |= (1 << 2);
- break;
- case 1:
- reg_x |= (1 << 24);
- break;
- case 2:
- reg_x |= (1 << 25);
- break;
- }
- reg_var[var_num++] =
- base & 0xffff;
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0x44, reg);
- pci_write_config32(dev, 0x48, reg_x);
- /* Set WideIO for as many IOs found (fall through is on purpose) */
- switch (var_num) {
- case 2:
- pci_write_config16(dev, 0x90, reg_var[2]);
- case 1:
- pci_write_config16(dev, 0x66, reg_var[1]);
- case 0:
- pci_write_config16(dev, 0x64, reg_var[0]);
- break;
- }
-}
-
-static void sb700_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- sb700_lpc_enable_childrens_resources(dev);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = sb700_lpc_read_resources,
- .set_resources = sb700_lpc_set_resources,
- .enable_resources = sb700_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .ops_pci = &lops_pci,
-};
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sb700.h"
-
-static void pci_init(struct device *dev)
-{
- u32 dword;
- u16 word;
- u8 byte;
-
- /* RPR 5.1 Enables the PCI-bridge subtractive decode */
- /* This setting is strongly recommended since it supports some legacy PCI add-on cards,such as BIOS debug cards */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 7;
- pci_write_config8(dev, 0x4B, byte);
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 5;
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR5.2 PCI-bridge upstream dual address window */
- /* this setting is applicable if the system memory is more than 4GB,and the PCI device can support dual address access */
- byte = pci_read_config8(dev, 0x50);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x50, byte);
-
- /* RPR 5.3 PCI bus 64-byte DMA read access */
- /* Enhance the PCI bus DMA performance */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 4;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 5.4 Enables the PCIB writes to be cacheline aligned. */
- /* The size of the writes will be set in the Cacheline Register */
- byte = pci_read_config8(dev, 0x40);
- byte |= 1 << 1;
- pci_write_config8(dev, 0x40, byte);
-
- /* RPR 5.5 Enables the PCIB to retain ownership of the bus on the Primary side and on the Secondary side when GNT# is deasserted */
- pci_write_config8(dev, 0x0D, 0x40);
- pci_write_config8(dev, 0x1B, 0x40);
-
- /* RPR 5.6 Enable the command matching checking function on "Memory Read" & "Memory Read Line" commands */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 6;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 5.7 When enabled, the PCI arbiter checks for the Bus Idle before asserting GNT# */
- byte = pci_read_config8(dev, 0x4B);
- byte |= 1 << 0;
- pci_write_config8(dev, 0x4B, byte);
-
- /* RPR 5.8 Adjusts the GNT# de-assertion time */
- word = pci_read_config16(dev, 0x64);
- word |= 1 << 12;
- pci_write_config16(dev, 0x64, word);
-
- /* RPR 5.9 Fast Back to Back transactions support */
- byte = pci_read_config8(dev, 0x48);
- byte |= 1 << 2;
- /* pci_write_config8(dev, 0x48, byte); */
-
- /* RPR 5.10 Enable Lock Operation */
- /* byte = pci_read_config8(dev, 0x48); */
- byte |= 1 << 3;
- pci_write_config8(dev, 0x48, byte);
-
- /* RPR 5.11 Enable additional optional PCI clock */
- word = pci_read_config16(dev, 0x64);
- word |= 1 << 8;
- pci_write_config16(dev, 0x64, word);
-
- /* RPR 5.12 Enable One-Prefetch-Channel Mode */
- dword = pci_read_config32(dev, 0x64);
- dword |= 1 << 20;
- pci_write_config32(dev, 0x64, dword);
-
- /* RPR 5.13 Disable PCIB MSI Capability */
- byte = pci_read_config8(dev, 0x40);
- byte &= ~(1 << 3);
- pci_write_config8(dev, 0x40, byte);
-
- /* rpr5.14 Adjusting CLKRUN# */
- dword = pci_read_config32(dev, 0x64);
- dword |= (1 << 15);
- pci_write_config32(dev, 0x64, dword);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_PCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
- outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
- outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "sb700.h"
-
-static int sata_drive_detect(int portnum, u16 iobar)
-{
- u8 byte, byte2;
- int i = 0;
- outb(0xA0 + 0x10 * (portnum % 2), iobar + 0x6);
- while (byte = inb(iobar + 0x6), byte2 = inb(iobar + 0x7),
- (byte != (0xA0 + 0x10 * (portnum % 2))) ||
- ((byte2 & 0x88) != 0)) {
- printk(BIOS_SPEW, "0x6=%x, 0x7=%x\n", byte, byte2);
- if (byte != (0xA0 + 0x10 * (portnum % 2))) {
- /* This will happen at the first iteration of this loop
- * if the first SATA port is unpopulated and the
- * second SATA port is poulated.
- */
- printk(BIOS_DEBUG, "drive no longer selected after %i ms, "
- "retrying init\n", i * 10);
- return 1;
- } else
- printk(BIOS_SPEW, "drive detection not yet completed, "
- "waiting...\n");
- mdelay(10);
- i++;
- }
- printk(BIOS_SPEW, "drive detection done after %i ms\n", i * 10);
- return 0;
-}
-
- /* This function can be overloaded in mainboard.c */
-
-void __attribute__((weak)) sb700_setup_sata_phys(struct device *dev) {
- /* RPR7.6.1 Program the PHY Global Control to 0x2C00 */
- pci_write_config16(dev, 0x86, 0x2c00);
-
- /* RPR7.6.2 SATA GENI PHY ports setting */
- pci_write_config32(dev, 0x88, 0x01B48017);
- pci_write_config32(dev, 0x8c, 0x01B48019);
- pci_write_config32(dev, 0x90, 0x01B48016);
- pci_write_config32(dev, 0x94, 0x01B48016);
- pci_write_config32(dev, 0x98, 0x01B48016);
- pci_write_config32(dev, 0x9C, 0x01B48016);
-
- /* RPR7.6.3 SATA GEN II PHY port setting for port [0~5]. */
- pci_write_config16(dev, 0xA0, 0xA09A);
- pci_write_config16(dev, 0xA2, 0xA09F);
- pci_write_config16(dev, 0xA4, 0xA07A);
- pci_write_config16(dev, 0xA6, 0xA07A);
- pci_write_config16(dev, 0xA8, 0xA07A);
- pci_write_config16(dev, 0xAA, 0xA07A);
-}
-
-static void sata_init(struct device *dev)
-{
- u8 byte;
- u16 word;
- u32 dword;
- u8 rev_id;
- u32 sata_bar5;
- u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
- int i, j;
-
- struct southbridge_ati_sb700_config *conf;
- conf = dev->chip_info;
-
- device_t sm_dev;
- /* SATA SMBus Disable */
- /* sm_dev = pci_locate_device(PCI_ID(0x1002, 0x4385), 0); */
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- /* Disable SATA SMBUS */
- byte = pci_read_config8(sm_dev, 0xad);
- byte |= (1 << 1);
- /* Enable SATA and power saving */
- byte = pci_read_config8(sm_dev, 0xad);
- byte |= (1 << 0);
- byte |= (1 << 5);
- pci_write_config8(sm_dev, 0xad, byte);
-
- /* RPR 7.2 SATA Initialization */
- /* Set the interrupt Mapping to INTG# */
- byte = pci_read_config8(sm_dev, 0xaf);
- byte = 0x6 << 2;
- pci_write_config8(sm_dev, 0xaf, byte);
-
- /* get rev_id */
- rev_id = pci_read_config8(sm_dev, 0x08) - 0x28;
-
- /* get base address */
- sata_bar5 = pci_read_config32(dev, 0x24) & ~0x3FF;
- sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7;
- sata_bar1 = pci_read_config16(dev, 0x14) & ~0x3;
- sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7;
- sata_bar3 = pci_read_config16(dev, 0x1C) & ~0x3;
- sata_bar4 = pci_read_config16(dev, 0x20) & ~0xf;
-
- printk(BIOS_SPEW, "sata_bar0=%x\n", sata_bar0); /* 3030 */
- printk(BIOS_SPEW, "sata_bar1=%x\n", sata_bar1); /* 3070 */
- printk(BIOS_SPEW, "sata_bar2=%x\n", sata_bar2); /* 3040 */
- printk(BIOS_SPEW, "sata_bar3=%x\n", sata_bar3); /* 3080 */
- printk(BIOS_SPEW, "sata_bar4=%x\n", sata_bar4); /* 3000 */
- printk(BIOS_SPEW, "sata_bar5=%x\n", sata_bar5); /* e0309000 */
-
- /* disable combined mode */
- byte = pci_read_config8(sm_dev, 0xAD);
- byte &= ~(1 << 3);
- pci_write_config8(sm_dev, 0xAD, byte);
- /* Program the 2C to 0x43801002 */
- dword = 0x43801002;
- pci_write_config32(dev, 0x2c, dword);
-
- /* SERR-Enable */
- word = pci_read_config16(dev, 0x04);
- word |= (1 << 8);
- pci_write_config16(dev, 0x04, word);
-
- /* Dynamic power saving */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 2);
- pci_write_config8(dev, 0x40, byte);
-
- /* Set SATA Operation Mode, Set to IDE mode */
- byte = pci_read_config8(dev, 0x40);
- byte |= (1 << 0);
- byte |= (1 << 4);
- pci_write_config8(dev, 0x40, byte);
-
- dword = 0x01018f00;
- pci_write_config32(dev, 0x8, dword);
-
- byte = pci_read_config8(dev, 0x40);
- byte &= ~(1 << 0);
- pci_write_config8(dev, 0x40, byte);
-
- /* Enable the SATA watchdog counter */
- byte = pci_read_config8(dev, 0x44);
- byte |= (1 << 0);
- pci_write_config8(dev, 0x44, byte);
-
- /* Set bit 29 and 24 for A12 */
- dword = pci_read_config32(dev, 0x40);
- if (rev_id < 0x14) /* before A12 */
- dword |= (1 << 29);
- else
- dword &= ~(1 << 29); /* A14 and above */
- pci_write_config32(dev, 0x40, dword);
-
- /* set bit 21 for A12 */
- dword = pci_read_config32(dev, 0x48);
- if (rev_id < 0x14) /* before A12 */
- dword |= 1 << 24 | 1 << 21;
- else {
- dword &= ~(1 << 24 | 1 << 21); /* A14 and above */
- dword &= ~0xFF80; /* 15:7 */
- dword |= 1 << 15 | 0x7F << 7;
- }
- pci_write_config32(dev, 0x48, dword);
-
- /* Program the watchdog counter to 0x10 */
- byte = 0x10;
- pci_write_config8(dev, 0x46, byte);
- sb700_setup_sata_phys(dev);
- /* Enable the I/O, MM, BusMaster access for SATA */
- byte = pci_read_config8(dev, 0x4);
- byte |= 7 << 0;
- pci_write_config8(dev, 0x4, byte);
-
- /* RPR7.7 SATA drive detection. */
- /* Use BAR5+0x128,BAR0 for Primary Slave */
- /* Use BAR5+0x1A8,BAR0 for Primary Slave */
- /* Use BAR5+0x228,BAR2 for Secondary Master */
- /* Use BAR5+0x2A8,BAR2 for Secondary Slave */
- /* Use BAR5+0x328,PATA_BAR0/2 for Primary/Secondary master emulation */
- /* Use BAR5+0x3A8,PATA_BAR0/2 for Primary/Secondary Slave emulation */
-
- /* TODO: port 4,5, which are PATA emulations. What are PATA_BARs? */
-
- for (i = 0; i < 4; i++) {
- byte = read8(sata_bar5 + 0x128 + 0x80 * i);
- printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
- byte &= 0xF;
- if( byte == 0x1 ) {
- /* If the drive status is 0x1 then we see it but we aren't talking to it. */
- /* Try to do something about it. */
- printk(BIOS_SPEW, "SATA device detected but not talking. Trying lower speed.\n");
-
- /* Read in Port-N Serial ATA Control Register */
- byte = read8(sata_bar5 + 0x12C + 0x80 * i);
-
- /* Set Reset Bit and 1.5g bit */
- byte |= 0x11;
- write8((sata_bar5 + 0x12C + 0x80 * i), byte);
-
- /* Wait 1ms */
- mdelay(1);
-
- /* Clear Reset Bit */
- byte &= ~0x01;
- write8((sata_bar5 + 0x12C + 0x80 * i), byte);
-
- /* Wait 1ms */
- mdelay(1);
-
- /* Reread status */
- byte = read8(sata_bar5 + 0x128 + 0x80 * i);
- printk(BIOS_SPEW, "SATA port %i status = %x\n", i, byte);
- byte &= 0xF;
- }
-
- if (byte == 0x3) {
- for (j = 0; j < 10; j++) {
- if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))
- break;
- }
- printk(BIOS_DEBUG, "%s %s device is %sready after %i tries\n",
- (i / 2) ? "Secondary" : "Primary",
- (i % 2 ) ? "Slave" : "Master",
- (j == 10) ? "not " : "",
- (j == 10) ? j : j + 1);
- } else {
- printk(BIOS_DEBUG, "No %s %s SATA drive on Slot%i\n",
- (i / 2) ? "Secondary" : "Primary",
- (i % 2 ) ? "Slave" : "Master", i);
- }
- }
-
- /* Below is CIM InitSataLateFar */
- /* Enable interrupts from the HBA */
- byte = read8(sata_bar5 + 0x4);
- byte |= 1 << 1;
- write8((sata_bar5 + 0x4), byte);
-
- /* Clear error status */
- write32((sata_bar5 + 0x130), 0xFFFFFFFF);
- write32((sata_bar5 + 0x1b0), 0xFFFFFFFF);
- write32((sata_bar5 + 0x230), 0xFFFFFFFF);
- write32((sata_bar5 + 0x2b0), 0xFFFFFFFF);
- write32((sata_bar5 + 0x330), 0xFFFFFFFF);
- write32((sata_bar5 + 0x3b0), 0xFFFFFFFF);
-
- /* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */
- /* ????? why CIM does not set the AcpiGpe0BlkAddr , but use it??? */
-
- /* word = 0x0000; */
- /* word = pm_ioread(0x28); */
- /* byte = pm_ioread(0x29); */
- /* word |= byte<<8; */
- /* printk(BIOS_DEBUG, "AcpiGpe0Blk addr = %x\n", word); */
- /* write32(word, 0x80000000); */
-}
-
-static struct pci_operations lops_pci = {
- /* .set_subsystem = pci_dev_set_subsystem, */
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_SATA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <pc80/mc146818rtc.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <cpu/x86/lapic.h>
-#include <arch/ioapic.h>
-#include <stdlib.h>
-#include "sb700.h"
-#include "sb700_smbus.c"
-
-#define NMI_OFF 0
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-/*
-* SB700 enables all USB controllers by default in SMBUS Control.
-* SB700 enables SATA by default in SMBUS Control.
-*/
-static void sm_init(device_t dev)
-{
- u8 byte;
- u8 byte_old;
- u32 dword;
- u32 ioapic_base;
- u32 on;
- u32 nmi_option;
-
- printk(BIOS_INFO, "sm_init().\n");
-
- ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */
- /* Don't rename APIC ID */
- /* TODO: We should call setup_ioapic() here. But kernel hangs if cpu is K8.
- * We need to check out why and change back. */
- clear_ioapic(ioapic_base);
-
- /* 2.10 Interrupt Routing/Filtering */
- dword = pci_read_config8(dev, 0x62);
- dword |= 3;
- pci_write_config8(dev, 0x62, dword);
-
- /* Delay back to back interrupts to the CPU. */
- dword = pci_read_config16(dev, 0x64);
- dword |= 1 << 13;
- pci_write_config16(dev, 0x64, dword);
-
- /* rrg:K8 INTR Enable (BIOS should set this bit after PIC initialization) */
- /* rpr 2.1 Enabling Legacy Interrupt */
- dword = pci_read_config8(dev, 0x62);
- dword |= 1 << 2;
- pci_write_config8(dev, 0x62, dword);
-
- dword = pci_read_config32(dev, 0x78);
- dword |= 1 << 9;
- pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */
-
- /* bit 10: MultiMediaTimerIrqEn */
- dword = pci_read_config8(dev, 0x64);
- dword |= 1 << 10;
- pci_write_config8(dev, 0x64, dword);
- /* enable serial irq */
- byte = pci_read_config8(dev, 0x69);
- byte |= 1 << 7; /* enable serial irq function */
- byte &= ~(0xF << 2);
- byte |= 4 << 2; /* set NumSerIrqBits=4 */
- pci_write_config8(dev, 0x69, byte);
-
- /* IRQ0From8254 */
- byte = pci_read_config8(dev, 0x41);
- byte &= ~(1 << 7);
- pci_write_config8(dev, 0x41, byte);
-
- byte = pm_ioread(0x61);
- byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */
- pm_iowrite(0x61, byte);
-
- /* disable SMI */
- byte = pm_ioread(0x53);
- byte |= 1 << 3;
- pm_iowrite(0x53, byte);
-
- /* power after power fail */
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pm_ioread(0x74);
- byte &= ~0x03;
- if (on) {
- byte |= 2;
- }
- byte |= 1 << 2;
- pm_iowrite(0x74, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
-
- byte = pm_ioread(0x68);
- byte &= ~(1 << 1);
- /* 2.7 */
- byte |= 1 << 2;
- pm_iowrite(0x68, byte);
-
- /* 2.7 */
- byte = pm_ioread(0x65);
- byte &= ~(1 << 7);
- pm_iowrite(0x65, byte);
-
- /* 2.16 */
- byte = pm_ioread(0x55);
- byte |= 1 << 5;
- pm_iowrite(0x55, byte);
-
- byte = pm_ioread(0xD7);
- byte |= 1 << 6 | 1 << 1;;
- pm_iowrite(0xD7, byte);
-
- /* 2.15 */
- byte = pm_ioread(0x42);
- byte &= ~(1 << 2);
- pm_iowrite(0x42, byte);
-
- /* Set up NMI on errors */
- byte = inb(0x70); /* RTC70 */
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- printk(BIOS_INFO, "++++++++++set NMI+++++\n");
- } else {
- byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */
- printk(BIOS_INFO, "++++++++++no set NMI+++++\n");
- }
- byte &= ~(1 << 7);
- if (byte != byte_old) {
- outb(byte, 0x70);
- }
-
- /* 2.11 IO Trap Settings */
- abcfg_reg(0x10090, 1 << 16, 1 << 16);
-
- /* ab index */
- pci_write_config32(dev, 0xF0, AB_INDX);
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* 4.3 Enabling Upstream DMA Access */
- axcfg_reg(0x04, 1 << 2, 1 << 2);
- /* 4.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */
- abcfg_reg(0x10060, 9 << 17, 9 << 17);
- abcfg_reg(0x10064, 9 << 17, 9 << 17);
-
- /* 4.5 Enabling OHCI Prefetch for Performance Enhancement, A12 */
- abcfg_reg(0x80, 1 << 0, 1<< 0);
-
- /* 4.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */
- /* 4.7 Enabling Additional Address Bits Checking in Downstream */
- /* 4.15 IO write and SMI ordering enhancement*/
- abcfg_reg(0x9c, 3 << 0 | 1 << 8, 3 << 0 | 1 << 8);
-
- /* 4.8 Set B-Link Prefetch Mode */
- abcfg_reg(0x80, 3 << 17, 3 << 17);
-
- /* 4.9 Enabling Detection of Upstream Interrupts */
- abcfg_reg(0x94, 1 << 20 | 0x7FFFF, 1 << 20 | 0x00FEE);
-
- /* 4.10: Enabling Downstream Posted Transactions to Pass Non-Posted
- * Transactions for the K8 Platform (for All Revisions) */
- abcfg_reg(0x10090, 1 << 8, 1 << 8);
-
- /* 4.11:Programming Cycle Delay for AB and BIF Clock Gating */
- /* 4.12: Enabling AB and BIF Clock Gating */
- abcfg_reg(0x10054, 0xFFFF0000, 0x1040000);
- abcfg_reg(0x54, 0xFF << 16, 4 << 16);
- abcfg_reg(0x54, 1 << 24, 0 << 24);
- abcfg_reg(0x98, 0x0000FF00, 0x00004700);
-
- /* 4.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */
- abcfg_reg(0x10054, 0x0000FFFF, 0x07FF);
-
- /* 4.14:Enabling Requester ID for upstream traffic. */
- abcfg_reg(0x98, 1 << 16, 1 << 16);
-
- /* 9.2: Enabling IDE Data Bus DD7 Pull Down Resistor */
- byte = pm2_ioread(0xE5);
- byte |= 1 << 2;
- pm2_iowrite(0xE5, byte);
-
- /* Enable IDE controller. */
- byte = pm_ioread(0x59);
- byte &= ~(1 << 1);
- pm_iowrite(0x59, byte);
-
- printk(BIOS_INFO, "sm_init() end\n");
-
- /* Enable NbSb virtual channel */
- axcfg_reg(0x114, 0x3f << 1, 0 << 1);
- axcfg_reg(0x120, 0x7f << 1, 0x7f << 1);
- axcfg_reg(0x120, 7 << 24, 1 << 24);
- axcfg_reg(0x120, 1 << 31, 1 << 31);
- abcfg_reg(0x50, 1 << 3, 1 << 3);
-}
-
-static int lsmbus_recv_byte(device_t dev)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, u8 val)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
-{
- u32 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-static void sb700_sm_read_resources(device_t dev)
-{
- struct resource *res;
- u8 byte;
-
- /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
- byte = pm_ioread(0x55);
- byte |= 1 << 7;
- pm_iowrite(0x55, byte);
-
- /* Get the normal pci resources of this device */
- /* pci_dev_read_resources(dev); */
-
- byte = pm_ioread(0x55);
- byte &= ~(1 << 7);
- pm_iowrite(0x55, byte);
-
- /* apic */
- res = new_resource(dev, 0x74);
- res->base = IO_APIC_ADDR;
- res->size = 256 * 0x10;
- res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
-
- #if 0 /* Linux ACPI crashes when it is 1. For late debugging. */
- res = new_resource(dev, 0x14); /* TODO: hpet */
- res->base = 0xfed00000; /* reset hpet to widely accepted address */
- res->size = 0x400;
- res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
- #endif
- /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
-
- /* smbus */
- res = new_resource(dev, 0x90);
- res->base = 0xB00;
- res->size = 0x10;
- res->limit = 0xFFFFUL; /* res->base + res->size -1; */
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
-
- compact_resources(dev);
-}
-
-static void sb700_sm_set_resources(struct device *dev)
-{
- struct resource *res;
- u8 byte;
-
- pci_dev_set_resources(dev);
-
- /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */
- byte = pm_ioread(0x52);
- byte |= 1 << 6;
- pm_iowrite(0x52, byte);
-
- res = find_resource(dev, 0x74);
- pci_write_config32(dev, 0x74, res->base | 1 << 3);
-#if 0 /* TODO:hpet */
- res = find_resource(dev, 0x14);
- pci_write_config32(dev, 0x14, res->base);
-#endif
- res = find_resource(dev, 0x90);
- pci_write_config32(dev, 0x90, res->base | 1);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = sb700_sm_read_resources,
- .set_resources = sb700_sm_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sm_init,
- .scan_bus = scan_static_bus,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_SM,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef _SB700_SMBUS_C_
-#define _SB700_SMBUS_C_
-
-#include "sb700_smbus.h"
-
-static inline void smbus_delay(void)
-{
- outb(inb(0x80), 0x80);
-}
-
-static int smbus_wait_until_ready(u32 smbus_io_base)
-{
- u32 loops;
- loops = SMBUS_TIMEOUT;
- do {
- u8 val;
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f;
- if (val == 0) { /* ready now */
- return 0;
- }
- outb(val, smbus_io_base + SMBHSTSTAT);
- } while (--loops);
- return -2; /* time out */
-}
-
-static int smbus_wait_until_done(u32 smbus_io_base)
-{
- u32 loops;
- loops = SMBUS_TIMEOUT;
- do {
- u8 val;
-
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f; /* mask off reserved bits */
- if (val & 0x1c) {
- return -5; /* error */
- }
- if (val == 0x02) {
- outb(val, smbus_io_base + SMBHSTSTAT); /* clear status */
- return 0;
- }
- } while (--loops);
- return -3; /* timeout */
-}
-
-int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTCMD);
-
- return byte;
-}
-
-int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command... */
- outb(val, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- return 0;
-}
-
-int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- return byte;
-}
-
-int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val)
-{
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; /* not ready */
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
-
- /* output value */
- outb(val, smbus_io_base + SMBHSTDAT0);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; /* Clear [4:2] */
- byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; /* timeout or error */
- }
-
- return 0;
-}
-
-static void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
-{
- u32 tmp;
-
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
- tmp = inl(AB_DATA);
- /* rpr 4.2
- * For certain revisions of the chip, the ABCFG registers,
- * with an address of 0x100NN (where 'N' is any hexadecimal
- * number), require an extra programming step.*/
- reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
-
- tmp &= ~mask;
- tmp |= val;
-
- /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
- outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
- outl(tmp, AB_DATA);
- reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
-}
-
-/* space = 0: AX_INDXC, AX_DATAC
- * space = 1: AX_INDXP, AX_DATAP
- */
-static inline void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
- u32 mask, u32 val)
-{
- u32 tmp;
-
- /* read axindc to tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- tmp = inl(AB_DATA);
-
- tmp &= ~mask;
- tmp |= val;
-
- /* write tmp */
- outl(space << 30 | space << 3 | 0x30, AB_INDX);
- outl(axindc, AB_DATA);
- outl(space << 30 | space << 3 | 0x34, AB_INDX);
- outl(tmp, AB_DATA);
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef SB700_SMBUS_H
-#define SB700_SMBUS_H
-
-#define SMBHSTSTAT 0x0
-#define SMBSLVSTAT 0x1
-#define SMBHSTCTRL 0x2
-#define SMBHSTCMD 0x3
-#define SMBHSTADDR 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBHSTBLKDAT 0x7
-
-#define SMBSLVCTRL 0x8
-#define SMBSLVCMD_SHADOW 0x9
-#define SMBSLVEVT 0xa
-#define SMBSLVDAT 0xc
-
-#define AX_INDXC 0
-#define AX_INDXP 1
-#define AXCFG 2
-#define ABCFG 3
-
-#define AB_INDX 0xCD8
-#define AB_DATA (AB_INDX+4)
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100*1000*10)
-
-#define abcfg_reg(reg, mask, val) \
- alink_ab_indx((ABCFG), (reg), (mask), (val))
-#define axcfg_reg(reg, mask, val) \
- alink_ab_indx((AXCFG), (reg), (mask), (val))
-#define axindxc_reg(reg, mask, val) \
- alink_ax_indx(0, (reg), (mask), (val))
-#define axindxp_reg(reg, mask, val) \
- alink_ax_indx(1, (reg), (mask), (val))
-
-int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
-int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
-int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
-int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
-
-
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Advanced Micro Devices, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <usbdebug.h>
-#include <arch/io.h>
-#include "sb700.h"
-
-static struct pci_operations lops_pci = {
- .set_subsystem = pci_dev_set_subsystem,
-};
-
-static void usb_init(struct device *dev)
-{
- u8 byte;
- u16 word;
-
- /* 6.1 Enable OHCI0-4 and EHCI Controllers */
- device_t sm_dev;
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- byte = pci_read_config8(sm_dev, 0x68);
- byte |= 0xFF;
- pci_write_config8(sm_dev, 0x68, byte);
-
- /* RPR 6.2 Enables the USB PME Event,Enable USB resume support */
- byte = pm_ioread(0x61);
- byte |= 1 << 6;
- pm_iowrite(0x61, byte);
- byte = pm_ioread(0x65);
- byte |= 1 << 2;
- pm_iowrite(0x65, byte);
-
- /* RPR 6.3 Support USB device wakeup from the S4/S5 state */
- byte = pm_ioread(0x65);
- byte &= ~(1 << 0);
- pm_iowrite(0x65, byte);
-
- /* RPR 6.5 Enable the USB controller to get reset by any software that generate a PCIRst# condition */
- byte = pm_ioread(0x65);
- byte |= (1 << 4);
- pm_iowrite(0x65, byte);
-
- /* RPR 6.10 Disable OHCI MSI Capability. */
- word = pci_read_config16(dev, 0x40);
- word |= (0x3 << 8);
- pci_write_config16(dev, 0x40, word);
-}
-
-static void usb_init2(struct device *dev)
-{
- u32 dword;
- u32 usb2_bar0;
- device_t sm_dev;
- u8 rev;
-
- sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
- rev = get_sb700_revision(sm_dev);
-
- /* dword = pci_read_config32(dev, 0xf8); */
- /* dword |= 40; */
- /* pci_write_config32(dev, 0xf8, dword); */
-
- usb2_bar0 = pci_read_config32(dev, 0x10) & ~0xFF;
- printk(BIOS_INFO, "usb2_bar0=0x%x\n", usb2_bar0);
-
- /* RPR6.4 Enables the USB PHY auto calibration resister to match 45ohm resistance */
- dword = 0x00020F00;
- write32(usb2_bar0 + 0xC0, dword);
-
- /* RPR6.9 Sets In/OUT FIFO threshold for best performance */
- dword = 0x00400040;
- write32(usb2_bar0 + 0xA4, dword);
-
- /* RPR6.11 Disabling EHCI Advance Asynchronous Enhancement */
- dword = pci_read_config32(dev, 0x50);
- dword |= (1 << 28);
- pci_write_config32(dev, 0x50, dword);
-
- /* RPR 6.12 EHCI Advance PHY Power Savings */
- /* RPR says it is just for A12. CIMM sets it when it is above A11. */
- /* But it makes the linux crash, so we skip it */
- #if 0
- dword = pci_read_config32(dev, 0x50);
- dword |= 1 << 31;
- pci_write_config32(dev, 0x50, dword);
- #endif
-
- /* RPR6.13 Enabling Fix for EHCI Controller Driver Yellow Sign Issue */
- /* RPR says it is just for A12. CIMx sets it when it is above A11. */
- dword = pci_read_config32(dev, 0x50);
- dword |= (1 << 20);
- pci_write_config32(dev, 0x50, dword);
-
- /* RPR6.15 EHCI Async Park Mode */
- dword = pci_read_config32(dev, 0x50);
- dword |= (1 << 23);
- pci_write_config32(dev, 0x50, dword);
-
- /* Each step below causes the linux crashes. Leave them here
- * for future debugging. */
-#if 0
- u8 byte;
- u16 word;
-
- /* RPR6.16 Disable EHCI MSI support */
- byte = pci_read_config8(dev, 0x50);
- byte |= (1 << 6);
- pci_write_config8(dev, 0x50, byte);
-
- /* RPR6.17 Disable the EHCI Dynamic Power Saving feature */
- word = read32(usb2_bar0 + 0xBC);
- word &= ~(1 << 12);
- write16(usb2_bar0 + 0xBC, word);
-
- /* RPR6.19 USB Controller DMA Read Delay Tolerant. */
- if (rev >= REV_SB700_A14) {
- byte = pci_read_config8(dev, 0x50);
- byte |= (1 << 7);
- pci_write_config8(dev, 0x50, byte);
- }
-
- /* RPR6.20 Async Park Mode. */
- /* RPR recommends not to set these bits. */
- #if 0
- dword = pci_read_config32(dev, 0x50);
- dword |= 1 << 23;
- if (rev >= REV_SB700_A14) {
- dword &= ~(1 << 2);
- }
- pci_write_config32(dev, 0x50, dword);
- #endif
-
- /* RPR6.22 Advance Async Enhancement */
- /* RPR6.23 USB Periodic Cache Setting */
- dword = pci_read_config32(dev, 0x50);
- if (rev == REV_SB700_A12) {
- dword |= 1 << 28; /* 6.22 */
- dword |= 1 << 27; /* 6.23 */
- } else if (rev >= REV_SB700_A14) {
- dword |= 1 << 3;
- dword &= ~(1 << 28); /* 6.22 */
- dword |= 1 << 8;
- dword &= ~(1 << 27); /* 6.23 */
- }
- printk(BIOS_DEBUG, "rpr 6.23, final dword=%x\n", dword);
-#endif
-}
-
-static void usb_set_resources(struct device *dev)
-{
-#if CONFIG_USBDEBUG
- struct resource *res;
- u32 base;
- u32 old_debug;
-
- old_debug = get_ehci_debug();
- set_ehci_debug(0);
-#endif
- pci_dev_set_resources(dev);
-
-#if CONFIG_USBDEBUG
- res = find_resource(dev, 0x10);
- set_ehci_debug(old_debug);
- if (!res)
- return;
- base = res->base;
- set_ehci_base(base);
- report_resource_stored(dev, res, "");
-#endif
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb_set_resources, /* pci_dev_set_resources, */
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_0_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_USB_18_0,
-};
-
-static const struct pci_driver usb_1_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_USB_18_1,
-};
-
-/* the pci id of usb ctrl 0 and 1 are the same. */
-/*
- * static const struct pci_driver usb_3_driver __pci_driver = {
- * .ops = &usb_ops,
- * .vendor = PCI_VENDOR_ID_ATI,
- * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_0,
- * };
- * static const struct pci_driver usb_4_driver __pci_driver = {
- * .ops = &usb_ops,
- * .vendor = PCI_VENDOR_ID_ATI,
- * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_1,
- * };
- */
-
-static const struct pci_driver usb_4_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_USB_20_5,
-};
-
-static struct device_operations usb_ops2 = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb_set_resources, /* pci_dev_set_resources, */
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init2,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_5_driver __pci_driver = {
- .ops = &usb_ops2,
- .vendor = PCI_VENDOR_ID_ATI,
- .device = PCI_DEVICE_ID_ATI_SB700_USB_18_2,
-};
-/*
- * static const struct pci_driver usb_5_driver __pci_driver = {
- * .ops = &usb_ops2,
- * .vendor = PCI_VENDOR_ID_ATI,
- * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_2,
- * };
- */
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <pc80/mc146818rtc.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <cpu/x86/lapic.h>
+#include <arch/ioapic.h>
+#include <stdlib.h>
+#include "sb700.h"
+#include "smbus.c"
+
+#define NMI_OFF 0
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+/*
+* SB700 enables all USB controllers by default in SMBUS Control.
+* SB700 enables SATA by default in SMBUS Control.
+*/
+static void sm_init(device_t dev)
+{
+ u8 byte;
+ u8 byte_old;
+ u32 dword;
+ u32 ioapic_base;
+ u32 on;
+ u32 nmi_option;
+
+ printk(BIOS_INFO, "sm_init().\n");
+
+ ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */
+ /* Don't rename APIC ID */
+ /* TODO: We should call setup_ioapic() here. But kernel hangs if cpu is K8.
+ * We need to check out why and change back. */
+ clear_ioapic(ioapic_base);
+
+ /* 2.10 Interrupt Routing/Filtering */
+ dword = pci_read_config8(dev, 0x62);
+ dword |= 3;
+ pci_write_config8(dev, 0x62, dword);
+
+ /* Delay back to back interrupts to the CPU. */
+ dword = pci_read_config16(dev, 0x64);
+ dword |= 1 << 13;
+ pci_write_config16(dev, 0x64, dword);
+
+ /* rrg:K8 INTR Enable (BIOS should set this bit after PIC initialization) */
+ /* rpr 2.1 Enabling Legacy Interrupt */
+ dword = pci_read_config8(dev, 0x62);
+ dword |= 1 << 2;
+ pci_write_config8(dev, 0x62, dword);
+
+ dword = pci_read_config32(dev, 0x78);
+ dword |= 1 << 9;
+ pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */
+
+ /* bit 10: MultiMediaTimerIrqEn */
+ dword = pci_read_config8(dev, 0x64);
+ dword |= 1 << 10;
+ pci_write_config8(dev, 0x64, dword);
+ /* enable serial irq */
+ byte = pci_read_config8(dev, 0x69);
+ byte |= 1 << 7; /* enable serial irq function */
+ byte &= ~(0xF << 2);
+ byte |= 4 << 2; /* set NumSerIrqBits=4 */
+ pci_write_config8(dev, 0x69, byte);
+
+ /* IRQ0From8254 */
+ byte = pci_read_config8(dev, 0x41);
+ byte &= ~(1 << 7);
+ pci_write_config8(dev, 0x41, byte);
+
+ byte = pm_ioread(0x61);
+ byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */
+ pm_iowrite(0x61, byte);
+
+ /* disable SMI */
+ byte = pm_ioread(0x53);
+ byte |= 1 << 3;
+ pm_iowrite(0x53, byte);
+
+ /* power after power fail */
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pm_ioread(0x74);
+ byte &= ~0x03;
+ if (on) {
+ byte |= 2;
+ }
+ byte |= 1 << 2;
+ pm_iowrite(0x74, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
+
+ byte = pm_ioread(0x68);
+ byte &= ~(1 << 1);
+ /* 2.7 */
+ byte |= 1 << 2;
+ pm_iowrite(0x68, byte);
+
+ /* 2.7 */
+ byte = pm_ioread(0x65);
+ byte &= ~(1 << 7);
+ pm_iowrite(0x65, byte);
+
+ /* 2.16 */
+ byte = pm_ioread(0x55);
+ byte |= 1 << 5;
+ pm_iowrite(0x55, byte);
+
+ byte = pm_ioread(0xD7);
+ byte |= 1 << 6 | 1 << 1;;
+ pm_iowrite(0xD7, byte);
+
+ /* 2.15 */
+ byte = pm_ioread(0x42);
+ byte &= ~(1 << 2);
+ pm_iowrite(0x42, byte);
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); /* RTC70 */
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ printk(BIOS_INFO, "++++++++++set NMI+++++\n");
+ } else {
+ byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */
+ printk(BIOS_INFO, "++++++++++no set NMI+++++\n");
+ }
+ byte &= ~(1 << 7);
+ if (byte != byte_old) {
+ outb(byte, 0x70);
+ }
+
+ /* 2.11 IO Trap Settings */
+ abcfg_reg(0x10090, 1 << 16, 1 << 16);
+
+ /* ab index */
+ pci_write_config32(dev, 0xF0, AB_INDX);
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* 4.3 Enabling Upstream DMA Access */
+ axcfg_reg(0x04, 1 << 2, 1 << 2);
+ /* 4.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */
+ abcfg_reg(0x10060, 9 << 17, 9 << 17);
+ abcfg_reg(0x10064, 9 << 17, 9 << 17);
+
+ /* 4.5 Enabling OHCI Prefetch for Performance Enhancement, A12 */
+ abcfg_reg(0x80, 1 << 0, 1<< 0);
+
+ /* 4.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */
+ /* 4.7 Enabling Additional Address Bits Checking in Downstream */
+ /* 4.15 IO write and SMI ordering enhancement*/
+ abcfg_reg(0x9c, 3 << 0 | 1 << 8, 3 << 0 | 1 << 8);
+
+ /* 4.8 Set B-Link Prefetch Mode */
+ abcfg_reg(0x80, 3 << 17, 3 << 17);
+
+ /* 4.9 Enabling Detection of Upstream Interrupts */
+ abcfg_reg(0x94, 1 << 20 | 0x7FFFF, 1 << 20 | 0x00FEE);
+
+ /* 4.10: Enabling Downstream Posted Transactions to Pass Non-Posted
+ * Transactions for the K8 Platform (for All Revisions) */
+ abcfg_reg(0x10090, 1 << 8, 1 << 8);
+
+ /* 4.11:Programming Cycle Delay for AB and BIF Clock Gating */
+ /* 4.12: Enabling AB and BIF Clock Gating */
+ abcfg_reg(0x10054, 0xFFFF0000, 0x1040000);
+ abcfg_reg(0x54, 0xFF << 16, 4 << 16);
+ abcfg_reg(0x54, 1 << 24, 0 << 24);
+ abcfg_reg(0x98, 0x0000FF00, 0x00004700);
+
+ /* 4.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */
+ abcfg_reg(0x10054, 0x0000FFFF, 0x07FF);
+
+ /* 4.14:Enabling Requester ID for upstream traffic. */
+ abcfg_reg(0x98, 1 << 16, 1 << 16);
+
+ /* 9.2: Enabling IDE Data Bus DD7 Pull Down Resistor */
+ byte = pm2_ioread(0xE5);
+ byte |= 1 << 2;
+ pm2_iowrite(0xE5, byte);
+
+ /* Enable IDE controller. */
+ byte = pm_ioread(0x59);
+ byte &= ~(1 << 1);
+ pm_iowrite(0x59, byte);
+
+ printk(BIOS_INFO, "sm_init() end\n");
+
+ /* Enable NbSb virtual channel */
+ axcfg_reg(0x114, 0x3f << 1, 0 << 1);
+ axcfg_reg(0x120, 0x7f << 1, 0x7f << 1);
+ axcfg_reg(0x120, 7 << 24, 1 << 24);
+ axcfg_reg(0x120, 1 << 31, 1 << 31);
+ abcfg_reg(0x50, 1 << 3, 1 << 3);
+}
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, u8 val)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
+{
+ u32 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static void sb700_sm_read_resources(device_t dev)
+{
+ struct resource *res;
+ u8 byte;
+
+ /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
+ byte = pm_ioread(0x55);
+ byte |= 1 << 7;
+ pm_iowrite(0x55, byte);
+
+ /* Get the normal pci resources of this device */
+ /* pci_dev_read_resources(dev); */
+
+ byte = pm_ioread(0x55);
+ byte &= ~(1 << 7);
+ pm_iowrite(0x55, byte);
+
+ /* apic */
+ res = new_resource(dev, 0x74);
+ res->base = IO_APIC_ADDR;
+ res->size = 256 * 0x10;
+ res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+
+ #if 0 /* Linux ACPI crashes when it is 1. For late debugging. */
+ res = new_resource(dev, 0x14); /* TODO: hpet */
+ res->base = 0xfed00000; /* reset hpet to widely accepted address */
+ res->size = 0x400;
+ res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
+ #endif
+ /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
+
+ /* smbus */
+ res = new_resource(dev, 0x90);
+ res->base = 0xB00;
+ res->size = 0x10;
+ res->limit = 0xFFFFUL; /* res->base + res->size -1; */
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
+
+ compact_resources(dev);
+}
+
+static void sb700_sm_set_resources(struct device *dev)
+{
+ struct resource *res;
+ u8 byte;
+
+ pci_dev_set_resources(dev);
+
+ /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */
+ byte = pm_ioread(0x52);
+ byte |= 1 << 6;
+ pm_iowrite(0x52, byte);
+
+ res = find_resource(dev, 0x74);
+ pci_write_config32(dev, 0x74, res->base | 1 << 3);
+#if 0 /* TODO:hpet */
+ res = find_resource(dev, 0x14);
+ pci_write_config32(dev, 0x14, res->base);
+#endif
+ res = find_resource(dev, 0x90);
+ pci_write_config32(dev, 0x90, res->base | 1);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = sb700_sm_read_resources,
+ .set_resources = sb700_sm_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sm_init,
+ .scan_bus = scan_static_bus,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_SM,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SB700_SMBUS_C_
+#define _SB700_SMBUS_C_
+
+#include "smbus.h"
+
+static inline void smbus_delay(void)
+{
+ outb(inb(0x80), 0x80);
+}
+
+static int smbus_wait_until_ready(u32 smbus_io_base)
+{
+ u32 loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ u8 val;
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0) { /* ready now */
+ return 0;
+ }
+ outb(val, smbus_io_base + SMBHSTSTAT);
+ } while (--loops);
+ return -2; /* time out */
+}
+
+static int smbus_wait_until_done(u32 smbus_io_base)
+{
+ u32 loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ u8 val;
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f; /* mask off reserved bits */
+ if (val & 0x1c) {
+ return -5; /* error */
+ }
+ if (val == 0x02) {
+ outb(val, smbus_io_base + SMBHSTSTAT); /* clear status */
+ return 0;
+ }
+ } while (--loops);
+ return -3; /* timeout */
+}
+
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ return byte;
+}
+
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 2) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ return 0;
+}
+
+int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ return byte;
+}
+
+int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val)
+{
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; /* not ready */
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBHSTADDR);
+
+ /* output value */
+ outb(val, smbus_io_base + SMBHSTDAT0);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; /* Clear [4:2] */
+ byte |= (1 << 3) | (1 << 6); /* Byte data read/write command, start the command */
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; /* timeout or error */
+ }
+
+ return 0;
+}
+
+static void alink_ab_indx(u32 reg_space, u32 reg_addr, u32 mask, u32 val)
+{
+ u32 tmp;
+
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX);
+ tmp = inl(AB_DATA);
+ /* rpr 4.2
+ * For certain revisions of the chip, the ABCFG registers,
+ * with an address of 0x100NN (where 'N' is any hexadecimal
+ * number), require an extra programming step.*/
+ reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* printk(BIOS_DEBUG, "about write %x, index=%x", tmp, (reg_space&0x3)<<30 | reg_addr); */
+ outl((reg_space & 0x3) << 30 | reg_addr, AB_INDX); /* probably we dont have to do it again. */
+ outl(tmp, AB_DATA);
+ reg_addr & 0x10000 ? outl(0, AB_INDX) : NULL;
+}
+
+/* space = 0: AX_INDXC, AX_DATAC
+ * space = 1: AX_INDXP, AX_DATAP
+ */
+static inline void alink_ax_indx(u32 space /*c or p? */ , u32 axindc,
+ u32 mask, u32 val)
+{
+ u32 tmp;
+
+ /* read axindc to tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ tmp = inl(AB_DATA);
+
+ tmp &= ~mask;
+ tmp |= val;
+
+ /* write tmp */
+ outl(space << 30 | space << 3 | 0x30, AB_INDX);
+ outl(axindc, AB_DATA);
+ outl(space << 30 | space << 3 | 0x34, AB_INDX);
+ outl(tmp, AB_DATA);
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef SB700_SMBUS_H
+#define SB700_SMBUS_H
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTRL 0x2
+#define SMBHSTCMD 0x3
+#define SMBHSTADDR 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBHSTBLKDAT 0x7
+
+#define SMBSLVCTRL 0x8
+#define SMBSLVCMD_SHADOW 0x9
+#define SMBSLVEVT 0xa
+#define SMBSLVDAT 0xc
+
+#define AX_INDXC 0
+#define AX_INDXP 1
+#define AXCFG 2
+#define ABCFG 3
+
+#define AB_INDX 0xCD8
+#define AB_DATA (AB_INDX+4)
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+#define abcfg_reg(reg, mask, val) \
+ alink_ab_indx((ABCFG), (reg), (mask), (val))
+#define axcfg_reg(reg, mask, val) \
+ alink_ab_indx((AXCFG), (reg), (mask), (val))
+#define axindxc_reg(reg, mask, val) \
+ alink_ax_indx(0, (reg), (mask), (val))
+#define axindxp_reg(reg, mask, val) \
+ alink_ax_indx(1, (reg), (mask), (val))
+
+int do_smbus_recv_byte(u32 smbus_io_base, u32 device);
+int do_smbus_send_byte(u32 smbus_io_base, u32 device, u8 val);
+int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
+int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address, u8 val);
+
+
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <usbdebug.h>
+#include <arch/io.h>
+#include "sb700.h"
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = pci_dev_set_subsystem,
+};
+
+static void usb_init(struct device *dev)
+{
+ u8 byte;
+ u16 word;
+
+ /* 6.1 Enable OHCI0-4 and EHCI Controllers */
+ device_t sm_dev;
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ byte = pci_read_config8(sm_dev, 0x68);
+ byte |= 0xFF;
+ pci_write_config8(sm_dev, 0x68, byte);
+
+ /* RPR 6.2 Enables the USB PME Event,Enable USB resume support */
+ byte = pm_ioread(0x61);
+ byte |= 1 << 6;
+ pm_iowrite(0x61, byte);
+ byte = pm_ioread(0x65);
+ byte |= 1 << 2;
+ pm_iowrite(0x65, byte);
+
+ /* RPR 6.3 Support USB device wakeup from the S4/S5 state */
+ byte = pm_ioread(0x65);
+ byte &= ~(1 << 0);
+ pm_iowrite(0x65, byte);
+
+ /* RPR 6.5 Enable the USB controller to get reset by any software that generate a PCIRst# condition */
+ byte = pm_ioread(0x65);
+ byte |= (1 << 4);
+ pm_iowrite(0x65, byte);
+
+ /* RPR 6.10 Disable OHCI MSI Capability. */
+ word = pci_read_config16(dev, 0x40);
+ word |= (0x3 << 8);
+ pci_write_config16(dev, 0x40, word);
+}
+
+static void usb_init2(struct device *dev)
+{
+ u32 dword;
+ u32 usb2_bar0;
+ device_t sm_dev;
+ u8 rev;
+
+ sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
+ rev = get_sb700_revision(sm_dev);
+
+ /* dword = pci_read_config32(dev, 0xf8); */
+ /* dword |= 40; */
+ /* pci_write_config32(dev, 0xf8, dword); */
+
+ usb2_bar0 = pci_read_config32(dev, 0x10) & ~0xFF;
+ printk(BIOS_INFO, "usb2_bar0=0x%x\n", usb2_bar0);
+
+ /* RPR6.4 Enables the USB PHY auto calibration resister to match 45ohm resistance */
+ dword = 0x00020F00;
+ write32(usb2_bar0 + 0xC0, dword);
+
+ /* RPR6.9 Sets In/OUT FIFO threshold for best performance */
+ dword = 0x00400040;
+ write32(usb2_bar0 + 0xA4, dword);
+
+ /* RPR6.11 Disabling EHCI Advance Asynchronous Enhancement */
+ dword = pci_read_config32(dev, 0x50);
+ dword |= (1 << 28);
+ pci_write_config32(dev, 0x50, dword);
+
+ /* RPR 6.12 EHCI Advance PHY Power Savings */
+ /* RPR says it is just for A12. CIMM sets it when it is above A11. */
+ /* But it makes the linux crash, so we skip it */
+ #if 0
+ dword = pci_read_config32(dev, 0x50);
+ dword |= 1 << 31;
+ pci_write_config32(dev, 0x50, dword);
+ #endif
+
+ /* RPR6.13 Enabling Fix for EHCI Controller Driver Yellow Sign Issue */
+ /* RPR says it is just for A12. CIMx sets it when it is above A11. */
+ dword = pci_read_config32(dev, 0x50);
+ dword |= (1 << 20);
+ pci_write_config32(dev, 0x50, dword);
+
+ /* RPR6.15 EHCI Async Park Mode */
+ dword = pci_read_config32(dev, 0x50);
+ dword |= (1 << 23);
+ pci_write_config32(dev, 0x50, dword);
+
+ /* Each step below causes the linux crashes. Leave them here
+ * for future debugging. */
+#if 0
+ u8 byte;
+ u16 word;
+
+ /* RPR6.16 Disable EHCI MSI support */
+ byte = pci_read_config8(dev, 0x50);
+ byte |= (1 << 6);
+ pci_write_config8(dev, 0x50, byte);
+
+ /* RPR6.17 Disable the EHCI Dynamic Power Saving feature */
+ word = read32(usb2_bar0 + 0xBC);
+ word &= ~(1 << 12);
+ write16(usb2_bar0 + 0xBC, word);
+
+ /* RPR6.19 USB Controller DMA Read Delay Tolerant. */
+ if (rev >= REV_SB700_A14) {
+ byte = pci_read_config8(dev, 0x50);
+ byte |= (1 << 7);
+ pci_write_config8(dev, 0x50, byte);
+ }
+
+ /* RPR6.20 Async Park Mode. */
+ /* RPR recommends not to set these bits. */
+ #if 0
+ dword = pci_read_config32(dev, 0x50);
+ dword |= 1 << 23;
+ if (rev >= REV_SB700_A14) {
+ dword &= ~(1 << 2);
+ }
+ pci_write_config32(dev, 0x50, dword);
+ #endif
+
+ /* RPR6.22 Advance Async Enhancement */
+ /* RPR6.23 USB Periodic Cache Setting */
+ dword = pci_read_config32(dev, 0x50);
+ if (rev == REV_SB700_A12) {
+ dword |= 1 << 28; /* 6.22 */
+ dword |= 1 << 27; /* 6.23 */
+ } else if (rev >= REV_SB700_A14) {
+ dword |= 1 << 3;
+ dword &= ~(1 << 28); /* 6.22 */
+ dword |= 1 << 8;
+ dword &= ~(1 << 27); /* 6.23 */
+ }
+ printk(BIOS_DEBUG, "rpr 6.23, final dword=%x\n", dword);
+#endif
+}
+
+static void usb_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+ struct resource *res;
+ u32 base;
+ u32 old_debug;
+
+ old_debug = get_ehci_debug();
+ set_ehci_debug(0);
+#endif
+ pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+ res = find_resource(dev, 0x10);
+ set_ehci_debug(old_debug);
+ if (!res)
+ return;
+ base = res->base;
+ set_ehci_base(base);
+ report_resource_stored(dev, res, "");
+#endif
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb_set_resources, /* pci_dev_set_resources, */
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_0_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_USB_18_0,
+};
+
+static const struct pci_driver usb_1_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_USB_18_1,
+};
+
+/* the pci id of usb ctrl 0 and 1 are the same. */
+/*
+ * static const struct pci_driver usb_3_driver __pci_driver = {
+ * .ops = &usb_ops,
+ * .vendor = PCI_VENDOR_ID_ATI,
+ * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_0,
+ * };
+ * static const struct pci_driver usb_4_driver __pci_driver = {
+ * .ops = &usb_ops,
+ * .vendor = PCI_VENDOR_ID_ATI,
+ * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_1,
+ * };
+ */
+
+static const struct pci_driver usb_4_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_USB_20_5,
+};
+
+static struct device_operations usb_ops2 = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb_set_resources, /* pci_dev_set_resources, */
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init2,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_5_driver __pci_driver = {
+ .ops = &usb_ops2,
+ .vendor = PCI_VENDOR_ID_ATI,
+ .device = PCI_DEVICE_ID_ATI_SB700_USB_18_2,
+};
+/*
+ * static const struct pci_driver usb_5_driver __pci_driver = {
+ * .ops = &usb_ops2,
+ * .vendor = PCI_VENDOR_ID_ATI,
+ * .device = PCI_DEVICE_ID_ATI_SB700_USB_19_2,
+ * };
+ */
-driver-y += bcm21000_pcie.c
+driver-y += pcie.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 University of Heidelberg
- * Written by Mondrian Nuessle <nuessle@uni-heidelberg.de> for
- * University of Heidelberg.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-
-static void pcie_init(struct device *dev)
-{
- /* Enable pci error detecting */
- uint32_t dword;
- uint32_t msicap;
-
- printk(BIOS_DEBUG, "PCIE enable.... dev= %s\n",dev_path(dev));
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (1<<30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
- /* enable MSI on PCIE: */
- msicap = pci_read_config32(dev, 0xa0);
- msicap |= (1<<16); /* enable MSI*/
- pci_write_config32(dev, 0xa0, msicap);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pcie_driver1 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB0,
-};
-
-static const struct pci_driver pcie_driver2 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB1,
-};
-
-static const struct pci_driver pcie_driver3 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB2,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 University of Heidelberg
+ * Written by Mondrian Nuessle <nuessle@uni-heidelberg.de> for
+ * University of Heidelberg.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+static void pcie_init(struct device *dev)
+{
+ /* Enable pci error detecting */
+ uint32_t dword;
+ uint32_t msicap;
+
+ printk(BIOS_DEBUG, "PCIE enable.... dev= %s\n",dev_path(dev));
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+ /* enable MSI on PCIE: */
+ msicap = pci_read_config32(dev, 0xa0);
+ msicap |= (1<<16); /* enable MSI*/
+ pci_write_config32(dev, 0xa0, msicap);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pcie_driver1 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB0,
+};
+
+static const struct pci_driver pcie_driver2 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB1,
+};
+
+static const struct pci_driver pcie_driver3 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM21000_EXB2,
+};
-driver-y += bcm5780_nic.c
-driver-y += bcm5780_pcix.c
-driver-y += bcm5780_pcie.c
+driver-y += nic.c
+driver-y += pcix.c
+driver-y += pcie.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-
-static void nic_init(struct device *dev)
-{
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);// it will init option rom
-#endif
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_BROADCOM,
- .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC,
-};
-
-static const struct pci_driver nic1_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_BROADCOM,
- .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC1,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-
-static void pcie_init(struct device *dev)
-{
-
- /* Enable pci error detecting */
- uint32_t dword;
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (1<<30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = &lops_pci,
-
-};
-
-static const struct pci_driver pcie_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PCIE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations ht_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = 0 ,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = &lops_pci,
-
-};
-
-static const struct pci_driver ht_driver __pci_driver = {
- .ops = &ht_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PXB,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+static void nic_init(struct device *dev)
+{
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);// it will init option rom
+#endif
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_BROADCOM,
+ .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC,
+};
+
+static const struct pci_driver nic1_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_BROADCOM,
+ .device = PCI_DEVICE_ID_BROADCOM_BCM5780_NIC1,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+static void pcie_init(struct device *dev)
+{
+
+ /* Enable pci error detecting */
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+
+};
+
+static const struct pci_driver pcie_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PCIE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = 0 ,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = &lops_pci,
+
+};
+
+static const struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5780_PXB,
+};
driver-y += bcm5785.c
-driver-y += bcm5785_usb.c
-driver-y += bcm5785_lpc.c
-driver-y += bcm5785_sb_pci_main.c
-driver-y += bcm5785_ide.c
-driver-y += bcm5785_sata.c
-ramstage-y += bcm5785_reset.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += sb_pci_main.c
+driver-y += ide.c
+driver-y += sata.c
+ramstage-y += reset.c
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-#include "bcm5785.h"
-
-static void bcm5785_enable_lpc(void)
-{
- uint8_t byte;
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
-
- /* LPC Control 0 */
- byte = pci_read_config8(dev, 0x44);
- /* Serial 0 */
- byte |= (1<<6);
- pci_write_config8(dev, 0x44, byte);
-
- /* LPC Control 4 */
- byte = pci_read_config8(dev, 0x48);
- /* superio port 0x2e/4e enable */
- byte |=(1<<1)|(1<<0);
- pci_write_config8(dev, 0x48, byte);
-}
-
-static void bcm5785_enable_wdt_port_cf9(void)
-{
- device_t dev;
- uint32_t dword;
- uint32_t dword_old;
-
- dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
-
- dword_old = pci_read_config32(dev, 0x4c);
- dword = dword_old | (1<<4); //enable Timer Func
- if(dword != dword_old ) {
- pci_write_config32(dev, 0x4c, dword);
- }
-
- dword_old = pci_read_config32(dev, 0x6c);
- dword = dword_old | (1<<9); //unhide Timer Func in pci space
- if(dword != dword_old ) {
- pci_write_config32(dev, 0x6c, dword);
- }
-
- dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);
-
- /* enable cf9 */
- pci_write_config8(dev, 0x40, (1<<2));
-}
-
-unsigned get_sbdn(unsigned bus)
-{
- device_t dev;
-
- /* Find the device.
- * There can only be one bcm5785 on a hypertransport chain/bus.
- */
- dev = pci_locate_device_on_bus(
- PCI_ID(0x1166, 0x0036),
- bus);
-
- return (dev>>15) & 0x1f;
-
-}
-
-#define SB_VFSMAF 0
-
-void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
-{
- //ACPI Decode Enable
- outb(0x0e, 0xcd6);
- outb((1<<3), 0xcd7);
-
- // set port to 0x2060
- outb(0x67, 0xcd6);
- outb(0x60, 0xcd7);
- outb(0x68, 0xcd6);
- outb(0x20, 0xcd7);
-
- outb(0x69, 0xcd6);
- outb(7, 0xcd7);
-
- outb(0x64, 0xcd6);
- outb(9, 0xcd7);
-}
-
-void ldtstop_sb(void)
-{
- outb(1, 0x2060);
-}
-
-
-void hard_reset(void)
-{
- bcm5785_enable_wdt_port_cf9();
-
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- bcm5785_enable_wdt_port_cf9();
-
- set_bios_reset();
-#if 1
- /* link reset */
-// outb(0x02, 0x0cf9);
- outb(0x06, 0x0cf9);
-#endif
-}
-
-static void bcm5785_enable_msg(void)
-{
- device_t dev;
- uint32_t dword;
- uint32_t dword_old;
- uint8_t byte;
-
- dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
-
- byte = pci_read_config8(dev, 0x42);
- byte = (1<<1); //enable a20
- pci_write_config8(dev, 0x42, byte);
-
- dword_old = pci_read_config32(dev, 0x6c);
- // bit 5: enable A20 Message
- // bit 4: enable interrupt messages
- // bit 3: enable reset init message
- // bit 2: enable keyboard init message
- // bit 1: enable upsteam messages
- // bit 0: enable shutdowm message to init generation
- dword = dword_old | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0); // bit 1 and bit 4 must be set, otherwise interrupt msg will not be delivered to the processor
- if(dword != dword_old ) {
- pci_write_config32(dev, 0x6c, dword);
- }
-}
-
-static void bcm5785_early_setup(void)
-{
- uint8_t byte;
- uint32_t dword;
- device_t dev;
-
-//F0
- // enable device on bcm5785 at first
- dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
- dword = pci_read_config32(dev, 0x64);
- dword |= (1<<15) | (1<<11) | (1<<3); // ioapci enable
- dword |= (1<<8); // USB enable
- dword |= /* (1<<27)|*/(1<<14); // IDE enable
- pci_write_config32(dev, 0x64, dword);
-
- byte = pci_read_config8(dev, 0x84);
- byte |= (1<<0); // SATA enable
- pci_write_config8(dev, 0x84, byte);
-
-// WDT and cf9 for later in coreboot_ram to call hard_reset
- bcm5785_enable_wdt_port_cf9();
-
- bcm5785_enable_msg();
-
-
-// IDE related
- //F0
- byte = pci_read_config8(dev, 0x4e);
- byte |= (1<<4); //enable IDE ext regs
- pci_write_config8(dev, 0x4e, byte);
-
- //F1
- dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
- byte = pci_read_config8(dev, 0x48);
- byte &= ~1; // disable pri channel
- pci_write_config8(dev, 0x48, byte);
- pci_write_config8(dev, 0xb0, 0x01);
- pci_write_config8(dev, 0xb2, 0x02);
- byte = pci_read_config8(dev, 0x06);
- byte |= (1<<4); // so b0, b2 can not be changed from now
- pci_write_config8(dev, 0x06, byte);
- byte = pci_read_config8(dev, 0x49);
- byte |= 1; // enable second channel
- pci_write_config8(dev, 0x49, byte);
-
- //F2
- dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
-
- byte = pci_read_config8(dev, 0x40);
- byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
- pci_write_config8(dev, 0x40, byte);
-
- pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end
-
-// USB related
- pci_write_config8(dev, 0x90, 0x40);
- pci_write_config8(dev, 0x92, 0x06);
- pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
- pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
- pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
- pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
- pci_write_config8(dev, 0xb4, 0x40);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "bcm5785_smbus.h"
-
-#define SMBUS_IO_BASE 0x1000
-
-static void enable_smbus(void)
-{
- device_t dev;
- dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); // 0x0201?
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- }
-
- print_debug("SMBus controller enabled\n");
- /* set smbus iobase */
- pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
- /* Set smbus iospace enable */
- pci_write_config8(dev, 0xd2, 0x03);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-}
-
-static inline int smbus_recv_byte(unsigned device)
-{
- return do_smbus_recv_byte(SMBUS_IO_BASE, device);
-}
-
-static inline int smbus_send_byte(unsigned device, unsigned char val)
-{
- return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
-}
-
-static inline int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
-static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-
-/* Enable 4MB ROM access at 0xFFC00000 - 0xFFFFFFFF. */
-static void bcm5785_enable_rom(void)
-{
- u8 byte;
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SERVERWORKS,
- PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN), 0);
-
- /* Set the 4MB enable bits. */
- byte = pci_read_config8(dev, 0x41);
- byte |= 0x0e;
- pci_write_config8(dev, 0x41, byte);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "bcm5785.h"
-
-static void bcm5785_ide_read_resources(device_t dev)
-{
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- /* BAR */
- pci_get_resource(dev, 0x64);
-
- compact_resources(dev);
-}
-
-static void ide_init(struct device *dev)
-{
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations ide_ops = {
- .read_resources = bcm5785_ide_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
-// .enable = bcm5785_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "bcm5785.h"
-
-static void lpc_init(device_t dev)
-{
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-}
-
-static void bcm5785_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-/**
- * Enable resources for children devices.
- *
- * @param dev The device whos children's resources are to be enabled.
- */
-static void bcm5785_lpc_enable_childrens_resources(device_t dev)
-{
- struct bus *link;
- uint32_t reg;
-
- reg = pci_read_config8(dev, 0x44);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child; child = child->sibling) {
- if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for(res = child->resource_list; res; res = res->next) {
- unsigned long base, end; // don't need long long
- if(!(res->flags & IORESOURCE_IO)) continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "bcm5785lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
- switch(base) {
- case 0x60: //KBC
- case 0x64:
- reg |= (1<<29);
- case 0x3f8: // COM1
- reg |= (1<<6); break;
- case 0x2f8: // COM2
- reg |= (1<<7); break;
- case 0x378: // Parallal 1
- reg |= (1<<0); break;
- case 0x3f0: // FD0
- reg |= (1<<26); break;
- case 0x220: // Aduio 0
- reg |= (1<<14); break;
- case 0x300: // Midi 0
- reg |= (1<<18); break;
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0x44, reg);
-
-
-}
-
-static void bcm5785_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- bcm5785_lpc_enable_childrens_resources(dev);
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = bcm5785_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = bcm5785_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
-// .enable = bcm5785_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFFF) << 20) | \
- (((DEV) & 0x1F) << 15) | \
- (((FN) & 0x7) << 12))
-
-typedef unsigned device_t;
-
-static void pci_write_config32(device_t dev, unsigned where, unsigned value)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outl(value, 0xCFC);
-}
-
-static unsigned pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- return inl(0xCFC);
-}
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
- outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
- outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "bcm5785.h"
-
-static void sata_init(struct device *dev)
-{
- uint8_t byte;
-
- u32 mmio;
- struct resource *res;
- u32 mmio_base;
- int i;
-
- if(!(dev->path.pci.devfn & 7)) { // only set it in Func0
- byte = pci_read_config8(dev, 0x78);
- byte |= (1<<7);
- pci_write_config8(dev, 0x78, byte);
-
- res = find_resource(dev, 0x24);
- mmio_base = res->base;
- mmio_base &= 0xfffffffc;
-
- write32(mmio_base + 0x10f0, 0x40000001);
- write32(mmio_base + 0x8c, 0x00ff2007);
- mdelay( 10 );
- write32(mmio_base + 0x8c, 0x78592009);
- mdelay( 10 );
- write32(mmio_base + 0x8c, 0x00082004);
- mdelay( 10 );
- write32(mmio_base + 0x8c, 0x00002004);
- mdelay( 10 );
-
- //init PHY
-
- printk(BIOS_DEBUG, "init PHY...\n");
- for(i=0; i<4; i++) {
- mmio = res->base + 0x100 * i;
- byte = read8(mmio + 0x40);
- printk(BIOS_DEBUG, "port %d PHY status = %02x\n", i, byte);
- if(byte & 0x4) {// bit 2 is set
- byte = read8(mmio+0x48);
- write8(mmio + 0x48, byte | 1);
- write8(mmio + 0x48, byte & (~1));
- byte = read8(mmio + 0x40);
- printk(BIOS_DEBUG, "after reset port %d PHY status = %02x\n", i, byte);
- }
- }
- }
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-// .enable = bcm5785_enable,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SATA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <device/smbus.h>
-#include "bcm5785.h"
-#include "bcm5785_smbus.h"
-
-#define NMI_OFF 0
-
-static void sb_init(device_t dev)
-{
- uint8_t byte;
- uint8_t byte_old;
- int nmi_option;
-
- /* Set up NMI on errors */
- byte = inb(0x70); // RTC70
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- } else {
- byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
- }
- if( byte != byte_old) {
- outb(byte, 0x70);
- }
-
-
-}
-
-static void bcm5785_sb_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
- /* Get Resource for SMBUS */
- pci_get_resource(dev, 0x90);
-
- compact_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
-
-}
-
-static int lsmbus_recv_byte(device_t dev)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-static int lsmbus_read_byte(device_t dev, uint8_t address)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x90);
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x2c,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations sb_ops = {
- .read_resources = bcm5785_sb_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sb_init,
- .scan_bus = scan_static_bus,
-// .enable = bcm5785_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver sb_driver __pci_driver = {
- .ops = &sb_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x0
-#define SMBSLVSTAT 0x1
-#define SMBHSTCTRL 0x2
-#define SMBHSTCMD 0x3
-#define SMBHSTADDR 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBHSTBLKDAT 0x7
-
-#define SMBSLVCTRL 0x8
-#define SMBSLVCMD_SHADOW 0x9
-#define SMBSLVEVT 0xa
-#define SMBSLVDAT 0xc
-
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100*1000*10)
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f;
- if (val == 0) { // ready now
- return 0;
- }
- outb(val, smbus_io_base + SMBHSTSTAT);
- } while(--loops);
- return -2; // time out
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
-
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f; // mask off reserved bits
- if ( val & 0x1c) {
- return -5; // error
- }
- if ( val == 0x02) {
- outb(val, smbus_io_base + SMBHSTSTAT); // clear status
- return 0; //
- }
- } while(--loops);
- return -3; // timeout
-}
-
-static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
-{
- uint8_t byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; // not ready
- }
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; // Clear [4:2]
- byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; // timeout or error
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTCMD);
-
- return byte;
-}
-
-static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
-{
- uint8_t byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; // not ready
- }
-
- /* set the command... */
- outb(val, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; // Clear [4:2]
- byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; // timeout or error
- }
-
- return 0;
-}
-
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- uint8_t byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; // not ready
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; // Clear [4:2]
- byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; // timeout or error
- }
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- return byte;
-}
-
-static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
-{
- uint8_t byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return -2; // not ready
- }
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
-
- /* output value */
- outb(val, smbus_io_base + SMBHSTDAT0);
-
- byte = inb(smbus_io_base + SMBHSTCTRL);
- byte &= 0xe3; // Clear [4:2]
- byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
- outb(byte, smbus_io_base + SMBHSTCTRL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3; // timeout or error
- }
-
- return 0;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "bcm5785.h"
-
-static void usb_init(struct device *dev)
-{
- uint32_t dword;
-
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<2)|(1<<1)|(1<<0);
- pci_write_config32(dev, 0x04, dword);
-
- pci_write_config8(dev, 0x41, 0x00); // Serversworks said
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
-// .enable = bcm5785_enable,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_SERVERWORKS,
- .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_USB,
-};
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "bcm5785_enable_rom.c"
+#include "enable_rom.c"
static void bootblock_southbridge_init(void)
{
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+#include "bcm5785.h"
+
+static void bcm5785_enable_lpc(void)
+{
+ uint8_t byte;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
+
+ /* LPC Control 0 */
+ byte = pci_read_config8(dev, 0x44);
+ /* Serial 0 */
+ byte |= (1<<6);
+ pci_write_config8(dev, 0x44, byte);
+
+ /* LPC Control 4 */
+ byte = pci_read_config8(dev, 0x48);
+ /* superio port 0x2e/4e enable */
+ byte |=(1<<1)|(1<<0);
+ pci_write_config8(dev, 0x48, byte);
+}
+
+static void bcm5785_enable_wdt_port_cf9(void)
+{
+ device_t dev;
+ uint32_t dword;
+ uint32_t dword_old;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+
+ dword_old = pci_read_config32(dev, 0x4c);
+ dword = dword_old | (1<<4); //enable Timer Func
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x4c, dword);
+ }
+
+ dword_old = pci_read_config32(dev, 0x6c);
+ dword = dword_old | (1<<9); //unhide Timer Func in pci space
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x6c, dword);
+ }
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0238), 0);
+
+ /* enable cf9 */
+ pci_write_config8(dev, 0x40, (1<<2));
+}
+
+unsigned get_sbdn(unsigned bus)
+{
+ device_t dev;
+
+ /* Find the device.
+ * There can only be one bcm5785 on a hypertransport chain/bus.
+ */
+ dev = pci_locate_device_on_bus(
+ PCI_ID(0x1166, 0x0036),
+ bus);
+
+ return (dev>>15) & 0x1f;
+
+}
+
+#define SB_VFSMAF 0
+
+void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
+{
+ //ACPI Decode Enable
+ outb(0x0e, 0xcd6);
+ outb((1<<3), 0xcd7);
+
+ // set port to 0x2060
+ outb(0x67, 0xcd6);
+ outb(0x60, 0xcd7);
+ outb(0x68, 0xcd6);
+ outb(0x20, 0xcd7);
+
+ outb(0x69, 0xcd6);
+ outb(7, 0xcd7);
+
+ outb(0x64, 0xcd6);
+ outb(9, 0xcd7);
+}
+
+void ldtstop_sb(void)
+{
+ outb(1, 0x2060);
+}
+
+
+void hard_reset(void)
+{
+ bcm5785_enable_wdt_port_cf9();
+
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void soft_reset(void)
+{
+ bcm5785_enable_wdt_port_cf9();
+
+ set_bios_reset();
+#if 1
+ /* link reset */
+// outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+#endif
+}
+
+static void bcm5785_enable_msg(void)
+{
+ device_t dev;
+ uint32_t dword;
+ uint32_t dword_old;
+ uint8_t byte;
+
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+
+ byte = pci_read_config8(dev, 0x42);
+ byte = (1<<1); //enable a20
+ pci_write_config8(dev, 0x42, byte);
+
+ dword_old = pci_read_config32(dev, 0x6c);
+ // bit 5: enable A20 Message
+ // bit 4: enable interrupt messages
+ // bit 3: enable reset init message
+ // bit 2: enable keyboard init message
+ // bit 1: enable upsteam messages
+ // bit 0: enable shutdowm message to init generation
+ dword = dword_old | (1<<5) | (1<<3) | (1<<2) | (1<<1) | (1<<0); // bit 1 and bit 4 must be set, otherwise interrupt msg will not be delivered to the processor
+ if(dword != dword_old ) {
+ pci_write_config32(dev, 0x6c, dword);
+ }
+}
+
+static void bcm5785_early_setup(void)
+{
+ uint8_t byte;
+ uint32_t dword;
+ device_t dev;
+
+//F0
+ // enable device on bcm5785 at first
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0);
+ dword = pci_read_config32(dev, 0x64);
+ dword |= (1<<15) | (1<<11) | (1<<3); // ioapci enable
+ dword |= (1<<8); // USB enable
+ dword |= /* (1<<27)|*/(1<<14); // IDE enable
+ pci_write_config32(dev, 0x64, dword);
+
+ byte = pci_read_config8(dev, 0x84);
+ byte |= (1<<0); // SATA enable
+ pci_write_config8(dev, 0x84, byte);
+
+// WDT and cf9 for later in coreboot_ram to call hard_reset
+ bcm5785_enable_wdt_port_cf9();
+
+ bcm5785_enable_msg();
+
+
+// IDE related
+ //F0
+ byte = pci_read_config8(dev, 0x4e);
+ byte |= (1<<4); //enable IDE ext regs
+ pci_write_config8(dev, 0x4e, byte);
+
+ //F1
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0214), 0);
+ byte = pci_read_config8(dev, 0x48);
+ byte &= ~1; // disable pri channel
+ pci_write_config8(dev, 0x48, byte);
+ pci_write_config8(dev, 0xb0, 0x01);
+ pci_write_config8(dev, 0xb2, 0x02);
+ byte = pci_read_config8(dev, 0x06);
+ byte |= (1<<4); // so b0, b2 can not be changed from now
+ pci_write_config8(dev, 0x06, byte);
+ byte = pci_read_config8(dev, 0x49);
+ byte |= 1; // enable second channel
+ pci_write_config8(dev, 0x49, byte);
+
+ //F2
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0234), 0);
+
+ byte = pci_read_config8(dev, 0x40);
+ byte |= (1<<3)|(1<<2); // LPC Retry, LPC to PCI DMA enable
+ pci_write_config8(dev, 0x40, byte);
+
+ pci_write_config32(dev, 0x60, 0x0000ffff); // LPC Memory hole start and end
+
+// USB related
+ pci_write_config8(dev, 0x90, 0x40);
+ pci_write_config8(dev, 0x92, 0x06);
+ pci_write_config8(dev, 0x9c, 0x7c); //PHY timinig register
+ pci_write_config8(dev, 0xa4, 0x02); //mask reg - low/full speed func
+ pci_write_config8(dev, 0xa5, 0x02); //mask reg - low/full speed func
+ pci_write_config8(dev, 0xa6, 0x00); //mask reg - high speed func
+ pci_write_config8(dev, 0xb4, 0x40);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "smbus.h"
+
+#define SMBUS_IO_BASE 0x1000
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(0x1166, 0x0205), 0); // 0x0201?
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ }
+
+ print_debug("SMBus controller enabled\n");
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
+ /* Set smbus iospace enable */
+ pci_write_config8(dev, 0xd2, 0x03);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static inline int smbus_recv_byte(unsigned device)
+{
+ return do_smbus_recv_byte(SMBUS_IO_BASE, device);
+}
+
+static inline int smbus_send_byte(unsigned device, unsigned char val)
+{
+ return do_smbus_send_byte(SMBUS_IO_BASE, device, val);
+}
+
+static inline int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+
+/* Enable 4MB ROM access at 0xFFC00000 - 0xFFFFFFFF. */
+static void bcm5785_enable_rom(void)
+{
+ u8 byte;
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SERVERWORKS,
+ PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN), 0);
+
+ /* Set the 4MB enable bits. */
+ byte = pci_read_config8(dev, 0x41);
+ byte |= 0x0e;
+ pci_write_config8(dev, 0x41, byte);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "bcm5785.h"
+
+static void bcm5785_ide_read_resources(device_t dev)
+{
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* BAR */
+ pci_get_resource(dev, 0x64);
+
+ compact_resources(dev);
+}
+
+static void ide_init(struct device *dev)
+{
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = bcm5785_ide_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "bcm5785.h"
+
+static void lpc_init(device_t dev)
+{
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+}
+
+static void bcm5785_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+/**
+ * Enable resources for children devices.
+ *
+ * @param dev The device whos children's resources are to be enabled.
+ */
+static void bcm5785_lpc_enable_childrens_resources(device_t dev)
+{
+ struct bus *link;
+ uint32_t reg;
+
+ reg = pci_read_config8(dev, 0x44);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child; child = child->sibling) {
+ if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for(res = child->resource_list; res; res = res->next) {
+ unsigned long base, end; // don't need long long
+ if(!(res->flags & IORESOURCE_IO)) continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "bcm5785lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
+ switch(base) {
+ case 0x60: //KBC
+ case 0x64:
+ reg |= (1<<29);
+ case 0x3f8: // COM1
+ reg |= (1<<6); break;
+ case 0x2f8: // COM2
+ reg |= (1<<7); break;
+ case 0x378: // Parallal 1
+ reg |= (1<<0); break;
+ case 0x3f0: // FD0
+ reg |= (1<<26); break;
+ case 0x220: // Aduio 0
+ reg |= (1<<14); break;
+ case 0x300: // Midi 0
+ reg |= (1<<18); break;
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0x44, reg);
+
+
+}
+
+static void bcm5785_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ bcm5785_lpc_enable_childrens_resources(dev);
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = bcm5785_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = bcm5785_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "bcm5785.h"
+
+static void sata_init(struct device *dev)
+{
+ uint8_t byte;
+
+ u32 mmio;
+ struct resource *res;
+ u32 mmio_base;
+ int i;
+
+ if(!(dev->path.pci.devfn & 7)) { // only set it in Func0
+ byte = pci_read_config8(dev, 0x78);
+ byte |= (1<<7);
+ pci_write_config8(dev, 0x78, byte);
+
+ res = find_resource(dev, 0x24);
+ mmio_base = res->base;
+ mmio_base &= 0xfffffffc;
+
+ write32(mmio_base + 0x10f0, 0x40000001);
+ write32(mmio_base + 0x8c, 0x00ff2007);
+ mdelay( 10 );
+ write32(mmio_base + 0x8c, 0x78592009);
+ mdelay( 10 );
+ write32(mmio_base + 0x8c, 0x00082004);
+ mdelay( 10 );
+ write32(mmio_base + 0x8c, 0x00002004);
+ mdelay( 10 );
+
+ //init PHY
+
+ printk(BIOS_DEBUG, "init PHY...\n");
+ for(i=0; i<4; i++) {
+ mmio = res->base + 0x100 * i;
+ byte = read8(mmio + 0x40);
+ printk(BIOS_DEBUG, "port %d PHY status = %02x\n", i, byte);
+ if(byte & 0x4) {// bit 2 is set
+ byte = read8(mmio+0x48);
+ write8(mmio + 0x48, byte | 1);
+ write8(mmio + 0x48, byte & (~1));
+ byte = read8(mmio + 0x40);
+ printk(BIOS_DEBUG, "after reset port %d PHY status = %02x\n", i, byte);
+ }
+ }
+ }
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = bcm5785_enable,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SATA,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <device/smbus.h>
+#include "bcm5785.h"
+#include "smbus.h"
+
+#define NMI_OFF 0
+
+static void sb_init(device_t dev)
+{
+ uint8_t byte;
+ uint8_t byte_old;
+ int nmi_option;
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); // RTC70
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ } else {
+ byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
+ }
+ if( byte != byte_old) {
+ outb(byte, 0x70);
+ }
+
+
+}
+
+static void bcm5785_sb_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+ /* Get Resource for SMBUS */
+ pci_get_resource(dev, 0x90);
+
+ compact_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+}
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x90);
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x2c,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations sb_ops = {
+ .read_resources = bcm5785_sb_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sb_init,
+ .scan_bus = scan_static_bus,
+// .enable = bcm5785_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver sb_driver __pci_driver = {
+ .ops = &sb_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SB_PCI_MAIN,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTRL 0x2
+#define SMBHSTCMD 0x3
+#define SMBHSTADDR 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBHSTBLKDAT 0x7
+
+#define SMBSLVCTRL 0x8
+#define SMBSLVCMD_SHADOW 0x9
+#define SMBSLVEVT 0xa
+#define SMBSLVDAT 0xc
+
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0) { // ready now
+ return 0;
+ }
+ outb(val, smbus_io_base + SMBHSTSTAT);
+ } while(--loops);
+ return -2; // time out
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f; // mask off reserved bits
+ if ( val & 0x1c) {
+ return -5; // error
+ }
+ if ( val == 0x02) {
+ outb(val, smbus_io_base + SMBHSTSTAT); // clear status
+ return 0; //
+ }
+ } while(--loops);
+ return -3; // timeout
+}
+
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ return byte;
+}
+
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<2) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ return 0;
+}
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBHSTADDR);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ return byte;
+}
+
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+ uint8_t byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return -2; // not ready
+ }
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|0 , smbus_io_base + SMBHSTADDR);
+
+ /* output value */
+ outb(val, smbus_io_base + SMBHSTDAT0);
+
+ byte = inb(smbus_io_base + SMBHSTCTRL);
+ byte &= 0xe3; // Clear [4:2]
+ byte |= (1<<3) | (1<<6); // Byte data read/write command, start the command
+ outb(byte, smbus_io_base + SMBHSTCTRL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3; // timeout or error
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "bcm5785.h"
+
+static void usb_init(struct device *dev)
+{
+ uint32_t dword;
+
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<2)|(1<<1)|(1<<0);
+ pci_write_config32(dev, 0x04, dword);
+
+ pci_write_config8(dev, 0x41, 0x00); // Serversworks said
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+// .enable = bcm5785_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
+ .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_USB,
+};
driver-y += esb6300.c
-driver-y += esb6300_reset.c
-driver-y += esb6300_uhci.c
-driver-y += esb6300_lpc.c
-driver-y += esb6300_ide.c
-driver-y += esb6300_sata.c
-driver-y += esb6300_ehci.c
-driver-y += esb6300_smbus.c
-driver-y += esb6300_pci.c
-driver-y += esb6300_pic.c
-driver-y += esb6300_bridge1c.c
-driver-y += esb6300_ac97.c
+driver-y += reset.c
+driver-y += uhci.c
+driver-y += lpc.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += ehci.c
+driver-y += smbus.c
+driver-y += pci.c
+driver-y += pic.c
+driver-y += bridge1c.c
+driver-y += ac97.c
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = ac97_set_subsystem,
+};
+static struct device_operations ac97_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97_audio_driver __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_AUDIO,
+};
+static const struct pci_driver ac97_modem_driver __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_MODEM,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void bridge1c_init(struct device *dev)
+{
+ /* configuration */
+ pci_write_config8(dev, 0x1b, 0x30);
+// pci_write_config8(dev, 0x3e, 0x07);
+ pci_write_config8(dev, 0x3e, 0x04); /* parity ignore */
+ pci_write_config8(dev, 0x6c, 0x0c); /* undocumented */
+ pci_write_config8(dev, 0xe0, 0x20);
+
+ /* SRB enable */
+ pci_write_config16(dev, 0xe4, 0x0232);
+
+ /* Burst size */
+ pci_write_config8(dev, 0xf0, 0x02);
+
+ /* prefetch threshold size */
+ pci_write_config16(dev, 0xf8, 0x2121);
+
+ /* primary latency */
+ pci_write_config8(dev, 0x0d, 0x28);
+
+ /* multi transaction timer */
+ pci_write_config8(dev, 0x42, 0x08);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = bridge1c_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_PCI_X,
+};
+
--- /dev/null
+#include "smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ print_spew("SMBus controller enabled\n");
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ pci_write_config8(dev, 0x40, 1);
+ pci_write_config8(dev, 0x4, 1);
+ /* SMBALERT_DIS */
+ pci_write_config8(dev, 0x11, 4);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+#ifdef DEADCODE
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+ return;
+ }
+ return;
+}
+
+static int smbus_write_block(unsigned device, unsigned length, unsigned cmd,
+ unsigned data1, unsigned data2)
+{
+ unsigned char byte;
+ unsigned char stat;
+ int i;
+
+ /* chear the PM timeout flags, SECOND_TO_STS */
+ outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
+
+ if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+ return -2;
+ }
+
+ /* setup transaction */
+ /* Obtain ownership */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+ for(stat=0;(stat&0x40)==0;) {
+ stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ /* clear the done bit */
+ outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
+
+ /* set the command address */
+ outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+
+ /* set the block length */
+ outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* try sending out the first byte of data here */
+ byte=(data1>>(0))&0x0ff;
+ outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+ /* issue a block write command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40,
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ for(i=0;i<length;i++) {
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
+ return -3;
+ }
+
+ /* load the next byte */
+ if(i>3)
+ byte=(data2>>(i%4))&0x0ff;
+ else
+ byte=(data1>>(i))&0x0ff;
+ outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+
+ /* clear the done bit */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
+ SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+
+ print_debug("SMBUS Block complete\n");
+ return 0;
+}
+#endif
+
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ehci_init(struct device *dev)
+{
+ uint32_t cmd;
+
+ printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_MASTER);
+
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ uint8_t access_cntl;
+ access_cntl = pci_read_config8(dev, 0x80);
+ /* Enable writes to protected registers */
+ pci_write_config8(dev, 0x80, access_cntl | 1);
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ /* Restore protection */
+ pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ehci_init,
+ .scan_bus = 0,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ehci_driver __pci_driver = {
+ .ops = &ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI,
+};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* Write the subsystem vendor and device id */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = ac97_set_subsystem,
-};
-static struct device_operations ac97_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97_audio_driver __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_AUDIO,
-};
-static const struct pci_driver ac97_modem_driver __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_AC97_MODEM,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void bridge1c_init(struct device *dev)
-{
- /* configuration */
- pci_write_config8(dev, 0x1b, 0x30);
-// pci_write_config8(dev, 0x3e, 0x07);
- pci_write_config8(dev, 0x3e, 0x04); /* parity ignore */
- pci_write_config8(dev, 0x6c, 0x0c); /* undocumented */
- pci_write_config8(dev, 0xe0, 0x20);
-
- /* SRB enable */
- pci_write_config16(dev, 0xe4, 0x0232);
-
- /* Burst size */
- pci_write_config8(dev, 0xf0, 0x02);
-
- /* prefetch threshold size */
- pci_write_config16(dev, 0xf8, 0x2121);
-
- /* primary latency */
- pci_write_config8(dev, 0x0d, 0x28);
-
- /* multi transaction timer */
- pci_write_config8(dev, 0x42, 0x08);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = bridge1c_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_PCI_X,
-};
-
+++ /dev/null
-#include "esb6300_smbus.h"
-
-#define SMBUS_IO_BASE 0x0f00
-
-static void enable_smbus(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- print_spew("SMBus controller enabled\n");
- pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
- pci_write_config8(dev, 0x40, 1);
- pci_write_config8(dev, 0x4, 1);
- /* SMBALERT_DIS */
- pci_write_config8(dev, 0x11, 4);
-
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-}
-
-static int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
-#ifdef DEADCODE
-static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
- return;
- }
- return;
-}
-
-static int smbus_write_block(unsigned device, unsigned length, unsigned cmd,
- unsigned data1, unsigned data2)
-{
- unsigned char byte;
- unsigned char stat;
- int i;
-
- /* chear the PM timeout flags, SECOND_TO_STS */
- outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
-
- if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
- return -2;
- }
-
- /* setup transaction */
- /* Obtain ownership */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- for(stat=0;(stat&0x40)==0;) {
- stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
- /* clear the done bit */
- outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
-
- /* set the command address */
- outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-
- /* set the block length */
- outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* try sending out the first byte of data here */
- byte=(data1>>(0))&0x0ff;
- outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
- /* issue a block write command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40,
- SMBUS_IO_BASE + SMBHSTCTL);
-
- for(i=0;i<length;i++) {
-
- /* poll for transaction completion */
- if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
- return -3;
- }
-
- /* load the next byte */
- if(i>3)
- byte=(data2>>(i%4))&0x0ff;
- else
- byte=(data1>>(i))&0x0ff;
- outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
-
- /* clear the done bit */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
- SMBUS_IO_BASE + SMBHSTSTAT);
- }
-
- print_debug("SMBUS Block complete\n");
- return 0;
-}
-#endif
-
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void ehci_init(struct device *dev)
-{
- uint32_t cmd;
-
- printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
-
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- uint8_t access_cntl;
- access_cntl = pci_read_config8(dev, 0x80);
- /* Enable writes to protected registers */
- pci_write_config8(dev, 0x80, access_cntl | 1);
- /* Write the subsystem vendor and device id */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- /* Restore protection */
- pci_write_config8(dev, 0x80, access_cntl);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &ehci_set_subsystem,
-};
-static struct device_operations ehci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ehci_init,
- .scan_bus = 0,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ehci_driver __pci_driver = {
- .ops = &ehci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void ide_init(struct device *dev)
-{
-
- /* Enable ide devices so the linux ide driver will work */
-
- /* Enable IDE devices */
- pci_write_config16(dev, 0x40, 0x0a307);
- pci_write_config16(dev, 0x42, 0x0a307);
- pci_write_config8(dev, 0x48, 0x05);
- pci_write_config16(dev, 0x4a, 0x0101);
- pci_write_config16(dev, 0x54, 0x5055);
-
-#if 0
- uint16_t word;
- word = pci_read_config16(dev, 0x40);
- word |= (1 << 15);
- pci_write_config16(dev, 0x40, word);
- word = pci_read_config16(dev, 0x42);
- word |= (1 << 15);
- pci_write_config16(dev, 0x42, word);
-#endif
- printk(BIOS_DEBUG, "IDE Enabled\n");
-}
-
-static void esb6300_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* This value is also visible in uchi[0-2] and smbus functions */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = esb6300_ide_set_subsystem,
-};
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_IDE,
-};
-
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "esb6300.h"
-
-#define ACPI_BAR 0x40
-#define GPIO_BAR 0x58
-
-#define NMI_OFF 0
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define SERIRQ_CNTL 0x64
-static void esb6300_enable_serial_irqs(device_t dev)
-{
- /* set packet length and toggle silent mode bit */
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
-}
-
-#define PCI_DMA_CFG 0x90
-static void esb6300_pci_dma_cfg(device_t dev)
-{
- /* Set PCI DMA CFG to lpc I/F DMA */
- pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
-}
-
-#define LPC_EN 0xe6
-static void esb6300_enable_lpc(device_t dev)
-{
- /* lpc i/f enable */
- pci_write_config8(dev, LPC_EN, 0x0d);
-}
-
-typedef struct southbridge_intel_esb6300_config config_t;
-
-static void set_esb6300_gpio_use_sel(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_use_sel, gpio_use_sel2;
-
-// gpio_use_sel = 0x1B003100;
-// gpio_use_sel2 = 0x03000000;
- gpio_use_sel = 0x1BBC31C0;
- gpio_use_sel2 = 0x03000FE1;
-#if 0
- int i;
- for(i = 0; i < 64; i++) {
- int val;
- switch(config->gpio[i] & ESB6300_GPIO_USE_MASK) {
- case ESB6300_GPIO_USE_AS_NATIVE: val = 0; break;
- case ESB6300_GPIO_USE_AS_GPIO: val = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_use_sel &= ~( 1 << i);
- gpio_use_sel |= (val << i);
- } else {
- gpio_use_sel2 &= ~( 1 << (i - 32));
- gpio_use_sel2 |= (val << (i - 32));
- }
- }
-#endif
- outl(gpio_use_sel, res->base + 0x00);
- outl(gpio_use_sel2, res->base + 0x30);
-}
-
-static void set_esb6300_gpio_direction(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_io_sel, gpio_io_sel2;
-
-// gpio_io_sel = 0x0000ffff;
-// gpio_io_sel2 = 0x00000000;
- gpio_io_sel = 0x1900ffff;
- gpio_io_sel2 = 0x00000fe1;
-#if 0
- int i;
- for(i = 0; i < 64; i++) {
- int val;
- switch(config->gpio[i] & ESB6300_GPIO_SEL_MASK) {
- case ESB6300_GPIO_SEL_OUTPUT: val = 0; break;
- case ESB6300_GPIO_SEL_INPUT: val = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_io_sel &= ~( 1 << i);
- gpio_io_sel |= (val << i);
- } else {
- gpio_io_sel2 &= ~( 1 << (i - 32));
- gpio_io_sel2 |= (val << (i - 32));
- }
- }
-#endif
- outl(gpio_io_sel, res->base + 0x04);
- outl(gpio_io_sel2, res->base + 0x34);
-}
-
-static void set_esb6300_gpio_level(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_lvl, gpio_lvl2;
- uint32_t gpio_blink;
-
-// gpio_lvl = 0x1b3f0000;
-// gpio_blink = 0x00040000;
-// gpio_lvl2 = 0x00000fff;
- gpio_lvl = 0x19370000;
- gpio_blink = 0x00000000;
- gpio_lvl2 = 0x00000fff;
-#if 0
- int i;
- for(i = 0; i < 64; i++) {
- int val, blink;
- switch(config->gpio[i] & ESB6300_GPIO_LVL_MASK) {
- case ESB6300_GPIO_LVL_LOW: val = 0; blink = 0; break;
- case ESB6300_GPIO_LVL_HIGH: val = 1; blink = 0; break;
- case ESB6300_GPIO_LVL_BLINK: val = 1; blink = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_lvl &= ~( 1 << i);
- gpio_blink &= ~( 1 << i);
- gpio_lvl |= ( val << i);
- gpio_blink |= (blink << i);
- } else {
- gpio_lvl2 &= ~( 1 << (i - 32));
- gpio_lvl2 |= (val << (i - 32));
- }
- }
-#endif
- outl(gpio_lvl, res->base + 0x0c);
- outl(gpio_blink, res->base + 0x18);
- outl(gpio_lvl2, res->base + 0x38);
-}
-
-static void set_esb6300_gpio_inv(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_inv;
-
- gpio_inv = 0x00003100;
-#if 0
- int i;
- for(i = 0; i < 32; i++) {
- int val;
- switch(config->gpio[i] & ESB6300_GPIO_INV_MASK) {
- case ESB6300_GPIO_INV_OFF: val = 0; break;
- case ESB6300_GPIO_INV_ON: val = 1; break;
- default:
- continue;
- }
- gpio_inv &= ~( 1 << i);
- gpio_inv |= (val << i);
- }
-#endif
- outl(gpio_inv, res->base + 0x2c);
-}
-
-static void esb6300_pirq_init(device_t dev)
-{
- config_t *config;
-
- /* Get the chip configuration */
- config = dev->chip_info;
-
- if(config->pirq_a_d) {
- pci_write_config32(dev, 0x60, config->pirq_a_d);
- }
- if(config->pirq_e_h) {
- pci_write_config32(dev, 0x68, config->pirq_e_h);
- }
-}
-
-
-static void esb6300_gpio_init(device_t dev)
-{
- struct resource *res;
- config_t *config;
-
- /* Skip if I don't have any configuration */
- if (!dev->chip_info) {
- return;
- }
- /* The programmer is responsible for ensuring
- * a valid gpio configuration.
- */
-
- /* Get the chip configuration */
- config = dev->chip_info;
- /* Find the GPIO bar */
- res = find_resource(dev, GPIO_BAR);
- if (!res) {
- return;
- }
-
- /* Set the use selects */
- set_esb6300_gpio_use_sel(dev, res, config);
-
- /* Set the IO direction */
- set_esb6300_gpio_direction(dev, res, config);
-
- /* Setup the input inverters */
- set_esb6300_gpio_inv(dev, res, config);
-
- /* Set the value on the GPIO output pins */
- set_esb6300_gpio_level(dev, res, config);
-
-}
-
-
-static void lpc_init(struct device *dev)
-{
- uint8_t byte;
- uint32_t value;
- int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
-
- /* sata settings */
- pci_write_config32(dev, 0x58, 0x00001181);
-
- /* IO APIC initialization */
- value = pci_read_config32(dev, 0xd0);
- value |= (1 << 8)|(1<<7);
- value |= (6 << 0)|(1<<13)|(1<<11);
- pci_write_config32(dev, 0xd0, value);
- setup_ioapic(IO_APIC_ADDR, 0); // don't rename IO APIC ID
-
- /* disable reset timer */
- pci_write_config8(dev, 0xd4, 0x02);
-
- /* cmos ram 2nd 128 */
- pci_write_config8(dev, 0xd8, 0x04);
-
- /* comm 2 */
- pci_write_config8(dev, 0xe0, 0x10);
-
- /* fwh sellect */
- pci_write_config32(dev, 0xe8, 0x00112233);
-
- /* fwh decode */
- pci_write_config8(dev, 0xf0, 0x0f);
-
- /* av disable, sata controller */
- pci_write_config8(dev, 0xf2, 0xc0);
-
- /* undocumented */
- pci_write_config8(dev, 0xa0, 0x20);
- pci_write_config8(dev, 0xad, 0x03);
- pci_write_config8(dev, 0xbb, 0x09);
-
- /* apic1 rout */
- pci_write_config8(dev, 0xf4, 0x40);
-
- /* undocumented */
- pci_write_config8(dev, 0xa0, 0x20);
- pci_write_config8(dev, 0xad, 0x03);
- pci_write_config8(dev, 0xbb, 0x09);
-
- esb6300_enable_serial_irqs(dev);
-
- esb6300_pci_dma_cfg(dev);
-
- esb6300_enable_lpc(dev);
-
- get_option(&pwr_on, "power_on_after_fail");
- byte = pci_read_config8(dev, 0xa4);
- byte &= 0xfe;
- if (!pwr_on) {
- byte |= 1;
- }
- pci_write_config8(dev, 0xa4, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
-
- /* Set up the PIRQ */
- esb6300_pirq_init(dev);
-
- /* Set the state of the gpio lines */
- esb6300_gpio_init(dev);
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-}
-
-static void esb6300_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- /* Add the ACPI BAR */
- res = pci_get_resource(dev, ACPI_BAR);
-
- /* Add the GPIO BAR */
- res = pci_get_resource(dev, GPIO_BAR);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void esb6300_lpc_enable_resources(device_t dev)
-{
- uint8_t acpi_cntl, gpio_cntl;
-
- /* Enable the normal pci resources */
- pci_dev_enable_resources(dev);
-
- /* Enable the ACPI bar */
- acpi_cntl = pci_read_config8(dev, 0x44);
- acpi_cntl |= (1 << 4);
- pci_write_config8(dev, 0x44, acpi_cntl);
-
- /* Enable the GPIO bar */
- gpio_cntl = pci_read_config8(dev, 0x5c);
- gpio_cntl |= (1 << 4);
- pci_write_config8(dev, 0x5c, gpio_cntl);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = esb6300_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = esb6300_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_LPC,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void pci_init(struct device *dev)
-{
-
- uint16_t word;
-
- /* Clear system errors */
- word = pci_read_config16(dev, 0x06);
- word |= 0xf900; /* Clear possible errors */
- pci_write_config16(dev, 0x06, word);
-
- word = pci_read_config16(dev, 0x1e);
- word |= 0xf800; /* Clear possible errors */
- pci_write_config16(dev, 0x1e, word);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_PCI,
-};
-
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/ioapic.h>
-#include "esb6300.h"
-
-static void pic_init(struct device *dev)
-{
-
- uint16_t word;
-
- /* Clear system errors */
- word = pci_read_config16(dev, 0x06);
- word |= 0xf900; /* Clear possible errors */
- pci_write_config16(dev, 0x06, word);
-
- /* enable interrupt lines */
- pci_write_config8(dev, 0x3c, 0xff);
-
- /* Setup the ioapic */
- clear_ioapic(IO_APIC_ADDR + 0x10000);
-}
-
-static void pic_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- /* Report the pic1 mbar resource */
- res = new_resource(dev, 0x44);
- res->base = IO_APIC_ADDR + 0x10000;
- res->size = 256;
- res->limit = res->base + res->size -1;
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
- dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
-}
-
-static struct pci_operations lops_pci = {
- /* Can we set the pci subsystem and device id? */
- .set_subsystem = 0,
-};
-
-static struct device_operations pci_ops = {
- .read_resources = pic_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = pic_init,
- .scan_bus = 0,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_APIC1,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9 */
- outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void sata_init(struct device *dev)
-{
- /* Enable sata devices so the linux sata driver will work */
-
- /* Enable SATA devices */
-
- printk(BIOS_DEBUG, "SATA init\n");
- /* SATA configuration */
- pci_write_config8(dev, 0x04, 0x07);
- pci_write_config8(dev, 0x09, 0x8f);
-
- /* Set timmings */
- pci_write_config16(dev, 0x40, 0x0a307);
- pci_write_config16(dev, 0x42, 0x0a307);
-
- /* Sync DMA */
- pci_write_config16(dev, 0x48, 0x000f);
- pci_write_config16(dev, 0x4a, 0x1111);
-
- /* 66 mhz */
- pci_write_config16(dev, 0x54, 0xf00f);
-
- /* Combine ide - sata configuration */
- pci_write_config8(dev, 0x90, 0x0);
-
- /* port 0 & 1 enable */
- pci_write_config8(dev, 0x92, 0x33);
-
- /* initialize SATA */
- pci_write_config16(dev, 0xa0, 0x0018);
- pci_write_config32(dev, 0xa4, 0x00000264);
- pci_write_config16(dev, 0xa0, 0x0040);
- pci_write_config32(dev, 0xa4, 0x00220043);
-
- printk(BIOS_DEBUG, "SATA Enabled\n");
-}
-
-static void esb6300_sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* This value is also visible in usb1, usb2 and smbus functions */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = esb6300_sata_set_subsystem,
-};
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver sata_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA,
-};
-
-static const struct pci_driver sata_driver_nr __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA_RAID,
-};
-
+++ /dev/null
-#include <device/device.h>
-#include <device/path.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <arch/io.h>
-#include "esb6300.h"
-#include "esb6300_smbus.h"
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static struct pci_operations lops_pci = {
- /* The subsystem id follows the ide controller */
- .set_subsystem = 0,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_SMB,
-};
-
+++ /dev/null
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x0
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-#include <delay.h>
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- udelay(100);
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while(byte & 1);
- return loops?0:-1;
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- udelay(100);
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
- return loops?0:-1;
-}
-
-static inline int smbus_wait_until_blk_done(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- udelay(100);
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while((byte&(1<<7)) == 0);
- return loops?0:-1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* setup transaction */
- /* disable interrupts */
- outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, smbus_io_base + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- global_status_register &= ~(3 << 5);
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
-
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "esb6300.h"
-
-static void uhci_init(struct device *dev)
-{
- uint32_t cmd;
-
-#if 1
- printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
-
-
- printk(BIOS_DEBUG, "done.\n");
-#endif
-
-}
-
-static struct pci_operations lops_pci = {
- /* The subsystem id follows the ide controller */
- .set_subsystem = 0,
-};
-
-static struct device_operations uhci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = uhci_init,
- .scan_bus = 0,
- .enable = esb6300_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb1_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_USB1,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_USB2,
-};
-
-/* Note: May or may not need different init than UHCI. */
-static const struct pci_driver ehci_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI,
-};
-
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void ide_init(struct device *dev)
+{
+
+ /* Enable ide devices so the linux ide driver will work */
+
+ /* Enable IDE devices */
+ pci_write_config16(dev, 0x40, 0x0a307);
+ pci_write_config16(dev, 0x42, 0x0a307);
+ pci_write_config8(dev, 0x48, 0x05);
+ pci_write_config16(dev, 0x4a, 0x0101);
+ pci_write_config16(dev, 0x54, 0x5055);
+
+#if 0
+ uint16_t word;
+ word = pci_read_config16(dev, 0x40);
+ word |= (1 << 15);
+ pci_write_config16(dev, 0x40, word);
+ word = pci_read_config16(dev, 0x42);
+ word |= (1 << 15);
+ pci_write_config16(dev, 0x42, word);
+#endif
+ printk(BIOS_DEBUG, "IDE Enabled\n");
+}
+
+static void esb6300_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* This value is also visible in uchi[0-2] and smbus functions */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = esb6300_ide_set_subsystem,
+};
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_IDE,
+};
+
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "esb6300.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x58
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define SERIRQ_CNTL 0x64
+static void esb6300_enable_serial_irqs(device_t dev)
+{
+ /* set packet length and toggle silent mode bit */
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+#define PCI_DMA_CFG 0x90
+static void esb6300_pci_dma_cfg(device_t dev)
+{
+ /* Set PCI DMA CFG to lpc I/F DMA */
+ pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
+}
+
+#define LPC_EN 0xe6
+static void esb6300_enable_lpc(device_t dev)
+{
+ /* lpc i/f enable */
+ pci_write_config8(dev, LPC_EN, 0x0d);
+}
+
+typedef struct southbridge_intel_esb6300_config config_t;
+
+static void set_esb6300_gpio_use_sel(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_use_sel, gpio_use_sel2;
+
+// gpio_use_sel = 0x1B003100;
+// gpio_use_sel2 = 0x03000000;
+ gpio_use_sel = 0x1BBC31C0;
+ gpio_use_sel2 = 0x03000FE1;
+#if 0
+ int i;
+ for(i = 0; i < 64; i++) {
+ int val;
+ switch(config->gpio[i] & ESB6300_GPIO_USE_MASK) {
+ case ESB6300_GPIO_USE_AS_NATIVE: val = 0; break;
+ case ESB6300_GPIO_USE_AS_GPIO: val = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_use_sel &= ~( 1 << i);
+ gpio_use_sel |= (val << i);
+ } else {
+ gpio_use_sel2 &= ~( 1 << (i - 32));
+ gpio_use_sel2 |= (val << (i - 32));
+ }
+ }
+#endif
+ outl(gpio_use_sel, res->base + 0x00);
+ outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_esb6300_gpio_direction(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_io_sel, gpio_io_sel2;
+
+// gpio_io_sel = 0x0000ffff;
+// gpio_io_sel2 = 0x00000000;
+ gpio_io_sel = 0x1900ffff;
+ gpio_io_sel2 = 0x00000fe1;
+#if 0
+ int i;
+ for(i = 0; i < 64; i++) {
+ int val;
+ switch(config->gpio[i] & ESB6300_GPIO_SEL_MASK) {
+ case ESB6300_GPIO_SEL_OUTPUT: val = 0; break;
+ case ESB6300_GPIO_SEL_INPUT: val = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_io_sel &= ~( 1 << i);
+ gpio_io_sel |= (val << i);
+ } else {
+ gpio_io_sel2 &= ~( 1 << (i - 32));
+ gpio_io_sel2 |= (val << (i - 32));
+ }
+ }
+#endif
+ outl(gpio_io_sel, res->base + 0x04);
+ outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_esb6300_gpio_level(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_lvl, gpio_lvl2;
+ uint32_t gpio_blink;
+
+// gpio_lvl = 0x1b3f0000;
+// gpio_blink = 0x00040000;
+// gpio_lvl2 = 0x00000fff;
+ gpio_lvl = 0x19370000;
+ gpio_blink = 0x00000000;
+ gpio_lvl2 = 0x00000fff;
+#if 0
+ int i;
+ for(i = 0; i < 64; i++) {
+ int val, blink;
+ switch(config->gpio[i] & ESB6300_GPIO_LVL_MASK) {
+ case ESB6300_GPIO_LVL_LOW: val = 0; blink = 0; break;
+ case ESB6300_GPIO_LVL_HIGH: val = 1; blink = 0; break;
+ case ESB6300_GPIO_LVL_BLINK: val = 1; blink = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_lvl &= ~( 1 << i);
+ gpio_blink &= ~( 1 << i);
+ gpio_lvl |= ( val << i);
+ gpio_blink |= (blink << i);
+ } else {
+ gpio_lvl2 &= ~( 1 << (i - 32));
+ gpio_lvl2 |= (val << (i - 32));
+ }
+ }
+#endif
+ outl(gpio_lvl, res->base + 0x0c);
+ outl(gpio_blink, res->base + 0x18);
+ outl(gpio_lvl2, res->base + 0x38);
+}
+
+static void set_esb6300_gpio_inv(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_inv;
+
+ gpio_inv = 0x00003100;
+#if 0
+ int i;
+ for(i = 0; i < 32; i++) {
+ int val;
+ switch(config->gpio[i] & ESB6300_GPIO_INV_MASK) {
+ case ESB6300_GPIO_INV_OFF: val = 0; break;
+ case ESB6300_GPIO_INV_ON: val = 1; break;
+ default:
+ continue;
+ }
+ gpio_inv &= ~( 1 << i);
+ gpio_inv |= (val << i);
+ }
+#endif
+ outl(gpio_inv, res->base + 0x2c);
+}
+
+static void esb6300_pirq_init(device_t dev)
+{
+ config_t *config;
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+
+ if(config->pirq_a_d) {
+ pci_write_config32(dev, 0x60, config->pirq_a_d);
+ }
+ if(config->pirq_e_h) {
+ pci_write_config32(dev, 0x68, config->pirq_e_h);
+ }
+}
+
+
+static void esb6300_gpio_init(device_t dev)
+{
+ struct resource *res;
+ config_t *config;
+
+ /* Skip if I don't have any configuration */
+ if (!dev->chip_info) {
+ return;
+ }
+ /* The programmer is responsible for ensuring
+ * a valid gpio configuration.
+ */
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+ /* Find the GPIO bar */
+ res = find_resource(dev, GPIO_BAR);
+ if (!res) {
+ return;
+ }
+
+ /* Set the use selects */
+ set_esb6300_gpio_use_sel(dev, res, config);
+
+ /* Set the IO direction */
+ set_esb6300_gpio_direction(dev, res, config);
+
+ /* Setup the input inverters */
+ set_esb6300_gpio_inv(dev, res, config);
+
+ /* Set the value on the GPIO output pins */
+ set_esb6300_gpio_level(dev, res, config);
+
+}
+
+
+static void lpc_init(struct device *dev)
+{
+ uint8_t byte;
+ uint32_t value;
+ int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /* sata settings */
+ pci_write_config32(dev, 0x58, 0x00001181);
+
+ /* IO APIC initialization */
+ value = pci_read_config32(dev, 0xd0);
+ value |= (1 << 8)|(1<<7);
+ value |= (6 << 0)|(1<<13)|(1<<11);
+ pci_write_config32(dev, 0xd0, value);
+ setup_ioapic(IO_APIC_ADDR, 0); // don't rename IO APIC ID
+
+ /* disable reset timer */
+ pci_write_config8(dev, 0xd4, 0x02);
+
+ /* cmos ram 2nd 128 */
+ pci_write_config8(dev, 0xd8, 0x04);
+
+ /* comm 2 */
+ pci_write_config8(dev, 0xe0, 0x10);
+
+ /* fwh sellect */
+ pci_write_config32(dev, 0xe8, 0x00112233);
+
+ /* fwh decode */
+ pci_write_config8(dev, 0xf0, 0x0f);
+
+ /* av disable, sata controller */
+ pci_write_config8(dev, 0xf2, 0xc0);
+
+ /* undocumented */
+ pci_write_config8(dev, 0xa0, 0x20);
+ pci_write_config8(dev, 0xad, 0x03);
+ pci_write_config8(dev, 0xbb, 0x09);
+
+ /* apic1 rout */
+ pci_write_config8(dev, 0xf4, 0x40);
+
+ /* undocumented */
+ pci_write_config8(dev, 0xa0, 0x20);
+ pci_write_config8(dev, 0xad, 0x03);
+ pci_write_config8(dev, 0xbb, 0x09);
+
+ esb6300_enable_serial_irqs(dev);
+
+ esb6300_pci_dma_cfg(dev);
+
+ esb6300_enable_lpc(dev);
+
+ get_option(&pwr_on, "power_on_after_fail");
+ byte = pci_read_config8(dev, 0xa4);
+ byte &= 0xfe;
+ if (!pwr_on) {
+ byte |= 1;
+ }
+ pci_write_config8(dev, 0xa4, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
+
+ /* Set up the PIRQ */
+ esb6300_pirq_init(dev);
+
+ /* Set the state of the gpio lines */
+ esb6300_gpio_init(dev);
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+}
+
+static void esb6300_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Add the ACPI BAR */
+ res = pci_get_resource(dev, ACPI_BAR);
+
+ /* Add the GPIO BAR */
+ res = pci_get_resource(dev, GPIO_BAR);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void esb6300_lpc_enable_resources(device_t dev)
+{
+ uint8_t acpi_cntl, gpio_cntl;
+
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable the ACPI bar */
+ acpi_cntl = pci_read_config8(dev, 0x44);
+ acpi_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x44, acpi_cntl);
+
+ /* Enable the GPIO bar */
+ gpio_cntl = pci_read_config8(dev, 0x5c);
+ gpio_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x5c, gpio_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = esb6300_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = esb6300_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_LPC,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void pci_init(struct device *dev)
+{
+
+ uint16_t word;
+
+ /* Clear system errors */
+ word = pci_read_config16(dev, 0x06);
+ word |= 0xf900; /* Clear possible errors */
+ pci_write_config16(dev, 0x06, word);
+
+ word = pci_read_config16(dev, 0x1e);
+ word |= 0xf800; /* Clear possible errors */
+ pci_write_config16(dev, 0x1e, word);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_PCI,
+};
+
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/ioapic.h>
+#include "esb6300.h"
+
+static void pic_init(struct device *dev)
+{
+
+ uint16_t word;
+
+ /* Clear system errors */
+ word = pci_read_config16(dev, 0x06);
+ word |= 0xf900; /* Clear possible errors */
+ pci_write_config16(dev, 0x06, word);
+
+ /* enable interrupt lines */
+ pci_write_config8(dev, 0x3c, 0xff);
+
+ /* Setup the ioapic */
+ clear_ioapic(IO_APIC_ADDR + 0x10000);
+}
+
+static void pic_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Report the pic1 mbar resource */
+ res = new_resource(dev, 0x44);
+ res->base = IO_APIC_ADDR + 0x10000;
+ res->size = 256;
+ res->limit = res->base + res->size -1;
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+ dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+}
+
+static struct pci_operations lops_pci = {
+ /* Can we set the pci subsystem and device id? */
+ .set_subsystem = 0,
+};
+
+static struct device_operations pci_ops = {
+ .read_resources = pic_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = pic_init,
+ .scan_bus = 0,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_APIC1,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9 */
+ outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void sata_init(struct device *dev)
+{
+ /* Enable sata devices so the linux sata driver will work */
+
+ /* Enable SATA devices */
+
+ printk(BIOS_DEBUG, "SATA init\n");
+ /* SATA configuration */
+ pci_write_config8(dev, 0x04, 0x07);
+ pci_write_config8(dev, 0x09, 0x8f);
+
+ /* Set timmings */
+ pci_write_config16(dev, 0x40, 0x0a307);
+ pci_write_config16(dev, 0x42, 0x0a307);
+
+ /* Sync DMA */
+ pci_write_config16(dev, 0x48, 0x000f);
+ pci_write_config16(dev, 0x4a, 0x1111);
+
+ /* 66 mhz */
+ pci_write_config16(dev, 0x54, 0xf00f);
+
+ /* Combine ide - sata configuration */
+ pci_write_config8(dev, 0x90, 0x0);
+
+ /* port 0 & 1 enable */
+ pci_write_config8(dev, 0x92, 0x33);
+
+ /* initialize SATA */
+ pci_write_config16(dev, 0xa0, 0x0018);
+ pci_write_config32(dev, 0xa4, 0x00000264);
+ pci_write_config16(dev, 0xa0, 0x0040);
+ pci_write_config32(dev, 0xa4, 0x00220043);
+
+ printk(BIOS_DEBUG, "SATA Enabled\n");
+}
+
+static void esb6300_sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* This value is also visible in usb1, usb2 and smbus functions */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = esb6300_sata_set_subsystem,
+};
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA,
+};
+
+static const struct pci_driver sata_driver_nr __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_SATA_RAID,
+};
+
--- /dev/null
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "esb6300.h"
+#include "smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static struct pci_operations lops_pci = {
+ /* The subsystem id follows the ide controller */
+ .set_subsystem = 0,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_SMB,
+};
+
--- /dev/null
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+#include <delay.h>
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ udelay(100);
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while(byte & 1);
+ return loops?0:-1;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ udelay(100);
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
+ return loops?0:-1;
+}
+
+static inline int smbus_wait_until_blk_done(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ udelay(100);
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while((byte&(1<<7)) == 0);
+ return loops?0:-1;
+}
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ global_status_register &= ~(3 << 5);
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
+
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "esb6300.h"
+
+static void uhci_init(struct device *dev)
+{
+ uint32_t cmd;
+
+#if 1
+ printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_MASTER);
+
+
+ printk(BIOS_DEBUG, "done.\n");
+#endif
+
+}
+
+static struct pci_operations lops_pci = {
+ /* The subsystem id follows the ide controller */
+ .set_subsystem = 0,
+};
+
+static struct device_operations uhci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = uhci_init,
+ .scan_bus = 0,
+ .enable = esb6300_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb1_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_USB1,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_USB2,
+};
+
+/* Note: May or may not need different init than UHCI. */
+static const struct pci_driver ehci_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_6300ESB_EHCI,
+};
+
driver-y += i3100.c
-driver-y += i3100_uhci.c
-driver-y += i3100_lpc.c
-driver-y += i3100_sata.c
-driver-y += i3100_ehci.c
-driver-y += i3100_smbus.c
-driver-y += i3100_pci.c
-ramstage-y += i3100_reset.c
-ramstage-y += i3100_pciexp_portb.c
+driver-y += uhci.c
+driver-y += lpc.c
+driver-y += sata.c
+driver-y += ehci.c
+driver-y += smbus.c
+driver-y += pci.c
+ramstage-y += reset.c
+ramstage-y += pciexp_portb.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+static void i3100_enable_superio(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
+
+ /* Enable decoding of I/O locations for SuperIO devices */
+ pci_write_config16(dev, 0x80, 0x0010);
+ pci_write_config16(dev, 0x82, 0x340f);
+
+ /* Enable the SERIRQs (start pulse width is 8 clock cycles) */
+ pci_write_config8(dev, 0x64, 0xD2);
+}
+
+static void i3100_halt_tco_timer(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
+
+ /* Temporarily enable the ACPI I/O range at 0x4000 */
+ pci_write_config32(dev, 0x40, 0x4000 | (1 << 0));
+ pci_write_config32(dev, 0x44, pci_read_config32(dev, 0x44) | (1 << 7));
+
+ /* Halt the TCO timer, preventing SMI and automatic reboot */
+ outw(inw(0x4068) | (1 << 11), 0x4068);
+
+ /* Disable the ACPI I/O range */
+ pci_write_config32(dev, 0x44, pci_read_config32(dev, 0x44) & ~(1 << 7));
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ print_spew("SMBus controller enabled\n");
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ pci_write_config8(dev, 0x40, 1);
+ pci_write_config8(dev, 0x4, 1);
+ /* SMBALERT_DIS */
+ outb(4, SMBUS_IO_BASE + SMBSLVCMD);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+}
+
+static int smbus_read_byte(u32 device, u32 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i3100.h"
+
+static void ehci_init(struct device *dev)
+{
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ u8 access_cntl;
+ access_cntl = pci_read_config8(dev, 0x80);
+ /* Enable writes to protected registers */
+ pci_write_config8(dev, 0x80, access_cntl | 1);
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ /* Restore protection */
+ pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ehci_init,
+ .scan_bus = 0,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ehci_driver __pci_driver = {
+ .ops = &ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_EHCI,
+};
+
+static const struct pci_driver ehci_driver_ep80579 __pci_driver = {
+ .ops = &ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_EHCI,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-static void i3100_enable_superio(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
-
- /* Enable decoding of I/O locations for SuperIO devices */
- pci_write_config16(dev, 0x80, 0x0010);
- pci_write_config16(dev, 0x82, 0x340f);
-
- /* Enable the SERIRQs (start pulse width is 8 clock cycles) */
- pci_write_config8(dev, 0x64, 0xD2);
-}
-
-static void i3100_halt_tco_timer(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
-
- /* Temporarily enable the ACPI I/O range at 0x4000 */
- pci_write_config32(dev, 0x40, 0x4000 | (1 << 0));
- pci_write_config32(dev, 0x44, pci_read_config32(dev, 0x44) | (1 << 7));
-
- /* Halt the TCO timer, preventing SMI and automatic reboot */
- outw(inw(0x4068) | (1 << 11), 0x4068);
-
- /* Disable the ACPI I/O range */
- pci_write_config32(dev, 0x44, pci_read_config32(dev, 0x44) & ~(1 << 7));
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include "i3100_smbus.h"
-
-#define SMBUS_IO_BASE 0x0f00
-
-static void enable_smbus(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- print_spew("SMBus controller enabled\n");
- pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
- pci_write_config8(dev, 0x40, 1);
- pci_write_config8(dev, 0x4, 1);
- /* SMBALERT_DIS */
- outb(4, SMBUS_IO_BASE + SMBSLVCMD);
-
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-}
-
-static int smbus_read_byte(u32 device, u32 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i3100.h"
-
-static void ehci_init(struct device *dev)
-{
-}
-
-static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- u8 access_cntl;
- access_cntl = pci_read_config8(dev, 0x80);
- /* Enable writes to protected registers */
- pci_write_config8(dev, 0x80, access_cntl | 1);
- /* Write the subsystem vendor and device id */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- /* Restore protection */
- pci_write_config8(dev, 0x80, access_cntl);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &ehci_set_subsystem,
-};
-static struct device_operations ehci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ehci_init,
- .scan_bus = 0,
- .enable = i3100_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ehci_driver __pci_driver = {
- .ops = &ehci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_EHCI,
-};
-
-static const struct pci_driver ehci_driver_ep80579 __pci_driver = {
- .ops = &ehci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_EHCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Linux Networx
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-/* This code is based on src/southbridge/intel/esb6300/esb6300_lpc.c */
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i3100.h"
-
-#define ACPI_BAR 0x40
-#define GPIO_BAR 0x48
-#define RCBA 0xf0
-
-#define SERIRQ_CNTL 0x64
-
-#define GEN_PMCON_1 0xA0
-#define GEN_PMCON_2 0xA2
-#define GEN_PMCON_3 0xA4
-
-#define NMI_OFF 0
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-static void i3100_enable_serial_irqs(device_t dev)
-{
- /* set packet length and toggle silent mode bit */
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
-}
-
-typedef struct southbridge_intel_i3100_config config_t;
-
-static void set_i3100_gpio_use_sel(
- device_t dev, struct resource *res, config_t *config)
-{
- u32 gpio_use_sel, gpio_use_sel2;
- int i;
-
- gpio_use_sel = inl(res->base + 0x00) | 0x0000c603;
- gpio_use_sel2 = inl(res->base + 0x30) | 0x00000100;
- for (i = 0; i < 64; i++) {
- int val;
- switch (config->gpio[i] & I3100_GPIO_USE_MASK) {
- case I3100_GPIO_USE_AS_NATIVE:
- val = 0;
- break;
- case I3100_GPIO_USE_AS_GPIO:
- val = 1;
- break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_use_sel &= ~(1 << i);
- gpio_use_sel |= (val << i);
- } else {
- gpio_use_sel2 &= ~(1 << (i - 32));
- gpio_use_sel2 |= (val << (i - 32));
- }
- }
- outl(gpio_use_sel, res->base + 0x00);
- outl(gpio_use_sel2, res->base + 0x30);
-}
-
-static void set_i3100_gpio_direction(
- device_t dev, struct resource *res, config_t *config)
-{
- u32 gpio_io_sel, gpio_io_sel2;
- int i;
-
- gpio_io_sel = inl(res->base + 0x04);
- gpio_io_sel2 = inl(res->base + 0x34);
- for (i = 0; i < 64; i++) {
- int val;
- switch (config->gpio[i] & I3100_GPIO_SEL_MASK) {
- case I3100_GPIO_SEL_OUTPUT:
- val = 0;
- break;
- case I3100_GPIO_SEL_INPUT:
- val = 1;
- break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_io_sel &= ~(1 << i);
- gpio_io_sel |= (val << i);
- } else {
- gpio_io_sel2 &= ~(1 << (i - 32));
- gpio_io_sel2 |= (val << (i - 32));
- }
- }
- outl(gpio_io_sel, res->base + 0x04);
- outl(gpio_io_sel2, res->base + 0x34);
-}
-
-static void set_i3100_gpio_level(
- device_t dev, struct resource *res, config_t *config)
-{
- u32 gpio_lvl, gpio_lvl2;
- u32 gpio_blink;
- int i;
-
- gpio_lvl = inl(res->base + 0x0c);
- gpio_blink = inl(res->base + 0x18);
- gpio_lvl2 = inl(res->base + 0x38);
- for (i = 0; i < 64; i++) {
- int val, blink;
- switch (config->gpio[i] & I3100_GPIO_LVL_MASK) {
- case I3100_GPIO_LVL_LOW:
- val = 0;
- blink = 0;
- break;
- case I3100_GPIO_LVL_HIGH:
- val = 1;
- blink = 0;
- break;
- case I3100_GPIO_LVL_BLINK:
- val = 1;
- blink = 1;
- break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_lvl &= ~(1 << i);
- gpio_blink &= ~(1 << i);
- gpio_lvl |= (val << i);
- gpio_blink |= (blink << i);
- } else {
- gpio_lvl2 &= ~(1 << (i - 32));
- gpio_lvl2 |= (val << (i - 32));
- }
- }
- outl(gpio_lvl, res->base + 0x0c);
- outl(gpio_blink, res->base + 0x18);
- outl(gpio_lvl2, res->base + 0x38);
-}
-
-static void set_i3100_gpio_inv(
- device_t dev, struct resource *res, config_t *config)
-{
- u32 gpio_inv;
- int i;
-
- gpio_inv = inl(res->base + 0x2c);
- for (i = 0; i < 32; i++) {
- int val;
- switch (config->gpio[i] & I3100_GPIO_INV_MASK) {
- case I3100_GPIO_INV_OFF:
- val = 0;
- break;
- case I3100_GPIO_INV_ON:
- val = 1;
- break;
- default:
- continue;
- }
- gpio_inv &= ~(1 << i);
- gpio_inv |= (val << i);
- }
- outl(gpio_inv, res->base + 0x2c);
-}
-
-static void i3100_pirq_init(device_t dev)
-{
- config_t *config;
-
- /* Get the chip configuration */
- config = dev->chip_info;
-
- if(config->pirq_a_d) {
- pci_write_config32(dev, 0x60, config->pirq_a_d);
- }
- if(config->pirq_e_h) {
- pci_write_config32(dev, 0x68, config->pirq_e_h);
- }
-}
-
-static void i3100_power_options(device_t dev) {
- u8 reg8;
- u16 reg16;
- int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- int nmi_option;
-
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- */
- get_option(&pwr_on, "power_on_after_fail");
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- reg8 &= 0xfe;
- if (pwr_on) {
- reg8 &= ~1;
- } else {
- reg8 |= 1;
- }
- /* avoid #S4 assertions */
- reg8 |= (3 << 4);
- /* minimum asssertion is 1 to 2 RTCCLK */
- reg8 &= ~(1 << 3);
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- printk(BIOS_INFO, "set power %s after power fail\n", pwr_on ? "on" : "off");
-
- /* Set up NMI on errors. */
- reg8 = inb(0x61);
- /* Higher Nibble must be 0 */
- reg8 &= 0x0f;
- /* IOCHK# NMI Enable */
- reg8 &= ~(1 << 3);
- /* PCI SERR# Enable */
- // reg8 &= ~(1 << 2);
- /* PCI SERR# Disable for now */
- reg8 |= (1 << 2);
- outb(reg8, 0x61);
-
- reg8 = inb(0x70);
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- /* Set NMI. */
- printk(BIOS_INFO, "NMI sources enabled.\n");
- reg8 &= ~(1 << 7);
- } else {
- /* Can't mask NMI from PCI-E and NMI_NOW */
- printk(BIOS_INFO, "NMI sources disabled.\n");
- reg8 |= ( 1 << 7);
- }
- outb(reg8, 0x70);
-
- // Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
- reg16 = pci_read_config16(dev, GEN_PMCON_1);
- reg16 &= ~((3 << 0) | (1 << 10));
- reg16 |= (1 << 3) | (1 << 5);
- /* CLKRUN_EN */
- // reg16 |= (1 << 2);
- pci_write_config16(dev, GEN_PMCON_1, reg16);
-
- // Set the board's GPI routing.
- // i82801gx_gpi_routing(dev);
-}
-
-static void i3100_gpio_init(device_t dev)
-{
- struct resource *res;
- config_t *config;
-
- /* Skip if I don't have any configuration */
- if (!dev->chip_info) {
- return;
- }
- /* The programmer is responsible for ensuring
- * a valid gpio configuration.
- */
-
- /* Get the chip configuration */
- config = dev->chip_info;
- /* Find the GPIO bar */
- res = find_resource(dev, GPIO_BAR);
- if (!res) {
- return;
- }
-
- /* Set the use selects */
- set_i3100_gpio_use_sel(dev, res, config);
-
- /* Set the IO direction */
- set_i3100_gpio_direction(dev, res, config);
-
- /* Setup the input inverters */
- set_i3100_gpio_inv(dev, res, config);
-
- /* Set the value on the GPIO output pins */
- set_i3100_gpio_level(dev, res, config);
-
-}
-
-
-static void lpc_init(struct device *dev)
-{
- struct resource *res;
-
- /* Enable IO APIC */
- res = find_resource(dev, RCBA);
- if (!res) {
- return;
- }
- *((u8 *)((u32)res->base + 0x31ff)) |= (1 << 0);
-
- // TODO this code sets int 0 of the IOAPIC in Virtual Wire Mode
- // (register 0x10/0x11) while the old code used int 1 (register 0x12)
- // ... Why?
- setup_ioapic(IO_APIC_ADDR, 0); // Don't rename IOAPIC ID
-
- /* Decode 0xffc00000 - 0xffffffff to fwh idsel 0 */
- pci_write_config32(dev, 0xd0, 0x00000000);
-
- i3100_enable_serial_irqs(dev);
-
- /* Set up the PIRQ */
- i3100_pirq_init(dev);
-
- /* Setup power options */
- i3100_power_options(dev);
-
- /* Set the state of the gpio lines */
- i3100_gpio_init(dev);
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-}
-
-static void i3100_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- /* Add the ACPI BAR */
- res = pci_get_resource(dev, ACPI_BAR);
-
- /* Add the GPIO BAR */
- res = pci_get_resource(dev, GPIO_BAR);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- /* Add resource for RCBA */
- res = new_resource(dev, RCBA);
- res->size = 0x4000;
- res->limit = 0xffffc000;
- res->align = 14;
- res->gran = 14;
- res->flags = IORESOURCE_MEM;
-}
-
-static void i3100_lpc_enable_resources(device_t dev)
-{
- u8 acpi_cntl, gpio_cntl;
-
- /* Enable the normal pci resources */
- pci_dev_enable_resources(dev);
-
- /* Enable the ACPI bar */
- acpi_cntl = pci_read_config8(dev, 0x44);
- acpi_cntl |= (1 << 7);
- pci_write_config8(dev, 0x44, acpi_cntl);
-
- /* Enable the GPIO bar */
- gpio_cntl = pci_read_config8(dev, 0x4c);
- gpio_cntl |= (1 << 4);
- pci_write_config8(dev, 0x4c, gpio_cntl);
-
- /* Enable the RCBA */
- pci_write_config32(dev, RCBA, pci_read_config32(dev, RCBA) | (1 << 0));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = i3100_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = i3100_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i3100_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_LPC,
-};
-
-static const struct pci_driver lpc_driver_ep80579 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i3100.h"
-
-static void pci_init(struct device *dev)
-{
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_PCI,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-/* This code is based on src/northbridge/intel/e7520/pciexp_porta.c */
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/pciexp.h>
-#include <arch/io.h>
-#include "chip.h"
-#include <reset.h>
-
-#define PCIE_LCTL 0x50
-#define PCIE_LSTS 0x52
-
-typedef struct northbridge_intel_i3100_config config_t;
-
-static void pcie_init(struct device *dev)
-{
-}
-
-static unsigned int pcie_scan_bridge(struct device *dev, unsigned int max)
-{
- u16 val;
- u16 ctl;
- int flag = 0;
- do {
- val = pci_read_config16(dev, PCIE_LSTS);
- printk(BIOS_DEBUG, "pcie portb link status: %02x\n", val);
- if ((val & (1<<10)) && (!flag)) { /* training error */
- ctl = pci_read_config16(dev, PCIE_LCTL);
- pci_write_config16(dev, PCIE_LCTL, (ctl | (1<<5)));
- val = pci_read_config16(dev, PCIE_LSTS);
- printk(BIOS_DEBUG, "pcie portb reset link status: %02x\n", val);
- flag=1;
- hard_reset();
- }
- } while (val & (3<<10));
- return pciexp_scan_bridge(dev, max);
-}
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pcie_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pci_driver_0 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB0,
-};
-
-static const struct pci_driver pci_driver_1 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB1,
-};
-
-static const struct pci_driver pci_driver_2 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB2,
-};
-
-static const struct pci_driver pci_driver_3 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB3,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-void hard_reset(void)
-{
- outb(0x06, 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-/* This code is based on src/southbridge/intel/esb6300/esb6300_sata.c */
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i3100.h"
-
-typedef struct southbridge_intel_i3100_config config_t;
-
-static void sata_init(struct device *dev)
-{
- u8 ahci;
-
- /* Get the chip configuration */
- ahci = (pci_read_config8(dev, SATA_MAP) >> 6) & 0x03;
-
- /* Enable SATA devices */
- printk(BIOS_INFO, "SATA init (%s mode)\n", ahci ? "AHCI" : "Legacy");
-
- if(ahci) {
- /* AHCI mode */
- pci_write_config8(dev, SATA_MAP, (1 << 6) | (0 << 0));
-
- /* Enable ports */
- pci_write_config8(dev, SATA_PCS, 0x03);
- pci_write_config8(dev, SATA_PCS + 1, 0x0F);
-
- /* Setup timings */
- pci_write_config16(dev, SATA_PTIM, 0x8000);
- pci_write_config16(dev, SATA_STIM, 0x8000);
-
- /* Synchronous DMA */
- pci_write_config8(dev, SATA_SYNCC, 0);
- pci_write_config16(dev, SATA_SYNCTIM, 0);
-
- /* IDE I/O configuration */
- pci_write_config32(dev, SATA_IIOC, 0);
-
- } else {
- /* SATA configuration */
- pci_write_config8(dev, SATA_CMD, 0x07);
- pci_write_config8(dev, SATA_PI, 0x8f);
-
- /* Set timings */
- pci_write_config16(dev, SATA_PTIM, 0x0a307);
- pci_write_config16(dev, SATA_STIM, 0x0a307);
-
- /* Sync DMA */
- pci_write_config8(dev, SATA_SYNCC, 0x0f);
- pci_write_config16(dev, SATA_SYNCTIM, 0x1111);
-
- /* Fast ATA */
- pci_write_config16(dev, SATA_IIOC, 0x1000);
-
- /* Select IDE mode */
- pci_write_config8(dev, SATA_MAP, 0x00);
-
- /* Enable ports 0-3 */
- pci_write_config8(dev, SATA_PCS + 1, 0x0f);
-
- }
- printk(BIOS_DEBUG, "SATA Enabled\n");
-}
-
-static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = sata_set_subsystem,
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_init,
- .scan_bus = 0,
- .enable = i3100_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_IDE,
-};
-
-static const struct pci_driver sata_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_AHCI,
-};
-
-static const struct pci_driver ide_driver_ep80579 __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_IDE,
-};
-
-static const struct pci_driver sata_driver_ep80579 __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_AHCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-#include <device/device.h>
-#include <device/path.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <arch/io.h>
-#include "i3100.h"
-#include "i3100_smbus.h"
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &smbus_set_subsystem,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = i3100_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_SMB,
-};
-
-static const struct pci_driver smbus_driver_ep80579 __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_SMB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This code is based on src/southbridge/intel/esb6300/esb6300_smbus.h */
-
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x0
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-#define SMBSLVCMD 0x11
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-static void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(u32 smbus_io_base)
-{
- u32 loops = SMBUS_TIMEOUT;
- u8 byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while (byte & 1);
- return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u32 smbus_io_base)
-{
- u32 loops = SMBUS_TIMEOUT;
- u8 byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while ((byte & 1) || (byte & ~((1 << 6)|(1 << 0))) == 0);
- return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(u32 smbus_io_base, u16 device, u8 address)
-{
- u8 global_status_register;
- u8 byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* setup transaction */
- /* disable interrupts */
- outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, smbus_io_base + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- global_status_register &= ~(3 << 5);
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Arastra, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i3100.h"
-
-static void uhci_init(struct device *dev)
-{
-}
-
-static void uhci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &uhci_set_subsystem,
-};
-
-static struct device_operations uhci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = uhci_init,
- .scan_bus = 0,
- .enable = i3100_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver uhci_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_UHCI,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_3100_UHCI2,
-};
-
-static const struct pci_driver uhci_driver_ep80579 __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_EP80579_UHCI,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Linux Networx
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_lpc.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i3100.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x48
+#define RCBA 0xf0
+
+#define SERIRQ_CNTL 0x64
+
+#define GEN_PMCON_1 0xA0
+#define GEN_PMCON_2 0xA2
+#define GEN_PMCON_3 0xA4
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+static void i3100_enable_serial_irqs(device_t dev)
+{
+ /* set packet length and toggle silent mode bit */
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+typedef struct southbridge_intel_i3100_config config_t;
+
+static void set_i3100_gpio_use_sel(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_use_sel, gpio_use_sel2;
+ int i;
+
+ gpio_use_sel = inl(res->base + 0x00) | 0x0000c603;
+ gpio_use_sel2 = inl(res->base + 0x30) | 0x00000100;
+ for (i = 0; i < 64; i++) {
+ int val;
+ switch (config->gpio[i] & I3100_GPIO_USE_MASK) {
+ case I3100_GPIO_USE_AS_NATIVE:
+ val = 0;
+ break;
+ case I3100_GPIO_USE_AS_GPIO:
+ val = 1;
+ break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_use_sel &= ~(1 << i);
+ gpio_use_sel |= (val << i);
+ } else {
+ gpio_use_sel2 &= ~(1 << (i - 32));
+ gpio_use_sel2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_use_sel, res->base + 0x00);
+ outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_i3100_gpio_direction(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_io_sel, gpio_io_sel2;
+ int i;
+
+ gpio_io_sel = inl(res->base + 0x04);
+ gpio_io_sel2 = inl(res->base + 0x34);
+ for (i = 0; i < 64; i++) {
+ int val;
+ switch (config->gpio[i] & I3100_GPIO_SEL_MASK) {
+ case I3100_GPIO_SEL_OUTPUT:
+ val = 0;
+ break;
+ case I3100_GPIO_SEL_INPUT:
+ val = 1;
+ break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_io_sel &= ~(1 << i);
+ gpio_io_sel |= (val << i);
+ } else {
+ gpio_io_sel2 &= ~(1 << (i - 32));
+ gpio_io_sel2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_io_sel, res->base + 0x04);
+ outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_i3100_gpio_level(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_lvl, gpio_lvl2;
+ u32 gpio_blink;
+ int i;
+
+ gpio_lvl = inl(res->base + 0x0c);
+ gpio_blink = inl(res->base + 0x18);
+ gpio_lvl2 = inl(res->base + 0x38);
+ for (i = 0; i < 64; i++) {
+ int val, blink;
+ switch (config->gpio[i] & I3100_GPIO_LVL_MASK) {
+ case I3100_GPIO_LVL_LOW:
+ val = 0;
+ blink = 0;
+ break;
+ case I3100_GPIO_LVL_HIGH:
+ val = 1;
+ blink = 0;
+ break;
+ case I3100_GPIO_LVL_BLINK:
+ val = 1;
+ blink = 1;
+ break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_lvl &= ~(1 << i);
+ gpio_blink &= ~(1 << i);
+ gpio_lvl |= (val << i);
+ gpio_blink |= (blink << i);
+ } else {
+ gpio_lvl2 &= ~(1 << (i - 32));
+ gpio_lvl2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_lvl, res->base + 0x0c);
+ outl(gpio_blink, res->base + 0x18);
+ outl(gpio_lvl2, res->base + 0x38);
+}
+
+static void set_i3100_gpio_inv(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_inv;
+ int i;
+
+ gpio_inv = inl(res->base + 0x2c);
+ for (i = 0; i < 32; i++) {
+ int val;
+ switch (config->gpio[i] & I3100_GPIO_INV_MASK) {
+ case I3100_GPIO_INV_OFF:
+ val = 0;
+ break;
+ case I3100_GPIO_INV_ON:
+ val = 1;
+ break;
+ default:
+ continue;
+ }
+ gpio_inv &= ~(1 << i);
+ gpio_inv |= (val << i);
+ }
+ outl(gpio_inv, res->base + 0x2c);
+}
+
+static void i3100_pirq_init(device_t dev)
+{
+ config_t *config;
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+
+ if(config->pirq_a_d) {
+ pci_write_config32(dev, 0x60, config->pirq_a_d);
+ }
+ if(config->pirq_e_h) {
+ pci_write_config32(dev, 0x68, config->pirq_e_h);
+ }
+}
+
+static void i3100_power_options(device_t dev) {
+ u8 reg8;
+ u16 reg16;
+ int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ int nmi_option;
+
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ */
+ get_option(&pwr_on, "power_on_after_fail");
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ reg8 &= 0xfe;
+ if (pwr_on) {
+ reg8 &= ~1;
+ } else {
+ reg8 |= 1;
+ }
+ /* avoid #S4 assertions */
+ reg8 |= (3 << 4);
+ /* minimum asssertion is 1 to 2 RTCCLK */
+ reg8 &= ~(1 << 3);
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ printk(BIOS_INFO, "set power %s after power fail\n", pwr_on ? "on" : "off");
+
+ /* Set up NMI on errors. */
+ reg8 = inb(0x61);
+ /* Higher Nibble must be 0 */
+ reg8 &= 0x0f;
+ /* IOCHK# NMI Enable */
+ reg8 &= ~(1 << 3);
+ /* PCI SERR# Enable */
+ // reg8 &= ~(1 << 2);
+ /* PCI SERR# Disable for now */
+ reg8 |= (1 << 2);
+ outb(reg8, 0x61);
+
+ reg8 = inb(0x70);
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ /* Set NMI. */
+ printk(BIOS_INFO, "NMI sources enabled.\n");
+ reg8 &= ~(1 << 7);
+ } else {
+ /* Can't mask NMI from PCI-E and NMI_NOW */
+ printk(BIOS_INFO, "NMI sources disabled.\n");
+ reg8 |= ( 1 << 7);
+ }
+ outb(reg8, 0x70);
+
+ // Enable CPU_SLP# and Intel Speedstep, set SMI# rate down
+ reg16 = pci_read_config16(dev, GEN_PMCON_1);
+ reg16 &= ~((3 << 0) | (1 << 10));
+ reg16 |= (1 << 3) | (1 << 5);
+ /* CLKRUN_EN */
+ // reg16 |= (1 << 2);
+ pci_write_config16(dev, GEN_PMCON_1, reg16);
+
+ // Set the board's GPI routing.
+ // i82801gx_gpi_routing(dev);
+}
+
+static void i3100_gpio_init(device_t dev)
+{
+ struct resource *res;
+ config_t *config;
+
+ /* Skip if I don't have any configuration */
+ if (!dev->chip_info) {
+ return;
+ }
+ /* The programmer is responsible for ensuring
+ * a valid gpio configuration.
+ */
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+ /* Find the GPIO bar */
+ res = find_resource(dev, GPIO_BAR);
+ if (!res) {
+ return;
+ }
+
+ /* Set the use selects */
+ set_i3100_gpio_use_sel(dev, res, config);
+
+ /* Set the IO direction */
+ set_i3100_gpio_direction(dev, res, config);
+
+ /* Setup the input inverters */
+ set_i3100_gpio_inv(dev, res, config);
+
+ /* Set the value on the GPIO output pins */
+ set_i3100_gpio_level(dev, res, config);
+
+}
+
+
+static void lpc_init(struct device *dev)
+{
+ struct resource *res;
+
+ /* Enable IO APIC */
+ res = find_resource(dev, RCBA);
+ if (!res) {
+ return;
+ }
+ *((u8 *)((u32)res->base + 0x31ff)) |= (1 << 0);
+
+ // TODO this code sets int 0 of the IOAPIC in Virtual Wire Mode
+ // (register 0x10/0x11) while the old code used int 1 (register 0x12)
+ // ... Why?
+ setup_ioapic(IO_APIC_ADDR, 0); // Don't rename IOAPIC ID
+
+ /* Decode 0xffc00000 - 0xffffffff to fwh idsel 0 */
+ pci_write_config32(dev, 0xd0, 0x00000000);
+
+ i3100_enable_serial_irqs(dev);
+
+ /* Set up the PIRQ */
+ i3100_pirq_init(dev);
+
+ /* Setup power options */
+ i3100_power_options(dev);
+
+ /* Set the state of the gpio lines */
+ i3100_gpio_init(dev);
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+}
+
+static void i3100_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Add the ACPI BAR */
+ res = pci_get_resource(dev, ACPI_BAR);
+
+ /* Add the GPIO BAR */
+ res = pci_get_resource(dev, GPIO_BAR);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ /* Add resource for RCBA */
+ res = new_resource(dev, RCBA);
+ res->size = 0x4000;
+ res->limit = 0xffffc000;
+ res->align = 14;
+ res->gran = 14;
+ res->flags = IORESOURCE_MEM;
+}
+
+static void i3100_lpc_enable_resources(device_t dev)
+{
+ u8 acpi_cntl, gpio_cntl;
+
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable the ACPI bar */
+ acpi_cntl = pci_read_config8(dev, 0x44);
+ acpi_cntl |= (1 << 7);
+ pci_write_config8(dev, 0x44, acpi_cntl);
+
+ /* Enable the GPIO bar */
+ gpio_cntl = pci_read_config8(dev, 0x4c);
+ gpio_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x4c, gpio_cntl);
+
+ /* Enable the RCBA */
+ pci_write_config32(dev, RCBA, pci_read_config32(dev, RCBA) | (1 << 0));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = i3100_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = i3100_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_LPC,
+};
+
+static const struct pci_driver lpc_driver_ep80579 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i3100.h"
+
+static void pci_init(struct device *dev)
+{
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCI,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* This code is based on src/northbridge/intel/e7520/pciexp_porta.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <arch/io.h>
+#include "chip.h"
+#include <reset.h>
+
+#define PCIE_LCTL 0x50
+#define PCIE_LSTS 0x52
+
+typedef struct northbridge_intel_i3100_config config_t;
+
+static void pcie_init(struct device *dev)
+{
+}
+
+static unsigned int pcie_scan_bridge(struct device *dev, unsigned int max)
+{
+ u16 val;
+ u16 ctl;
+ int flag = 0;
+ do {
+ val = pci_read_config16(dev, PCIE_LSTS);
+ printk(BIOS_DEBUG, "pcie portb link status: %02x\n", val);
+ if ((val & (1<<10)) && (!flag)) { /* training error */
+ ctl = pci_read_config16(dev, PCIE_LCTL);
+ pci_write_config16(dev, PCIE_LCTL, (ctl | (1<<5)));
+ val = pci_read_config16(dev, PCIE_LSTS);
+ printk(BIOS_DEBUG, "pcie portb reset link status: %02x\n", val);
+ flag=1;
+ hard_reset();
+ }
+ } while (val & (3<<10));
+ return pciexp_scan_bridge(dev, max);
+}
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pcie_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pci_driver_0 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB0,
+};
+
+static const struct pci_driver pci_driver_1 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB1,
+};
+
+static const struct pci_driver pci_driver_2 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB2,
+};
+
+static const struct pci_driver pci_driver_3 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCIE_PB3,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+ outb(0x06, 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_sata.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i3100.h"
+
+typedef struct southbridge_intel_i3100_config config_t;
+
+static void sata_init(struct device *dev)
+{
+ u8 ahci;
+
+ /* Get the chip configuration */
+ ahci = (pci_read_config8(dev, SATA_MAP) >> 6) & 0x03;
+
+ /* Enable SATA devices */
+ printk(BIOS_INFO, "SATA init (%s mode)\n", ahci ? "AHCI" : "Legacy");
+
+ if(ahci) {
+ /* AHCI mode */
+ pci_write_config8(dev, SATA_MAP, (1 << 6) | (0 << 0));
+
+ /* Enable ports */
+ pci_write_config8(dev, SATA_PCS, 0x03);
+ pci_write_config8(dev, SATA_PCS + 1, 0x0F);
+
+ /* Setup timings */
+ pci_write_config16(dev, SATA_PTIM, 0x8000);
+ pci_write_config16(dev, SATA_STIM, 0x8000);
+
+ /* Synchronous DMA */
+ pci_write_config8(dev, SATA_SYNCC, 0);
+ pci_write_config16(dev, SATA_SYNCTIM, 0);
+
+ /* IDE I/O configuration */
+ pci_write_config32(dev, SATA_IIOC, 0);
+
+ } else {
+ /* SATA configuration */
+ pci_write_config8(dev, SATA_CMD, 0x07);
+ pci_write_config8(dev, SATA_PI, 0x8f);
+
+ /* Set timings */
+ pci_write_config16(dev, SATA_PTIM, 0x0a307);
+ pci_write_config16(dev, SATA_STIM, 0x0a307);
+
+ /* Sync DMA */
+ pci_write_config8(dev, SATA_SYNCC, 0x0f);
+ pci_write_config16(dev, SATA_SYNCTIM, 0x1111);
+
+ /* Fast ATA */
+ pci_write_config16(dev, SATA_IIOC, 0x1000);
+
+ /* Select IDE mode */
+ pci_write_config8(dev, SATA_MAP, 0x00);
+
+ /* Enable ports 0-3 */
+ pci_write_config8(dev, SATA_PCS + 1, 0x0f);
+
+ }
+ printk(BIOS_DEBUG, "SATA Enabled\n");
+}
+
+static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = sata_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_IDE,
+};
+
+static const struct pci_driver sata_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_AHCI,
+};
+
+static const struct pci_driver ide_driver_ep80579 __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_IDE,
+};
+
+static const struct pci_driver sata_driver_ep80579 __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_AHCI,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "i3100.h"
+#include "smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &smbus_set_subsystem,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_SMB,
+};
+
+static const struct pci_driver smbus_driver_ep80579 __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_SMB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_smbus.h */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+#define SMBSLVCMD 0x11
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(u32 smbus_io_base)
+{
+ u32 loops = SMBUS_TIMEOUT;
+ u8 byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u32 smbus_io_base)
+{
+ u32 loops = SMBUS_TIMEOUT;
+ u8 byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6)|(1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+static int do_smbus_read_byte(u32 smbus_io_base, u16 device, u8 address)
+{
+ u8 global_status_register;
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ global_status_register &= ~(3 << 5);
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i3100.h"
+
+static void uhci_init(struct device *dev)
+{
+}
+
+static void uhci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &uhci_set_subsystem,
+};
+
+static struct device_operations uhci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = uhci_init,
+ .scan_bus = 0,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver uhci_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_UHCI,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_UHCI2,
+};
+
+static const struct pci_driver uhci_driver_ep80579 __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_EP80579_UHCI,
+};
##
driver-y += i82371eb.c
-driver-y += i82371eb_isa.c
-driver-y += i82371eb_ide.c
-driver-y += i82371eb_usb.c
-driver-y += i82371eb_smbus.c
-driver-y += i82371eb_reset.c
-driver-$(CONFIG_HAVE_ACPI_TABLES) += i82371eb_fadt.c
+driver-y += isa.c
+driver-y += ide.c
+driver-y += usb.c
+driver-y += smbus.c
+driver-y += reset.c
+driver-$(CONFIG_HAVE_ACPI_TABLES) += fadt.c
driver-$(CONFIG_HAVE_ACPI_TABLES) += acpi_tables.c
-romstage-y += i82371eb_early_pm.c
-romstage-y += i82371eb_early_smbus.c
+romstage-y += early_pm.c
+romstage-y += early_smbus.c
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "southbridge/intel/i82371eb/i82371eb_enable_rom.c"
+#include "southbridge/intel/i82371eb/enable_rom.c"
static void bootblock_southbridge_init(void)
{
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "i82371eb.h"
+
+void enable_pm(void)
+{
+ device_t dev;
+ u8 reg8;
+ u16 reg16;
+
+ /* Get the SMBus/PM device of the 82371AB/EB/MB. */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI), 0);
+
+ /* Set the PM I/O base. */
+ pci_write_config32(dev, PMBA, DEFAULT_PMBASE | 1);
+
+ /* Enable access to the PM I/O space. */
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 |= PCI_COMMAND_IO;
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+
+ /* PM I/O Space Enable (PMIOSE). */
+ reg8 = pci_read_config8(dev, PMREGMISC);
+ reg8 |= PMIOSE;
+ pci_write_config8(dev, PMREGMISC, reg8);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include "i82371eb.h"
+#include "smbus.h"
+
+void enable_smbus(void)
+{
+ device_t dev;
+ u8 reg8;
+ u16 reg16;
+
+ /* Get the SMBus/PM device of the 82371AB/EB/MB. */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI), 0);
+
+ /* Set the SMBus I/O base. */
+ pci_write_config32(dev, SMBBA, SMBUS_IO_BASE | 1);
+
+ /* Enable the SMBus controller host interface. */
+ reg8 = pci_read_config8(dev, SMBHSTCFG);
+ reg8 |= SMB_HST_EN;
+ pci_write_config8(dev, SMBHSTCFG, reg8);
+
+ /* Enable access to the SMBus I/O space. */
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 |= PCI_COMMAND_IO;
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+
+ /* Clear any lingering errors, so the transaction will run. */
+ outb(inb(SMBUS_IO_BASE + SMBHST_STATUS), SMBUS_IO_BASE + SMBHST_STATUS);
+}
+
+int smbus_read_byte(u8 device, u8 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+#include "i82371eb.h"
+
+static void i82371eb_enable_rom(void)
+{
+ u16 reg16;
+ device_t dev;
+
+ /*
+ * Note: The Intel 82371AB/EB/MB ISA device can be on different
+ * PCI bus:device.function locations on different boards.
+ * Examples we encountered: 00:07.0, 00:04.0, or 00:14.0.
+ * But scanning for the PCI IDs (instead of hardcoding
+ * bus/device/function numbers) works on all boards.
+ */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_ISA), 0);
+
+ /* Enable access to the whole ROM, disable ROM write access. */
+ reg16 = pci_read_config16(dev, XBCS);
+ reg16 |= LOWER_BIOS_ENABLE;
+ reg16 |= EXT_BIOS_ENABLE;
+ reg16 |= EXT_BIOS_ENABLE_1MB;
+ reg16 &= ~(WRITE_PROTECT_ENABLE); /* Disable ROM write access. */
+ pci_write_config16(dev, XBCS, reg16);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Based on src/southbridge/via/vt8237r/vt8237_fadt.c
+ *
+ * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
+ * Copyright (C) 2007, 2009 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <arch/acpi.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82371eb.h"
+
+/**
+ * Create the Fixed ACPI Description Tables (FADT) for any board with this SB.
+ * Reference: ACPIspec40a, 5.2.9, page 118
+ */
+void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+ device_t dev;
+
+ /* Power management controller */
+ dev = dev_find_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI, 0);
+
+ memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+ header->length = 244;
+ header->revision = 1;
+ memcpy(header->oem_id, "CORE ", 6);
+ memcpy(header->oem_table_id, "COREBOOT", 8);
+ memcpy(header->asl_compiler_id, "CORE", 4);
+ header->asl_compiler_revision = 42;
+
+ fadt->firmware_ctrl = (u32)facs;
+ fadt->dsdt = (u32)dsdt;
+ fadt->preferred_pm_profile = 0; /* unspecified */
+ fadt->sci_int = 9;
+ fadt->smi_cmd = 0; /* smi command port */
+ fadt->acpi_enable = 0; /* acpi enable smi command */
+ fadt->acpi_disable = 0; /* acpi disable smi command */
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0x0;
+
+ fadt->pm1a_evt_blk = DEFAULT_PMBASE;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = DEFAULT_PMBASE + PMCNTRL;
+ fadt->pm1b_cnt_blk = 0x0;
+
+ fadt->pm2_cnt_blk = 0;
+ fadt->pm_tmr_blk = DEFAULT_PMBASE + PMTMR;
+ fadt->gpe0_blk = DEFAULT_PMBASE + GPSTS;
+ fadt->gpe1_blk = 0x0;
+ fadt->gpe1_base = 0;
+ fadt->gpe1_blk_len = 0;
+
+ /* *_len define register width in bytes */
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 0; /* not supported */
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 4;
+
+ fadt->cst_cnt = 0; /* smi command to indicate c state changed notification */
+ fadt->p_lvl2_lat = 101; /* >100 means c2 not supported */
+ fadt->p_lvl3_lat = 1001; /* >1000 means c3 not supported */
+ fadt->flush_size = 0; /* only needed if cpu wbinvd is broken */
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 1; /* bit 1:3 in PCNTRL reg (pmbase+0x10) */
+ fadt->duty_width = 3; /* this width is in bits */
+ fadt->day_alrm = 0x0d; /* rtc cmos ram offset */
+ fadt->mon_alrm = 0x0; /* not supported */
+ fadt->century = 0x0; /* not supported */
+ /*
+ * bit meaning
+ * 0 1: We have user-visible legacy devices
+ * 1 1: 8042
+ * 2 0: VGA is ok to probe
+ * 3 1: MSI are not supported
+ */
+ fadt->iapc_boot_arch = 0xb;
+ /*
+ * bit meaning
+ * 0 WBINVD
+ * Processors in new ACPI-compatible systems are required to
+ * support this function and indicate this to OSPM by setting
+ * this field.
+ * 1 WBINVD_FLUSH
+ * If set, indicates that the hardware flushes all caches on the
+ * WBINVD instruction and maintains memory coherency, but does
+ * not guarantee the caches are invalidated.
+ * 2 PROC_C1
+ * C1 power state (x86 hlt instruction) is supported on all cpus
+ * 3 P_LVL2_UP
+ * 0: C2 only on uniprocessor, 1: C2 on uni- and multiprocessor
+ * 4 PWR_BUTTON
+ * 0: pwr button is fixed feature
+ * 1: pwr button has control method device if present
+ * 5 SLP_BUTTON
+ * 0: sleep button is fixed feature
+ * 1: sleep button has control method device if present
+ * 6 FIX_RTC
+ * 0: RTC wake status supported in fixed register spce
+ * 7 RTC_S4
+ * 1: RTC can wake from S4
+ * 8 TMR_VAL_EXT
+ * 1: pmtimer is 32bit, 0: pmtimer is 24bit
+ * 9 DCK_CAP
+ * 1: system supports docking station
+ * 10 RESET_REG_SUPPORT
+ * 1: fadt describes reset register for system reset
+ * 11 SEALED_CASE
+ * 1: No expansion possible, sealed case
+ * 12 HEADLESS
+ * 1: Video output, keyboard and mouse are not connected
+ * 13 CPU_SW_SLP
+ * 1: Special processor instruction needs to be executed
+ * after writing SLP_TYP
+ * 14 PCI_EXP_WAK
+ * 1: PM1 regs support PCIEXP_WAKE_(STS|EN), must be set
+ * on platforms with pci express support
+ * 15 USE_PLATFORM_CLOCK
+ * 1: OS should prefer platform clock over processor internal
+ * clock.
+ * 16 S4_RTC_STS_VALID
+ * 17 REMOTE_POWER_ON_CAPABLE
+ * 1: platform correctly supports OSPM leaving GPE wake events
+ * armed prior to an S5 transition.
+ * 18 FORCE_APIC_CLUSTER_MODEL
+ * 19 FORCE_APIC_PHYSICAL_DESTINATION_MODE
+ */
+ fadt->flags = 0xa5;
+
+ fadt->reset_reg.space_id = 0;
+ fadt->reset_reg.bit_width = 0;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0x0;
+ fadt->reset_reg.addrh = 0x0;
+ fadt->reset_value = 0;
+
+ fadt->x_firmware_ctl_l = (u32)facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = (u32)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
+}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_def.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "i82371eb.h"
-
-void enable_pm(void)
-{
- device_t dev;
- u8 reg8;
- u16 reg16;
-
- /* Get the SMBus/PM device of the 82371AB/EB/MB. */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI), 0);
-
- /* Set the PM I/O base. */
- pci_write_config32(dev, PMBA, DEFAULT_PMBASE | 1);
-
- /* Enable access to the PM I/O space. */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 |= PCI_COMMAND_IO;
- pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /* PM I/O Space Enable (PMIOSE). */
- reg8 = pci_read_config8(dev, PMREGMISC);
- reg8 |= PMIOSE;
- pci_write_config8(dev, PMREGMISC, reg8);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <device/pci_def.h>
-#include "i82371eb.h"
-#include "i82371eb_smbus.h"
-
-void enable_smbus(void)
-{
- device_t dev;
- u8 reg8;
- u16 reg16;
-
- /* Get the SMBus/PM device of the 82371AB/EB/MB. */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI), 0);
-
- /* Set the SMBus I/O base. */
- pci_write_config32(dev, SMBBA, SMBUS_IO_BASE | 1);
-
- /* Enable the SMBus controller host interface. */
- reg8 = pci_read_config8(dev, SMBHSTCFG);
- reg8 |= SMB_HST_EN;
- pci_write_config8(dev, SMBHSTCFG, reg8);
-
- /* Enable access to the SMBus I/O space. */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 |= PCI_COMMAND_IO;
- pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /* Clear any lingering errors, so the transaction will run. */
- outb(inb(SMBUS_IO_BASE + SMBHST_STATUS), SMBUS_IO_BASE + SMBHST_STATUS);
-}
-
-int smbus_read_byte(u8 device, u8 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-#include "i82371eb.h"
-
-static void i82371eb_enable_rom(void)
-{
- u16 reg16;
- device_t dev;
-
- /*
- * Note: The Intel 82371AB/EB/MB ISA device can be on different
- * PCI bus:device.function locations on different boards.
- * Examples we encountered: 00:07.0, 00:04.0, or 00:14.0.
- * But scanning for the PCI IDs (instead of hardcoding
- * bus/device/function numbers) works on all boards.
- */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_ISA), 0);
-
- /* Enable access to the whole ROM, disable ROM write access. */
- reg16 = pci_read_config16(dev, XBCS);
- reg16 |= LOWER_BIOS_ENABLE;
- reg16 |= EXT_BIOS_ENABLE;
- reg16 |= EXT_BIOS_ENABLE_1MB;
- reg16 &= ~(WRITE_PROTECT_ENABLE); /* Disable ROM write access. */
- pci_write_config16(dev, XBCS, reg16);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Based on src/southbridge/via/vt8237r/vt8237_fadt.c
- *
- * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
- * Copyright (C) 2007, 2009 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-#include <arch/acpi.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82371eb.h"
-
-/**
- * Create the Fixed ACPI Description Tables (FADT) for any board with this SB.
- * Reference: ACPIspec40a, 5.2.9, page 118
- */
-void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
-{
- acpi_header_t *header = &(fadt->header);
- device_t dev;
-
- /* Power management controller */
- dev = dev_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI, 0);
-
- memset((void *) fadt, 0, sizeof(acpi_fadt_t));
- memcpy(header->signature, "FACP", 4);
- header->length = 244;
- header->revision = 1;
- memcpy(header->oem_id, "CORE ", 6);
- memcpy(header->oem_table_id, "COREBOOT", 8);
- memcpy(header->asl_compiler_id, "CORE", 4);
- header->asl_compiler_revision = 42;
-
- fadt->firmware_ctrl = (u32)facs;
- fadt->dsdt = (u32)dsdt;
- fadt->preferred_pm_profile = 0; /* unspecified */
- fadt->sci_int = 9;
- fadt->smi_cmd = 0; /* smi command port */
- fadt->acpi_enable = 0; /* acpi enable smi command */
- fadt->acpi_disable = 0; /* acpi disable smi command */
- fadt->s4bios_req = 0x0;
- fadt->pstate_cnt = 0x0;
-
- fadt->pm1a_evt_blk = DEFAULT_PMBASE;
- fadt->pm1b_evt_blk = 0x0;
- fadt->pm1a_cnt_blk = DEFAULT_PMBASE + PMCNTRL;
- fadt->pm1b_cnt_blk = 0x0;
-
- fadt->pm2_cnt_blk = 0;
- fadt->pm_tmr_blk = DEFAULT_PMBASE + PMTMR;
- fadt->gpe0_blk = DEFAULT_PMBASE + GPSTS;
- fadt->gpe1_blk = 0x0;
- fadt->gpe1_base = 0;
- fadt->gpe1_blk_len = 0;
-
- /* *_len define register width in bytes */
- fadt->pm1_evt_len = 4;
- fadt->pm1_cnt_len = 2;
- fadt->pm2_cnt_len = 0; /* not supported */
- fadt->pm_tmr_len = 4;
- fadt->gpe0_blk_len = 4;
-
- fadt->cst_cnt = 0; /* smi command to indicate c state changed notification */
- fadt->p_lvl2_lat = 101; /* >100 means c2 not supported */
- fadt->p_lvl3_lat = 1001; /* >1000 means c3 not supported */
- fadt->flush_size = 0; /* only needed if cpu wbinvd is broken */
- fadt->flush_stride = 0;
- fadt->duty_offset = 1; /* bit 1:3 in PCNTRL reg (pmbase+0x10) */
- fadt->duty_width = 3; /* this width is in bits */
- fadt->day_alrm = 0x0d; /* rtc cmos ram offset */
- fadt->mon_alrm = 0x0; /* not supported */
- fadt->century = 0x0; /* not supported */
- /*
- * bit meaning
- * 0 1: We have user-visible legacy devices
- * 1 1: 8042
- * 2 0: VGA is ok to probe
- * 3 1: MSI are not supported
- */
- fadt->iapc_boot_arch = 0xb;
- /*
- * bit meaning
- * 0 WBINVD
- * Processors in new ACPI-compatible systems are required to
- * support this function and indicate this to OSPM by setting
- * this field.
- * 1 WBINVD_FLUSH
- * If set, indicates that the hardware flushes all caches on the
- * WBINVD instruction and maintains memory coherency, but does
- * not guarantee the caches are invalidated.
- * 2 PROC_C1
- * C1 power state (x86 hlt instruction) is supported on all cpus
- * 3 P_LVL2_UP
- * 0: C2 only on uniprocessor, 1: C2 on uni- and multiprocessor
- * 4 PWR_BUTTON
- * 0: pwr button is fixed feature
- * 1: pwr button has control method device if present
- * 5 SLP_BUTTON
- * 0: sleep button is fixed feature
- * 1: sleep button has control method device if present
- * 6 FIX_RTC
- * 0: RTC wake status supported in fixed register spce
- * 7 RTC_S4
- * 1: RTC can wake from S4
- * 8 TMR_VAL_EXT
- * 1: pmtimer is 32bit, 0: pmtimer is 24bit
- * 9 DCK_CAP
- * 1: system supports docking station
- * 10 RESET_REG_SUPPORT
- * 1: fadt describes reset register for system reset
- * 11 SEALED_CASE
- * 1: No expansion possible, sealed case
- * 12 HEADLESS
- * 1: Video output, keyboard and mouse are not connected
- * 13 CPU_SW_SLP
- * 1: Special processor instruction needs to be executed
- * after writing SLP_TYP
- * 14 PCI_EXP_WAK
- * 1: PM1 regs support PCIEXP_WAKE_(STS|EN), must be set
- * on platforms with pci express support
- * 15 USE_PLATFORM_CLOCK
- * 1: OS should prefer platform clock over processor internal
- * clock.
- * 16 S4_RTC_STS_VALID
- * 17 REMOTE_POWER_ON_CAPABLE
- * 1: platform correctly supports OSPM leaving GPE wake events
- * armed prior to an S5 transition.
- * 18 FORCE_APIC_CLUSTER_MODEL
- * 19 FORCE_APIC_PHYSICAL_DESTINATION_MODE
- */
- fadt->flags = 0xa5;
-
- fadt->reset_reg.space_id = 0;
- fadt->reset_reg.bit_width = 0;
- fadt->reset_reg.bit_offset = 0;
- fadt->reset_reg.resv = 0;
- fadt->reset_reg.addrl = 0x0;
- fadt->reset_reg.addrh = 0x0;
- fadt->reset_value = 0;
-
- fadt->x_firmware_ctl_l = (u32)facs;
- fadt->x_firmware_ctl_h = 0;
- fadt->x_dsdt_l = (u32)dsdt;
- fadt->x_dsdt_h = 0;
-
- fadt->x_pm1a_evt_blk.space_id = 1;
- fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1a_evt_blk.bit_offset = 0;
- fadt->x_pm1a_evt_blk.resv = 0;
- fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
- fadt->x_pm1a_evt_blk.addrh = 0x0;
-
- fadt->x_pm1b_evt_blk.space_id = 1;
- fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1b_evt_blk.bit_offset = 0;
- fadt->x_pm1b_evt_blk.resv = 0;
- fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
- fadt->x_pm1b_evt_blk.addrh = 0x0;
-
- fadt->x_pm1a_cnt_blk.space_id = 1;
- fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1a_cnt_blk.bit_offset = 0;
- fadt->x_pm1a_cnt_blk.resv = 0;
- fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
- fadt->x_pm1a_cnt_blk.addrh = 0x0;
-
- fadt->x_pm1b_cnt_blk.space_id = 1;
- fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1b_cnt_blk.bit_offset = 0;
- fadt->x_pm1b_cnt_blk.resv = 0;
- fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
- fadt->x_pm1b_cnt_blk.addrh = 0x0;
-
- fadt->x_pm2_cnt_blk.space_id = 1;
- fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
- fadt->x_pm2_cnt_blk.bit_offset = 0;
- fadt->x_pm2_cnt_blk.resv = 0;
- fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
- fadt->x_pm2_cnt_blk.addrh = 0x0;
-
- fadt->x_pm_tmr_blk.space_id = 1;
- fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
- fadt->x_pm_tmr_blk.bit_offset = 0;
- fadt->x_pm_tmr_blk.resv = 0;
- fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
- fadt->x_pm_tmr_blk.addrh = 0x0;
-
- fadt->x_gpe0_blk.space_id = 1;
- fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
- fadt->x_gpe0_blk.bit_offset = 0;
- fadt->x_gpe0_blk.resv = 0;
- fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
- fadt->x_gpe0_blk.addrh = 0x0;
-
- fadt->x_gpe1_blk.space_id = 1;
- fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
- fadt->x_gpe1_blk.bit_offset = 0;
- fadt->x_gpe1_blk.resv = 0;
- fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
- fadt->x_gpe1_blk.addrh = 0x0;
-
- header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* TODO: Check if this really works for all of the southbridges. */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82371eb.h"
-
-/**
- * Initialize the IDE controller.
- *
- * Depending on the configuration variables 'ide0_enable' and 'ide1_enable'
- * enable or disable the primary and secondary IDE interface, respectively.
- *
- * Depending on the configuration variable 'ide_legacy_enable' enable or
- * disable access to the legacy IDE ports and the PCI Bus Master IDE I/O
- * registers (this is required for e.g. FILO).
- *
- * @param dev The device to use.
- */
-static void ide_init_enable(struct device *dev)
-{
- u16 reg16;
- struct southbridge_intel_i82371eb_config *conf = dev->chip_info;
-
- /* Enable/disable the primary IDE interface. */
- reg16 = pci_read_config16(dev, IDETIM_PRI);
- reg16 = ONOFF(conf->ide0_enable, reg16, IDE_DECODE_ENABLE);
- pci_write_config16(dev, IDETIM_PRI, reg16);
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
- conf->ide0_enable ? "on" : "off");
-
- /* Enable/disable the secondary IDE interface. */
- reg16 = pci_read_config16(dev, IDETIM_SEC);
- reg16 = ONOFF(conf->ide1_enable, reg16, IDE_DECODE_ENABLE);
- pci_write_config16(dev, IDETIM_SEC, reg16);
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
- conf->ide1_enable ? "on" : "off");
-
- /* Enable access to the legacy IDE ports (both primary and secondary),
- * and the PCI Bus Master IDE I/O registers.
- * Only do this if at least one IDE interface is enabled.
- */
- if (conf->ide0_enable || conf->ide1_enable) {
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 = ONOFF(conf->ide_legacy_enable, reg16,
- (PCI_COMMAND_IO | PCI_COMMAND_MASTER));
- pci_write_config16(dev, PCI_COMMAND, reg16);
- printk(BIOS_DEBUG, "IDE: Access to legacy IDE ports: %s\n",
- conf->ide_legacy_enable ? "on" : "off");
- }
-}
-
-/**
- * Initialize the Ultra DMA/33 support of the IDE controller.
- *
- * Depending on the configuration variables 'ide0_drive0_udma33_enable',
- * 'ide0_drive1_udma33_enable', 'ide1_drive0_udma33_enable', and
- * 'ide1_drive1_udma33_enable' enable or disable Ultra DMA/33 support for
- * the respective IDE controller and drive.
- *
- * Only do that if the respective controller is actually enabled, of course.
- *
- * @param dev The device to use.
- */
-static void ide_init_udma33(struct device *dev)
-{
- u8 reg8;
- struct southbridge_intel_i82371eb_config *conf = dev->chip_info;
-
- /* Enable/disable UDMA/33 operation (primary IDE interface). */
- if (conf->ide0_enable) {
- reg8 = pci_read_config8(dev, UDMACTL);
- reg8 = ONOFF(conf->ide0_drive0_udma33_enable, reg8, PSDE0);
- reg8 = ONOFF(conf->ide0_drive1_udma33_enable, reg8, PSDE1);
- pci_write_config8(dev, UDMACTL, reg8);
-
- printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
- "Primary IDE interface", 0,
- conf->ide0_drive0_udma33_enable ? "on" : "off");
- printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
- "Primary IDE interface", 1,
- conf->ide0_drive1_udma33_enable ? "on" : "off");
- }
-
- /* Enable/disable Ultra DMA/33 operation (secondary IDE interface). */
- if (conf->ide1_enable) {
- reg8 = pci_read_config8(dev, UDMACTL);
- reg8 = ONOFF(conf->ide1_drive0_udma33_enable, reg8, SSDE0);
- reg8 = ONOFF(conf->ide1_drive1_udma33_enable, reg8, SSDE1);
- pci_write_config8(dev, UDMACTL, reg8);
-
- printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
- "Secondary IDE interface", 0,
- conf->ide1_drive0_udma33_enable ? "on" : "off");
- printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
- "Secondary IDE interface", 1,
- conf->ide1_drive1_udma33_enable ? "on" : "off");
- }
-}
-
-/**
- * IDE init for the Intel 82371FB/SB IDE controller.
- *
- * These devices do not support UDMA/33, so don't attempt to enable it.
- *
- * @param dev The device to use.
- */
-static void ide_init_i82371fb_sb(struct device *dev)
-{
- ide_init_enable(dev);
-}
-
-/**
- * IDE init for the Intel 82371AB/EB/MB IDE controller.
- *
- * @param dev The device to use.
- */
-static void ide_init_i82371ab_eb_mb(struct device *dev)
-{
- ide_init_enable(dev);
- ide_init_udma33(dev);
-}
-
-/* Intel 82371FB/SB */
-static const struct device_operations ide_ops_fb_sb = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init_i82371fb_sb,
- .scan_bus = 0,
- .enable = 0,
- .ops_pci = 0, /* No subsystem IDs on 82371XX! */
-};
-
-/* Intel 82371AB/EB/MB */
-static const struct device_operations ide_ops_ab_eb_mb = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init_i82371ab_eb_mb,
- .scan_bus = 0,
- .enable = 0,
- .ops_pci = 0, /* No subsystem IDs on 82371XX! */
-};
-
-/* Intel 82371FB (PIIX) */
-static const struct pci_driver ide_driver_fb __pci_driver = {
- .ops = &ide_ops_fb_sb,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371FB_IDE,
-};
-
-/* Intel 82371SB (PIIX3) */
-static const struct pci_driver ide_driver_sb __pci_driver = {
- .ops = &ide_ops_fb_sb,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371SB_IDE,
-};
-
-/* Intel 82371MX (MPIIX) */
-static const struct pci_driver ide_driver_mx __pci_driver = {
- .ops = &ide_ops_fb_sb,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371MX_ISA_IDE,
-};
-
-/* Intel 82437MX (part of the 430MX chipset) */
-static const struct pci_driver ide_driver_82437mx __pci_driver = {
- .ops = &ide_ops_fb_sb,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82437MX_ISA_IDE,
-};
-
-/* Intel 82371AB/EB/MB */
-static const struct pci_driver ide_driver_ab_eb_mb __pci_driver = {
- .ops = &ide_ops_ab_eb_mb,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371AB_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/isa-dma.h>
-#include <pc80/mc146818rtc.h>
-#include <arch/ioapic.h>
-#include "i82371eb.h"
-
-#if CONFIG_IOAPIC
-static void enable_intel_82093aa_ioapic(void)
-{
- u16 reg16;
- u32 reg32;
- u8 ioapic_id = 2;
- volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
- volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
- device_t dev;
-
- dev = dev_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_ISA, 0);
-
- /* Enable IOAPIC. */
- reg16 = pci_read_config16(dev, XBCS);
- reg16 |= (1 << 8); /* APIC Chip Select */
- pci_write_config16(dev, XBCS, reg16);
-
- /* Set the IOAPIC ID. */
- *ioapic_index = 0;
- *ioapic_data = ioapic_id << 24;
-
- /* Read back and verify the IOAPIC ID. */
- *ioapic_index = 0;
- reg32 = (*ioapic_data >> 24) & 0x0f;
- printk(BIOS_DEBUG, "IOAPIC ID = %x\n", reg32);
- if (reg32 != ioapic_id)
- die("IOAPIC error!\n");
-}
-#endif
-
-static void isa_init(struct device *dev)
-{
- u32 reg32;
-
- /* Initialize the real time clock (RTC). */
- rtc_init(0);
-
- /*
- * Enable special cycles, needed for soft poweroff.
- */
- reg32 = pci_read_config16(dev, PCI_COMMAND);
- reg32 |= PCI_COMMAND_SPECIAL;
- pci_write_config16(dev, PCI_COMMAND, reg32);
-
- /*
- * The PIIX4 can support the full ISA bus, or the Extended I/O (EIO)
- * bus, which is a subset of ISA. We select the full ISA bus here.
- */
- reg32 = pci_read_config32(dev, GENCFG);
- reg32 |= ISA; /* Select ISA, not EIO. */
- pci_write_config16(dev, GENCFG, reg32);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
-#if CONFIG_IOAPIC
- /*
- * Unlike most other southbridges the 82371EB doesn't have a built-in
- * IOAPIC. Instead, 82371EB-based boards that support multiple CPUs
- * have a discrete IOAPIC (Intel 82093AA) soldered onto the board.
- *
- * Thus, we can/must only enable the IOAPIC if it actually exists,
- * i.e. the respective mainboard does "select IOAPIC".
- */
- enable_intel_82093aa_ioapic();
-#endif
-}
-
-static void sb_read_resources(struct device *dev)
-{
- struct resource *res;
-
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 1);
- res->base = 0x0UL;
- res->size = 0x1000UL;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 2);
- res->base = 0xff800000UL;
- res->size = 0x00800000UL; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
- IORESOURCE_RESERVE;
-
-#if CONFIG_IOAPIC
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
- IORESOURCE_RESERVE;
-#endif
-}
-
-static const struct device_operations isa_ops = {
- .read_resources = sb_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = isa_init,
- .scan_bus = scan_static_bus, /* TODO: Needed? */
- .enable = 0,
- .ops_pci = 0, /* No subsystem IDs on 82371EB! */
-};
-
-static const struct pci_driver isa_driver __pci_driver = {
- .ops = &isa_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371AB_ISA,
-};
-
-static const struct pci_driver isa_SB_driver __pci_driver = {
- .ops = &isa_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371SB_ISA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include "i82371eb.h"
-
-/**
- * Initiate a hard reset.
- */
-void i82371eb_hard_reset(void)
-{
- outb(SRST | RCPU, RC);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2010 Keith Hui <buurin@gmail.com>
- * Copyright (C) 2010 Idwer Vollering <vidwer@gmail.com>
- * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <console/console.h>
-#include <stdint.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/smbus.h>
-#include "i82371eb.h"
-#include "i82371eb_smbus.h"
-
-static void pwrmgt_enable(struct device *dev)
-{
- struct southbridge_intel_i82371eb_config *sb = dev->chip_info;
- u32 reg, gpo = sb->gpo;
-
- /* Sets the base address of power management ports. */
- pci_write_config16(dev, PMBA, DEFAULT_PMBASE | 1);
-
- /* Set Power Management IO Space Enable bit */
- u8 val = pci_read_config8(dev, PMREGMISC);
- pci_write_config8(dev, PMREGMISC, val | 1);
-
- /* set global control:
- * bit25 (lid_pol): 1=invert lid polarity
- * bit24 (sm_freeze): 1=freeze idle and standby timers
- * bit16 (end of smi): 0=disable smi assertion (cleared by hw)
- * bits8-15,26: global standby timer inital count 127 * 4minutes
- * bit2 (thrm_pol): 1=active low THRM#
- * bit0 (smi_en): 1=disable smi generation upon smi event
- */
- reg = (sb->lid_polarity<<25)|
- (1<<24)|
- (0xff<<8)|
- (sb->thrm_polarity<<2);
- outl(reg, DEFAULT_PMBASE + GLBCTL);
-
- /* set processor control:
- * bit12 (stpclk_en): 1=enable stopping of host clk on lvl3
- * bit11 (sleep_en): 1=enable slp# assertion on lvl3
- * bit9 (cc_en): 1=enable clk control with lvl2 and lvl3 regs
- */
- outl(0, DEFAULT_PMBASE + PCNTRL);
-
- /* disable smi event enables */
- outw(0, DEFAULT_PMBASE + GLBEN);
- outl(0, DEFAULT_PMBASE + DEVCTL);
-
- /* set default gpo value.
- * power-on default is 0x7fffbfffh */
- if (gpo) {
- /* only 8bit access allowed */
- outb( gpo & 0xff, DEFAULT_PMBASE + GPO0);
- outb((gpo >> 8) & 0xff, DEFAULT_PMBASE + GPO1);
- outb((gpo >> 16) & 0xff, DEFAULT_PMBASE + GPO2);
- outb((gpo >> 24) & 0xff, DEFAULT_PMBASE + GPO3);
- } else {
- printk(BIOS_SPEW,
- "%s: gpo default missing in devicetree.cb!\n", __func__);
- }
-
- /* Clear status events. */
- outw(0xffff, DEFAULT_PMBASE + PMSTS);
- outw(0xffff, DEFAULT_PMBASE + GPSTS);
- outw(0xffff, DEFAULT_PMBASE + GLBSTS);
- outl(0xffffffff, DEFAULT_PMBASE + DEVSTS);
-
- /* set pmcntrl default */
- outw(SUS_TYP_S0|SCI_EN, DEFAULT_PMBASE + PMCNTRL);
-}
-
-static void pwrmgt_read_resources(struct device *dev)
-{
- struct resource *res;
-
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 1);
- res->base = DEFAULT_PMBASE;
- res->size = 0x0040;
- res->limit = 0xffff;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
- IORESOURCE_RESERVE;
-
- res = new_resource(dev, 2);
- res->base = SMBUS_IO_BASE;
- res->size = 0x0010;
- res->limit = 0xffff;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
- IORESOURCE_RESERVE;
-}
-
-
-static const struct smbus_bus_operations lops_smbus_bus = {
-};
-
-static const struct device_operations smbus_ops = {
- .read_resources = pwrmgt_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = pwrmgt_enable,
- .ops_pci = 0, /* No subsystem IDs on 82371EB! */
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-/* Note: There's no SMBus on 82371FB/SB/MX and 82437MX. */
-
-/* Intel 82371AB/EB/MB */
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI,
-};
+++ /dev/null
-#include <device/smbus_def.h>
-#include "i82371eb.h"
-
-#define SMBHST_STATUS 0x0
-#define SMBHST_CTL 0x2
-#define SMBHST_CMD 0x3
-#define SMBHST_ADDR 0x4
-#define SMBHST_DAT 0x5
-
-#define SMBUS_TIMEOUT (100*1000*10)
-#define SMBUS_STATUS_MASK 0x1e
-#define SMBUS_ERROR_FLAG (1<<2)
-
-int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address);
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(smbus_io_base + SMBHST_STATUS);
- if ((val & 0x1) == 0) {
- break;
- }
-#if 0
- if(loops == (SMBUS_TIMEOUT / 2)) {
- outw(inw(smbus_io_base + SMBHST_STATUS),
- smbus_io_base + SMBHST_STATUS);
- }
-#endif
- } while(--loops);
- return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned short val;
- smbus_delay();
-
- val = inb(smbus_io_base + SMBHST_STATUS);
- // Make sure the command is done
- if ((val & 0x1) != 0) {
- continue;
- }
- // Don't break out until one of the interrupt
- // flags is set.
- if (val & 0xfe) {
- break;
- }
- } while(--loops);
- return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
-}
-
-int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned status_register;
- unsigned byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
-
- /* setup transaction */
-
- /* clear any lingering errors, so the transaction will run */
- outb(0x1e, smbus_io_base + SMBHST_STATUS);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR);
-
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHST_CMD);
-
- /* clear the data word...*/
- outb(0, smbus_io_base + SMBHST_DAT);
-
- /* start a byte read with interrupts disabled */
- outb( (0x02 << 2)|(1<<6), smbus_io_base + SMBHST_CTL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- status_register = inw(smbus_io_base + SMBHST_STATUS);
-
- /* read results of transaction */
- byte = inw(smbus_io_base + SMBHST_DAT) & 0xff;
-
- if (status_register & 0x04) {
-#if 0
- print_debug("Read fail ");
- print_debug_hex16(status_register);
- print_debug("\n");
-#endif
- return SMBUS_ERROR;
- }
- return byte;
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82371eb.h"
-
-/**
- * Initialize the USB (UHCI) controller.
- *
- * Depending on the configuration variable 'usb_enable', enable or
- * disable the USB (UHCI) controller.
- *
- * @param dev The device to use.
- */
-static void usb_init(struct device *dev)
-{
- /* TODO: No special init needed? */
-}
-
-static const struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = 0,
- .ops_pci = 0, /* No subsystem IDs on 82371EB! */
-};
-
-/* Note: No USB on 82371FB/MX (PIIX/MPIIX) and 82437MX. */
-
-/* Intel 82371SB (PIIX3) */
-static const struct pci_driver usb_driver_sb __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371SB_USB,
-};
-
-/* Intel 82371AB/EB/MB (PIIX4/PIIX4E/PIIX4M) */
-/* The 440MX (82443MX) consists of 82443BX + 82371EB (uses same PCI IDs). */
-static const struct pci_driver usb_driver_ab_eb_mb __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82371AB_USB,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* TODO: Check if this really works for all of the southbridges. */
+
+#include <stdint.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82371eb.h"
+
+/**
+ * Initialize the IDE controller.
+ *
+ * Depending on the configuration variables 'ide0_enable' and 'ide1_enable'
+ * enable or disable the primary and secondary IDE interface, respectively.
+ *
+ * Depending on the configuration variable 'ide_legacy_enable' enable or
+ * disable access to the legacy IDE ports and the PCI Bus Master IDE I/O
+ * registers (this is required for e.g. FILO).
+ *
+ * @param dev The device to use.
+ */
+static void ide_init_enable(struct device *dev)
+{
+ u16 reg16;
+ struct southbridge_intel_i82371eb_config *conf = dev->chip_info;
+
+ /* Enable/disable the primary IDE interface. */
+ reg16 = pci_read_config16(dev, IDETIM_PRI);
+ reg16 = ONOFF(conf->ide0_enable, reg16, IDE_DECODE_ENABLE);
+ pci_write_config16(dev, IDETIM_PRI, reg16);
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
+ conf->ide0_enable ? "on" : "off");
+
+ /* Enable/disable the secondary IDE interface. */
+ reg16 = pci_read_config16(dev, IDETIM_SEC);
+ reg16 = ONOFF(conf->ide1_enable, reg16, IDE_DECODE_ENABLE);
+ pci_write_config16(dev, IDETIM_SEC, reg16);
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
+ conf->ide1_enable ? "on" : "off");
+
+ /* Enable access to the legacy IDE ports (both primary and secondary),
+ * and the PCI Bus Master IDE I/O registers.
+ * Only do this if at least one IDE interface is enabled.
+ */
+ if (conf->ide0_enable || conf->ide1_enable) {
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 = ONOFF(conf->ide_legacy_enable, reg16,
+ (PCI_COMMAND_IO | PCI_COMMAND_MASTER));
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+ printk(BIOS_DEBUG, "IDE: Access to legacy IDE ports: %s\n",
+ conf->ide_legacy_enable ? "on" : "off");
+ }
+}
+
+/**
+ * Initialize the Ultra DMA/33 support of the IDE controller.
+ *
+ * Depending on the configuration variables 'ide0_drive0_udma33_enable',
+ * 'ide0_drive1_udma33_enable', 'ide1_drive0_udma33_enable', and
+ * 'ide1_drive1_udma33_enable' enable or disable Ultra DMA/33 support for
+ * the respective IDE controller and drive.
+ *
+ * Only do that if the respective controller is actually enabled, of course.
+ *
+ * @param dev The device to use.
+ */
+static void ide_init_udma33(struct device *dev)
+{
+ u8 reg8;
+ struct southbridge_intel_i82371eb_config *conf = dev->chip_info;
+
+ /* Enable/disable UDMA/33 operation (primary IDE interface). */
+ if (conf->ide0_enable) {
+ reg8 = pci_read_config8(dev, UDMACTL);
+ reg8 = ONOFF(conf->ide0_drive0_udma33_enable, reg8, PSDE0);
+ reg8 = ONOFF(conf->ide0_drive1_udma33_enable, reg8, PSDE1);
+ pci_write_config8(dev, UDMACTL, reg8);
+
+ printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
+ "Primary IDE interface", 0,
+ conf->ide0_drive0_udma33_enable ? "on" : "off");
+ printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
+ "Primary IDE interface", 1,
+ conf->ide0_drive1_udma33_enable ? "on" : "off");
+ }
+
+ /* Enable/disable Ultra DMA/33 operation (secondary IDE interface). */
+ if (conf->ide1_enable) {
+ reg8 = pci_read_config8(dev, UDMACTL);
+ reg8 = ONOFF(conf->ide1_drive0_udma33_enable, reg8, SSDE0);
+ reg8 = ONOFF(conf->ide1_drive1_udma33_enable, reg8, SSDE1);
+ pci_write_config8(dev, UDMACTL, reg8);
+
+ printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
+ "Secondary IDE interface", 0,
+ conf->ide1_drive0_udma33_enable ? "on" : "off");
+ printk(BIOS_DEBUG, "IDE: %s, drive %d: UDMA/33: %s\n",
+ "Secondary IDE interface", 1,
+ conf->ide1_drive1_udma33_enable ? "on" : "off");
+ }
+}
+
+/**
+ * IDE init for the Intel 82371FB/SB IDE controller.
+ *
+ * These devices do not support UDMA/33, so don't attempt to enable it.
+ *
+ * @param dev The device to use.
+ */
+static void ide_init_i82371fb_sb(struct device *dev)
+{
+ ide_init_enable(dev);
+}
+
+/**
+ * IDE init for the Intel 82371AB/EB/MB IDE controller.
+ *
+ * @param dev The device to use.
+ */
+static void ide_init_i82371ab_eb_mb(struct device *dev)
+{
+ ide_init_enable(dev);
+ ide_init_udma33(dev);
+}
+
+/* Intel 82371FB/SB */
+static const struct device_operations ide_ops_fb_sb = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init_i82371fb_sb,
+ .scan_bus = 0,
+ .enable = 0,
+ .ops_pci = 0, /* No subsystem IDs on 82371XX! */
+};
+
+/* Intel 82371AB/EB/MB */
+static const struct device_operations ide_ops_ab_eb_mb = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init_i82371ab_eb_mb,
+ .scan_bus = 0,
+ .enable = 0,
+ .ops_pci = 0, /* No subsystem IDs on 82371XX! */
+};
+
+/* Intel 82371FB (PIIX) */
+static const struct pci_driver ide_driver_fb __pci_driver = {
+ .ops = &ide_ops_fb_sb,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371FB_IDE,
+};
+
+/* Intel 82371SB (PIIX3) */
+static const struct pci_driver ide_driver_sb __pci_driver = {
+ .ops = &ide_ops_fb_sb,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371SB_IDE,
+};
+
+/* Intel 82371MX (MPIIX) */
+static const struct pci_driver ide_driver_mx __pci_driver = {
+ .ops = &ide_ops_fb_sb,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371MX_ISA_IDE,
+};
+
+/* Intel 82437MX (part of the 430MX chipset) */
+static const struct pci_driver ide_driver_82437mx __pci_driver = {
+ .ops = &ide_ops_fb_sb,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82437MX_ISA_IDE,
+};
+
+/* Intel 82371AB/EB/MB */
+static const struct pci_driver ide_driver_ab_eb_mb __pci_driver = {
+ .ops = &ide_ops_ab_eb_mb,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371AB_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/isa-dma.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/ioapic.h>
+#include "i82371eb.h"
+
+#if CONFIG_IOAPIC
+static void enable_intel_82093aa_ioapic(void)
+{
+ u16 reg16;
+ u32 reg32;
+ u8 ioapic_id = 2;
+ volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
+ volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
+ device_t dev;
+
+ dev = dev_find_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_ISA, 0);
+
+ /* Enable IOAPIC. */
+ reg16 = pci_read_config16(dev, XBCS);
+ reg16 |= (1 << 8); /* APIC Chip Select */
+ pci_write_config16(dev, XBCS, reg16);
+
+ /* Set the IOAPIC ID. */
+ *ioapic_index = 0;
+ *ioapic_data = ioapic_id << 24;
+
+ /* Read back and verify the IOAPIC ID. */
+ *ioapic_index = 0;
+ reg32 = (*ioapic_data >> 24) & 0x0f;
+ printk(BIOS_DEBUG, "IOAPIC ID = %x\n", reg32);
+ if (reg32 != ioapic_id)
+ die("IOAPIC error!\n");
+}
+#endif
+
+static void isa_init(struct device *dev)
+{
+ u32 reg32;
+
+ /* Initialize the real time clock (RTC). */
+ rtc_init(0);
+
+ /*
+ * Enable special cycles, needed for soft poweroff.
+ */
+ reg32 = pci_read_config16(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_SPECIAL;
+ pci_write_config16(dev, PCI_COMMAND, reg32);
+
+ /*
+ * The PIIX4 can support the full ISA bus, or the Extended I/O (EIO)
+ * bus, which is a subset of ISA. We select the full ISA bus here.
+ */
+ reg32 = pci_read_config32(dev, GENCFG);
+ reg32 |= ISA; /* Select ISA, not EIO. */
+ pci_write_config16(dev, GENCFG, reg32);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+#if CONFIG_IOAPIC
+ /*
+ * Unlike most other southbridges the 82371EB doesn't have a built-in
+ * IOAPIC. Instead, 82371EB-based boards that support multiple CPUs
+ * have a discrete IOAPIC (Intel 82093AA) soldered onto the board.
+ *
+ * Thus, we can/must only enable the IOAPIC if it actually exists,
+ * i.e. the respective mainboard does "select IOAPIC".
+ */
+ enable_intel_82093aa_ioapic();
+#endif
+}
+
+static void sb_read_resources(struct device *dev)
+{
+ struct resource *res;
+
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 1);
+ res->base = 0x0UL;
+ res->size = 0x1000UL;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 2);
+ res->base = 0xff800000UL;
+ res->size = 0x00800000UL; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
+ IORESOURCE_RESERVE;
+
+#if CONFIG_IOAPIC
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
+ IORESOURCE_RESERVE;
+#endif
+}
+
+static const struct device_operations isa_ops = {
+ .read_resources = sb_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = isa_init,
+ .scan_bus = scan_static_bus, /* TODO: Needed? */
+ .enable = 0,
+ .ops_pci = 0, /* No subsystem IDs on 82371EB! */
+};
+
+static const struct pci_driver isa_driver __pci_driver = {
+ .ops = &isa_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371AB_ISA,
+};
+
+static const struct pci_driver isa_SB_driver __pci_driver = {
+ .ops = &isa_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371SB_ISA,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include "i82371eb.h"
+
+/**
+ * Initiate a hard reset.
+ */
+void i82371eb_hard_reset(void)
+{
+ outb(SRST | RCPU, RC);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2010 Keith Hui <buurin@gmail.com>
+ * Copyright (C) 2010 Idwer Vollering <vidwer@gmail.com>
+ * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/smbus.h>
+#include "i82371eb.h"
+#include "smbus.h"
+
+static void pwrmgt_enable(struct device *dev)
+{
+ struct southbridge_intel_i82371eb_config *sb = dev->chip_info;
+ u32 reg, gpo = sb->gpo;
+
+ /* Sets the base address of power management ports. */
+ pci_write_config16(dev, PMBA, DEFAULT_PMBASE | 1);
+
+ /* Set Power Management IO Space Enable bit */
+ u8 val = pci_read_config8(dev, PMREGMISC);
+ pci_write_config8(dev, PMREGMISC, val | 1);
+
+ /* set global control:
+ * bit25 (lid_pol): 1=invert lid polarity
+ * bit24 (sm_freeze): 1=freeze idle and standby timers
+ * bit16 (end of smi): 0=disable smi assertion (cleared by hw)
+ * bits8-15,26: global standby timer inital count 127 * 4minutes
+ * bit2 (thrm_pol): 1=active low THRM#
+ * bit0 (smi_en): 1=disable smi generation upon smi event
+ */
+ reg = (sb->lid_polarity<<25)|
+ (1<<24)|
+ (0xff<<8)|
+ (sb->thrm_polarity<<2);
+ outl(reg, DEFAULT_PMBASE + GLBCTL);
+
+ /* set processor control:
+ * bit12 (stpclk_en): 1=enable stopping of host clk on lvl3
+ * bit11 (sleep_en): 1=enable slp# assertion on lvl3
+ * bit9 (cc_en): 1=enable clk control with lvl2 and lvl3 regs
+ */
+ outl(0, DEFAULT_PMBASE + PCNTRL);
+
+ /* disable smi event enables */
+ outw(0, DEFAULT_PMBASE + GLBEN);
+ outl(0, DEFAULT_PMBASE + DEVCTL);
+
+ /* set default gpo value.
+ * power-on default is 0x7fffbfffh */
+ if (gpo) {
+ /* only 8bit access allowed */
+ outb( gpo & 0xff, DEFAULT_PMBASE + GPO0);
+ outb((gpo >> 8) & 0xff, DEFAULT_PMBASE + GPO1);
+ outb((gpo >> 16) & 0xff, DEFAULT_PMBASE + GPO2);
+ outb((gpo >> 24) & 0xff, DEFAULT_PMBASE + GPO3);
+ } else {
+ printk(BIOS_SPEW,
+ "%s: gpo default missing in devicetree.cb!\n", __func__);
+ }
+
+ /* Clear status events. */
+ outw(0xffff, DEFAULT_PMBASE + PMSTS);
+ outw(0xffff, DEFAULT_PMBASE + GPSTS);
+ outw(0xffff, DEFAULT_PMBASE + GLBSTS);
+ outl(0xffffffff, DEFAULT_PMBASE + DEVSTS);
+
+ /* set pmcntrl default */
+ outw(SUS_TYP_S0|SCI_EN, DEFAULT_PMBASE + PMCNTRL);
+}
+
+static void pwrmgt_read_resources(struct device *dev)
+{
+ struct resource *res;
+
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 1);
+ res->base = DEFAULT_PMBASE;
+ res->size = 0x0040;
+ res->limit = 0xffff;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
+ IORESOURCE_RESERVE;
+
+ res = new_resource(dev, 2);
+ res->base = SMBUS_IO_BASE;
+ res->size = 0x0010;
+ res->limit = 0xffff;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED |
+ IORESOURCE_RESERVE;
+}
+
+
+static const struct smbus_bus_operations lops_smbus_bus = {
+};
+
+static const struct device_operations smbus_ops = {
+ .read_resources = pwrmgt_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = pwrmgt_enable,
+ .ops_pci = 0, /* No subsystem IDs on 82371EB! */
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+/* Note: There's no SMBus on 82371FB/SB/MX and 82437MX. */
+
+/* Intel 82371AB/EB/MB */
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI,
+};
--- /dev/null
+#include <device/smbus_def.h>
+#include "i82371eb.h"
+
+#define SMBHST_STATUS 0x0
+#define SMBHST_CTL 0x2
+#define SMBHST_CMD 0x3
+#define SMBHST_ADDR 0x4
+#define SMBHST_DAT 0x5
+
+#define SMBUS_TIMEOUT (100*1000*10)
+#define SMBUS_STATUS_MASK 0x1e
+#define SMBUS_ERROR_FLAG (1<<2)
+
+int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address);
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+ outb(0x80, 0x80);
+ outb(0x80, 0x80);
+ outb(0x80, 0x80);
+ outb(0x80, 0x80);
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(smbus_io_base + SMBHST_STATUS);
+ if ((val & 0x1) == 0) {
+ break;
+ }
+#if 0
+ if(loops == (SMBUS_TIMEOUT / 2)) {
+ outw(inw(smbus_io_base + SMBHST_STATUS),
+ smbus_io_base + SMBHST_STATUS);
+ }
+#endif
+ } while(--loops);
+ return loops?0:SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned short val;
+ smbus_delay();
+
+ val = inb(smbus_io_base + SMBHST_STATUS);
+ // Make sure the command is done
+ if ((val & 0x1) != 0) {
+ continue;
+ }
+ // Don't break out until one of the interrupt
+ // flags is set.
+ if (val & 0xfe) {
+ break;
+ }
+ } while(--loops);
+ return loops?0:SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+}
+
+int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned status_register;
+ unsigned byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+
+ /* setup transaction */
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(0x1e, smbus_io_base + SMBHST_STATUS);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBHST_ADDR);
+
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHST_CMD);
+
+ /* clear the data word...*/
+ outb(0, smbus_io_base + SMBHST_DAT);
+
+ /* start a byte read with interrupts disabled */
+ outb( (0x02 << 2)|(1<<6), smbus_io_base + SMBHST_CTL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ status_register = inw(smbus_io_base + SMBHST_STATUS);
+
+ /* read results of transaction */
+ byte = inw(smbus_io_base + SMBHST_DAT) & 0xff;
+
+ if (status_register & 0x04) {
+#if 0
+ print_debug("Read fail ");
+ print_debug_hex16(status_register);
+ print_debug("\n");
+#endif
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82371eb.h"
+
+/**
+ * Initialize the USB (UHCI) controller.
+ *
+ * Depending on the configuration variable 'usb_enable', enable or
+ * disable the USB (UHCI) controller.
+ *
+ * @param dev The device to use.
+ */
+static void usb_init(struct device *dev)
+{
+ /* TODO: No special init needed? */
+}
+
+static const struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = 0,
+ .ops_pci = 0, /* No subsystem IDs on 82371EB! */
+};
+
+/* Note: No USB on 82371FB/MX (PIIX/MPIIX) and 82437MX. */
+
+/* Intel 82371SB (PIIX3) */
+static const struct pci_driver usb_driver_sb __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371SB_USB,
+};
+
+/* Intel 82371AB/EB/MB (PIIX4/PIIX4E/PIIX4M) */
+/* The 440MX (82443MX) consists of 82443BX + 82371EB (uses same PCI IDs). */
+static const struct pci_driver usb_driver_ab_eb_mb __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82371AB_USB,
+};
##
driver-y += i82801ax.c
-driver-y += i82801ax_ac97.c
-driver-y += i82801ax_ide.c
-driver-y += i82801ax_lpc.c
-driver-y += i82801ax_pci.c
-driver-y += i82801ax_smbus.c
-driver-y += i82801ax_usb.c
+driver-y += ac97.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += pci.c
+driver-y += smbus.c
+driver-y += usb.c
-ramstage-y += i82801ax_reset.c
-ramstage-y += i82801ax_watchdog.c
+ramstage-y += reset.c
+ramstage-y += watchdog.c
-romstage-y += i82801ax_early_smbus.c
+romstage-y += early_smbus.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801ax.h"
+
+static struct device_operations ac97_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = i82801ax_enable,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_ac97_audio __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AA_AC97_AUDIO,
+};
+
+static const struct pci_driver i82801aa_ac97_modem __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AA_AC97_MODEM,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_ac97_audio __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AB_AC97_AUDIO,
+};
+
+static const struct pci_driver i82801ab_ac97_modem __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AB_AC97_MODEM,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include "i82801ax.h"
+#include "smbus.h"
+
+void enable_smbus(void)
+{
+ device_t dev;
+
+ /* Set the SMBus device statically (D31:F3). */
+ dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ /* Set SMBus I/O base. */
+ pci_write_config32(dev, SMB_BASE,
+ SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+
+ /* Set SMBus enable. */
+ pci_write_config8(dev, HOSTC, HST_EN);
+
+ /* Set SMBus I/O space enable. */
+ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ /* Disable interrupt generation. */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* Clear any lingering errors, so transactions can run. */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ print_debug("SMBus controller enabled\n");
+}
+
+int smbus_read_byte(u8 device, u8 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801ax.h"
-
-static struct device_operations ac97_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = i82801ax_enable,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_ac97_audio __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AA_AC97_AUDIO,
-};
-
-static const struct pci_driver i82801aa_ac97_modem __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AA_AC97_MODEM,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_ac97_audio __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AB_AC97_AUDIO,
-};
-
-static const struct pci_driver i82801ab_ac97_modem __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AB_AC97_MODEM,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <device/pci_def.h>
-#include "i82801ax.h"
-#include "i82801ax_smbus.h"
-
-void enable_smbus(void)
-{
- device_t dev;
-
- /* Set the SMBus device statically (D31:F3). */
- dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- /* Set SMBus I/O base. */
- pci_write_config32(dev, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
-
- /* Set SMBus enable. */
- pci_write_config8(dev, HOSTC, HST_EN);
-
- /* Set SMBus I/O space enable. */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Disable interrupt generation. */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* Clear any lingering errors, so transactions can run. */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- print_debug("SMBus controller enabled\n");
-}
-
-int smbus_read_byte(u8 device, u8 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- * Copyright (C) 2005 Digital Design Corporation
- * (Written by Steven J. Magnani <steve@digidescorp.com> for Digital Design)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801ax.h"
-
-typedef struct southbridge_intel_i82801ax_config config_t;
-
-static void ide_init(struct device *dev)
-{
- u16 reg16;
- config_t *conf = dev->chip_info;
-
- reg16 = pci_read_config16(dev, IDE_TIM_PRI);
- reg16 &= ~IDE_DECODE_ENABLE;
- if (!conf || conf->ide0_enable)
- reg16 |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
- conf->ide0_enable ? "on" : "off");
- pci_write_config16(dev, IDE_TIM_PRI, reg16);
-
- reg16 = pci_read_config16(dev, IDE_TIM_SEC);
- reg16 &= ~IDE_DECODE_ENABLE;
- if (!conf || conf->ide1_enable)
- reg16 |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
- conf->ide0_enable ? "on" : "off");
- pci_write_config16(dev, IDE_TIM_SEC, reg16);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = i82801ax_enable,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2411,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2421,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2003 SuSE Linux AG
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801ax.h"
-
-#define GPIO_BASE_ADDR 0x00000500 /* GPIO Base Address Register */
-
-#define NMI_OFF 0
-
-typedef struct southbridge_intel_i82801ax_config config_t;
-
-/* PIRQ[n]_ROUT[3:0] - IRQ Routing (ISA compatible)
- * 0x00 - 0000 = Reserved
- * 0x01 - 0001 = Reserved
- * 0x02 - 0010 = Reserved
- * 0x03 - 0011 = IRQ3
- * 0x04 - 0100 = IRQ4
- * 0x05 - 0101 = IRQ5
- * 0x06 - 0110 = IRQ6
- * 0x07 - 0111 = IRQ7
- * 0x08 - 1000 = Reserved
- * 0x09 - 1001 = IRQ9
- * 0x0A - 1010 = IRQ10
- * 0x0B - 1011 = IRQ11
- * 0x0C - 1100 = IRQ12
- * 0x0D - 1101 = Reserved
- * 0x0E - 1110 = IRQ14
- * 0x0F - 1111 = IRQ15
- *
- * PIRQ[n]_ROUT[7] - Interrupt Routing Enable (IRQEN)
- * 0 - The PIRQ is routed to the ISA-compatible interrupt specified above.
- * 1 - The PIRQ is not routed to the 8259.
- */
-
-#define PIRQA 0x03
-#define PIRQB 0x04
-#define PIRQC 0x05
-#define PIRQD 0x06
-
-/*
- * Use 0x0ef8 for a bitmap to cover all these IRQ's.
- * Use the defined IRQ values above or set mainboard
- * specific IRQ values in your devicetree.cb.
- */
-static void i82801ax_enable_apic(struct device *dev)
-{
- u32 reg32;
- volatile u32 *ioapic_index = (volatile u32 *)IO_APIC_ADDR;
- volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
-
- /* Set ACPI base address (I/O space). */
- pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
-
- /* Enable ACPI I/O range decode and ACPI power management. */
- pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
-
- reg32 = pci_read_config32(dev, GEN_CNTL);
- reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
- reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */
- reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */
- reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */
- pci_write_config32(dev, GEN_CNTL, reg32);
- printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
-
- *ioapic_index = 0;
- *ioapic_data = (1 << 25);
-
- *ioapic_index = 0;
- reg32 = *ioapic_data;
- printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
- if (reg32 != (1 << 25))
- die("APIC Error\n");
-
- /* TODO: From i82801ca, needed/useful on other ICH? */
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
-}
-
-static void i82801ax_enable_serial_irqs(struct device *dev)
-{
- /* Set packet length and toggle silent mode bit. */
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
- /* TODO: Explain/#define the real meaning of these magic numbers. */
-}
-
-static void i82801ax_pirq_init(device_t dev)
-{
- u8 reg8;
- config_t *config = dev->chip_info;
-
- reg8 = (config->pirqa_routing) ? config->pirqa_routing : PIRQA;
- pci_write_config8(dev, PIRQA_ROUT, reg8);
-
- reg8 = (config->pirqb_routing) ? config->pirqb_routing : PIRQB;
- pci_write_config8(dev, PIRQB_ROUT, reg8);
-
- reg8 = (config->pirqc_routing) ? config->pirqc_routing : PIRQC;
- pci_write_config8(dev, PIRQC_ROUT, reg8);
-
- reg8 = (config->pirqd_routing) ? config->pirqd_routing : PIRQD;
- pci_write_config8(dev, PIRQD_ROUT, reg8);
-}
-
-static void i82801ax_power_options(device_t dev)
-{
- uint8_t byte;
- int pwr_on = -1;
- int nmi_option;
-
- /* power after power fail */
- /* FIXME this doesn't work! */
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- */
- pci_write_config8(dev, GEN_PMCON_3, pwr_on ? 0 : 1);
- printk(BIOS_INFO, "Set power %s if power fails\n", pwr_on ? "on" : "off");
-
- /* Set up NMI on errors. */
- byte = inb(0x61);
- byte &= ~(1 << 3); /* IOCHK# NMI Enable */
- byte &= ~(1 << 2); /* PCI SERR# Enable */
- outb(byte, 0x61);
- byte = inb(0x70);
-
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* Set NMI. */
- outb(byte, 0x70);
- }
-}
-
-static void gpio_init(device_t dev)
-{
- pci_write_config32(dev, GPIO_BASE, (GPIO_BASE_ADDR | 1));
- pci_write_config8(dev, GPIO_CNTL, GPIO_EN);
-}
-
-static void i82801ax_rtc_init(struct device *dev)
-{
- uint8_t reg8;
- uint32_t reg32;
- int rtc_failed;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- rtc_failed = reg8 & RTC_BATTERY_DEAD;
- if (rtc_failed) {
- reg8 &= ~(1 << 1); /* Preserve the power fail state. */
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- }
- reg32 = pci_read_config32(dev, GEN_STA);
- rtc_failed |= reg32 & (1 << 2);
- rtc_init(rtc_failed);
-
- /* Enable access to the upper 128 byte bank of CMOS RAM. */
- pci_write_config8(dev, RTC_CONF, 0x04);
-}
-
-static void i82801ax_lpc_route_dma(struct device *dev, uint8_t mask)
-{
- uint16_t reg16;
- int i;
-
- reg16 = pci_read_config16(dev, PCI_DMA_CFG);
- reg16 &= 0x300;
- for (i = 0; i < 8; i++) {
- if (i == 4)
- continue;
- reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
- }
- pci_write_config16(dev, PCI_DMA_CFG, reg16);
-}
-
-static void i82801ax_lpc_decode_en(device_t dev)
-{
- /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
- * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
- * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
- * We also need to set the value for LPC I/F Enables Register.
- */
- pci_write_config8(dev, COM_DEC, 0x10);
- pci_write_config16(dev, LPC_EN, 0x300F);
-}
-
-static void lpc_init(struct device *dev)
-{
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
- /* IO APIC initialization. */
- i82801ax_enable_apic(dev);
-
- i82801ax_enable_serial_irqs(dev);
-
- /* Setup the PIRQ. */
- i82801ax_pirq_init(dev);
-
- /* Setup power options. */
- i82801ax_power_options(dev);
-
- /* Set the state of the GPIO lines. */
- gpio_init(dev);
-
- /* Initialize the real time clock. */
- i82801ax_rtc_init(dev);
-
- /* Route DMA. */
- i82801ax_lpc_route_dma(dev, 0xff);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
- /* Setup decode ports and LPC I/F enables. */
- i82801ax_lpc_decode_en(dev);
-}
-
-static void i82801ax_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = i82801ax_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i82801ax_enable,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_lpc __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2410,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_lpc __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2420,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-static void pci_init(struct device *dev)
-{
- u16 reg16;
-
- /* Clear possible errors. */
- reg16 = pci_read_config16(dev, PCI_STATUS);
- reg16 |= 0xf900;
- pci_write_config16(dev, PCI_STATUS, reg16);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_pci __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2418,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_pci __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2428,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2002 Eric Biederman <ebiederm@xmission.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-#include <arch/io.h>
-
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9. */
- outb((1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <arch/io.h>
-#include "i82801ax.h"
-#include "i82801ax_smbus.h"
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static const struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = i82801ax_enable,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_smb __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AA_SMB,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_smb __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AB_SMB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-#include "i82801ax.h"
-
-int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address);
-
-static void smbus_delay(void)
-{
- inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while (byte & 1);
- return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
- return loops ? 0 : -1;
-}
-
-int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* Setup transaction */
- /* Disable interrupts */
- outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
- /* Set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- /* Set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- /* Set up for a byte data read */
- outb((inb(smbus_io_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
- (smbus_io_base + SMBHSTCTL));
- /* Clear any lingering errors, so the transaction will run */
- outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
-
- /* Clear the data byte... */
- outb(0, smbus_io_base + SMBHSTDAT0);
-
- /* Start the command */
- outb((inb(smbus_io_base + SMBHSTCTL) | 0x40),
- smbus_io_base + SMBHSTCTL);
-
- /* Poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
- /* Ignore the "In Use" status... */
- global_status_register &= ~(3 << 5);
-
- /* Read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801ax.h"
-
-static void usb_init(struct device *dev)
-{
- /* TODO: Any init needed? Some ports have it, others don't. */
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = i82801ax_enable,
-};
-
-/* 82801AA (ICH) */
-static const struct pci_driver i82801aa_usb1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AA_USB,
-};
-
-/* 82801AB (ICH0) */
-static const struct pci_driver i82801ab_usb1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801AB_USB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 John Dufresne <jon.dufresne@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <watchdog.h>
-
-/* TODO: I'm fairly sure the same functionality is provided elsewhere. */
-
-void watchdog_off(void)
-{
- device_t dev;
- unsigned long value, base;
-
- /* Turn off the ICH5 watchdog. */
- dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
-
- /* Enable I/O space. */
- value = pci_read_config16(dev, 0x04);
- value |= (1 << 10);
- pci_write_config16(dev, 0x04, value);
-
- /* Get TCO base. */
- base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
-
- /* Disable the watchdog timer. */
- value = inw(base + 0x08);
- value |= 1 << 11;
- outw(value, base + 0x08);
-
- /* Clear TCO timeout status. */
- outw(0x0008, base + 0x04);
- outw(0x0002, base + 0x06);
-
- printk(BIOS_DEBUG, "ICH Watchdog disabled\n");
-}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ * Copyright (C) 2005 Digital Design Corporation
+ * (Written by Steven J. Magnani <steve@digidescorp.com> for Digital Design)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801ax.h"
+
+typedef struct southbridge_intel_i82801ax_config config_t;
+
+static void ide_init(struct device *dev)
+{
+ u16 reg16;
+ config_t *conf = dev->chip_info;
+
+ reg16 = pci_read_config16(dev, IDE_TIM_PRI);
+ reg16 &= ~IDE_DECODE_ENABLE;
+ if (!conf || conf->ide0_enable)
+ reg16 |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
+ conf->ide0_enable ? "on" : "off");
+ pci_write_config16(dev, IDE_TIM_PRI, reg16);
+
+ reg16 = pci_read_config16(dev, IDE_TIM_SEC);
+ reg16 &= ~IDE_DECODE_ENABLE;
+ if (!conf || conf->ide1_enable)
+ reg16 |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
+ conf->ide0_enable ? "on" : "off");
+ pci_write_config16(dev, IDE_TIM_SEC, reg16);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = i82801ax_enable,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2411,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2421,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2003 SuSE Linux AG
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801ax.h"
+
+#define GPIO_BASE_ADDR 0x00000500 /* GPIO Base Address Register */
+
+#define NMI_OFF 0
+
+typedef struct southbridge_intel_i82801ax_config config_t;
+
+/* PIRQ[n]_ROUT[3:0] - IRQ Routing (ISA compatible)
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ *
+ * PIRQ[n]_ROUT[7] - Interrupt Routing Enable (IRQEN)
+ * 0 - The PIRQ is routed to the ISA-compatible interrupt specified above.
+ * 1 - The PIRQ is not routed to the 8259.
+ */
+
+#define PIRQA 0x03
+#define PIRQB 0x04
+#define PIRQC 0x05
+#define PIRQD 0x06
+
+/*
+ * Use 0x0ef8 for a bitmap to cover all these IRQ's.
+ * Use the defined IRQ values above or set mainboard
+ * specific IRQ values in your devicetree.cb.
+ */
+static void i82801ax_enable_apic(struct device *dev)
+{
+ u32 reg32;
+ volatile u32 *ioapic_index = (volatile u32 *)IO_APIC_ADDR;
+ volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
+
+ /* Set ACPI base address (I/O space). */
+ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
+
+ /* Enable ACPI I/O range decode and ACPI power management. */
+ pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
+
+ reg32 = pci_read_config32(dev, GEN_CNTL);
+ reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
+ reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */
+ reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */
+ reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */
+ pci_write_config32(dev, GEN_CNTL, reg32);
+ printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
+
+ *ioapic_index = 0;
+ *ioapic_data = (1 << 25);
+
+ *ioapic_index = 0;
+ reg32 = *ioapic_data;
+ printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
+ if (reg32 != (1 << 25))
+ die("APIC Error\n");
+
+ /* TODO: From i82801ca, needed/useful on other ICH? */
+ *ioapic_index = 3; /* Select Boot Configuration register. */
+ *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
+}
+
+static void i82801ax_enable_serial_irqs(struct device *dev)
+{
+ /* Set packet length and toggle silent mode bit. */
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
+ /* TODO: Explain/#define the real meaning of these magic numbers. */
+}
+
+static void i82801ax_pirq_init(device_t dev)
+{
+ u8 reg8;
+ config_t *config = dev->chip_info;
+
+ reg8 = (config->pirqa_routing) ? config->pirqa_routing : PIRQA;
+ pci_write_config8(dev, PIRQA_ROUT, reg8);
+
+ reg8 = (config->pirqb_routing) ? config->pirqb_routing : PIRQB;
+ pci_write_config8(dev, PIRQB_ROUT, reg8);
+
+ reg8 = (config->pirqc_routing) ? config->pirqc_routing : PIRQC;
+ pci_write_config8(dev, PIRQC_ROUT, reg8);
+
+ reg8 = (config->pirqd_routing) ? config->pirqd_routing : PIRQD;
+ pci_write_config8(dev, PIRQD_ROUT, reg8);
+}
+
+static void i82801ax_power_options(device_t dev)
+{
+ uint8_t byte;
+ int pwr_on = -1;
+ int nmi_option;
+
+ /* power after power fail */
+ /* FIXME this doesn't work! */
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ */
+ pci_write_config8(dev, GEN_PMCON_3, pwr_on ? 0 : 1);
+ printk(BIOS_INFO, "Set power %s if power fails\n", pwr_on ? "on" : "off");
+
+ /* Set up NMI on errors. */
+ byte = inb(0x61);
+ byte &= ~(1 << 3); /* IOCHK# NMI Enable */
+ byte &= ~(1 << 2); /* PCI SERR# Enable */
+ outb(byte, 0x61);
+ byte = inb(0x70);
+
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* Set NMI. */
+ outb(byte, 0x70);
+ }
+}
+
+static void gpio_init(device_t dev)
+{
+ pci_write_config32(dev, GPIO_BASE, (GPIO_BASE_ADDR | 1));
+ pci_write_config8(dev, GPIO_CNTL, GPIO_EN);
+}
+
+static void i82801ax_rtc_init(struct device *dev)
+{
+ uint8_t reg8;
+ uint32_t reg32;
+ int rtc_failed;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ rtc_failed = reg8 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ reg8 &= ~(1 << 1); /* Preserve the power fail state. */
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ }
+ reg32 = pci_read_config32(dev, GEN_STA);
+ rtc_failed |= reg32 & (1 << 2);
+ rtc_init(rtc_failed);
+
+ /* Enable access to the upper 128 byte bank of CMOS RAM. */
+ pci_write_config8(dev, RTC_CONF, 0x04);
+}
+
+static void i82801ax_lpc_route_dma(struct device *dev, uint8_t mask)
+{
+ uint16_t reg16;
+ int i;
+
+ reg16 = pci_read_config16(dev, PCI_DMA_CFG);
+ reg16 &= 0x300;
+ for (i = 0; i < 8; i++) {
+ if (i == 4)
+ continue;
+ reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
+ }
+ pci_write_config16(dev, PCI_DMA_CFG, reg16);
+}
+
+static void i82801ax_lpc_decode_en(device_t dev)
+{
+ /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
+ * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
+ * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
+ * We also need to set the value for LPC I/F Enables Register.
+ */
+ pci_write_config8(dev, COM_DEC, 0x10);
+ pci_write_config16(dev, LPC_EN, 0x300F);
+}
+
+static void lpc_init(struct device *dev)
+{
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+
+ /* IO APIC initialization. */
+ i82801ax_enable_apic(dev);
+
+ i82801ax_enable_serial_irqs(dev);
+
+ /* Setup the PIRQ. */
+ i82801ax_pirq_init(dev);
+
+ /* Setup power options. */
+ i82801ax_power_options(dev);
+
+ /* Set the state of the GPIO lines. */
+ gpio_init(dev);
+
+ /* Initialize the real time clock. */
+ i82801ax_rtc_init(dev);
+
+ /* Route DMA. */
+ i82801ax_lpc_route_dma(dev, 0xff);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+ /* Setup decode ports and LPC I/F enables. */
+ i82801ax_lpc_decode_en(dev);
+}
+
+static void i82801ax_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = i82801ax_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801ax_enable,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_lpc __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2410,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_lpc __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2420,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+static void pci_init(struct device *dev)
+{
+ u16 reg16;
+
+ /* Clear possible errors. */
+ reg16 = pci_read_config16(dev, PCI_STATUS);
+ reg16 |= 0xf900;
+ pci_write_config16(dev, PCI_STATUS, reg16);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_pci __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2418,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_pci __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2428,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2002 Eric Biederman <ebiederm@xmission.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+#include <arch/io.h>
+
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9. */
+ outb((1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include "i82801ax.h"
+#include "smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static const struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = i82801ax_enable,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_smb __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AA_SMB,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_smb __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AB_SMB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+#include "i82801ax.h"
+
+int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address);
+
+static void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+static int smbus_wait_until_ready(u16 smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u16 smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ /* Set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ (smbus_io_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+ /* Clear the data byte... */
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* Start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40),
+ smbus_io_base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the "In Use" status... */
+ global_status_register &= ~(3 << 5);
+
+ /* Read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801ax.h"
+
+static void usb_init(struct device *dev)
+{
+ /* TODO: Any init needed? Some ports have it, others don't. */
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = i82801ax_enable,
+};
+
+/* 82801AA (ICH) */
+static const struct pci_driver i82801aa_usb1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AA_USB,
+};
+
+/* 82801AB (ICH0) */
+static const struct pci_driver i82801ab_usb1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801AB_USB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 John Dufresne <jon.dufresne@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <watchdog.h>
+
+/* TODO: I'm fairly sure the same functionality is provided elsewhere. */
+
+void watchdog_off(void)
+{
+ device_t dev;
+ unsigned long value, base;
+
+ /* Turn off the ICH5 watchdog. */
+ dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
+
+ /* Enable I/O space. */
+ value = pci_read_config16(dev, 0x04);
+ value |= (1 << 10);
+ pci_write_config16(dev, 0x04, value);
+
+ /* Get TCO base. */
+ base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
+
+ /* Disable the watchdog timer. */
+ value = inw(base + 0x08);
+ value |= 1 << 11;
+ outw(value, base + 0x08);
+
+ /* Clear TCO timeout status. */
+ outw(0x0008, base + 0x04);
+ outw(0x0002, base + 0x06);
+
+ printk(BIOS_DEBUG, "ICH Watchdog disabled\n");
+}
##
driver-y += i82801bx.c
-driver-y += i82801bx_ac97.c
-driver-y += i82801bx_ide.c
-driver-y += i82801bx_lpc.c
-driver-y += i82801bx_nic.c
-driver-y += i82801bx_pci.c
-driver-y += i82801bx_smbus.c
-driver-y += i82801bx_usb.c
+driver-y += ac97.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += nic.c
+driver-y += pci.c
+driver-y += smbus.c
+driver-y += usb.c
-ramstage-y += i82801bx_reset.c
-ramstage-y += i82801bx_watchdog.c
+ramstage-y += reset.c
+ramstage-y += watchdog.c
-romstage-y += i82801bx_early_smbus.c
+romstage-y += early_smbus.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801bx.h"
+
+static struct device_operations ac97_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = i82801bx_enable,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_ac97_audio __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_AC97_AUDIO,
+};
+
+static const struct pci_driver i82801ba_ac97_modem __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_AC97_MODEM,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include "i82801bx.h"
+#include "smbus.h"
+
+void enable_smbus(void)
+{
+ device_t dev;
+
+ /* Set the SMBus device statically (D31:F3). */
+ dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ /* Set SMBus I/O base. */
+ pci_write_config32(dev, SMB_BASE,
+ SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+
+ /* Set SMBus enable. */
+ pci_write_config8(dev, HOSTC, HST_EN);
+
+ /* Set SMBus I/O space enable. */
+ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ /* Disable interrupt generation. */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* Clear any lingering errors, so transactions can run. */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ print_debug("SMBus controller enabled\n");
+}
+
+int smbus_read_byte(u8 device, u8 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801bx.h"
-
-static struct device_operations ac97_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = i82801bx_enable,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_ac97_audio __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_AC97_AUDIO,
-};
-
-static const struct pci_driver i82801ba_ac97_modem __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_AC97_MODEM,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <device/pci_def.h>
-#include "i82801bx.h"
-#include "i82801bx_smbus.h"
-
-void enable_smbus(void)
-{
- device_t dev;
-
- /* Set the SMBus device statically (D31:F3). */
- dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- /* Set SMBus I/O base. */
- pci_write_config32(dev, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
-
- /* Set SMBus enable. */
- pci_write_config8(dev, HOSTC, HST_EN);
-
- /* Set SMBus I/O space enable. */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Disable interrupt generation. */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* Clear any lingering errors, so transactions can run. */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- print_debug("SMBus controller enabled\n");
-}
-
-int smbus_read_byte(u8 device, u8 address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- * Copyright (C) 2005 Digital Design Corporation
- * (Written by Steven J. Magnani <steve@digidescorp.com> for Digital Design)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801bx.h"
-
-typedef struct southbridge_intel_i82801bx_config config_t;
-
-static void ide_init(struct device *dev)
-{
- u16 reg16;
- config_t *conf = dev->chip_info;
-
- reg16 = pci_read_config16(dev, IDE_TIM_PRI);
- reg16 &= ~IDE_DECODE_ENABLE;
- if (!conf || conf->ide0_enable)
- reg16 |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
- conf->ide0_enable ? "on" : "off");
- pci_write_config16(dev, IDE_TIM_PRI, reg16);
-
- reg16 = pci_read_config16(dev, IDE_TIM_SEC);
- reg16 &= ~IDE_DECODE_ENABLE;
- if (!conf || conf->ide1_enable)
- reg16 |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
- conf->ide0_enable ? "on" : "off");
- pci_write_config16(dev, IDE_TIM_SEC, reg16);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = i82801bx_enable,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x244b,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2003 SuSE Linux AG
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801bx.h"
-
-#define NMI_OFF 0
-
-typedef struct southbridge_intel_i82801bx_config config_t;
-
-/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
- * 0x00 - 0000 = Reserved
- * 0x01 - 0001 = Reserved
- * 0x02 - 0010 = Reserved
- * 0x03 - 0011 = IRQ3
- * 0x04 - 0100 = IRQ4
- * 0x05 - 0101 = IRQ5
- * 0x06 - 0110 = IRQ6
- * 0x07 - 0111 = IRQ7
- * 0x08 - 1000 = Reserved
- * 0x09 - 1001 = IRQ9
- * 0x0A - 1010 = IRQ10
- * 0x0B - 1011 = IRQ11
- * 0x0C - 1100 = IRQ12
- * 0x0D - 1101 = Reserved
- * 0x0E - 1110 = IRQ14
- * 0x0F - 1111 = IRQ15
- *
- * PIRQ[n]_ROUT[7] - Interrupt Routing Enable (IRQEN)
- * 0 - The PIRQ is routed to the ISA-compatible interrupt specified above.
- * 1 - The PIRQ is not routed to the 8259.
- */
-
-#define PIRQA 0x03
-#define PIRQB 0x04
-#define PIRQC 0x05
-#define PIRQD 0x06
-#define PIRQE 0x07
-#define PIRQF 0x09
-#define PIRQG 0x0A
-#define PIRQH 0x0B
-
-/*
- * Use 0x0ef8 for a bitmap to cover all these IRQ's.
- * Use the defined IRQ values above or set mainboard
- * specific IRQ values in your devicetree.cb.
-*/
-static void i82801bx_enable_apic(struct device *dev)
-{
- uint32_t reg32;
- volatile uint32_t *ioapic_index = (volatile uint32_t *)IO_APIC_ADDR;
- volatile uint32_t *ioapic_data = (volatile uint32_t *)(IO_APIC_ADDR + 0x10);
-
- /* Set ACPI base address (I/O space). */
- pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
-
- /* Enable ACPI I/O range decode and ACPI power management. */
- pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
-
- reg32 = pci_read_config32(dev, GEN_CNTL);
- reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
- reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */
- reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */
- reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */
- pci_write_config32(dev, GEN_CNTL, reg32);
- printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
-
- *ioapic_index = 0;
- *ioapic_data = (1 << 25);
-
- *ioapic_index = 0;
- reg32 = *ioapic_data;
- printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
- if (reg32 != (1 << 25))
- die("APIC Error\n");
-
- /* TODO: From i82801ca, needed/useful on other ICH? */
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
-}
-
-static void i82801bx_enable_serial_irqs(struct device *dev)
-{
- /* Set packet length and toggle silent mode bit. */
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
- /* TODO: Explain/#define the real meaning of these magic numbers. */
-}
-
-static void i82801bx_pirq_init(device_t dev, uint16_t ich_model)
-{
- u8 reg8;
- config_t *config = dev->chip_info;
-
- reg8 = (config->pirqa_routing) ? config->pirqa_routing : PIRQA;
- pci_write_config8(dev, PIRQA_ROUT, reg8);
-
- reg8 = (config->pirqb_routing) ? config->pirqb_routing : PIRQB;
- pci_write_config8(dev, PIRQB_ROUT, reg8);
-
- reg8 = (config->pirqc_routing) ? config->pirqc_routing : PIRQC;
- pci_write_config8(dev, PIRQC_ROUT, reg8);
-
- reg8 = (config->pirqd_routing) ? config->pirqd_routing : PIRQD;
- pci_write_config8(dev, PIRQD_ROUT, reg8);
-
-
- reg8 = (config->pirqe_routing) ? config->pirqe_routing : PIRQE;
- pci_write_config8(dev, PIRQE_ROUT, reg8);
-
- reg8 = (config->pirqf_routing) ? config->pirqf_routing : PIRQF;
- pci_write_config8(dev, PIRQF_ROUT, reg8);
-
- reg8 = (config->pirqg_routing) ? config->pirqg_routing : PIRQG;
- pci_write_config8(dev, PIRQG_ROUT, reg8);
-
- reg8 = (config->pirqh_routing) ? config->pirqh_routing : PIRQH;
- pci_write_config8(dev, PIRQH_ROUT, reg8);
-}
-
-static void i82801bx_power_options(device_t dev)
-{
- uint8_t byte;
- int pwr_on = -1;
- int nmi_option;
-
- /* power after power fail */
- /* FIXME this doesn't work! */
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- */
- pci_write_config8(dev, GEN_PMCON_3, pwr_on ? 0 : 1);
- printk(BIOS_INFO, "Set power %s if power fails\n", pwr_on ? "on" : "off");
-
- /* Set up NMI on errors. */
- byte = inb(0x61);
- byte &= ~(1 << 3); /* IOCHK# NMI Enable */
- byte &= ~(1 << 2); /* PCI SERR# Enable */
- outb(byte, 0x61);
- byte = inb(0x70);
-
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* Set NMI. */
- outb(byte, 0x70);
- }
-}
-
-static void gpio_init(device_t dev)
-{
- /* Set the value for GPIO base address register and enable GPIO. */
- pci_write_config32(dev, GPIO_BASE, (GPIO_BASE_ADDR | 1));
- pci_write_config8(dev, GPIO_CNTL, GPIO_EN);
-}
-
-static void i82801bx_rtc_init(struct device *dev)
-{
- uint8_t reg8;
- uint32_t reg32;
- int rtc_failed;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- rtc_failed = reg8 & RTC_BATTERY_DEAD;
- if (rtc_failed) {
- reg8 &= ~(1 << 1); /* Preserve the power fail state. */
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- }
- reg32 = pci_read_config32(dev, GEN_STS);
- rtc_failed |= reg32 & (1 << 2);
- rtc_init(rtc_failed);
-
- /* Enable access to the upper 128 byte bank of CMOS RAM. */
- pci_write_config8(dev, RTC_CONF, 0x04);
-}
-
-static void i82801bx_lpc_route_dma(struct device *dev, uint8_t mask)
-{
- uint16_t reg16;
- int i;
-
- reg16 = pci_read_config16(dev, PCI_DMA_CFG);
- reg16 &= 0x300;
- for (i = 0; i < 8; i++) {
- if (i == 4)
- continue;
- reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
- }
- pci_write_config16(dev, PCI_DMA_CFG, reg16);
-}
-
-static void i82801bx_lpc_decode_en(device_t dev, uint16_t ich_model)
-{
- /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
- * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
- * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
- * We also need to set the value for LPC I/F Enables Register.
- */
- pci_write_config8(dev, COM_DEC, 0x10);
- pci_write_config16(dev, LPC_EN, 0x300F);
-}
-
-static void lpc_init(struct device *dev)
-{
- uint16_t ich_model = pci_read_config16(dev, PCI_DEVICE_ID);
-
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
- /* IO APIC initialization. */
- i82801bx_enable_apic(dev);
-
- i82801bx_enable_serial_irqs(dev);
-
- /* Setup the PIRQ. */
- i82801bx_pirq_init(dev, ich_model);
-
- /* Setup power options. */
- i82801bx_power_options(dev);
-
- /* Set the state of the GPIO lines. */
- gpio_init(dev);
-
- /* Initialize the real time clock. */
- i82801bx_rtc_init(dev);
-
- /* Route DMA. */
- i82801bx_lpc_route_dma(dev, 0xff);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
- /* Setup decode ports and LPC I/F enables. */
- i82801bx_lpc_decode_en(dev, ich_model);
-}
-
-static void i82801bx_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = i82801bx_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i82801bx_enable,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_lpc __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2440,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_nic __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_LAN,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Tyan Computer
- * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801bx.h"
-
-static void pci_init(struct device *dev)
-{
- u16 reg16;
-
- /* Clear system errors */
- reg16 = pci_read_config16(dev, PCI_STATUS);
- reg16 |= 0xf900; /* Clear possible errors */
- pci_write_config16(dev, PCI_STATUS, reg16);
-
- reg16 = pci_read_config16(dev, SECSTS);
- reg16 |= 0xf800; /* Clear possible errors */
- pci_write_config16(dev, SECSTS, reg16);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801misc_pci __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x244e,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2002 Eric Biederman <ebiederm@xmission.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9. */
- outb((1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <arch/io.h>
-#include "i82801bx.h"
-#include "i82801bx_smbus.h"
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static const struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = i82801bx_enable,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_smb __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_SMB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-
-static void smbus_delay(void)
-{
- inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while (byte & 1);
- return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
- return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* Setup transaction */
- /* Disable interrupts */
- outb(inb(smbus_io_base + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* Set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- /* Set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- /* Set up for a byte data read */
- outb((inb(smbus_io_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
- (smbus_io_base + SMBHSTCTL));
- /* Clear any lingering errors, so the transaction will run */
- outb(inb(smbus_io_base + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* Clear the data byte... */
- outb(0, smbus_io_base + SMBHSTDAT0);
-
- /* Start the command */
- outb((inb(smbus_io_base + SMBHSTCTL) | 0x40),
- smbus_io_base + SMBHSTCTL);
-
- /* Poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
- /* Ignore the "In Use" status... */
- global_status_register &= ~(3 << 5);
-
- /* Read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801bx.h"
-
-static void usb_init(struct device *dev)
-{
- /* TODO: Any init needed? Some ports have it, others don't. */
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = i82801bx_enable,
-};
-
-/* 82801BA/BAM (ICH2/ICH2-M) */
-static const struct pci_driver i82801ba_usb1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_USB1,
-};
-
-static const struct pci_driver i82801ba_usb2 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801BA_USB2,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 John Dufresne <jon.dufresne@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <watchdog.h>
-
-/* TODO: I'm fairly sure the same functionality is provided elsewhere. */
-
-void watchdog_off(void)
-{
- device_t dev;
- unsigned long value, base;
-
- /* Turn off the ICH5 watchdog. */
- dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
-
- /* Enable I/O space. */
- value = pci_read_config16(dev, 0x04);
- value |= (1 << 10);
- pci_write_config16(dev, 0x04, value);
-
- /* Get TCO base. */
- base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
-
- /* Disable the watchdog timer. */
- value = inw(base + 0x08);
- value |= 1 << 11;
- outw(value, base + 0x08);
-
- /* Clear TCO timeout status. */
- outw(0x0008, base + 0x04);
- outw(0x0002, base + 0x06);
-
- printk(BIOS_DEBUG, "ICH Watchdog disabled\n");
-}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ * Copyright (C) 2005 Digital Design Corporation
+ * (Written by Steven J. Magnani <steve@digidescorp.com> for Digital Design)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801bx.h"
+
+typedef struct southbridge_intel_i82801bx_config config_t;
+
+static void ide_init(struct device *dev)
+{
+ u16 reg16;
+ config_t *conf = dev->chip_info;
+
+ reg16 = pci_read_config16(dev, IDE_TIM_PRI);
+ reg16 &= ~IDE_DECODE_ENABLE;
+ if (!conf || conf->ide0_enable)
+ reg16 |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Primary",
+ conf->ide0_enable ? "on" : "off");
+ pci_write_config16(dev, IDE_TIM_PRI, reg16);
+
+ reg16 = pci_read_config16(dev, IDE_TIM_SEC);
+ reg16 &= ~IDE_DECODE_ENABLE;
+ if (!conf || conf->ide1_enable)
+ reg16 |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE: %s IDE interface: %s\n", "Secondary",
+ conf->ide0_enable ? "on" : "off");
+ pci_write_config16(dev, IDE_TIM_SEC, reg16);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = i82801bx_enable,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x244b,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2003 SuSE Linux AG
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801bx.h"
+
+#define NMI_OFF 0
+
+typedef struct southbridge_intel_i82801bx_config config_t;
+
+/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ *
+ * PIRQ[n]_ROUT[7] - Interrupt Routing Enable (IRQEN)
+ * 0 - The PIRQ is routed to the ISA-compatible interrupt specified above.
+ * 1 - The PIRQ is not routed to the 8259.
+ */
+
+#define PIRQA 0x03
+#define PIRQB 0x04
+#define PIRQC 0x05
+#define PIRQD 0x06
+#define PIRQE 0x07
+#define PIRQF 0x09
+#define PIRQG 0x0A
+#define PIRQH 0x0B
+
+/*
+ * Use 0x0ef8 for a bitmap to cover all these IRQ's.
+ * Use the defined IRQ values above or set mainboard
+ * specific IRQ values in your devicetree.cb.
+*/
+static void i82801bx_enable_apic(struct device *dev)
+{
+ uint32_t reg32;
+ volatile uint32_t *ioapic_index = (volatile uint32_t *)IO_APIC_ADDR;
+ volatile uint32_t *ioapic_data = (volatile uint32_t *)(IO_APIC_ADDR + 0x10);
+
+ /* Set ACPI base address (I/O space). */
+ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
+
+ /* Enable ACPI I/O range decode and ACPI power management. */
+ pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
+
+ reg32 = pci_read_config32(dev, GEN_CNTL);
+ reg32 |= (1 << 13); /* Coprocessor error enable (COPR_ERR_EN) */
+ reg32 |= (3 << 7); /* IOAPIC enable (APIC_EN) */
+ reg32 |= (1 << 2); /* DMA collection buffer enable (DCB_EN) */
+ reg32 |= (1 << 1); /* Delayed transaction enable (DTE) */
+ pci_write_config32(dev, GEN_CNTL, reg32);
+ printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
+
+ *ioapic_index = 0;
+ *ioapic_data = (1 << 25);
+
+ *ioapic_index = 0;
+ reg32 = *ioapic_data;
+ printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
+ if (reg32 != (1 << 25))
+ die("APIC Error\n");
+
+ /* TODO: From i82801ca, needed/useful on other ICH? */
+ *ioapic_index = 3; /* Select Boot Configuration register. */
+ *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
+}
+
+static void i82801bx_enable_serial_irqs(struct device *dev)
+{
+ /* Set packet length and toggle silent mode bit. */
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
+ /* TODO: Explain/#define the real meaning of these magic numbers. */
+}
+
+static void i82801bx_pirq_init(device_t dev, uint16_t ich_model)
+{
+ u8 reg8;
+ config_t *config = dev->chip_info;
+
+ reg8 = (config->pirqa_routing) ? config->pirqa_routing : PIRQA;
+ pci_write_config8(dev, PIRQA_ROUT, reg8);
+
+ reg8 = (config->pirqb_routing) ? config->pirqb_routing : PIRQB;
+ pci_write_config8(dev, PIRQB_ROUT, reg8);
+
+ reg8 = (config->pirqc_routing) ? config->pirqc_routing : PIRQC;
+ pci_write_config8(dev, PIRQC_ROUT, reg8);
+
+ reg8 = (config->pirqd_routing) ? config->pirqd_routing : PIRQD;
+ pci_write_config8(dev, PIRQD_ROUT, reg8);
+
+
+ reg8 = (config->pirqe_routing) ? config->pirqe_routing : PIRQE;
+ pci_write_config8(dev, PIRQE_ROUT, reg8);
+
+ reg8 = (config->pirqf_routing) ? config->pirqf_routing : PIRQF;
+ pci_write_config8(dev, PIRQF_ROUT, reg8);
+
+ reg8 = (config->pirqg_routing) ? config->pirqg_routing : PIRQG;
+ pci_write_config8(dev, PIRQG_ROUT, reg8);
+
+ reg8 = (config->pirqh_routing) ? config->pirqh_routing : PIRQH;
+ pci_write_config8(dev, PIRQH_ROUT, reg8);
+}
+
+static void i82801bx_power_options(device_t dev)
+{
+ uint8_t byte;
+ int pwr_on = -1;
+ int nmi_option;
+
+ /* power after power fail */
+ /* FIXME this doesn't work! */
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ */
+ pci_write_config8(dev, GEN_PMCON_3, pwr_on ? 0 : 1);
+ printk(BIOS_INFO, "Set power %s if power fails\n", pwr_on ? "on" : "off");
+
+ /* Set up NMI on errors. */
+ byte = inb(0x61);
+ byte &= ~(1 << 3); /* IOCHK# NMI Enable */
+ byte &= ~(1 << 2); /* PCI SERR# Enable */
+ outb(byte, 0x61);
+ byte = inb(0x70);
+
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* Set NMI. */
+ outb(byte, 0x70);
+ }
+}
+
+static void gpio_init(device_t dev)
+{
+ /* Set the value for GPIO base address register and enable GPIO. */
+ pci_write_config32(dev, GPIO_BASE, (GPIO_BASE_ADDR | 1));
+ pci_write_config8(dev, GPIO_CNTL, GPIO_EN);
+}
+
+static void i82801bx_rtc_init(struct device *dev)
+{
+ uint8_t reg8;
+ uint32_t reg32;
+ int rtc_failed;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ rtc_failed = reg8 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ reg8 &= ~(1 << 1); /* Preserve the power fail state. */
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ }
+ reg32 = pci_read_config32(dev, GEN_STS);
+ rtc_failed |= reg32 & (1 << 2);
+ rtc_init(rtc_failed);
+
+ /* Enable access to the upper 128 byte bank of CMOS RAM. */
+ pci_write_config8(dev, RTC_CONF, 0x04);
+}
+
+static void i82801bx_lpc_route_dma(struct device *dev, uint8_t mask)
+{
+ uint16_t reg16;
+ int i;
+
+ reg16 = pci_read_config16(dev, PCI_DMA_CFG);
+ reg16 &= 0x300;
+ for (i = 0; i < 8; i++) {
+ if (i == 4)
+ continue;
+ reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
+ }
+ pci_write_config16(dev, PCI_DMA_CFG, reg16);
+}
+
+static void i82801bx_lpc_decode_en(device_t dev, uint16_t ich_model)
+{
+ /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
+ * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
+ * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
+ * We also need to set the value for LPC I/F Enables Register.
+ */
+ pci_write_config8(dev, COM_DEC, 0x10);
+ pci_write_config16(dev, LPC_EN, 0x300F);
+}
+
+static void lpc_init(struct device *dev)
+{
+ uint16_t ich_model = pci_read_config16(dev, PCI_DEVICE_ID);
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+
+ /* IO APIC initialization. */
+ i82801bx_enable_apic(dev);
+
+ i82801bx_enable_serial_irqs(dev);
+
+ /* Setup the PIRQ. */
+ i82801bx_pirq_init(dev, ich_model);
+
+ /* Setup power options. */
+ i82801bx_power_options(dev);
+
+ /* Set the state of the GPIO lines. */
+ gpio_init(dev);
+
+ /* Initialize the real time clock. */
+ i82801bx_rtc_init(dev);
+
+ /* Route DMA. */
+ i82801bx_lpc_route_dma(dev, 0xff);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+ /* Setup decode ports and LPC I/F enables. */
+ i82801bx_lpc_decode_en(dev, ich_model);
+}
+
+static void i82801bx_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = i82801bx_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801bx_enable,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_lpc __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2440,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_nic __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_LAN,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Tyan Computer
+ * (Written by Yinghai Lu <yinghailu@gmail.com> for Tyan Computer)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801bx.h"
+
+static void pci_init(struct device *dev)
+{
+ u16 reg16;
+
+ /* Clear system errors */
+ reg16 = pci_read_config16(dev, PCI_STATUS);
+ reg16 |= 0xf900; /* Clear possible errors */
+ pci_write_config16(dev, PCI_STATUS, reg16);
+
+ reg16 = pci_read_config16(dev, SECSTS);
+ reg16 |= 0xf800; /* Clear possible errors */
+ pci_write_config16(dev, SECSTS, reg16);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801misc_pci __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x244e,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2002 Eric Biederman <ebiederm@xmission.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9. */
+ outb((1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include "i82801bx.h"
+#include "smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static const struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = i82801bx_enable,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_smb __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_SMB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+static void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+static int smbus_wait_until_ready(u16 smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u16 smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+static int do_smbus_read_byte(u16 smbus_io_base, u8 device, u8 address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ /* Set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ (smbus_io_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* Clear the data byte... */
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* Start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40),
+ smbus_io_base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the "In Use" status... */
+ global_status_register &= ~(3 << 5);
+
+ /* Read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801bx.h"
+
+static void usb_init(struct device *dev)
+{
+ /* TODO: Any init needed? Some ports have it, others don't. */
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = i82801bx_enable,
+};
+
+/* 82801BA/BAM (ICH2/ICH2-M) */
+static const struct pci_driver i82801ba_usb1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_USB1,
+};
+
+static const struct pci_driver i82801ba_usb2 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801BA_USB2,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 John Dufresne <jon.dufresne@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <watchdog.h>
+
+/* TODO: I'm fairly sure the same functionality is provided elsewhere. */
+
+void watchdog_off(void)
+{
+ device_t dev;
+ unsigned long value, base;
+
+ /* Turn off the ICH5 watchdog. */
+ dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
+
+ /* Enable I/O space. */
+ value = pci_read_config16(dev, 0x04);
+ value |= (1 << 10);
+ pci_write_config16(dev, 0x04, value);
+
+ /* Get TCO base. */
+ base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
+
+ /* Disable the watchdog timer. */
+ value = inw(base + 0x08);
+ value |= 1 << 11;
+ outw(value, base + 0x08);
+
+ /* Clear TCO timeout status. */
+ outw(0x0008, base + 0x04);
+ outw(0x0002, base + 0x06);
+
+ printk(BIOS_DEBUG, "ICH Watchdog disabled\n");
+}
driver-y += i82801cx.c
-driver-y += i82801cx_usb.c
-driver-y += i82801cx_lpc.c
-driver-y += i82801cx_ide.c
-driver-y += i82801cx_ac97.c
-#driver-y += i82801cx_nic.c
-driver-y += i82801cx_pci.c
-ramstage-y += i82801cx_reset.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += ide.c
+driver-y += ac97.c
+#driver-y += nic.c
+driver-y += pci.c
+ramstage-y += reset.c
--- /dev/null
+/*
+ * (C) 2003 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801cx.h"
+
+
+static struct device_operations ac97audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = i82801cx_enable,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static const struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_AC97_AUDIO,
+};
+
+
+static struct device_operations ac97modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = i82801cx_enable,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static const struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_AC97_MODEM,
+};
--- /dev/null
+#include <device/pci_ids.h>
+#include "i82801cx.h"
+
+static void enable_smbus(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ print_debug("SMBus controller enabled\n");
+ /* set smbus iobase */
+ pci_write_config32(dev, SMB_BASE, SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+ /* Set smbus enable */
+ pci_write_config8(dev, HOSTC, HST_EN);
+ /* Set smbus iospace enable */
+ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+// See http://www.coreboot.org/pipermail/linuxbios/2004-September/009077.html
+// for a description of this function.
+static int smbus_wait_until_active(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1)) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : -4;
+}
+
+static int smbus_wait_until_ready(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ // !HOST_BUSY?
+ if ((val & 1) == 0) {
+ break;
+ }
+ if(loops == (SMBUS_TIMEOUT / 2)) {
+ // Clear status flags
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
+ SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ } while(--loops);
+ return loops?0:-2;
+}
+
+static int smbus_wait_until_done(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ // !HOST_BUSY?
+ if ( (val & 1) == 0) {
+ break;
+ }
+ // BYTE_DONE or SUCCESS or error?
+ if ((val & ~((1<<6)|(1<<0)) ) != 0 ) {
+ break;
+ }
+ } while(--loops);
+ return loops?0:-3;
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ unsigned char global_control_register;
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready() < 0) {
+ return -2;
+ }
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+ /* set to read from the specified device */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start a byte read, with interrupts disabled */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+ /* poll for it to start */
+ if (smbus_wait_until_active() < 0) {
+ return -4;
+ }
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done() < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+ // SUCCESS?
+ if (global_status_register != 2) {
+ return -1;
+ }
+ return byte;
+}
+++ /dev/null
-/*
- * (C) 2003 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801cx.h"
-
-
-static struct device_operations ac97audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = i82801cx_enable,
- .init = 0,
- .scan_bus = 0,
-};
-
-static const struct pci_driver ac97audio_driver __pci_driver = {
- .ops = &ac97audio_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_AC97_AUDIO,
-};
-
-
-static struct device_operations ac97modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = i82801cx_enable,
- .init = 0,
- .scan_bus = 0,
-};
-
-static const struct pci_driver ac97modem_driver __pci_driver = {
- .ops = &ac97modem_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_AC97_MODEM,
-};
+++ /dev/null
-#include <device/pci_ids.h>
-#include "i82801cx.h"
-
-static void enable_smbus(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- print_debug("SMBus controller enabled\n");
- /* set smbus iobase */
- pci_write_config32(dev, SMB_BASE, SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
- /* Set smbus enable */
- pci_write_config8(dev, HOSTC, HST_EN);
- /* Set smbus iospace enable */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-}
-
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-// See http://www.coreboot.org/pipermail/linuxbios/2004-September/009077.html
-// for a description of this function.
-static int smbus_wait_until_active(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1)) {
- break;
- }
- } while (--loops);
- return loops ? 0 : -4;
-}
-
-static int smbus_wait_until_ready(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- // !HOST_BUSY?
- if ((val & 1) == 0) {
- break;
- }
- if(loops == (SMBUS_TIMEOUT / 2)) {
- // Clear status flags
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
- SMBUS_IO_BASE + SMBHSTSTAT);
- }
- } while(--loops);
- return loops?0:-2;
-}
-
-static int smbus_wait_until_done(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
-
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- // !HOST_BUSY?
- if ( (val & 1) == 0) {
- break;
- }
- // BYTE_DONE or SUCCESS or error?
- if ((val & ~((1<<6)|(1<<0)) ) != 0 ) {
- break;
- }
- } while(--loops);
- return loops?0:-3;
-}
-
-static int smbus_read_byte(unsigned device, unsigned address)
-{
- unsigned char global_control_register;
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready() < 0) {
- return -2;
- }
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
- /* set to read from the specified device */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2<<2), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start a byte read, with interrupts disabled */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
- /* poll for it to start */
- if (smbus_wait_until_active() < 0) {
- return -4;
- }
-
- /* poll for transaction completion */
- if (smbus_wait_until_done() < 0) {
- return -3;
- }
-
- global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1<<6); /* Ignore the In Use Status... */
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
- // SUCCESS?
- if (global_status_register != 2) {
- return -1;
- }
- return byte;
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801cx.h"
-
-
-static void ide_init(struct device *dev)
-{
- /* Enable ide devices so the linux ide driver will work */
- uint16_t ideTimingConfig;
- int enable_primary = 1;
- int enable_secondary = 1;
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- if (enable_primary) {
- /* Enable first ide interface */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE0 ");
- }
- pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- if (enable_secondary) {
- /* Enable secondary ide interface */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE1 ");
- }
- pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = i82801cx_enable,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_IDE,
-};
+++ /dev/null
-/*
- * (C) 2003 Linux Networx, SuSE Linux AG
- * (C) 2004 Tyan Computer
- * (c) 2005 Digital Design Corporation
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801cx.h"
-
-#define NMI_OFF 0
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-
-static void i82801cx_enable_ioapic( struct device *dev)
-{
- uint32_t dword;
- volatile uint32_t* ioapic_index = (volatile uint32_t*)IO_APIC_ADDR;
- volatile uint32_t* ioapic_data = (volatile uint32_t*)(IO_APIC_ADDR + 0x10);
-
- dword = pci_read_config32(dev, GEN_CNTL);
- dword |= (3 << 7); /* enable ioapic & disable SMBus interrupts */
- dword |= (1 <<13); /* coprocessor error enable */
- dword |= (1 << 1); /* delay transaction enable */
- dword |= (1 << 2); /* DMA collection buf enable */
- pci_write_config32(dev, GEN_CNTL, dword);
- printk(BIOS_DEBUG, "ioapic southbridge enabled %x\n",dword);
-
- // Must program the APIC's ID before using it
-
- *ioapic_index = 0; // Select APIC ID register
- *ioapic_data = (2<<24);
-
- // Hang if the ID didn't take (chip not present?)
- *ioapic_index = 0;
- dword = *ioapic_data;
- printk(BIOS_DEBUG, "Southbridge apic id = %x\n", (dword>>24) & 0xF);
- if(dword != (2<<24))
- die("");
-
- *ioapic_index = 3; // Select Boot Configuration register
- *ioapic_data = 1; // Use Processor System Bus to deliver interrupts
-}
-
-// This is how interrupts are received from the Super I/O chip
-static void i82801cx_enable_serial_irqs( struct device *dev)
-{
- // Recognize serial IRQs, continuous mode, frame size 21, 4 clock start frame pulse width
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
-}
-
-/**
- * Route all DMA channels to either PCI or LPC.
- *
- * @param dev TODO
- * @param mask Identifies whether each channel should be used for PCI DMA
- * (bit = 0) or LPC DMA (bit = 1). The LSb controls channel 0.
- * Channel 4 is not used (reserved).
- */
-static void i82801cx_lpc_route_dma( struct device *dev, uint8_t mask)
-{
- uint16_t dmaConfig;
- int channelIndex;
-
- dmaConfig = pci_read_config16(dev, PCI_DMA_CFG);
- dmaConfig &= 0x300; // Preserve reserved bits
- for(channelIndex = 0; channelIndex < 8; channelIndex++) {
- if (channelIndex == 4)
- continue; // Register doesn't support channel 4
- dmaConfig |= ((mask & (1 << channelIndex))? 3:1) << (channelIndex*2);
- }
- pci_write_config16(dev, PCI_DMA_CFG, dmaConfig);
-}
-
-static void i82801cx_rtc_init(struct device *dev)
-{
- uint32_t dword;
- int rtc_failed;
- int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- uint8_t pmcon3 = pci_read_config8(dev, GEN_PMCON_3);
-
- rtc_failed = pmcon3 & RTC_BATTERY_DEAD;
- if (rtc_failed) {
- // Clear the RTC_BATTERY_DEAD bit, but preserve
- // the RTC_POWER_FAILED, G3 state, and reserved bits
- // NOTE: RTC_BATTERY_DEAD and RTC_POWER_FAILED are "write-1-clear" bits
- pmcon3 &= ~RTC_POWER_FAILED;
- }
-
- get_option(&pwr_on, "power_on_after_fail");
- pmcon3 &= ~SLEEP_AFTER_POWER_FAIL;
- if (!pwr_on) {
- pmcon3 |= SLEEP_AFTER_POWER_FAIL;
- }
- pci_write_config8(dev, GEN_PMCON_3, pmcon3);
- printk(BIOS_INFO, "set power %s after power fail\n",
- pwr_on ? "on" : "off");
-
- // See if the Safe Mode jumper is set
- dword = pci_read_config32(dev, GEN_STS);
- rtc_failed |= dword & (1 << 2);
-
- rtc_init(rtc_failed);
-}
-
-
-static void i82801cx_1f0_misc(struct device *dev)
-{
- // Prevent LPC disabling, enable parity errors, and SERR# (System Error)
- pci_write_config16(dev, PCI_COMMAND, 0x014f);
-
- // Set ACPI base address to 0x1100 (I/O space)
- pci_write_config32(dev, PMBASE, 0x00001101);
-
- // Enable ACPI I/O and power management
- pci_write_config8(dev, ACPI_CNTL, 0x10);
-
- // Set GPIO base address to 0x1180 (I/O space)
- pci_write_config32(dev, GPIO_BASE, 0x00001181);
-
- // Enable GPIO
- pci_write_config8(dev, GPIO_CNTL, 0x10);
-
- // Route PIRQA to IRQ11, PIRQB to IRQ3, PIRQC to IRQ5, PIRQD to IRQ10
- pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
-
- // Route PIRQE to IRQ7. Leave PIRQF - PIRQH unrouted.
- pci_write_config8(dev, PIRQE_ROUT, 0x07);
-
- // Enable access to the upper 128 byte bank of CMOS RAM
- pci_write_config8(dev, RTC_CONF, 0x04);
-
- // Decode 0x3F8-0x3FF (COM1) for COMA port,
- // 0x2F8-0x2FF (COM2) for COMB
- pci_write_config8(dev, COM_DEC, 0x10);
-
- // LPT decode defaults to 0x378-0x37F and 0x778-0x77F
- // Floppy decode defaults to 0x3F0-0x3F5, 0x3F7
-
- // Enable COMA, COMB, LPT, floppy;
- // disable microcontroller, Super I/O, sound, gameport
- pci_write_config16(dev, LPC_EN, 0x000F);
-}
-
-static void lpc_init(struct device *dev)
-{
- uint8_t byte;
- int pwr_on=-1;
- int nmi_option;
-
- /* IO APIC initialization */
- i82801cx_enable_ioapic(dev);
-
- i82801cx_enable_serial_irqs(dev);
-
- /* power after power fail */
- /* FIXME this doesn't work! */
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- */
- byte = pci_read_config8(dev, GEN_PMCON_3);
- if (pwr_on)
- byte &= ~1; // Return to S0 (boot) after power is re-applied
- else
- byte |= 1; // Return to S5
- pci_write_config8(dev, GEN_PMCON_3, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
-
- /* Set up NMI on errors */
- byte = inb(0x61);
- byte &= ~(1 << 3); /* IOCHK# NMI Enable */
- byte &= ~(1 << 2); /* PCI SERR# Enable */
- outb(byte, 0x61);
- byte = inb(0x70);
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- outb(byte, 0x70);
- }
-
- /* Initialize the real time clock */
- i82801cx_rtc_init(dev);
-
- i82801cx_lpc_route_dma(dev, 0xff);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- i82801cx_1f0_misc(dev);
-}
-
-static void i82801cx_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = i82801cx_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = 0,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_LPC,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801cx.h"
-
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
-};
-
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_LAN,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801cx.h"
-
-static void pci_init(struct device *dev)
-{
- // NOTE: the original (v1) 'CA code set these in the bridge register (0x3E-3F)
- /* Enable pci error detecting */
- uint32_t dword = pci_read_config32(dev, PCI_COMMAND);
- dword |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
- pci_write_config32(dev, PCI_COMMAND, dword);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_PCI,
-};
-
+++ /dev/null
-#include <arch/io.h>
-#include "i82801cx.h"
-
-void i82801cx_hard_reset(void)
-{
- /* Try rebooting through port 0xcf9 */
- // Hard reset without power cycle
- outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
-}
+++ /dev/null
-#include <smbus.h>
-#include <pci.h>
-#include <arch/io.h>
-#include "i82801cx.h"
-
-#define PM_BUS 0
-#define PM_DEVFN PCI_DEVFN(0x1f,3)
-
-void smbus_enable(void)
-{
- /* iobase addr */
- pcibios_write_config_dword(PM_BUS, PM_DEVFN, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
- /* smbus enable */
- pcibios_write_config_byte(PM_BUS, PM_DEVFN, HOSTC, HST_EN);
- /* iospace enable */
- pcibios_write_config_word(PM_BUS, PM_DEVFN, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-}
-
-static void smbus_wait_until_ready(void)
-{
- // Loop while HOST_BUSY
- while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
- /* nop */
- }
-}
-
-static void smbus_wait_until_done(void)
-{
- unsigned char byte;
-
- // Loop while HOST_BUSY
- do {
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
- while((byte &1) == 1);
-
- // Wait for SUCCESS or error or BYTE_DONE
- while( (byte & ~1) == 0) {
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
-}
-
-int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
-{
- unsigned char host_status_register;
- unsigned char byte;
-
- smbus_wait_until_ready();
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* set to read from the specified device */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
-
- host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
- *result = byte;
- return host_status_register != 0x02; // return true if !SUCCESS
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801cx.h"
-
-static void usb_init(struct device *dev)
-{
-
-#if 0
- uint32_t cmd;
- printk(BIOS_DEBUG, "USB: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
-
-
- printk(BIOS_DEBUG, "done.\n");
-#endif
-
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = i82801cx_enable,
-};
-
-static const struct pci_driver usb_driver_1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_USB1,
-};
-static const struct pci_driver usb_driver_2 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_USB2,
-};
-static const struct pci_driver usb_driver_3 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801CA_USB3,
-};
-
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801cx.h"
+
+
+static void ide_init(struct device *dev)
+{
+ /* Enable ide devices so the linux ide driver will work */
+ uint16_t ideTimingConfig;
+ int enable_primary = 1;
+ int enable_secondary = 1;
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ if (enable_primary) {
+ /* Enable first ide interface */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE0 ");
+ }
+ pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ if (enable_secondary) {
+ /* Enable secondary ide interface */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE1 ");
+ }
+ pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = i82801cx_enable,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_IDE,
+};
--- /dev/null
+/*
+ * (C) 2003 Linux Networx, SuSE Linux AG
+ * (C) 2004 Tyan Computer
+ * (c) 2005 Digital Design Corporation
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801cx.h"
+
+#define NMI_OFF 0
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+
+static void i82801cx_enable_ioapic( struct device *dev)
+{
+ uint32_t dword;
+ volatile uint32_t* ioapic_index = (volatile uint32_t*)IO_APIC_ADDR;
+ volatile uint32_t* ioapic_data = (volatile uint32_t*)(IO_APIC_ADDR + 0x10);
+
+ dword = pci_read_config32(dev, GEN_CNTL);
+ dword |= (3 << 7); /* enable ioapic & disable SMBus interrupts */
+ dword |= (1 <<13); /* coprocessor error enable */
+ dword |= (1 << 1); /* delay transaction enable */
+ dword |= (1 << 2); /* DMA collection buf enable */
+ pci_write_config32(dev, GEN_CNTL, dword);
+ printk(BIOS_DEBUG, "ioapic southbridge enabled %x\n",dword);
+
+ // Must program the APIC's ID before using it
+
+ *ioapic_index = 0; // Select APIC ID register
+ *ioapic_data = (2<<24);
+
+ // Hang if the ID didn't take (chip not present?)
+ *ioapic_index = 0;
+ dword = *ioapic_data;
+ printk(BIOS_DEBUG, "Southbridge apic id = %x\n", (dword>>24) & 0xF);
+ if(dword != (2<<24))
+ die("");
+
+ *ioapic_index = 3; // Select Boot Configuration register
+ *ioapic_data = 1; // Use Processor System Bus to deliver interrupts
+}
+
+// This is how interrupts are received from the Super I/O chip
+static void i82801cx_enable_serial_irqs( struct device *dev)
+{
+ // Recognize serial IRQs, continuous mode, frame size 21, 4 clock start frame pulse width
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0<< 0));
+}
+
+/**
+ * Route all DMA channels to either PCI or LPC.
+ *
+ * @param dev TODO
+ * @param mask Identifies whether each channel should be used for PCI DMA
+ * (bit = 0) or LPC DMA (bit = 1). The LSb controls channel 0.
+ * Channel 4 is not used (reserved).
+ */
+static void i82801cx_lpc_route_dma( struct device *dev, uint8_t mask)
+{
+ uint16_t dmaConfig;
+ int channelIndex;
+
+ dmaConfig = pci_read_config16(dev, PCI_DMA_CFG);
+ dmaConfig &= 0x300; // Preserve reserved bits
+ for(channelIndex = 0; channelIndex < 8; channelIndex++) {
+ if (channelIndex == 4)
+ continue; // Register doesn't support channel 4
+ dmaConfig |= ((mask & (1 << channelIndex))? 3:1) << (channelIndex*2);
+ }
+ pci_write_config16(dev, PCI_DMA_CFG, dmaConfig);
+}
+
+static void i82801cx_rtc_init(struct device *dev)
+{
+ uint32_t dword;
+ int rtc_failed;
+ int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ uint8_t pmcon3 = pci_read_config8(dev, GEN_PMCON_3);
+
+ rtc_failed = pmcon3 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ // Clear the RTC_BATTERY_DEAD bit, but preserve
+ // the RTC_POWER_FAILED, G3 state, and reserved bits
+ // NOTE: RTC_BATTERY_DEAD and RTC_POWER_FAILED are "write-1-clear" bits
+ pmcon3 &= ~RTC_POWER_FAILED;
+ }
+
+ get_option(&pwr_on, "power_on_after_fail");
+ pmcon3 &= ~SLEEP_AFTER_POWER_FAIL;
+ if (!pwr_on) {
+ pmcon3 |= SLEEP_AFTER_POWER_FAIL;
+ }
+ pci_write_config8(dev, GEN_PMCON_3, pmcon3);
+ printk(BIOS_INFO, "set power %s after power fail\n",
+ pwr_on ? "on" : "off");
+
+ // See if the Safe Mode jumper is set
+ dword = pci_read_config32(dev, GEN_STS);
+ rtc_failed |= dword & (1 << 2);
+
+ rtc_init(rtc_failed);
+}
+
+
+static void i82801cx_1f0_misc(struct device *dev)
+{
+ // Prevent LPC disabling, enable parity errors, and SERR# (System Error)
+ pci_write_config16(dev, PCI_COMMAND, 0x014f);
+
+ // Set ACPI base address to 0x1100 (I/O space)
+ pci_write_config32(dev, PMBASE, 0x00001101);
+
+ // Enable ACPI I/O and power management
+ pci_write_config8(dev, ACPI_CNTL, 0x10);
+
+ // Set GPIO base address to 0x1180 (I/O space)
+ pci_write_config32(dev, GPIO_BASE, 0x00001181);
+
+ // Enable GPIO
+ pci_write_config8(dev, GPIO_CNTL, 0x10);
+
+ // Route PIRQA to IRQ11, PIRQB to IRQ3, PIRQC to IRQ5, PIRQD to IRQ10
+ pci_write_config32(dev, PIRQA_ROUT, 0x0A05030B);
+
+ // Route PIRQE to IRQ7. Leave PIRQF - PIRQH unrouted.
+ pci_write_config8(dev, PIRQE_ROUT, 0x07);
+
+ // Enable access to the upper 128 byte bank of CMOS RAM
+ pci_write_config8(dev, RTC_CONF, 0x04);
+
+ // Decode 0x3F8-0x3FF (COM1) for COMA port,
+ // 0x2F8-0x2FF (COM2) for COMB
+ pci_write_config8(dev, COM_DEC, 0x10);
+
+ // LPT decode defaults to 0x378-0x37F and 0x778-0x77F
+ // Floppy decode defaults to 0x3F0-0x3F5, 0x3F7
+
+ // Enable COMA, COMB, LPT, floppy;
+ // disable microcontroller, Super I/O, sound, gameport
+ pci_write_config16(dev, LPC_EN, 0x000F);
+}
+
+static void lpc_init(struct device *dev)
+{
+ uint8_t byte;
+ int pwr_on=-1;
+ int nmi_option;
+
+ /* IO APIC initialization */
+ i82801cx_enable_ioapic(dev);
+
+ i82801cx_enable_serial_irqs(dev);
+
+ /* power after power fail */
+ /* FIXME this doesn't work! */
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ */
+ byte = pci_read_config8(dev, GEN_PMCON_3);
+ if (pwr_on)
+ byte &= ~1; // Return to S0 (boot) after power is re-applied
+ else
+ byte |= 1; // Return to S5
+ pci_write_config8(dev, GEN_PMCON_3, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
+
+ /* Set up NMI on errors */
+ byte = inb(0x61);
+ byte &= ~(1 << 3); /* IOCHK# NMI Enable */
+ byte &= ~(1 << 2); /* PCI SERR# Enable */
+ outb(byte, 0x61);
+ byte = inb(0x70);
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ outb(byte, 0x70);
+ }
+
+ /* Initialize the real time clock */
+ i82801cx_rtc_init(dev);
+
+ i82801cx_lpc_route_dma(dev, 0xff);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ i82801cx_1f0_misc(dev);
+}
+
+static void i82801cx_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = i82801cx_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = 0,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_LPC,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801cx.h"
+
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_LAN,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801cx.h"
+
+static void pci_init(struct device *dev)
+{
+ // NOTE: the original (v1) 'CA code set these in the bridge register (0x3E-3F)
+ /* Enable pci error detecting */
+ uint32_t dword = pci_read_config32(dev, PCI_COMMAND);
+ dword |= (PCI_COMMAND_SERR | PCI_COMMAND_PARITY);
+ pci_write_config32(dev, PCI_COMMAND, dword);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_PCI,
+};
+
--- /dev/null
+#include <arch/io.h>
+#include "i82801cx.h"
+
+void i82801cx_hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9 */
+ // Hard reset without power cycle
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
--- /dev/null
+#include <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+#include "i82801cx.h"
+
+#define PM_BUS 0
+#define PM_DEVFN PCI_DEVFN(0x1f,3)
+
+void smbus_enable(void)
+{
+ /* iobase addr */
+ pcibios_write_config_dword(PM_BUS, PM_DEVFN, SMB_BASE,
+ SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+ /* smbus enable */
+ pcibios_write_config_byte(PM_BUS, PM_DEVFN, HOSTC, HST_EN);
+ /* iospace enable */
+ pcibios_write_config_word(PM_BUS, PM_DEVFN, PCI_COMMAND, PCI_COMMAND_IO);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+}
+
+static void smbus_wait_until_ready(void)
+{
+ // Loop while HOST_BUSY
+ while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
+ /* nop */
+ }
+}
+
+static void smbus_wait_until_done(void)
+{
+ unsigned char byte;
+
+ // Loop while HOST_BUSY
+ do {
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ while((byte &1) == 1);
+
+ // Wait for SUCCESS or error or BYTE_DONE
+ while( (byte & ~1) == 0) {
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+}
+
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+ unsigned char host_status_register;
+ unsigned char byte;
+
+ smbus_wait_until_ready();
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* set to read from the specified device */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+
+ host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+ *result = byte;
+ return host_status_register != 0x02; // return true if !SUCCESS
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801cx.h"
+
+static void usb_init(struct device *dev)
+{
+
+#if 0
+ uint32_t cmd;
+ printk(BIOS_DEBUG, "USB: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+
+
+ printk(BIOS_DEBUG, "done.\n");
+#endif
+
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = i82801cx_enable,
+};
+
+static const struct pci_driver usb_driver_1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_USB1,
+};
+static const struct pci_driver usb_driver_2 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_USB2,
+};
+static const struct pci_driver usb_driver_3 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801CA_USB3,
+};
+
##
driver-y += i82801dx.c
-driver-y += i82801dx_ac97.c
-driver-y += i82801dx_ide.c
-driver-y += i82801dx_lpc.c
-#driver-y += i82801dx_pci.c
-driver-y += i82801dx_usb.c
-driver-y += i82801dx_usb2.c
+driver-y += ac97.c
+driver-y += ide.c
+driver-y += lpc.c
+#driver-y += pci.c
+driver-y += usb.c
+driver-y += usb2.c
-ramstage-y += i82801dx_reset.c
-ramstage-$(CONFIG_HAVE_SMI_HANDLER) += i82801dx_smi.c
+ramstage-y += reset.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
-smm-$(CONFIG_HAVE_SMI_HANDLER) += i82801dx_smihandler.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "i82801dx.h"
+
+#define NAMBAR 0x10
+#define MASTER_VOL 0x02
+#define PAGING 0x24
+#define EXT_AUDIO 0x28
+#define FUNC_SEL 0x66
+#define INFO_IO 0x68
+#define CONNECTOR 0x6a
+#define VENDOR_ID1 0x7c
+#define VENDOR_ID2 0x7e
+#define SEC_VENDOR_ID1 0xfc
+#define SEC_VENDOR_ID2 0xfe
+
+#define NABMBAR 0x14
+#define GLOB_CNT 0x2c
+#define GLOB_STA 0x30
+#define CAS 0x34
+
+#define MMBAR 0x10
+#define EXT_MODEM_ID1 0x3c
+#define EXT_MODEM_ID2 0xbc
+
+#define MBAR 0x14
+#define SEC_CODEC 0x40
+
+
+/* FIXME. This table is probably mainboard specific */
+static u16 ac97_function[16*2][4] = {
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) }
+};
+
+static u16 nabmbar;
+static u16 nambar;
+
+static int ac97_semaphore(void)
+{
+ int timeout;
+ u8 reg8;
+
+ timeout = 0xffff;
+ do {
+ reg8 = inb(nabmbar + CAS);
+ timeout--;
+ } while ((reg8 & 1) && timeout);
+ if (! timeout) {
+ printk(BIOS_DEBUG, "Timeout!\n");
+ }
+
+ return (!timeout);
+}
+
+static void init_cnr(void)
+{
+ // TODO
+}
+
+static void program_sigid(struct device *dev, u32 id)
+{
+ pci_write_config32(dev, 0x2c, id);
+}
+
+static void ac97_audio_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+ int i;
+
+ printk(BIOS_DEBUG, "Initializing AC'97 Audio.\n");
+
+ /* top 16 bits are zero, so don't read them */
+ nabmbar = pci_read_config16(dev, NABMBAR) & 0xfffe;
+ nambar = pci_read_config16(dev, NAMBAR) & 0xfffe;
+
+ reg16 = inw(nabmbar + GLOB_CNT);
+ reg16 |= (1 << 1); /* Remove AC_RESET# */
+ outw(reg16, nabmbar + GLOB_CNT);
+
+ /* Wait 600ms. Ouch. */
+ udelay(600 * 1000);
+
+ init_cnr();
+
+ /* Detect Primary AC'97 Codec */
+ reg32 = inl(nabmbar + GLOB_STA);
+ if ((reg32 & ((1 << 28) | (1 << 9) | (1 << 8))) == 0) {
+ /* Primary Codec not found */
+ printk(BIOS_DEBUG, "No primary codec. Disabling AC'97 Audio.\n");
+ return;
+ }
+
+ ac97_semaphore();
+
+ /* Detect if codec is programmable */
+ outw(0x8000, nambar + MASTER_VOL);
+ ac97_semaphore();
+ if (inw(nambar + MASTER_VOL) != 0x8000) {
+ printk(BIOS_DEBUG, "Codec not programmable. Disabling AC'97 Audio.\n");
+ return;
+ }
+
+ /* Program Vendor IDs */
+ reg32 = inw(nambar + VENDOR_ID1);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(nambar + VENDOR_ID2);
+
+ program_sigid(dev, reg32);
+
+ /* Is Codec AC'97 2.3 compliant? */
+ reg16 = inw(nambar + EXT_AUDIO);
+ /* [11:10] = 10b -> AC'97 2.3 */
+ if ((reg16 & 0x0c00) != 0x0800) {
+ /* No 2.3 Codec. We're done */
+ return;
+ }
+
+ /* Select Page 1 */
+ reg16 = inw(nambar + PAGING);
+ reg16 &= 0xfff0;
+ reg16 |= 0x0001;
+ outw(reg16, nambar + PAGING);
+
+ for (i = 0x0a * 2; i > 0; i--) {
+ outw(i, nambar + FUNC_SEL);
+
+ /* Function could not be selected. Next one */
+ if (inw(nambar + FUNC_SEL) != i)
+ continue;
+
+ reg16 = inw(nambar + INFO_IO);
+
+ /* Function Information present? */
+ if (!(reg16 & (1 << 0)))
+ continue;
+
+ /* Function Information valid? */
+ if (!(reg16 & (1 << 4)))
+ continue;
+
+ /* Program Buffer Delay [9:5] */
+ reg16 &= 0x03e0;
+ reg16 |= ac97_function[i][0];
+
+ /* Program Gain [15:11] */
+ reg16 |= ac97_function[i][1];
+
+ /* Program Inversion [10] */
+ reg16 |= ac97_function[i][2];
+
+ outw(reg16, nambar + INFO_IO);
+
+ /* Program Connector / Jack Location */
+ reg16 = inw(nambar + CONNECTOR);
+ reg16 &= 0x1fff;
+ reg16 |= ac97_function[i][3];
+ outw(reg16, nambar + CONNECTOR);
+ }
+}
+
+static void ac97_modem_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+ u16 mmbar, mbar;
+
+ mmbar = pci_read_config16(dev, MMBAR) & 0xfffe;
+ mbar = pci_read_config16(dev, MBAR) & 0xfffe;
+
+ reg16 = inw(mmbar + EXT_MODEM_ID1);
+ if ((reg16 & 0xc000) != 0xc000 ) {
+ if (reg16 & (1 << 0)) {
+ reg32 = inw(mmbar + VENDOR_ID2);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(mmbar + VENDOR_ID1);
+ program_sigid(dev, reg32);
+ return;
+ }
+ }
+
+ /* Secondary codec? */
+ reg16 = inw(mbar + SEC_CODEC);
+ if ((reg16 & (1 << 9)) == 0)
+ return;
+
+ reg16 = inw(mmbar + EXT_MODEM_ID2);
+ if ((reg16 & 0xc000) == 0x4000) {
+ if (reg16 & (1 << 0)) {
+ reg32 = inw(mmbar + SEC_VENDOR_ID2);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(mmbar + SEC_VENDOR_ID1);
+ program_sigid(dev, reg32);
+ return;
+ }
+ }
+}
+
+static struct device_operations ac97_audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = i82801dx_enable,
+ .init = ac97_audio_init,
+ .scan_bus = 0,
+};
+
+static struct device_operations ac97_modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = i82801dx_enable,
+ .init = ac97_modem_init,
+ .scan_bus = 0,
+};
+
+/* 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) */
+static const struct pci_driver i82801db_ac97_audio __pci_driver = {
+ .ops = &ac97_audio_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_AUDIO,
+};
+
+static const struct pci_driver i82801db_ac97_modem __pci_driver = {
+ .ops = &ac97_modem_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_MODEM,
+};
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "i82801dx.h"
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+//#define SMBUS_TIMEOUT (100*1000*10)
+
+static void enable_smbus(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ printk(BIOS_DEBUG, "SMBus controller enabled\n");
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ /* Set smbus enable */
+ pci_write_config8(dev, 0x40, 0x01);
+ /* Set smbus iospace enable */
+ pci_write_config16(dev, 0x4, 0x01);
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_active(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1)) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : -4;
+}
+
+static int smbus_wait_until_ready(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1) == 0) {
+ break;
+ }
+ if (loops == (SMBUS_TIMEOUT / 2)) {
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
+ SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ } while (--loops);
+ return loops ? 0 : -2;
+}
+
+static int smbus_wait_until_done(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1) == 0) {
+ break;
+ }
+ if ((val & ~((1 << 6) | (1 << 0))) != 0) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : -3;
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ /* printk(BIOS_ERR, "smbus_read_byte\n"); */
+ if (smbus_wait_until_ready() < 0) {
+ printk(BIOS_ERR, "SMBUS not ready (%02x)\n", -2);
+ return -2;
+ }
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte... */
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start a byte read, with interrupts disabled */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
+ SMBUS_IO_BASE + SMBHSTCTL);
+ /* poll for it to start */
+ if (smbus_wait_until_active() < 0) {
+ printk(BIOS_ERR, "SMBUS not active (%02x)\n", -4);
+ return -4;
+ }
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done() < 0) {
+ printk(BIOS_ERR, "SMBUS not completed (%02x)\n", -3);
+ return -3;
+ }
+
+ global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1 << 6); /* Ignore the In Use Status... */
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+ if (global_status_register != 2) {
+ //printk(BIOS_SPEW, "%s: no device (%02x, %02x)\n", __func__, device, address);
+ return -1;
+ }
+ //printk(BIOS_DEBUG, "%s: %02x@%02x = %02x\n", __func__, device, address, byte);
+ return byte;
+}
+
+#if 0
+static void smbus_write_byte(unsigned device, unsigned address,
+ unsigned char val)
+{
+ if (smbus_wait_until_ready() < 0) {
+ return;
+ }
+
+ /* by LYH */
+ outb(0x37, SMBUS_IO_BASE + SMBHSTSTAT);
+ /* set the device I'm talking too */
+ outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR);
+
+ /* data to send */
+ outb(val, SMBUS_IO_BASE + SMBHSTDAT);
+
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+
+ /* start the command */
+ outb(0xa, SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+ return;
+}
+#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "i82801dx.h"
-
-#define NAMBAR 0x10
-#define MASTER_VOL 0x02
-#define PAGING 0x24
-#define EXT_AUDIO 0x28
-#define FUNC_SEL 0x66
-#define INFO_IO 0x68
-#define CONNECTOR 0x6a
-#define VENDOR_ID1 0x7c
-#define VENDOR_ID2 0x7e
-#define SEC_VENDOR_ID1 0xfc
-#define SEC_VENDOR_ID2 0xfe
-
-#define NABMBAR 0x14
-#define GLOB_CNT 0x2c
-#define GLOB_STA 0x30
-#define CAS 0x34
-
-#define MMBAR 0x10
-#define EXT_MODEM_ID1 0x3c
-#define EXT_MODEM_ID2 0xbc
-
-#define MBAR 0x14
-#define SEC_CODEC 0x40
-
-
-/* FIXME. This table is probably mainboard specific */
-static u16 ac97_function[16*2][4] = {
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) }
-};
-
-static u16 nabmbar;
-static u16 nambar;
-
-static int ac97_semaphore(void)
-{
- int timeout;
- u8 reg8;
-
- timeout = 0xffff;
- do {
- reg8 = inb(nabmbar + CAS);
- timeout--;
- } while ((reg8 & 1) && timeout);
- if (! timeout) {
- printk(BIOS_DEBUG, "Timeout!\n");
- }
-
- return (!timeout);
-}
-
-static void init_cnr(void)
-{
- // TODO
-}
-
-static void program_sigid(struct device *dev, u32 id)
-{
- pci_write_config32(dev, 0x2c, id);
-}
-
-static void ac97_audio_init(struct device *dev)
-{
- u16 reg16;
- u32 reg32;
- int i;
-
- printk(BIOS_DEBUG, "Initializing AC'97 Audio.\n");
-
- /* top 16 bits are zero, so don't read them */
- nabmbar = pci_read_config16(dev, NABMBAR) & 0xfffe;
- nambar = pci_read_config16(dev, NAMBAR) & 0xfffe;
-
- reg16 = inw(nabmbar + GLOB_CNT);
- reg16 |= (1 << 1); /* Remove AC_RESET# */
- outw(reg16, nabmbar + GLOB_CNT);
-
- /* Wait 600ms. Ouch. */
- udelay(600 * 1000);
-
- init_cnr();
-
- /* Detect Primary AC'97 Codec */
- reg32 = inl(nabmbar + GLOB_STA);
- if ((reg32 & ((1 << 28) | (1 << 9) | (1 << 8))) == 0) {
- /* Primary Codec not found */
- printk(BIOS_DEBUG, "No primary codec. Disabling AC'97 Audio.\n");
- return;
- }
-
- ac97_semaphore();
-
- /* Detect if codec is programmable */
- outw(0x8000, nambar + MASTER_VOL);
- ac97_semaphore();
- if (inw(nambar + MASTER_VOL) != 0x8000) {
- printk(BIOS_DEBUG, "Codec not programmable. Disabling AC'97 Audio.\n");
- return;
- }
-
- /* Program Vendor IDs */
- reg32 = inw(nambar + VENDOR_ID1);
- reg32 <<= 16;
- reg32 |= (u16)inw(nambar + VENDOR_ID2);
-
- program_sigid(dev, reg32);
-
- /* Is Codec AC'97 2.3 compliant? */
- reg16 = inw(nambar + EXT_AUDIO);
- /* [11:10] = 10b -> AC'97 2.3 */
- if ((reg16 & 0x0c00) != 0x0800) {
- /* No 2.3 Codec. We're done */
- return;
- }
-
- /* Select Page 1 */
- reg16 = inw(nambar + PAGING);
- reg16 &= 0xfff0;
- reg16 |= 0x0001;
- outw(reg16, nambar + PAGING);
-
- for (i = 0x0a * 2; i > 0; i--) {
- outw(i, nambar + FUNC_SEL);
-
- /* Function could not be selected. Next one */
- if (inw(nambar + FUNC_SEL) != i)
- continue;
-
- reg16 = inw(nambar + INFO_IO);
-
- /* Function Information present? */
- if (!(reg16 & (1 << 0)))
- continue;
-
- /* Function Information valid? */
- if (!(reg16 & (1 << 4)))
- continue;
-
- /* Program Buffer Delay [9:5] */
- reg16 &= 0x03e0;
- reg16 |= ac97_function[i][0];
-
- /* Program Gain [15:11] */
- reg16 |= ac97_function[i][1];
-
- /* Program Inversion [10] */
- reg16 |= ac97_function[i][2];
-
- outw(reg16, nambar + INFO_IO);
-
- /* Program Connector / Jack Location */
- reg16 = inw(nambar + CONNECTOR);
- reg16 &= 0x1fff;
- reg16 |= ac97_function[i][3];
- outw(reg16, nambar + CONNECTOR);
- }
-}
-
-static void ac97_modem_init(struct device *dev)
-{
- u16 reg16;
- u32 reg32;
- u16 mmbar, mbar;
-
- mmbar = pci_read_config16(dev, MMBAR) & 0xfffe;
- mbar = pci_read_config16(dev, MBAR) & 0xfffe;
-
- reg16 = inw(mmbar + EXT_MODEM_ID1);
- if ((reg16 & 0xc000) != 0xc000 ) {
- if (reg16 & (1 << 0)) {
- reg32 = inw(mmbar + VENDOR_ID2);
- reg32 <<= 16;
- reg32 |= (u16)inw(mmbar + VENDOR_ID1);
- program_sigid(dev, reg32);
- return;
- }
- }
-
- /* Secondary codec? */
- reg16 = inw(mbar + SEC_CODEC);
- if ((reg16 & (1 << 9)) == 0)
- return;
-
- reg16 = inw(mmbar + EXT_MODEM_ID2);
- if ((reg16 & 0xc000) == 0x4000) {
- if (reg16 & (1 << 0)) {
- reg32 = inw(mmbar + SEC_VENDOR_ID2);
- reg32 <<= 16;
- reg32 |= (u16)inw(mmbar + SEC_VENDOR_ID1);
- program_sigid(dev, reg32);
- return;
- }
- }
-}
-
-static struct device_operations ac97_audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = i82801dx_enable,
- .init = ac97_audio_init,
- .scan_bus = 0,
-};
-
-static struct device_operations ac97_modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = i82801dx_enable,
- .init = ac97_modem_init,
- .scan_bus = 0,
-};
-
-/* 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) */
-static const struct pci_driver i82801db_ac97_audio __pci_driver = {
- .ops = &ac97_audio_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_AUDIO,
-};
-
-static const struct pci_driver i82801db_ac97_modem __pci_driver = {
- .ops = &ac97_modem_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_AC97_MODEM,
-};
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "i82801dx.h"
-
-#define SMBHSTSTAT 0x0
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-//#define SMBUS_TIMEOUT (100*1000*10)
-
-static void enable_smbus(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- printk(BIOS_DEBUG, "SMBus controller enabled\n");
- /* set smbus iobase */
- pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
- /* Set smbus enable */
- pci_write_config8(dev, 0x40, 0x01);
- /* Set smbus iospace enable */
- pci_write_config16(dev, 0x4, 0x01);
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-}
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_active(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1)) {
- break;
- }
- } while (--loops);
- return loops ? 0 : -4;
-}
-
-static int smbus_wait_until_ready(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1) == 0) {
- break;
- }
- if (loops == (SMBUS_TIMEOUT / 2)) {
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
- SMBUS_IO_BASE + SMBHSTSTAT);
- }
- } while (--loops);
- return loops ? 0 : -2;
-}
-
-static int smbus_wait_until_done(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
-
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1) == 0) {
- break;
- }
- if ((val & ~((1 << 6) | (1 << 0))) != 0) {
- break;
- }
- } while (--loops);
- return loops ? 0 : -3;
-}
-
-static int smbus_read_byte(unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- /* printk(BIOS_ERR, "smbus_read_byte\n"); */
- if (smbus_wait_until_ready() < 0) {
- printk(BIOS_ERR, "SMBUS not ready (%02x)\n", -2);
- return -2;
- }
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte... */
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start a byte read, with interrupts disabled */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
- SMBUS_IO_BASE + SMBHSTCTL);
- /* poll for it to start */
- if (smbus_wait_until_active() < 0) {
- printk(BIOS_ERR, "SMBUS not active (%02x)\n", -4);
- return -4;
- }
-
- /* poll for transaction completion */
- if (smbus_wait_until_done() < 0) {
- printk(BIOS_ERR, "SMBUS not completed (%02x)\n", -3);
- return -3;
- }
-
- global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~(1 << 6); /* Ignore the In Use Status... */
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
- if (global_status_register != 2) {
- //printk(BIOS_SPEW, "%s: no device (%02x, %02x)\n", __func__, device, address);
- return -1;
- }
- //printk(BIOS_DEBUG, "%s: %02x@%02x = %02x\n", __func__, device, address, byte);
- return byte;
-}
-
-#if 0
-static void smbus_write_byte(unsigned device, unsigned address,
- unsigned char val)
-{
- if (smbus_wait_until_ready() < 0) {
- return;
- }
-
- /* by LYH */
- outb(0x37, SMBUS_IO_BASE + SMBHSTSTAT);
- /* set the device I'm talking too */
- outw(((device & 0x7f) << 1) | 0, SMBUS_IO_BASE + SMBHSTADDR);
-
- /* data to send */
- outb(val, SMBUS_IO_BASE + SMBHSTDAT);
-
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-
- /* start the command */
- outb(0xa, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
- return;
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801dx.h"
-
-typedef struct southbridge_intel_i82801dx_config config_t;
-
-static void ide_init(struct device *dev)
-{
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- /* Enable IDE devices so the Linux IDE driver will work. */
- uint16_t ideTimingConfig;
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- if (!config || config->ide0_enable) {
- /* Enable primary IDE interface. */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE0: Primary IDE interface is enabled\n");
- } else {
- printk(BIOS_INFO, "IDE0: Primary IDE interface is disabled\n");
- }
- pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- if (!config || config->ide1_enable) {
- /* Enable secondary IDE interface. */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- printk(BIOS_DEBUG, "IDE1: Secondary IDE interface is enabled\n");
- } else {
- printk(BIOS_INFO, "IDE1: Secondary IDE interface is disabled\n");
- }
- pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = i82801dx_enable,
-};
-
-/* 82801DB */
-static const struct pci_driver i82801db_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x24cb,
-};
-
-/* 82801DBM */
-static const struct pci_driver i82801dbm_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x24ca,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2004 SuSE Linux AG
- * Copyright (C) 2004 Tyan Computer
- * Copyright (C) 2010 Joseph Smith <joe@settoplinux.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801dx.h"
-
-#define NMI_OFF 0
-
-typedef struct southbridge_intel_i82801dx_config config_t;
-
-static void i82801dx_enable_ioapic(struct device *dev)
-{
- u32 reg32;
- volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
- volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
-
- /* Set ACPI base address (I/O space). */
- pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
-
- /* Enable ACPI I/O and power management. */
- pci_write_config8(dev, ACPI_CNTL, 0x10);
-
- reg32 = pci_read_config32(dev, GEN_CNTL);
- reg32 |= (3 << 7); /* Enable IOAPIC */
- reg32 |= (1 << 13); /* Coprocessor error enable */
- reg32 |= (1 << 1); /* Delayed transaction enable */
- reg32 |= (1 << 2); /* DMA collection buffer enable */
- pci_write_config32(dev, GEN_CNTL, reg32);
- printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
-
- *ioapic_index = 0;
- *ioapic_data = (1 << 25);
-
- *ioapic_index = 0;
- reg32 = *ioapic_data;
- printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
- if (reg32 != (1 << 25))
- die("APIC Error\n");
-
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
-}
-
-static void i82801dx_enable_serial_irqs(struct device *dev)
-{
- /* Set packet length and toggle silent mode bit. */
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
-}
-
-static void i82801dx_pirq_init(device_t dev)
-{
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
- pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
- pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
- pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
- pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
- pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
- pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
- pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
-}
-
-static void i82801dx_power_options(device_t dev)
-{
- u8 reg8;
- u16 reg16, pmbase;
- u32 reg32;
- const char *state;
-
- int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- int nmi_option;
-
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- *
- * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
- */
- if (get_option(&pwr_on, "power_on_after_fail") < 0)
- pwr_on = MAINBOARD_POWER_ON;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- reg8 &= 0xfe;
- switch (pwr_on) {
- case MAINBOARD_POWER_OFF:
- reg8 |= 1;
- state = "off";
- break;
- case MAINBOARD_POWER_ON:
- reg8 &= ~1;
- state = "on";
- break;
- case MAINBOARD_POWER_KEEP:
- reg8 &= ~1;
- state = "state keep";
- break;
- default:
- state = "undefined";
- }
-
- reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
-
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- printk(BIOS_INFO, "Set power %s after power failure.\n", state);
-
- /* Set up NMI on errors. */
- reg8 = inb(0x61);
- reg8 &= 0x0f; /* Higher Nibble must be 0 */
- reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
- // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
- reg8 |= (1 << 2); /* PCI SERR# Disable for now */
- outb(reg8, 0x61);
-
- reg8 = inb(0x70);
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- printk(BIOS_INFO, "NMI sources enabled.\n");
- reg8 &= ~(1 << 7); /* Set NMI. */
- } else {
- printk(BIOS_INFO, "NMI sources disabled.\n");
- reg8 |= ( 1 << 7); /* Disable NMI. */
- }
- outb(reg8, 0x70);
-
- /* Set SMI# rate down and enable CPU_SLP# */
- reg16 = pci_read_config16(dev, GEN_PMCON_1);
- reg16 &= ~(3 << 0); // SMI# rate 1 minute
- reg16 |= (1 << 5); // CPUSLP_EN Desktop only
- pci_write_config16(dev, GEN_PMCON_1, reg16);
-
- pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
-
- /* Set up power management block and determine sleep mode */
- reg32 = inl(pmbase + 0x04); // PM1_CNT
-
- reg32 &= ~(7 << 10); // SLP_TYP
- reg32 |= (1 << 0); // SCI_EN
- outl(reg32, pmbase + 0x04);
-}
-
-static void gpio_init(device_t dev)
-{
- /* This should be done in romstage.c already */
- pci_write_config32(dev, GPIO_BASE, (GPIOBASE_ADDR | 1));
- pci_write_config8(dev, GPIO_CNTL, 0x10);
-}
-
-static void i82801dx_rtc_init(struct device *dev)
-{
- u8 reg8;
- u32 reg32;
- int rtc_failed;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- rtc_failed = reg8 & RTC_BATTERY_DEAD;
- if (rtc_failed) {
- reg8 &= ~(1 << 1); /* Preserve the power fail state. */
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- }
- reg32 = pci_read_config32(dev, GEN_STS);
- rtc_failed |= reg32 & (1 << 2);
- rtc_init(rtc_failed);
-
- /* Enable access to the upper 128 byte bank of CMOS RAM. */
- pci_write_config8(dev, RTC_CONF, 0x04);
-}
-
-static void i82801dx_lpc_route_dma(struct device *dev, u8 mask)
-{
- u16 reg16;
- int i;
-
- reg16 = pci_read_config16(dev, PCI_DMA_CFG);
- reg16 &= 0x300;
- for (i = 0; i < 8; i++) {
- if (i == 4)
- continue;
- reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
- }
- pci_write_config16(dev, PCI_DMA_CFG, reg16);
-}
-
-static void i82801dx_lpc_decode_en(device_t dev)
-{
- /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
- * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
- * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
- * We also need to set the value for LPC I/F Enables Register.
- */
- pci_write_config8(dev, COM_DEC, 0x10);
- pci_write_config16(dev, LPC_EN, 0x300F);
-}
-
-/* ICH4 does not mention HPET in the docs, but
- * all ICH3 and ICH4 do have HPETs built in.
- */
-static void enable_hpet(struct device *dev)
-{
- u32 reg32, hpet, val;
-
- /* Set HPET base address and enable it */
- printk(BIOS_DEBUG, "Enabling HPET at 0x%x\n", HPET_ADDR);
- reg32 = pci_read_config32(dev, GEN_CNTL);
- /*
- * Bit 17 is HPET enable bit.
- * Bit 16:15 control the HPET base address.
- */
- reg32 &= ~(3 << 15); /* Clear it */
-
- hpet = HPET_ADDR >> 12;
- hpet &= 0x3;
-
- reg32 |= (hpet << 15);
- reg32 |= (1 << 17); /* Enable HPET. */
- pci_write_config32(dev, GEN_CNTL, reg32);
-
- /* Check to see whether it took */
- reg32 = pci_read_config32(dev, GEN_CNTL);
- val = reg32 >> 15;
- val &= 0x7;
-
- if ((val & 0x4) && (hpet == (val & 0x3))) {
- printk(BIOS_INFO, "HPET enabled at 0x%x\n", HPET_ADDR);
- } else {
- printk(BIOS_WARNING, "HPET was not enabled correctly\n");
- reg32 &= ~(1 << 17); /* Clear Enable */
- pci_write_config32(dev, GEN_CNTL, reg32);
- }
-}
-
-static void lpc_init(struct device *dev)
-{
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
- /* IO APIC initialization. */
- i82801dx_enable_ioapic(dev);
-
- i82801dx_enable_serial_irqs(dev);
-
- /* Setup the PIRQ. */
- i82801dx_pirq_init(dev);
-
- /* Setup power options. */
- i82801dx_power_options(dev);
-
- /* Set the state of the GPIO lines. */
- gpio_init(dev);
-
- /* Initialize the real time clock. */
- i82801dx_rtc_init(dev);
-
- /* Route DMA. */
- i82801dx_lpc_route_dma(dev, 0xff);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
- /* Setup decode ports and LPC I/F enables. */
- i82801dx_lpc_decode_en(dev);
-
- /* Initialize the High Precision Event Timers */
- enable_hpet(dev);
-}
-
-static void i82801dx_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = i82801dx_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i82801dx_enable,
-};
-
-/* 82801DB/DBL */
-static const struct pci_driver lpc_driver_db __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_LPC,
-};
-
-/* 82801DBM */
-static const struct pci_driver lpc_driver_dbm __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DBM_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-typedef struct {
- /* Miscellaneous */
- u16 osys; /* 0x00 - Operating System */
- u8 smif; /* 0x02 - SMI function call ("TRAP") */
- u8 prm0; /* 0x03 - SMI function call parameter */
- u8 prm1; /* 0x04 - SMI function call parameter */
- u8 scif; /* 0x05 - SCI function call (via _L00) */
- u8 prm2; /* 0x06 - SCI function call parameter */
- u8 prm3; /* 0x07 - SCI function call parameter */
- u8 lckf; /* 0x08 - Global Lock function for EC */
- u8 prm4; /* 0x09 - Lock function parameter */
- u8 prm5; /* 0x0a - Lock function parameter */
- u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
- u8 lids; /* 0x0f - LID state (open = 1) */
- u8 pwrs; /* 0x10 - Power state (AC = 1) */
- u8 dbgs; /* 0x11 - Debug state */
- u8 linx; /* 0x12 - Linux OS */
- u8 dckn; /* 0x13 - PCIe docking state */
- /* Thermal policy */
- u8 actt; /* 0x14 - active trip point */
- u8 psvt; /* 0x15 - passive trip point */
- u8 tc1v; /* 0x16 - passive trip point TC1 */
- u8 tc2v; /* 0x17 - passive trip point TC2 */
- u8 tspv; /* 0x18 - passive trip point TSP */
- u8 crtt; /* 0x19 - critical trip point */
- u8 dtse; /* 0x1a - Digital Thermal Sensor enable */
- u8 dts1; /* 0x1b - DT sensor 1 */
- u8 dts2; /* 0x1c - DT sensor 2 */
- u8 rsvd2;
- /* Battery Support */
- u8 bnum; /* 0x1e - number of batteries */
- u8 b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
- u8 b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
- u8 rsvd3[3];
- /* Processor Identification */
- u8 apic; /* 0x28 - APIC enabled */
- u8 mpen; /* 0x29 - MP capable/enabled */
- u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
- u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
- u8 ppcm; /* 0x2c - Max. PPC state */
- u8 rsvd4[5];
- /* Super I/O & CMOS config */
- u8 natp; /* 0x32 - SIO type */
- u8 cmap; /* 0x33 - */
- u8 cmbp; /* 0x34 - */
- u8 lptp; /* 0x35 - LPT port */
- u8 fdcp; /* 0x36 - Floppy Disk Controller */
- u8 rfdv; /* 0x37 - */
- u8 hotk; /* 0x38 - Hot Key */
- u8 rtcf;
- u8 util;
- u8 acin;
- /* Integrated Graphics Device */
- u8 igds; /* 0x3c - IGD state */
- u8 tlst; /* 0x3d - Display Toggle List Pointer */
- u8 cadl; /* 0x3e - currently attached devices */
- u8 padl; /* 0x3f - previously attached devices */
- u16 cste; /* 0x40 - current display state */
- u16 nste; /* 0x42 - next display state */
- u16 sste; /* 0x44 - set display state */
- u8 ndid; /* 0x46 - number of device ids */
- u32 did[5]; /* 0x47 - 5b device id 1..5 */
- u8 rsvd5[0x9];
- /* Backlight Control */
- u8 blcs; /* 0x64 - Backlight Control possible */
- u8 brtl;
- u8 odds;
- u8 rsvd6[0x7];
- /* Ambient Light Sensors*/
- u8 alse; /* 0x6e - ALS enable */
- u8 alaf;
- u8 llow;
- u8 lhih;
- u8 rsvd7[0x6];
- /* EMA */
- u8 emae; /* 0x78 - EMA enable */
- u16 emap;
- u16 emal;
- u8 rsvd8[0x5];
- /* MEF */
- u8 mefe; /* 0x82 - MEF enable */
- u8 rsvd9[0x9];
- /* TPM support */
- u8 tpmp; /* 0x8c - TPM */
- u8 tpme;
- u8 rsvd10[8];
- /* SATA */
- u8 gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
- u8 gtf1[7];
- u8 gtf2[7];
- u8 idem;
- u8 idet;
- u8 rsvd11[7];
- /* IGD OpRegion (not implemented yet) */
- u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
- u8 ibtt;
- u8 ipat;
- u8 itvf;
- u8 itvm;
- u8 ipsc;
- u8 iblc;
- u8 ibia;
- u8 issc;
- u8 i409;
- u8 i509;
- u8 i609;
- u8 i709;
- u8 idmm;
- u8 idms;
- u8 if1e;
- u8 hvco;
- u32 nxd[8];
- u8 rsvd12[8];
- /* Mainboard specific */
- u8 dock; /* 0xf0 - Docking Status */
- u8 bten;
- u8 rsvd13[14];
-} __attribute__((packed)) global_nvs_t;
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801dx.h"
-
-static void pci_init(struct device *dev)
-{
- /* Enable pci error detecting */
- uint32_t dword;
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* SERR# Enable */
- dword |= (1 << 6); /* Parity Error Response */
- pci_write_config32(dev, 0x04, dword);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
-};
-
-/* 82801DB */
-static const struct pci_driver pci_driver_db __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_PCI,
-};
-
-/* 82801DBM/DBL */
-static const struct pci_driver pci_driver_dbm __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DBM_PCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9 */
- outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "i82801dx.h"
-#include <smbus.h>
-#include <pci.h>
-#include <arch/io.h>
-
-#define PM_BUS 0
-#define PM_DEVFN PCI_DEVFN(0x1f,3)
-
-void smbus_enable(void)
-{
- unsigned char byte;
- /* iobase addr */
- pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1);
- /* smbus enable */
- pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40, 1);
- /* iospace enable */
- pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
-
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
-}
-
-void smbus_setup(void)
-{
- outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
-}
-
-static void smbus_wait_until_ready(void)
-{
- while ((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
- /* nop */
- }
-}
-
-static void smbus_wait_until_done(void)
-{
- unsigned char byte;
- do {
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
- while ((byte & 1) == 1);
- while ((byte & ~1) == 0) {
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
-}
-
-int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
-{
- unsigned char host_status_register;
- unsigned char byte;
-
- smbus_wait_until_ready();
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte... */
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
-
- host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
- *result = byte;
- return host_status_register != 0x02;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <console/console.h>
-#include <arch/io.h>
-#include <cpu/cpu.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/smm.h>
-#include <string.h>
-#include "i82801dx.h"
-
-extern unsigned char _binary_smm_start;
-extern unsigned char _binary_smm_size;
-
-/* I945 */
-#define SMRAM 0x90
-#define D_OPEN (1 << 6)
-#define D_CLS (1 << 5)
-#define D_LCK (1 << 4)
-#define G_SMRAME (1 << 3)
-#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
-
-/* While we read PMBASE dynamically in case it changed, let's
- * initialize it with a sane value
- */
-static u16 pmbase = PMBASE_ADDR;
-
-/**
- * @brief read and clear PM1_STS
- * @return PM1_STS register
- */
-static u16 reset_pm1_status(void)
-{
- u16 reg16;
-
- reg16 = inw(pmbase + PM1_STS);
- /* set status bits are cleared by writing 1 to them */
- outw(reg16, pmbase + PM1_STS);
-
- return reg16;
-}
-
-static void dump_pm1_status(u16 pm1_sts)
-{
- printk(BIOS_DEBUG, "PM1_STS: ");
- if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
- if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
- if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
- if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
- if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
- if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
- if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
- if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
- printk(BIOS_DEBUG, "\n");
-}
-
-/**
- * @brief read and clear SMI_STS
- * @return SMI_STS register
- */
-static u32 reset_smi_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + SMI_STS);
-
- return reg32;
-}
-
-static void dump_smi_status(u32 smi_sts)
-{
- printk(BIOS_DEBUG, "SMI_STS: ");
- if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
- if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
- if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
- if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
- if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
- if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
- if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
- if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
- if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
- if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
- if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
- if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
- if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
- if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
- if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
- if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
- if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
- if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
- if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
- if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear GPE0_STS
- * @return GPE0_STS register
- */
-static u32 reset_gpe0_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + GPE0_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + GPE0_STS);
-
- return reg32;
-}
-
-static void dump_gpe0_status(u32 gpe0_sts)
-{
- int i;
- printk(BIOS_DEBUG, "GPE0_STS: ");
- for (i=31; i<= 16; i--) {
- if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
- }
- if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
- if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
- if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
- if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
- if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
- if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
- if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
- if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
- if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
- if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
- if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
- if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
- if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
- if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear ALT_GP_SMI_STS
- * @return ALT_GP_SMI_STS register
- */
-static u16 reset_alt_gp_smi_status(void)
-{
- u16 reg16;
-
- reg16 = inl(pmbase + ALT_GP_SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg16, pmbase + ALT_GP_SMI_STS);
-
- return reg16;
-}
-
-static void dump_alt_gp_smi_status(u16 alt_gp_smi_sts)
-{
- int i;
- printk(BIOS_DEBUG, "ALT_GP_SMI_STS: ");
- for (i=15; i<= 0; i--) {
- if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", (i-16));
- }
- printk(BIOS_DEBUG, "\n");
-}
-
-
-
-/**
- * @brief read and clear TCOx_STS
- * @return TCOx_STS registers
- */
-static u32 reset_tco_status(void)
-{
- u32 tcobase = pmbase + 0x60;
- u32 reg32;
-
- reg32 = inl(tcobase + 0x04);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
- if (reg32 & (1 << 18))
- outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
-
- return reg32;
-}
-
-
-static void dump_tco_status(u32 tco_sts)
-{
- printk(BIOS_DEBUG, "TCO_STS: ");
- if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
- if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
- if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
- if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
- if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
- if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
- if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
- if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
- if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
- if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
- if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
- if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
- if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-
-/**
- * @brief Set the EOS bit
- */
-static void smi_set_eos(void)
-{
- u8 reg8;
-
- reg8 = inb(pmbase + SMI_EN);
- reg8 |= EOS;
- outb(reg8, pmbase + SMI_EN);
-}
-
-extern uint8_t smm_relocation_start, smm_relocation_end;
-
-static void smm_relocate(void)
-{
- u32 smi_en;
- u16 pm1_en;
-
- printk(BIOS_DEBUG, "Initializing SMM handler...");
-
- pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), 0x40) & 0xfffc;
- printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);
-
- smi_en = inl(pmbase + SMI_EN);
- if (smi_en & APMC_EN) {
- printk(BIOS_INFO, "SMI# handler already enabled?\n");
- return;
- }
-
- /* copy the SMM relocation code */
- memcpy((void *)0x38000, &smm_relocation_start,
- &smm_relocation_end - &smm_relocation_start);
-
- printk(BIOS_DEBUG, "\n");
- dump_smi_status(reset_smi_status());
- dump_pm1_status(reset_pm1_status());
- dump_gpe0_status(reset_gpe0_status());
- dump_alt_gp_smi_status(reset_alt_gp_smi_status());
- dump_tco_status(reset_tco_status());
-
- /* Enable SMI generation:
- * - on TCO events
- * - on APMC writes (io 0xb2)
- * - on writes to SLP_EN (sleep states)
- * - on writes to GBL_RLS (bios commands)
- * No SMIs:
- * - on microcontroller writes (io 0x62/0x66)
- */
-
- smi_en = 0; /* reset SMI enables */
-
-#if 0
- smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN;
-#endif
- smi_en |= TCO_EN;
- smi_en |= APMC_EN;
-#if DEBUG_PERIODIC_SMIS
- /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
- * periodic SMIs.
- */
- smi_en |= PERIODIC_EN;
-#endif
- smi_en |= SLP_SMI_EN;
- smi_en |= BIOS_EN;
-
- /* The following need to be on for SMIs to happen */
- smi_en |= EOS | GBL_SMI_EN;
-
- outl(smi_en, pmbase + SMI_EN);
-
- pm1_en = 0;
- pm1_en |= PWRBTN_EN;
- pm1_en |= GBL_EN;
- outw(pm1_en, pmbase + PM1_EN);
-
- /**
- * There are several methods of raising a controlled SMI# via
- * software, among them:
- * - Writes to io 0xb2 (APMC)
- * - Writes to the Local Apic ICR with Delivery mode SMI.
- *
- * Using the local apic is a bit more tricky. According to
- * AMD Family 11 Processor BKDG no destination shorthand must be
- * used.
- * The whole SMM initialization is quite a bit hardware specific, so
- * I'm not too worried about the better of the methods at the moment
- */
-
- /* raise an SMI interrupt */
- printk(BIOS_SPEW, " ... raise SMI#\n");
- outb(0x00, 0xb2);
-}
-
-static void smm_install(void)
-{
- /* enable the SMM memory window */
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- D_OPEN | G_SMRAME | C_BASE_SEG);
-
- /* copy the real SMM handler */
- memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
- wbinvd();
-
- /* close the SMM memory window and enable normal SMM */
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- G_SMRAME | C_BASE_SEG);
-}
-
-void smm_init(void)
-{
- /* Put SMM code to 0xa0000 */
- smm_install();
-
- /* Put relocation code to 0x38000 and relocate SMBASE */
- smm_relocate();
-
- /* We're done. Make sure SMIs can happen! */
- smi_set_eos();
-}
-
-void smm_lock(void)
-{
- /* LOCK the SMM memory window and enable normal SMM.
- * After running this function, only a full reset can
- * make the SMM registers writable again.
- */
- printk(BIOS_DEBUG, "Locking SMM.\n");
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- D_LCK | G_SMRAME | C_BASE_SEG);
-}
-
-void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
-{
- /* The GDT or coreboot table is going to live here. But a long time
- * after we relocated the GNVS, so this is not troublesome.
- */
- *(u32 *)0x500 = (u32)gnvs;
- *(u32 *)0x504 = (u32)tcg;
- *(u32 *)0x508 = (u32)smi1;
- outb(0xea, 0xb2);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <types.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/smm.h>
-#include <device/pci_def.h>
-#include "i82801dx.h"
-
-#define DEBUG_SMI
-
-#define APM_CNT 0xb2
-#define CST_CONTROL 0x85
-#define PST_CONTROL 0x80
-#define ACPI_DISABLE 0x1e
-#define ACPI_ENABLE 0xe1
-#define GNVS_UPDATE 0xea
-#define MBI_UPDATE 0xeb
-#define APM_STS 0xb3
-
-/* I830M */
-#define SMRAM 0x90
-#define D_OPEN (1 << 6)
-#define D_CLS (1 << 5)
-#define D_LCK (1 << 4)
-#define G_SMRANE (1 << 3)
-#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
-
-#include "i82801dx_nvs.h"
-
-/* While we read PMBASE dynamically in case it changed, let's
- * initialize it with a sane value
- */
-u16 pmbase = PMBASE_ADDR;
-u8 smm_initialized = 0;
-
-unsigned char *mbi = NULL;
-u32 mbi_len;
-u8 mbi_initialized = 0;
-
-/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
- * by coreboot.
- */
-global_nvs_t *gnvs = (global_nvs_t *)0x0;
-void *tcg = (void *)0x0;
-void *smi1 = (void *)0x0;
-
-/**
- * @brief read and clear PM1_STS
- * @return PM1_STS register
- */
-static u16 reset_pm1_status(void)
-{
- u16 reg16;
-
- reg16 = inw(pmbase + PM1_STS);
- /* set status bits are cleared by writing 1 to them */
- outw(reg16, pmbase + PM1_STS);
-
- return reg16;
-}
-
-static void dump_pm1_status(u16 pm1_sts)
-{
- printk(BIOS_SPEW, "PM1_STS: ");
- if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK ");
- if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK ");
- if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR ");
- if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC ");
- if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN ");
- if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL ");
- if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM ");
- if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF ");
- printk(BIOS_SPEW, "\n");
- int reg16 = inw(pmbase + PM1_EN);
- printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
-}
-
-/**
- * @brief read and clear SMI_STS
- * @return SMI_STS register
- */
-static u32 reset_smi_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + SMI_STS);
-
- return reg32;
-}
-
-static void dump_smi_status(u32 smi_sts)
-{
- printk(BIOS_DEBUG, "SMI_STS: ");
- if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
- if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
- if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
- if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
- if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
- if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
- if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
- if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
- if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
- if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
- if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
- if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
- if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
- if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
- if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
- if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
- if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
- if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
- if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
- if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear GPE0_STS
- * @return GPE0_STS register
- */
-static u32 reset_gpe0_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + GPE0_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + GPE0_STS);
-
- return reg32;
-}
-
-static void dump_gpe0_status(u32 gpe0_sts)
-{
- int i;
- printk(BIOS_DEBUG, "GPE0_STS: ");
- for (i=31; i<= 16; i--) {
- if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
- }
- if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
- if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
- if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
- if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
- if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
- if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
- if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
- if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
- if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
- if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
- if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
- if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
- if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
- if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear TCOx_STS
- * @return TCOx_STS registers
- */
-static u32 reset_tco_status(void)
-{
- u32 tcobase = pmbase + 0x60;
- u32 reg32;
-
- reg32 = inl(tcobase + 0x04);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
- if (reg32 & (1 << 18))
- outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
-
- return reg32;
-}
-
-
-static void dump_tco_status(u32 tco_sts)
-{
- printk(BIOS_DEBUG, "TCO_STS: ");
- if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
- if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
- if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
- if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
- if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
- if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
- if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
- if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
- if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
- if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
- if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
- if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
- if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
- printk(BIOS_DEBUG, "\n");
-}
-
-/* We are using PCIe accesses for now
- * 1. the chipset can do it
- * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
- */
-// #include "../../../northbridge/intel/i945/pcie_config.c"
-
-int southbridge_io_trap_handler(int smif)
-{
- switch (smif) {
- case 0x32:
- printk(BIOS_DEBUG, "OS Init\n");
- /* gnvs->smif:
- * On success, the IO Trap Handler returns 0
- * On failure, the IO Trap Handler returns a value != 0
- */
- gnvs->smif = 0;
- return 1; /* IO trap handled */
- }
-
- /* Not handled */
- return 0;
-}
-
-/**
- * @brief Set the EOS bit
- */
-void southbridge_smi_set_eos(void)
-{
- u8 reg8;
-
- reg8 = inb(pmbase + SMI_EN);
- reg8 |= EOS;
- outb(reg8, pmbase + SMI_EN);
-}
-
-static void busmaster_disable_on_bus(int bus)
-{
- int slot, func;
- unsigned int val;
- unsigned char hdr;
-
- for (slot = 0; slot < 0x20; slot++) {
- for (func = 0; func < 8; func++) {
- u32 reg32;
- device_t dev = PCI_DEV(bus, slot, func);
-
- val = pci_read_config32(dev, PCI_VENDOR_ID);
-
- if (val == 0xffffffff || val == 0x00000000 ||
- val == 0x0000ffff || val == 0xffff0000)
- continue;
-
- /* Disable Bus Mastering for this one device */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 &= ~PCI_COMMAND_MASTER;
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- /* If this is a bridge, then follow it. */
- hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
- hdr &= 0x7f;
- if (hdr == PCI_HEADER_TYPE_BRIDGE ||
- hdr == PCI_HEADER_TYPE_CARDBUS) {
- unsigned int buses;
- buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
- busmaster_disable_on_bus((buses >> 8) & 0xff);
- }
- }
- }
-}
-
-
-static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
-{
- u8 reg8;
- u32 reg32;
- u8 slp_typ;
- /* FIXME: the power state on boot should be read from
- * CMOS or even better from GNVS. Right now it's hard
- * coded at compile time.
- */
- u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
-
- /* First, disable further SMIs */
- reg8 = inb(pmbase + SMI_EN);
- reg8 &= ~SLP_SMI_EN;
- outb(reg8, pmbase + SMI_EN);
-
- /* Figure out SLP_TYP */
- reg32 = inl(pmbase + PM1_CNT);
- printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
- slp_typ = (reg32 >> 10) & 7;
-
- /* Next, do the deed.
- */
-
- switch (slp_typ) {
- case 0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
- case 1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
- case 5:
- printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
- /* Invalidate the cache before going to S3 */
- wbinvd();
- break;
- case 6: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
- case 7:
- printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
-
- outl(0, pmbase + GPE0_EN);
-
- /* Should we keep the power state after a power loss?
- * In case the setting is "ON" or "OFF" we don't have
- * to do anything. But if it's "KEEP" we have to switch
- * to "OFF" before entering S5.
- */
- if (s5pwr == MAINBOARD_POWER_KEEP) {
- reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
- reg8 |= 1;
- pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
- }
-
- /* also iterates over all bridges on bus 0 */
- busmaster_disable_on_bus(0);
- break;
- default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
- }
-
- /* Write back to the SLP register to cause the originally intended
- * event again. We need to set BIT13 (SLP_EN) though to make the
- * sleep happen.
- */
- outl(reg32 | SLP_EN, pmbase + PM1_CNT);
-
- /* In most sleep states, the code flow of this function ends at
- * the line above. However, if we entered sleep state S1 and wake
- * up again, we will continue to execute code in this function.
- */
- reg32 = inl(pmbase + PM1_CNT);
- if (reg32 & SCI_EN) {
- /* The OS is not an ACPI OS, so we set the state to S0 */
- reg32 &= ~(SLP_EN | SLP_TYP);
- outl(reg32, pmbase + PM1_CNT);
- }
-}
-
-static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 pmctrl;
- u8 reg8;
-
- /* Emulate B2 register as the FADT / Linux expects it */
-
- reg8 = inb(APM_CNT);
- switch (reg8) {
- case CST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "C-state control\n");
- break;
- case PST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "P-state control\n");
- break;
- case ACPI_DISABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl &= ~SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
- break;
- case ACPI_ENABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl |= SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
- break;
- case GNVS_UPDATE:
- if (smm_initialized) {
- printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
- return;
- }
- gnvs = *(global_nvs_t **)0x500;
- tcg = *(void **)0x504;
- smi1 = *(void **)0x508;
- smm_initialized = 1;
- printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
- break;
- case MBI_UPDATE: // FIXME
- if (mbi_initialized) {
- printk(BIOS_DEBUG, "SMI#: mbi already registered!\n");
- return;
- }
- mbi = *(void **)0x500;
- mbi_len = *(u32 *)0x504;
- mbi_initialized = 1;
- printk(BIOS_DEBUG, "SMI#: Registered MBI at %p (%d bytes)\n", mbi, mbi_len);
- break;
-
- default:
- printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);
- }
-}
-
-static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 pm1_sts;
-
- pm1_sts = reset_pm1_status();
- dump_pm1_status(pm1_sts);
-
- /* While OSPM is not active, poweroff immediately
- * on a power button event.
- */
- if (pm1_sts & PWRBTN_STS) {
- // power button pressed
- u32 reg32;
- reg32 = (7 << 10) | (1 << 13);
- outl(reg32, pmbase + PM1_CNT);
- }
-}
-
-static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 gpe0_sts;
-
- gpe0_sts = reset_gpe0_status();
- dump_gpe0_status(gpe0_sts);
-}
-
-static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 reg16;
- reg16 = inw(pmbase + ALT_GP_SMI_STS);
- outl(reg16, pmbase + ALT_GP_SMI_STS);
-
- reg16 &= inw(pmbase + ALT_GP_SMI_EN);
-
- if (mainboard_smi_gpi) {
- mainboard_smi_gpi(reg16);
- } else {
- if (reg16)
- printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16);
- }
-}
-
-static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & MCSMI_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Microcontroller SMI.\n");
-}
-
-
-
-static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 tco_sts;
-
- tco_sts = reset_tco_status();
-
- /* Any TCO event? */
- if (!tco_sts)
- return;
-
- if (tco_sts & (1 << 8)) { // BIOSWR
- u8 bios_cntl;
-
- bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
-
- if (bios_cntl & 1) {
- /* BWE is RW, so the SMI was caused by a
- * write to BWE, not by a write to the BIOS
- */
-
- /* This is the place where we notice someone
- * is trying to tinker with the BIOS. We are
- * trying to be nice and just ignore it. A more
- * resolute answer would be to power down the
- * box.
- */
- printk(BIOS_DEBUG, "Switching back to RO\n");
- pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
- } /* No else for now? */
- } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
- /* Handle TCO timeout */
- printk(BIOS_DEBUG, "TCO Timeout.\n");
- } else if (!tco_sts) {
- dump_tco_status(tco_sts);
- }
-}
-
-static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & PERIODIC_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Periodic SMI.\n");
-}
-
-static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
-{
-#define IOTRAP(x) (trap_sts & (1 << x))
-#if 0
- u32 trap_sts, trap_cycle;
- u32 data, mask = 0;
- int i;
-
- trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
- RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
-
- trap_cycle = RCBA32(0x1e10);
- for (i=16; i<20; i++) {
- if (trap_cycle & (1 << i))
- mask |= (0xff << ((i - 16) << 2));
- }
-
-
- /* IOTRAP(3) SMI function call */
- if (IOTRAP(3)) {
- if (gnvs && gnvs->smif)
- io_trap_handler(gnvs->smif); // call function smif
- return;
- }
-
- /* IOTRAP(2) currently unused
- * IOTRAP(1) currently unused */
-
- /* IOTRAP(0) SMIC */
- if (IOTRAP(0)) {
- if (!(trap_cycle & (1 << 24))) { // It's a write
- printk(BIOS_DEBUG, "SMI1 command\n");
- data = RCBA32(0x1e18);
- data &= mask;
- // if (smi1)
- // southbridge_smi_command(data);
- // return;
- }
- // Fall through to debug
- }
-
- printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc);
- for (i=0; i < 4; i++) if(IOTRAP(i)) printk(BIOS_DEBUG, " TRAPÂ = %d\n", i);
- printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
- printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
- printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
-
- if (!(trap_cycle & (1 << 24))) {
- /* Write Cycle */
- data = RCBA32(0x1e18);
- printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
- }
-#endif
-#undef IOTRAP
-}
-
-typedef void (*smi_handler_t)(unsigned int node,
- smm_state_save_area_t *state_save);
-
-smi_handler_t southbridge_smi[32] = {
- NULL, // [0] reserved
- NULL, // [1] reserved
- NULL, // [2] BIOS_STS
- NULL, // [3] LEGACY_USB_STS
- southbridge_smi_sleep, // [4] SLP_SMI_STS
- southbridge_smi_apmc, // [5] APM_STS
- NULL, // [6] SWSMI_TMR_STS
- NULL, // [7] reserved
- southbridge_smi_pm1, // [8] PM1_STS
- southbridge_smi_gpe0, // [9] GPE0_STS
- southbridge_smi_gpi, // [10] GPI_STS
- southbridge_smi_mc, // [11] MCSMI_STS
- NULL, // [12] DEVMON_STS
- southbridge_smi_tco, // [13] TCO_STS
- southbridge_smi_periodic, // [14] PERIODIC_STS
- NULL, // [15] SERIRQ_SMI_STS
- NULL, // [16] SMBUS_SMI_STS
- NULL, // [17] LEGACY_USB2_STS
- NULL, // [18] INTEL_USB2_STS
- NULL, // [19] reserved
- NULL, // [20] PCI_EXP_SMI_STS
- southbridge_smi_monitor, // [21] MONITOR_STS
- NULL, // [22] reserved
- NULL, // [23] reserved
- NULL, // [24] reserved
- NULL, // [25] EL_SMI_STS
- NULL, // [26] SPI_STS
- NULL, // [27] reserved
- NULL, // [28] reserved
- NULL, // [29] reserved
- NULL, // [30] reserved
- NULL // [31] reserved
-};
-
-/**
- * @brief Interrupt handler for SMI#
- *
- * @param smm_revision revision of the smm state save map
- */
-
-void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
-{
- int i, dump = 0;
- u32 smi_sts;
-
- /* Update global variable pmbase */
- pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
-
- /* We need to clear the SMI status registers, or we won't see what's
- * happening in the following calls.
- */
- smi_sts = reset_smi_status();
-
- /* Filter all non-enabled SMI events */
- // FIXME Double check, this clears MONITOR
- // smi_sts &= inl(pmbase + SMI_EN);
-
- /* Call SMI sub handler for each of the status bits */
- for (i = 0; i < 31; i++) {
- if (smi_sts & (1 << i)) {
- if (southbridge_smi[i])
- southbridge_smi[i](node, state_save);
- else {
- printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no "
- "handler available.\n", i);
- dump = 1;
- }
- }
- }
-
- if(dump) {
- dump_smi_status(smi_sts);
- }
-
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Joseph Smith <joe@settoplinux.org>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-static void i82801dx_halt_tco_timer(void)
-{
- /* Set the LPC device statically. */
- device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
-
- /* Temporarily set ACPI base address (I/O space). */
- pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
-
- /* Enable ACPI I/O. */
- pci_write_config8(dev, ACPI_CNTL, 0x10);
-
- /* Halt the TCO timer, preventing SMI and automatic reboot */
- outw(inw(PMBASE_ADDR + TCOBASE + TCO1_CNT) | (1 << 11),
- PMBASE_ADDR + TCOBASE + TCO1_CNT);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Ronald G. Minnich
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801dx.h"
-
-static void usb_init(struct device *dev)
-{
- u32 cmd;
- printk(BIOS_DEBUG, "USB: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = i82801dx_enable,
-};
-
-/* 82801DB/DBL/DBM USB1 */
-static const struct pci_driver usb_driver_1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_USB1,
-};
-
-/* 82801DB/DBL/DBM USB2 */
-static const struct pci_driver usb_driver_2 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_USB2,
-};
-
-/* 82801DB/DBL/DBM USB3 */
-static const struct pci_driver usb_driver_3 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_USB3,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Tyan
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801dx.h"
-
-static void usb2_init(struct device *dev)
-{
- u32 cmd;
- printk(BIOS_DEBUG, "USB: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static struct device_operations usb2_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb2_init,
- .scan_bus = 0,
- .enable = i82801dx_enable,
-};
-
-/* 82801DB/DBM USB 2.0 */
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb2_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801DB_EHCI,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+typedef struct southbridge_intel_i82801dx_config config_t;
+
+static void ide_init(struct device *dev)
+{
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ /* Enable IDE devices so the Linux IDE driver will work. */
+ uint16_t ideTimingConfig;
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ if (!config || config->ide0_enable) {
+ /* Enable primary IDE interface. */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE0: Primary IDE interface is enabled\n");
+ } else {
+ printk(BIOS_INFO, "IDE0: Primary IDE interface is disabled\n");
+ }
+ pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ if (!config || config->ide1_enable) {
+ /* Enable secondary IDE interface. */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ printk(BIOS_DEBUG, "IDE1: Secondary IDE interface is enabled\n");
+ } else {
+ printk(BIOS_INFO, "IDE1: Secondary IDE interface is disabled\n");
+ }
+ pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = i82801dx_enable,
+};
+
+/* 82801DB */
+static const struct pci_driver i82801db_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x24cb,
+};
+
+/* 82801DBM */
+static const struct pci_driver i82801dbm_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x24ca,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2004 SuSE Linux AG
+ * Copyright (C) 2004 Tyan Computer
+ * Copyright (C) 2010 Joseph Smith <joe@settoplinux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801dx.h"
+
+#define NMI_OFF 0
+
+typedef struct southbridge_intel_i82801dx_config config_t;
+
+static void i82801dx_enable_ioapic(struct device *dev)
+{
+ u32 reg32;
+ volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
+ volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
+
+ /* Set ACPI base address (I/O space). */
+ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
+
+ /* Enable ACPI I/O and power management. */
+ pci_write_config8(dev, ACPI_CNTL, 0x10);
+
+ reg32 = pci_read_config32(dev, GEN_CNTL);
+ reg32 |= (3 << 7); /* Enable IOAPIC */
+ reg32 |= (1 << 13); /* Coprocessor error enable */
+ reg32 |= (1 << 1); /* Delayed transaction enable */
+ reg32 |= (1 << 2); /* DMA collection buffer enable */
+ pci_write_config32(dev, GEN_CNTL, reg32);
+ printk(BIOS_DEBUG, "IOAPIC Southbridge enabled %x\n", reg32);
+
+ *ioapic_index = 0;
+ *ioapic_data = (1 << 25);
+
+ *ioapic_index = 0;
+ reg32 = *ioapic_data;
+ printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", reg32);
+ if (reg32 != (1 << 25))
+ die("APIC Error\n");
+
+ *ioapic_index = 3; /* Select Boot Configuration register. */
+ *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
+}
+
+static void i82801dx_enable_serial_irqs(struct device *dev)
+{
+ /* Set packet length and toggle silent mode bit. */
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
+}
+
+static void i82801dx_pirq_init(device_t dev)
+{
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
+ pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
+ pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
+ pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
+ pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
+ pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
+ pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
+ pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
+}
+
+static void i82801dx_power_options(device_t dev)
+{
+ u8 reg8;
+ u16 reg16, pmbase;
+ u32 reg32;
+ const char *state;
+
+ int pwr_on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ int nmi_option;
+
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ *
+ * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
+ */
+ if (get_option(&pwr_on, "power_on_after_fail") < 0)
+ pwr_on = MAINBOARD_POWER_ON;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ reg8 &= 0xfe;
+ switch (pwr_on) {
+ case MAINBOARD_POWER_OFF:
+ reg8 |= 1;
+ state = "off";
+ break;
+ case MAINBOARD_POWER_ON:
+ reg8 &= ~1;
+ state = "on";
+ break;
+ case MAINBOARD_POWER_KEEP:
+ reg8 &= ~1;
+ state = "state keep";
+ break;
+ default:
+ state = "undefined";
+ }
+
+ reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
+
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ printk(BIOS_INFO, "Set power %s after power failure.\n", state);
+
+ /* Set up NMI on errors. */
+ reg8 = inb(0x61);
+ reg8 &= 0x0f; /* Higher Nibble must be 0 */
+ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
+ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
+ reg8 |= (1 << 2); /* PCI SERR# Disable for now */
+ outb(reg8, 0x61);
+
+ reg8 = inb(0x70);
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ printk(BIOS_INFO, "NMI sources enabled.\n");
+ reg8 &= ~(1 << 7); /* Set NMI. */
+ } else {
+ printk(BIOS_INFO, "NMI sources disabled.\n");
+ reg8 |= ( 1 << 7); /* Disable NMI. */
+ }
+ outb(reg8, 0x70);
+
+ /* Set SMI# rate down and enable CPU_SLP# */
+ reg16 = pci_read_config16(dev, GEN_PMCON_1);
+ reg16 &= ~(3 << 0); // SMI# rate 1 minute
+ reg16 |= (1 << 5); // CPUSLP_EN Desktop only
+ pci_write_config16(dev, GEN_PMCON_1, reg16);
+
+ pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+
+ /* Set up power management block and determine sleep mode */
+ reg32 = inl(pmbase + 0x04); // PM1_CNT
+
+ reg32 &= ~(7 << 10); // SLP_TYP
+ reg32 |= (1 << 0); // SCI_EN
+ outl(reg32, pmbase + 0x04);
+}
+
+static void gpio_init(device_t dev)
+{
+ /* This should be done in romstage.c already */
+ pci_write_config32(dev, GPIO_BASE, (GPIOBASE_ADDR | 1));
+ pci_write_config8(dev, GPIO_CNTL, 0x10);
+}
+
+static void i82801dx_rtc_init(struct device *dev)
+{
+ u8 reg8;
+ u32 reg32;
+ int rtc_failed;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ rtc_failed = reg8 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ reg8 &= ~(1 << 1); /* Preserve the power fail state. */
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ }
+ reg32 = pci_read_config32(dev, GEN_STS);
+ rtc_failed |= reg32 & (1 << 2);
+ rtc_init(rtc_failed);
+
+ /* Enable access to the upper 128 byte bank of CMOS RAM. */
+ pci_write_config8(dev, RTC_CONF, 0x04);
+}
+
+static void i82801dx_lpc_route_dma(struct device *dev, u8 mask)
+{
+ u16 reg16;
+ int i;
+
+ reg16 = pci_read_config16(dev, PCI_DMA_CFG);
+ reg16 &= 0x300;
+ for (i = 0; i < 8; i++) {
+ if (i == 4)
+ continue;
+ reg16 |= ((mask & (1 << i)) ? 3 : 1) << (i * 2);
+ }
+ pci_write_config16(dev, PCI_DMA_CFG, reg16);
+}
+
+static void i82801dx_lpc_decode_en(device_t dev)
+{
+ /* Decode 0x3F8-0x3FF (COM1) for COMA port, 0x2F8-0x2FF (COM2) for COMB.
+ * LPT decode defaults to 0x378-0x37F and 0x778-0x77F.
+ * Floppy decode defaults to 0x3F0-0x3F5, 0x3F7.
+ * We also need to set the value for LPC I/F Enables Register.
+ */
+ pci_write_config8(dev, COM_DEC, 0x10);
+ pci_write_config16(dev, LPC_EN, 0x300F);
+}
+
+/* ICH4 does not mention HPET in the docs, but
+ * all ICH3 and ICH4 do have HPETs built in.
+ */
+static void enable_hpet(struct device *dev)
+{
+ u32 reg32, hpet, val;
+
+ /* Set HPET base address and enable it */
+ printk(BIOS_DEBUG, "Enabling HPET at 0x%x\n", HPET_ADDR);
+ reg32 = pci_read_config32(dev, GEN_CNTL);
+ /*
+ * Bit 17 is HPET enable bit.
+ * Bit 16:15 control the HPET base address.
+ */
+ reg32 &= ~(3 << 15); /* Clear it */
+
+ hpet = HPET_ADDR >> 12;
+ hpet &= 0x3;
+
+ reg32 |= (hpet << 15);
+ reg32 |= (1 << 17); /* Enable HPET. */
+ pci_write_config32(dev, GEN_CNTL, reg32);
+
+ /* Check to see whether it took */
+ reg32 = pci_read_config32(dev, GEN_CNTL);
+ val = reg32 >> 15;
+ val &= 0x7;
+
+ if ((val & 0x4) && (hpet == (val & 0x3))) {
+ printk(BIOS_INFO, "HPET enabled at 0x%x\n", HPET_ADDR);
+ } else {
+ printk(BIOS_WARNING, "HPET was not enabled correctly\n");
+ reg32 &= ~(1 << 17); /* Clear Enable */
+ pci_write_config32(dev, GEN_CNTL, reg32);
+ }
+}
+
+static void lpc_init(struct device *dev)
+{
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+
+ /* IO APIC initialization. */
+ i82801dx_enable_ioapic(dev);
+
+ i82801dx_enable_serial_irqs(dev);
+
+ /* Setup the PIRQ. */
+ i82801dx_pirq_init(dev);
+
+ /* Setup power options. */
+ i82801dx_power_options(dev);
+
+ /* Set the state of the GPIO lines. */
+ gpio_init(dev);
+
+ /* Initialize the real time clock. */
+ i82801dx_rtc_init(dev);
+
+ /* Route DMA. */
+ i82801dx_lpc_route_dma(dev, 0xff);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+ /* Setup decode ports and LPC I/F enables. */
+ i82801dx_lpc_decode_en(dev);
+
+ /* Initialize the High Precision Event Timers */
+ enable_hpet(dev);
+}
+
+static void i82801dx_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = i82801dx_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801dx_enable,
+};
+
+/* 82801DB/DBL */
+static const struct pci_driver lpc_driver_db __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_LPC,
+};
+
+/* 82801DBM */
+static const struct pci_driver lpc_driver_dbm __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DBM_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+typedef struct {
+ /* Miscellaneous */
+ u16 osys; /* 0x00 - Operating System */
+ u8 smif; /* 0x02 - SMI function call ("TRAP") */
+ u8 prm0; /* 0x03 - SMI function call parameter */
+ u8 prm1; /* 0x04 - SMI function call parameter */
+ u8 scif; /* 0x05 - SCI function call (via _L00) */
+ u8 prm2; /* 0x06 - SCI function call parameter */
+ u8 prm3; /* 0x07 - SCI function call parameter */
+ u8 lckf; /* 0x08 - Global Lock function for EC */
+ u8 prm4; /* 0x09 - Lock function parameter */
+ u8 prm5; /* 0x0a - Lock function parameter */
+ u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
+ u8 lids; /* 0x0f - LID state (open = 1) */
+ u8 pwrs; /* 0x10 - Power state (AC = 1) */
+ u8 dbgs; /* 0x11 - Debug state */
+ u8 linx; /* 0x12 - Linux OS */
+ u8 dckn; /* 0x13 - PCIe docking state */
+ /* Thermal policy */
+ u8 actt; /* 0x14 - active trip point */
+ u8 psvt; /* 0x15 - passive trip point */
+ u8 tc1v; /* 0x16 - passive trip point TC1 */
+ u8 tc2v; /* 0x17 - passive trip point TC2 */
+ u8 tspv; /* 0x18 - passive trip point TSP */
+ u8 crtt; /* 0x19 - critical trip point */
+ u8 dtse; /* 0x1a - Digital Thermal Sensor enable */
+ u8 dts1; /* 0x1b - DT sensor 1 */
+ u8 dts2; /* 0x1c - DT sensor 2 */
+ u8 rsvd2;
+ /* Battery Support */
+ u8 bnum; /* 0x1e - number of batteries */
+ u8 b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
+ u8 b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
+ u8 rsvd3[3];
+ /* Processor Identification */
+ u8 apic; /* 0x28 - APIC enabled */
+ u8 mpen; /* 0x29 - MP capable/enabled */
+ u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
+ u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
+ u8 ppcm; /* 0x2c - Max. PPC state */
+ u8 rsvd4[5];
+ /* Super I/O & CMOS config */
+ u8 natp; /* 0x32 - SIO type */
+ u8 cmap; /* 0x33 - */
+ u8 cmbp; /* 0x34 - */
+ u8 lptp; /* 0x35 - LPT port */
+ u8 fdcp; /* 0x36 - Floppy Disk Controller */
+ u8 rfdv; /* 0x37 - */
+ u8 hotk; /* 0x38 - Hot Key */
+ u8 rtcf;
+ u8 util;
+ u8 acin;
+ /* Integrated Graphics Device */
+ u8 igds; /* 0x3c - IGD state */
+ u8 tlst; /* 0x3d - Display Toggle List Pointer */
+ u8 cadl; /* 0x3e - currently attached devices */
+ u8 padl; /* 0x3f - previously attached devices */
+ u16 cste; /* 0x40 - current display state */
+ u16 nste; /* 0x42 - next display state */
+ u16 sste; /* 0x44 - set display state */
+ u8 ndid; /* 0x46 - number of device ids */
+ u32 did[5]; /* 0x47 - 5b device id 1..5 */
+ u8 rsvd5[0x9];
+ /* Backlight Control */
+ u8 blcs; /* 0x64 - Backlight Control possible */
+ u8 brtl;
+ u8 odds;
+ u8 rsvd6[0x7];
+ /* Ambient Light Sensors*/
+ u8 alse; /* 0x6e - ALS enable */
+ u8 alaf;
+ u8 llow;
+ u8 lhih;
+ u8 rsvd7[0x6];
+ /* EMA */
+ u8 emae; /* 0x78 - EMA enable */
+ u16 emap;
+ u16 emal;
+ u8 rsvd8[0x5];
+ /* MEF */
+ u8 mefe; /* 0x82 - MEF enable */
+ u8 rsvd9[0x9];
+ /* TPM support */
+ u8 tpmp; /* 0x8c - TPM */
+ u8 tpme;
+ u8 rsvd10[8];
+ /* SATA */
+ u8 gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
+ u8 gtf1[7];
+ u8 gtf2[7];
+ u8 idem;
+ u8 idet;
+ u8 rsvd11[7];
+ /* IGD OpRegion (not implemented yet) */
+ u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
+ u8 ibtt;
+ u8 ipat;
+ u8 itvf;
+ u8 itvm;
+ u8 ipsc;
+ u8 iblc;
+ u8 ibia;
+ u8 issc;
+ u8 i409;
+ u8 i509;
+ u8 i609;
+ u8 i709;
+ u8 idmm;
+ u8 idms;
+ u8 if1e;
+ u8 hvco;
+ u32 nxd[8];
+ u8 rsvd12[8];
+ /* Mainboard specific */
+ u8 dock; /* 0xf0 - Docking Status */
+ u8 bten;
+ u8 rsvd13[14];
+} __attribute__((packed)) global_nvs_t;
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void pci_init(struct device *dev)
+{
+ /* Enable pci error detecting */
+ uint32_t dword;
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* SERR# Enable */
+ dword |= (1 << 6); /* Parity Error Response */
+ pci_write_config32(dev, 0x04, dword);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+/* 82801DB */
+static const struct pci_driver pci_driver_db __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_PCI,
+};
+
+/* 82801DBM/DBL */
+static const struct pci_driver pci_driver_dbm __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DBM_PCI,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9 */
+ outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "i82801dx.h"
+#include <smbus.h>
+#include <pci.h>
+#include <arch/io.h>
+
+#define PM_BUS 0
+#define PM_DEVFN PCI_DEVFN(0x1f,3)
+
+void smbus_enable(void)
+{
+ unsigned char byte;
+ /* iobase addr */
+ pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x20, SMBUS_IO_BASE | 1);
+ /* smbus enable */
+ pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0x40, 1);
+ /* iospace enable */
+ pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+}
+
+void smbus_setup(void)
+{
+ outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static void smbus_wait_until_ready(void)
+{
+ while ((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
+ /* nop */
+ }
+}
+
+static void smbus_wait_until_done(void)
+{
+ unsigned char byte;
+ do {
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ while ((byte & 1) == 1);
+ while ((byte & ~1) == 0) {
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+}
+
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+ unsigned char host_status_register;
+ unsigned char byte;
+
+ smbus_wait_until_ready();
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte... */
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+
+ host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+ *result = byte;
+ return host_status_register != 0x02;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <string.h>
+#include "i82801dx.h"
+
+extern unsigned char _binary_smm_start;
+extern unsigned char _binary_smm_size;
+
+/* I945 */
+#define SMRAM 0x90
+#define D_OPEN (1 << 6)
+#define D_CLS (1 << 5)
+#define D_LCK (1 << 4)
+#define G_SMRAME (1 << 3)
+#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+
+/* While we read PMBASE dynamically in case it changed, let's
+ * initialize it with a sane value
+ */
+static u16 pmbase = PMBASE_ADDR;
+
+/**
+ * @brief read and clear PM1_STS
+ * @return PM1_STS register
+ */
+static u16 reset_pm1_status(void)
+{
+ u16 reg16;
+
+ reg16 = inw(pmbase + PM1_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outw(reg16, pmbase + PM1_STS);
+
+ return reg16;
+}
+
+static void dump_pm1_status(u16 pm1_sts)
+{
+ printk(BIOS_DEBUG, "PM1_STS: ");
+ if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
+ if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
+ if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
+ if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
+ if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
+ if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
+ if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
+ if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+/**
+ * @brief read and clear SMI_STS
+ * @return SMI_STS register
+ */
+static u32 reset_smi_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + SMI_STS);
+
+ return reg32;
+}
+
+static void dump_smi_status(u32 smi_sts)
+{
+ printk(BIOS_DEBUG, "SMI_STS: ");
+ if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
+ if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
+ if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
+ if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
+ if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
+ if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
+ if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
+ if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
+ if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
+ if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
+ if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
+ if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
+ if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
+ if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
+ if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
+ if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
+ if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
+ if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
+ if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
+ if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear GPE0_STS
+ * @return GPE0_STS register
+ */
+static u32 reset_gpe0_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + GPE0_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + GPE0_STS);
+
+ return reg32;
+}
+
+static void dump_gpe0_status(u32 gpe0_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ for (i=31; i<= 16; i--) {
+ if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
+ }
+ if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
+ if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
+ if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
+ if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
+ if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
+ if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
+ if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
+ if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
+ if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
+ if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
+ if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
+ if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
+ if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
+ if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear ALT_GP_SMI_STS
+ * @return ALT_GP_SMI_STS register
+ */
+static u16 reset_alt_gp_smi_status(void)
+{
+ u16 reg16;
+
+ reg16 = inl(pmbase + ALT_GP_SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg16, pmbase + ALT_GP_SMI_STS);
+
+ return reg16;
+}
+
+static void dump_alt_gp_smi_status(u16 alt_gp_smi_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "ALT_GP_SMI_STS: ");
+ for (i=15; i<= 0; i--) {
+ if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", (i-16));
+ }
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+
+/**
+ * @brief read and clear TCOx_STS
+ * @return TCOx_STS registers
+ */
+static u32 reset_tco_status(void)
+{
+ u32 tcobase = pmbase + 0x60;
+ u32 reg32;
+
+ reg32 = inl(tcobase + 0x04);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
+ if (reg32 & (1 << 18))
+ outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
+
+ return reg32;
+}
+
+
+static void dump_tco_status(u32 tco_sts)
+{
+ printk(BIOS_DEBUG, "TCO_STS: ");
+ if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
+ if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
+ if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
+ if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
+ if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
+ if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
+ if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
+ if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
+ if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
+ if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
+ if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
+ if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
+ if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+
+/**
+ * @brief Set the EOS bit
+ */
+static void smi_set_eos(void)
+{
+ u8 reg8;
+
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 |= EOS;
+ outb(reg8, pmbase + SMI_EN);
+}
+
+extern uint8_t smm_relocation_start, smm_relocation_end;
+
+static void smm_relocate(void)
+{
+ u32 smi_en;
+ u16 pm1_en;
+
+ printk(BIOS_DEBUG, "Initializing SMM handler...");
+
+ pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), 0x40) & 0xfffc;
+ printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);
+
+ smi_en = inl(pmbase + SMI_EN);
+ if (smi_en & APMC_EN) {
+ printk(BIOS_INFO, "SMI# handler already enabled?\n");
+ return;
+ }
+
+ /* copy the SMM relocation code */
+ memcpy((void *)0x38000, &smm_relocation_start,
+ &smm_relocation_end - &smm_relocation_start);
+
+ printk(BIOS_DEBUG, "\n");
+ dump_smi_status(reset_smi_status());
+ dump_pm1_status(reset_pm1_status());
+ dump_gpe0_status(reset_gpe0_status());
+ dump_alt_gp_smi_status(reset_alt_gp_smi_status());
+ dump_tco_status(reset_tco_status());
+
+ /* Enable SMI generation:
+ * - on TCO events
+ * - on APMC writes (io 0xb2)
+ * - on writes to SLP_EN (sleep states)
+ * - on writes to GBL_RLS (bios commands)
+ * No SMIs:
+ * - on microcontroller writes (io 0x62/0x66)
+ */
+
+ smi_en = 0; /* reset SMI enables */
+
+#if 0
+ smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN;
+#endif
+ smi_en |= TCO_EN;
+ smi_en |= APMC_EN;
+#if DEBUG_PERIODIC_SMIS
+ /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
+ * periodic SMIs.
+ */
+ smi_en |= PERIODIC_EN;
+#endif
+ smi_en |= SLP_SMI_EN;
+ smi_en |= BIOS_EN;
+
+ /* The following need to be on for SMIs to happen */
+ smi_en |= EOS | GBL_SMI_EN;
+
+ outl(smi_en, pmbase + SMI_EN);
+
+ pm1_en = 0;
+ pm1_en |= PWRBTN_EN;
+ pm1_en |= GBL_EN;
+ outw(pm1_en, pmbase + PM1_EN);
+
+ /**
+ * There are several methods of raising a controlled SMI# via
+ * software, among them:
+ * - Writes to io 0xb2 (APMC)
+ * - Writes to the Local Apic ICR with Delivery mode SMI.
+ *
+ * Using the local apic is a bit more tricky. According to
+ * AMD Family 11 Processor BKDG no destination shorthand must be
+ * used.
+ * The whole SMM initialization is quite a bit hardware specific, so
+ * I'm not too worried about the better of the methods at the moment
+ */
+
+ /* raise an SMI interrupt */
+ printk(BIOS_SPEW, " ... raise SMI#\n");
+ outb(0x00, 0xb2);
+}
+
+static void smm_install(void)
+{
+ /* enable the SMM memory window */
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ D_OPEN | G_SMRAME | C_BASE_SEG);
+
+ /* copy the real SMM handler */
+ memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
+ wbinvd();
+
+ /* close the SMM memory window and enable normal SMM */
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ G_SMRAME | C_BASE_SEG);
+}
+
+void smm_init(void)
+{
+ /* Put SMM code to 0xa0000 */
+ smm_install();
+
+ /* Put relocation code to 0x38000 and relocate SMBASE */
+ smm_relocate();
+
+ /* We're done. Make sure SMIs can happen! */
+ smi_set_eos();
+}
+
+void smm_lock(void)
+{
+ /* LOCK the SMM memory window and enable normal SMM.
+ * After running this function, only a full reset can
+ * make the SMM registers writable again.
+ */
+ printk(BIOS_DEBUG, "Locking SMM.\n");
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ D_LCK | G_SMRAME | C_BASE_SEG);
+}
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+ /* The GDT or coreboot table is going to live here. But a long time
+ * after we relocated the GNVS, so this is not troublesome.
+ */
+ *(u32 *)0x500 = (u32)gnvs;
+ *(u32 *)0x504 = (u32)tcg;
+ *(u32 *)0x508 = (u32)smi1;
+ outb(0xea, 0xb2);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <device/pci_def.h>
+#include "i82801dx.h"
+
+#define DEBUG_SMI
+
+#define APM_CNT 0xb2
+#define CST_CONTROL 0x85
+#define PST_CONTROL 0x80
+#define ACPI_DISABLE 0x1e
+#define ACPI_ENABLE 0xe1
+#define GNVS_UPDATE 0xea
+#define MBI_UPDATE 0xeb
+#define APM_STS 0xb3
+
+/* I830M */
+#define SMRAM 0x90
+#define D_OPEN (1 << 6)
+#define D_CLS (1 << 5)
+#define D_LCK (1 << 4)
+#define G_SMRANE (1 << 3)
+#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+
+#include "nvs.h"
+
+/* While we read PMBASE dynamically in case it changed, let's
+ * initialize it with a sane value
+ */
+u16 pmbase = PMBASE_ADDR;
+u8 smm_initialized = 0;
+
+unsigned char *mbi = NULL;
+u32 mbi_len;
+u8 mbi_initialized = 0;
+
+/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+global_nvs_t *gnvs = (global_nvs_t *)0x0;
+void *tcg = (void *)0x0;
+void *smi1 = (void *)0x0;
+
+/**
+ * @brief read and clear PM1_STS
+ * @return PM1_STS register
+ */
+static u16 reset_pm1_status(void)
+{
+ u16 reg16;
+
+ reg16 = inw(pmbase + PM1_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outw(reg16, pmbase + PM1_STS);
+
+ return reg16;
+}
+
+static void dump_pm1_status(u16 pm1_sts)
+{
+ printk(BIOS_SPEW, "PM1_STS: ");
+ if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK ");
+ if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK ");
+ if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR ");
+ if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC ");
+ if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN ");
+ if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL ");
+ if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM ");
+ if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF ");
+ printk(BIOS_SPEW, "\n");
+ int reg16 = inw(pmbase + PM1_EN);
+ printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
+}
+
+/**
+ * @brief read and clear SMI_STS
+ * @return SMI_STS register
+ */
+static u32 reset_smi_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + SMI_STS);
+
+ return reg32;
+}
+
+static void dump_smi_status(u32 smi_sts)
+{
+ printk(BIOS_DEBUG, "SMI_STS: ");
+ if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
+ if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
+ if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
+ if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
+ if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
+ if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
+ if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
+ if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
+ if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
+ if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
+ if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
+ if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
+ if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
+ if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
+ if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
+ if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
+ if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
+ if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
+ if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
+ if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear GPE0_STS
+ * @return GPE0_STS register
+ */
+static u32 reset_gpe0_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + GPE0_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + GPE0_STS);
+
+ return reg32;
+}
+
+static void dump_gpe0_status(u32 gpe0_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ for (i=31; i<= 16; i--) {
+ if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
+ }
+ if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
+ if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
+ if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
+ if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
+ if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
+ if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
+ if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
+ if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
+ if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
+ if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
+ if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
+ if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
+ if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
+ if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear TCOx_STS
+ * @return TCOx_STS registers
+ */
+static u32 reset_tco_status(void)
+{
+ u32 tcobase = pmbase + 0x60;
+ u32 reg32;
+
+ reg32 = inl(tcobase + 0x04);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
+ if (reg32 & (1 << 18))
+ outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
+
+ return reg32;
+}
+
+
+static void dump_tco_status(u32 tco_sts)
+{
+ printk(BIOS_DEBUG, "TCO_STS: ");
+ if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
+ if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
+ if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
+ if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
+ if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
+ if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
+ if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
+ if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
+ if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
+ if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
+ if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
+ if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
+ if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+/* We are using PCIe accesses for now
+ * 1. the chipset can do it
+ * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
+ */
+// #include "../../../northbridge/intel/i945/pcie_config.c"
+
+int southbridge_io_trap_handler(int smif)
+{
+ switch (smif) {
+ case 0x32:
+ printk(BIOS_DEBUG, "OS Init\n");
+ /* gnvs->smif:
+ * On success, the IO Trap Handler returns 0
+ * On failure, the IO Trap Handler returns a value != 0
+ */
+ gnvs->smif = 0;
+ return 1; /* IO trap handled */
+ }
+
+ /* Not handled */
+ return 0;
+}
+
+/**
+ * @brief Set the EOS bit
+ */
+void southbridge_smi_set_eos(void)
+{
+ u8 reg8;
+
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 |= EOS;
+ outb(reg8, pmbase + SMI_EN);
+}
+
+static void busmaster_disable_on_bus(int bus)
+{
+ int slot, func;
+ unsigned int val;
+ unsigned char hdr;
+
+ for (slot = 0; slot < 0x20; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 reg32;
+ device_t dev = PCI_DEV(bus, slot, func);
+
+ val = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ if (val == 0xffffffff || val == 0x00000000 ||
+ val == 0x0000ffff || val == 0xffff0000)
+ continue;
+
+ /* Disable Bus Mastering for this one device */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 &= ~PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* If this is a bridge, then follow it. */
+ hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
+ hdr &= 0x7f;
+ if (hdr == PCI_HEADER_TYPE_BRIDGE ||
+ hdr == PCI_HEADER_TYPE_CARDBUS) {
+ unsigned int buses;
+ buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+ busmaster_disable_on_bus((buses >> 8) & 0xff);
+ }
+ }
+ }
+}
+
+
+static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u8 reg8;
+ u32 reg32;
+ u8 slp_typ;
+ /* FIXME: the power state on boot should be read from
+ * CMOS or even better from GNVS. Right now it's hard
+ * coded at compile time.
+ */
+ u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /* First, disable further SMIs */
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 &= ~SLP_SMI_EN;
+ outb(reg8, pmbase + SMI_EN);
+
+ /* Figure out SLP_TYP */
+ reg32 = inl(pmbase + PM1_CNT);
+ printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
+ slp_typ = (reg32 >> 10) & 7;
+
+ /* Next, do the deed.
+ */
+
+ switch (slp_typ) {
+ case 0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
+ case 1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
+ case 5:
+ printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+ /* Invalidate the cache before going to S3 */
+ wbinvd();
+ break;
+ case 6: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
+ case 7:
+ printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+
+ outl(0, pmbase + GPE0_EN);
+
+ /* Should we keep the power state after a power loss?
+ * In case the setting is "ON" or "OFF" we don't have
+ * to do anything. But if it's "KEEP" we have to switch
+ * to "OFF" before entering S5.
+ */
+ if (s5pwr == MAINBOARD_POWER_KEEP) {
+ reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
+ reg8 |= 1;
+ pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
+ }
+
+ /* also iterates over all bridges on bus 0 */
+ busmaster_disable_on_bus(0);
+ break;
+ default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
+ }
+
+ /* Write back to the SLP register to cause the originally intended
+ * event again. We need to set BIT13 (SLP_EN) though to make the
+ * sleep happen.
+ */
+ outl(reg32 | SLP_EN, pmbase + PM1_CNT);
+
+ /* In most sleep states, the code flow of this function ends at
+ * the line above. However, if we entered sleep state S1 and wake
+ * up again, we will continue to execute code in this function.
+ */
+ reg32 = inl(pmbase + PM1_CNT);
+ if (reg32 & SCI_EN) {
+ /* The OS is not an ACPI OS, so we set the state to S0 */
+ reg32 &= ~(SLP_EN | SLP_TYP);
+ outl(reg32, pmbase + PM1_CNT);
+ }
+}
+
+static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 pmctrl;
+ u8 reg8;
+
+ /* Emulate B2 register as the FADT / Linux expects it */
+
+ reg8 = inb(APM_CNT);
+ switch (reg8) {
+ case CST_CONTROL:
+ /* Calling this function seems to cause
+ * some kind of race condition in Linux
+ * and causes a kernel oops
+ */
+ printk(BIOS_DEBUG, "C-state control\n");
+ break;
+ case PST_CONTROL:
+ /* Calling this function seems to cause
+ * some kind of race condition in Linux
+ * and causes a kernel oops
+ */
+ printk(BIOS_DEBUG, "P-state control\n");
+ break;
+ case ACPI_DISABLE:
+ pmctrl = inl(pmbase + PM1_CNT);
+ pmctrl &= ~SCI_EN;
+ outl(pmctrl, pmbase + PM1_CNT);
+ printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
+ break;
+ case ACPI_ENABLE:
+ pmctrl = inl(pmbase + PM1_CNT);
+ pmctrl |= SCI_EN;
+ outl(pmctrl, pmbase + PM1_CNT);
+ printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
+ break;
+ case GNVS_UPDATE:
+ if (smm_initialized) {
+ printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
+ return;
+ }
+ gnvs = *(global_nvs_t **)0x500;
+ tcg = *(void **)0x504;
+ smi1 = *(void **)0x508;
+ smm_initialized = 1;
+ printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
+ break;
+ case MBI_UPDATE: // FIXME
+ if (mbi_initialized) {
+ printk(BIOS_DEBUG, "SMI#: mbi already registered!\n");
+ return;
+ }
+ mbi = *(void **)0x500;
+ mbi_len = *(u32 *)0x504;
+ mbi_initialized = 1;
+ printk(BIOS_DEBUG, "SMI#: Registered MBI at %p (%d bytes)\n", mbi, mbi_len);
+ break;
+
+ default:
+ printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);
+ }
+}
+
+static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u16 pm1_sts;
+
+ pm1_sts = reset_pm1_status();
+ dump_pm1_status(pm1_sts);
+
+ /* While OSPM is not active, poweroff immediately
+ * on a power button event.
+ */
+ if (pm1_sts & PWRBTN_STS) {
+ // power button pressed
+ u32 reg32;
+ reg32 = (7 << 10) | (1 << 13);
+ outl(reg32, pmbase + PM1_CNT);
+ }
+}
+
+static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 gpe0_sts;
+
+ gpe0_sts = reset_gpe0_status();
+ dump_gpe0_status(gpe0_sts);
+}
+
+static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u16 reg16;
+ reg16 = inw(pmbase + ALT_GP_SMI_STS);
+ outl(reg16, pmbase + ALT_GP_SMI_STS);
+
+ reg16 &= inw(pmbase + ALT_GP_SMI_EN);
+
+ if (mainboard_smi_gpi) {
+ mainboard_smi_gpi(reg16);
+ } else {
+ if (reg16)
+ printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16);
+ }
+}
+
+static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_EN);
+
+ /* Are periodic SMIs enabled? */
+ if ((reg32 & MCSMI_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Microcontroller SMI.\n");
+}
+
+
+
+static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 tco_sts;
+
+ tco_sts = reset_tco_status();
+
+ /* Any TCO event? */
+ if (!tco_sts)
+ return;
+
+ if (tco_sts & (1 << 8)) { // BIOSWR
+ u8 bios_cntl;
+
+ bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
+
+ if (bios_cntl & 1) {
+ /* BWE is RW, so the SMI was caused by a
+ * write to BWE, not by a write to the BIOS
+ */
+
+ /* This is the place where we notice someone
+ * is trying to tinker with the BIOS. We are
+ * trying to be nice and just ignore it. A more
+ * resolute answer would be to power down the
+ * box.
+ */
+ printk(BIOS_DEBUG, "Switching back to RO\n");
+ pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
+ } /* No else for now? */
+ } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+ /* Handle TCO timeout */
+ printk(BIOS_DEBUG, "TCO Timeout.\n");
+ } else if (!tco_sts) {
+ dump_tco_status(tco_sts);
+ }
+}
+
+static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_EN);
+
+ /* Are periodic SMIs enabled? */
+ if ((reg32 & PERIODIC_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+#if 0
+ u32 trap_sts, trap_cycle;
+ u32 data, mask = 0;
+ int i;
+
+ trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
+ RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
+
+ trap_cycle = RCBA32(0x1e10);
+ for (i=16; i<20; i++) {
+ if (trap_cycle & (1 << i))
+ mask |= (0xff << ((i - 16) << 2));
+ }
+
+
+ /* IOTRAP(3) SMI function call */
+ if (IOTRAP(3)) {
+ if (gnvs && gnvs->smif)
+ io_trap_handler(gnvs->smif); // call function smif
+ return;
+ }
+
+ /* IOTRAP(2) currently unused
+ * IOTRAP(1) currently unused */
+
+ /* IOTRAP(0) SMIC */
+ if (IOTRAP(0)) {
+ if (!(trap_cycle & (1 << 24))) { // It's a write
+ printk(BIOS_DEBUG, "SMI1 command\n");
+ data = RCBA32(0x1e18);
+ data &= mask;
+ // if (smi1)
+ // southbridge_smi_command(data);
+ // return;
+ }
+ // Fall through to debug
+ }
+
+ printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc);
+ for (i=0; i < 4; i++) if(IOTRAP(i)) printk(BIOS_DEBUG, " TRAPÂ = %d\n", i);
+ printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+ printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
+ printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
+
+ if (!(trap_cycle & (1 << 24))) {
+ /* Write Cycle */
+ data = RCBA32(0x1e18);
+ printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
+ }
+#endif
+#undef IOTRAP
+}
+
+typedef void (*smi_handler_t)(unsigned int node,
+ smm_state_save_area_t *state_save);
+
+smi_handler_t southbridge_smi[32] = {
+ NULL, // [0] reserved
+ NULL, // [1] reserved
+ NULL, // [2] BIOS_STS
+ NULL, // [3] LEGACY_USB_STS
+ southbridge_smi_sleep, // [4] SLP_SMI_STS
+ southbridge_smi_apmc, // [5] APM_STS
+ NULL, // [6] SWSMI_TMR_STS
+ NULL, // [7] reserved
+ southbridge_smi_pm1, // [8] PM1_STS
+ southbridge_smi_gpe0, // [9] GPE0_STS
+ southbridge_smi_gpi, // [10] GPI_STS
+ southbridge_smi_mc, // [11] MCSMI_STS
+ NULL, // [12] DEVMON_STS
+ southbridge_smi_tco, // [13] TCO_STS
+ southbridge_smi_periodic, // [14] PERIODIC_STS
+ NULL, // [15] SERIRQ_SMI_STS
+ NULL, // [16] SMBUS_SMI_STS
+ NULL, // [17] LEGACY_USB2_STS
+ NULL, // [18] INTEL_USB2_STS
+ NULL, // [19] reserved
+ NULL, // [20] PCI_EXP_SMI_STS
+ southbridge_smi_monitor, // [21] MONITOR_STS
+ NULL, // [22] reserved
+ NULL, // [23] reserved
+ NULL, // [24] reserved
+ NULL, // [25] EL_SMI_STS
+ NULL, // [26] SPI_STS
+ NULL, // [27] reserved
+ NULL, // [28] reserved
+ NULL, // [29] reserved
+ NULL, // [30] reserved
+ NULL // [31] reserved
+};
+
+/**
+ * @brief Interrupt handler for SMI#
+ *
+ * @param smm_revision revision of the smm state save map
+ */
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+ int i, dump = 0;
+ u32 smi_sts;
+
+ /* Update global variable pmbase */
+ pmbase = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+
+ /* We need to clear the SMI status registers, or we won't see what's
+ * happening in the following calls.
+ */
+ smi_sts = reset_smi_status();
+
+ /* Filter all non-enabled SMI events */
+ // FIXME Double check, this clears MONITOR
+ // smi_sts &= inl(pmbase + SMI_EN);
+
+ /* Call SMI sub handler for each of the status bits */
+ for (i = 0; i < 31; i++) {
+ if (smi_sts & (1 << i)) {
+ if (southbridge_smi[i])
+ southbridge_smi[i](node, state_save);
+ else {
+ printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no "
+ "handler available.\n", i);
+ dump = 1;
+ }
+ }
+ }
+
+ if(dump) {
+ dump_smi_status(smi_sts);
+ }
+
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Joseph Smith <joe@settoplinux.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+static void i82801dx_halt_tco_timer(void)
+{
+ /* Set the LPC device statically. */
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x0);
+
+ /* Temporarily set ACPI base address (I/O space). */
+ pci_write_config32(dev, PMBASE, (PMBASE_ADDR | 1));
+
+ /* Enable ACPI I/O. */
+ pci_write_config8(dev, ACPI_CNTL, 0x10);
+
+ /* Halt the TCO timer, preventing SMI and automatic reboot */
+ outw(inw(PMBASE_ADDR + TCOBASE + TCO1_CNT) | (1 << 11),
+ PMBASE_ADDR + TCOBASE + TCO1_CNT);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Ronald G. Minnich
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void usb_init(struct device *dev)
+{
+ u32 cmd;
+ printk(BIOS_DEBUG, "USB: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = i82801dx_enable,
+};
+
+/* 82801DB/DBL/DBM USB1 */
+static const struct pci_driver usb_driver_1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_USB1,
+};
+
+/* 82801DB/DBL/DBM USB2 */
+static const struct pci_driver usb_driver_2 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_USB2,
+};
+
+/* 82801DB/DBL/DBM USB3 */
+static const struct pci_driver usb_driver_3 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_USB3,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Tyan
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801dx.h"
+
+static void usb2_init(struct device *dev)
+{
+ u32 cmd;
+ printk(BIOS_DEBUG, "USB: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static struct device_operations usb2_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb2_init,
+ .scan_bus = 0,
+ .enable = i82801dx_enable,
+};
+
+/* 82801DB/DBM USB 2.0 */
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801DB_EHCI,
+};
driver-y += i82801ex.c
-driver-y += i82801ex_uhci.c
-driver-y += i82801ex_lpc.c
-driver-y += i82801ex_ide.c
-driver-y += i82801ex_sata.c
-driver-y += i82801ex_ehci.c
-driver-y += i82801ex_smbus.c
-driver-y += i82801ex_pci.c
-driver-y += i82801ex_ac97.c
-ramstage-y += i82801ex_watchdog.c
-ramstage-y += i82801ex_reset.c
+driver-y += uhci.c
+driver-y += lpc.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += ehci.c
+driver-y += smbus.c
+driver-y += pci.c
+driver-y += ac97.c
+ramstage-y += watchdog.c
+ramstage-y += reset.c
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = ac97_set_subsystem,
+};
+static struct device_operations ac97_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .enable = i82801ex_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ac97_audio_driver __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_AUDIO,
+};
+static const struct pci_driver ac97_modem_driver __pci_driver = {
+ .ops = &ac97_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_MODEM,
+};
--- /dev/null
+#include "smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+ device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ print_spew("SMBus controller enabled\n");
+
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ print_debug_hex32(pci_read_config32(dev, 0x20));
+ /* Set smbus enable */
+ pci_write_config8(dev, 0x40, 1);
+ /* Set smbus iospace enable */
+ pci_write_config8(dev, 0x4, 1);
+ /* SMBALERT_DIS */
+ pci_write_config8(dev, 0x11, 4);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+}
+
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+#ifdef UNUSED_CODE
+static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+ return;
+ }
+
+ print_debug("Unimplemented smbus_write_byte() called.\n");
+
+#if 0
+ /* setup transaction */
+ /* disable interrupts */
+ outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)),
+ SMBUS_IO_BASE + SMBGCTL);
+ /* set the device I'm talking too */
+ outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR);
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data write */ /* FIXME */
+ outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL);
+ /* clear any lingering errors, so the transaction will run */
+ /* Do I need to write the bits to a 1 to clear an error? */
+ outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
+
+ /* clear the data word...*/
+ outw(val, SMBUS_IO_BASE + SMBHSTDAT);
+
+ /* start the command */
+ outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done(SMBUS_IO_BASE);
+#endif
+ return;
+}
+
+static int smbus_write_block(unsigned device, unsigned length, unsigned cmd,
+ unsigned data1, unsigned data2)
+{
+ unsigned char byte;
+ unsigned char stat;
+ int i;
+
+ /* chear the PM timeout flags, SECOND_TO_STS */
+ outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
+
+ if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
+ return -2;
+ }
+
+ /* setup transaction */
+ /* Obtain ownership */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+ for(stat=0;(stat&0x40)==0;) {
+ stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ /* clear the done bit */
+ outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
+
+ /* set the command address */
+ outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+
+ /* set the block length */
+ outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* try sending out the first byte of data here */
+ byte=(data1>>(0))&0x0ff;
+ outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+ /* issue a block write command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40,
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ for(i=0;i<length;i++) {
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
+ return -3;
+ }
+
+ /* load the next byte */
+ if(i>3)
+ byte=(data2>>(i%4))&0x0ff;
+ else
+ byte=(data1>>(i))&0x0ff;
+ outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
+
+ /* clear the done bit */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
+ SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+
+ print_debug("SMBUS Block complete\n");
+ return 0;
+}
+#endif
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void ehci_init(struct device *dev)
+{
+ uint32_t cmd;
+
+ printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_MASTER);
+
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ uint8_t access_cntl;
+ access_cntl = pci_read_config8(dev, 0x80);
+ /* Enable writes to protected registers */
+ pci_write_config8(dev, 0x80, access_cntl | 1);
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ /* Restore protection */
+ pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ehci_init,
+ .scan_bus = 0,
+ .enable = i82801ex_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ehci_driver __pci_driver = {
+ .ops = &ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_EHCI,
+};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* Write the subsystem vendor and device id */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = ac97_set_subsystem,
-};
-static struct device_operations ac97_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .enable = i82801ex_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ac97_audio_driver __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_AUDIO,
-};
-static const struct pci_driver ac97_modem_driver __pci_driver = {
- .ops = &ac97_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_AC97_MODEM,
-};
+++ /dev/null
-#include "i82801ex_smbus.h"
-
-#define SMBUS_IO_BASE 0x0f00
-
-static void enable_smbus(void)
-{
- device_t dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- print_spew("SMBus controller enabled\n");
-
- pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
- print_debug_hex32(pci_read_config32(dev, 0x20));
- /* Set smbus enable */
- pci_write_config8(dev, 0x40, 1);
- /* Set smbus iospace enable */
- pci_write_config8(dev, 0x4, 1);
- /* SMBALERT_DIS */
- pci_write_config8(dev, 0x11, 4);
-
- /* Disable interrupt generation */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-}
-
-static int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
-#ifdef UNUSED_CODE
-static void smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
- return;
- }
-
- print_debug("Unimplemented smbus_write_byte() called.\n");
-
-#if 0
- /* setup transaction */
- /* disable interrupts */
- outw(inw(SMBUS_IO_BASE + SMBGCTL) & ~((1<<10)|(1<<9)|(1<<8)|(1<<4)),
- SMBUS_IO_BASE + SMBGCTL);
- /* set the device I'm talking too */
- outw(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADDR);
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data write */ /* FIXME */
- outw((inw(SMBUS_IO_BASE + SMBGCTL) & ~7) | (0x1), SMBUS_IO_BASE + SMBGCTL);
- /* clear any lingering errors, so the transaction will run */
- /* Do I need to write the bits to a 1 to clear an error? */
- outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS);
-
- /* clear the data word...*/
- outw(val, SMBUS_IO_BASE + SMBHSTDAT);
-
- /* start the command */
- outw((inw(SMBUS_IO_BASE + SMBGCTL) | (1 << 3)), SMBUS_IO_BASE + SMBGCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done(SMBUS_IO_BASE);
-#endif
- return;
-}
-
-static int smbus_write_block(unsigned device, unsigned length, unsigned cmd,
- unsigned data1, unsigned data2)
-{
- unsigned char byte;
- unsigned char stat;
- int i;
-
- /* chear the PM timeout flags, SECOND_TO_STS */
- outw(inw(0x0400 + 0x66), 0x0400 + 0x66);
-
- if (smbus_wait_until_ready(SMBUS_IO_BASE) < 0) {
- return -2;
- }
-
- /* setup transaction */
- /* Obtain ownership */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- for(stat=0;(stat&0x40)==0;) {
- stat = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- }
- /* clear the done bit */
- outb(0x80, SMBUS_IO_BASE + SMBHSTSTAT);
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1), SMBUS_IO_BASE + SMBXMITADD);
-
- /* set the command address */
- outb(cmd & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
-
- /* set the block length */
- outb(length & 0xFF, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* try sending out the first byte of data here */
- byte=(data1>>(0))&0x0ff;
- outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
- /* issue a block write command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x5 << 2) | 0x40,
- SMBUS_IO_BASE + SMBHSTCTL);
-
- for(i=0;i<length;i++) {
-
- /* poll for transaction completion */
- if (smbus_wait_until_blk_done(SMBUS_IO_BASE) < 0) {
- return -3;
- }
-
- /* load the next byte */
- if(i>3)
- byte=(data2>>(i%4))&0x0ff;
- else
- byte=(data1>>(i))&0x0ff;
- outb(byte,SMBUS_IO_BASE + SMBBLKDAT);
-
- /* clear the done bit */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT),
- SMBUS_IO_BASE + SMBHSTSTAT);
- }
-
- print_debug("SMBUS Block complete\n");
- return 0;
-}
-#endif
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void ehci_init(struct device *dev)
-{
- uint32_t cmd;
-
- printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
-
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- uint8_t access_cntl;
- access_cntl = pci_read_config8(dev, 0x80);
- /* Enable writes to protected registers */
- pci_write_config8(dev, 0x80, access_cntl | 1);
- /* Write the subsystem vendor and device id */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- /* Restore protection */
- pci_write_config8(dev, 0x80, access_cntl);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &ehci_set_subsystem,
-};
-static struct device_operations ehci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ehci_init,
- .scan_bus = 0,
- .enable = i82801ex_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ehci_driver __pci_driver = {
- .ops = &ehci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_EHCI,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void ide_init(struct device *dev)
-{
- /* Enable IDE devices and timmings */
- pci_write_config16(dev, 0x40, 0x0a307); // IDE0
- pci_write_config16(dev, 0x42, 0x0a307); // IDE1
- pci_write_config8(dev, 0x48, 0x05);
- pci_write_config16(dev, 0x4a, 0x0101);
- pci_write_config16(dev, 0x54, 0x5055);
- printk(BIOS_DEBUG, "IDE Enabled\n");
-}
-
-static void i82801ex_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* This value is also visible in uchi[0-2] and smbus functions */
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = i82801ex_ide_set_subsystem,
-};
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_IDE,
-};
-
+++ /dev/null
-/*
- * (C) 2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801ex.h"
-
-#define ACPI_BAR 0x40
-#define GPIO_BAR 0x58
-
-#define NMI_OFF 0
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#define SERIRQ_CNTL 0x64
-static void i82801ex_enable_serial_irqs(device_t dev)
-{
- /* set packet length and toggle silent mode bit */
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
- pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
-}
-
-#define PCI_DMA_CFG 0x90
-static void i82801ex_pci_dma_cfg(device_t dev)
-{
- /* Set PCI DMA CFG to lpc I/F DMA */
- pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
-}
-
-#define LPC_EN 0xe6
-static void i82801ex_enable_lpc(device_t dev)
-{
- /* lpc i/f enable */
- pci_write_config8(dev, LPC_EN, 0x0d);
-}
-
-typedef struct southbridge_intel_i82801ex_config config_t;
-
-static void set_i82801ex_gpio_use_sel(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_use_sel, gpio_use_sel2;
- int i;
-
- gpio_use_sel = 0x1A003180;
- gpio_use_sel2 = 0x00000007;
- for(i = 0; i < 64; i++) {
- int val;
- switch(config->gpio[i] & ICH5R_GPIO_USE_MASK) {
- case ICH5R_GPIO_USE_AS_NATIVE: val = 0; break;
- case ICH5R_GPIO_USE_AS_GPIO: val = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_use_sel &= ~( 1 << i);
- gpio_use_sel |= (val << i);
- } else {
- gpio_use_sel2 &= ~( 1 << (i - 32));
- gpio_use_sel2 |= (val << (i - 32));
- }
- }
- outl(gpio_use_sel, res->base + 0x00);
- outl(gpio_use_sel2, res->base + 0x30);
-}
-
-static void set_i82801ex_gpio_direction(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_io_sel, gpio_io_sel2;
- int i;
-
- gpio_io_sel = 0x0000ffff;
- gpio_io_sel2 = 0x00000300;
- for(i = 0; i < 64; i++) {
- int val;
- switch(config->gpio[i] & ICH5R_GPIO_SEL_MASK) {
- case ICH5R_GPIO_SEL_OUTPUT: val = 0; break;
- case ICH5R_GPIO_SEL_INPUT: val = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_io_sel &= ~( 1 << i);
- gpio_io_sel |= (val << i);
- } else {
- gpio_io_sel2 &= ~( 1 << (i - 32));
- gpio_io_sel2 |= (val << (i - 32));
- }
- }
- outl(gpio_io_sel, res->base + 0x04);
- outl(gpio_io_sel2, res->base + 0x34);
-}
-
-static void set_i82801ex_gpio_level(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_lvl, gpio_lvl2;
- uint32_t gpio_blink;
- int i;
-
- gpio_lvl = 0x1b3f0000;
- gpio_blink = 0x00040000;
- gpio_lvl2 = 0x00030207;
- for(i = 0; i < 64; i++) {
- int val, blink;
- switch(config->gpio[i] & ICH5R_GPIO_LVL_MASK) {
- case ICH5R_GPIO_LVL_LOW: val = 0; blink = 0; break;
- case ICH5R_GPIO_LVL_HIGH: val = 1; blink = 0; break;
- case ICH5R_GPIO_LVL_BLINK: val = 1; blink = 1; break;
- default:
- continue;
- }
- /* The caller is responsible for not playing with unimplemented bits */
- if (i < 32) {
- gpio_lvl &= ~( 1 << i);
- gpio_blink &= ~( 1 << i);
- gpio_lvl |= ( val << i);
- gpio_blink |= (blink << i);
- } else {
- gpio_lvl2 &= ~( 1 << (i - 32));
- gpio_lvl2 |= (val << (i - 32));
- }
- }
- outl(gpio_lvl, res->base + 0x0c);
- outl(gpio_blink, res->base + 0x18);
- outl(gpio_lvl2, res->base + 0x38);
-}
-
-static void set_i82801ex_gpio_inv(
- device_t dev, struct resource *res, config_t *config)
-{
- uint32_t gpio_inv;
- int i;
-
- gpio_inv = 0x00000000;
- for(i = 0; i < 32; i++) {
- int val;
- switch(config->gpio[i] & ICH5R_GPIO_INV_MASK) {
- case ICH5R_GPIO_INV_OFF: val = 0; break;
- case ICH5R_GPIO_INV_ON: val = 1; break;
- default:
- continue;
- }
- gpio_inv &= ~( 1 << i);
- gpio_inv |= (val << i);
- }
- outl(gpio_inv, res->base + 0x2c);
-}
-
-static void i82801ex_pirq_init(device_t dev)
-{
- config_t *config;
-
- /* Get the chip configuration */
- config = dev->chip_info;
-
- if(config->pirq_a_d) {
- pci_write_config32(dev, 0x60, config->pirq_a_d);
- }
- if(config->pirq_e_h) {
- pci_write_config32(dev, 0x68, config->pirq_e_h);
- }
-}
-
-
-static void i82801ex_gpio_init(device_t dev)
-{
- struct resource *res;
- config_t *config;
-
- /* Skip if I don't have any configuration */
- if (!dev->chip_info) {
- return;
- }
- /* The programmer is responsible for ensuring
- * a valid gpio configuration.
- */
-
- /* Get the chip configuration */
- config = dev->chip_info;
- /* Find the GPIO bar */
- res = find_resource(dev, GPIO_BAR);
- if (!res) {
- return;
- }
-
- /* Set the use selects */
- set_i82801ex_gpio_use_sel(dev, res, config);
-
- /* Set the IO direction */
- set_i82801ex_gpio_direction(dev, res, config);
-
- /* Setup the input inverters */
- set_i82801ex_gpio_inv(dev, res, config);
-
- /* Set the value on the GPIO output pins */
- set_i82801ex_gpio_level(dev, res, config);
-
-}
-
-static void enable_hpet(struct device *dev)
-{
- const unsigned long hpet_address = 0xfed00000;
-
- uint32_t dword;
- uint32_t code = (0 & 0x3);
-
- dword = pci_read_config32(dev, GEN_CNTL);
- dword |= (1 << 17); /* enable hpet */
-
- /* Bits [16:15] Memory Address Range
- * 00 FED0_0000h - FED0_03FFh
- * 01 FED0_1000h - FED0_13FFh
- * 10 FED0_2000h - FED0_23FFh
- * 11 FED0_3000h - FED0_33FFh
- */
-
- dword &= ~(3 << 15); /* clear it */
- dword |= (code<<15);
- pci_write_config32(dev, GEN_CNTL, dword);
-
- printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address | (code <<12) );
-}
-
-static void lpc_init(struct device *dev)
-{
- uint8_t byte;
- uint32_t value;
- int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
-
- /* IO APIC initialization */
- value = pci_read_config32(dev, 0xd0);
- value |= (1 << 8)|(1<<7)|(1<<1);
- pci_write_config32(dev, 0xd0, value);
- value = pci_read_config32(dev, 0xd4);
- value |= (1<<1);
- pci_write_config32(dev, 0xd4, value);
- setup_ioapic(IO_APIC_ADDR, 0); // Don't rename IO APIC ID.
-
- i82801ex_enable_serial_irqs(dev);
-
- i82801ex_pci_dma_cfg(dev);
-
- i82801ex_enable_lpc(dev);
-
- /* Clear SATA to non raid */
- pci_write_config8(dev, 0xae, 0x00);
-
- get_option(&pwr_on, "power_on_after_fail");
- byte = pci_read_config8(dev, 0xa4);
- byte &= 0xfe;
- if (!pwr_on) {
- byte |= 1;
- }
- pci_write_config8(dev, 0xa4, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
-
- /* Set up the PIRQ */
- i82801ex_pirq_init(dev);
-
- /* Set the state of the gpio lines */
- i82801ex_gpio_init(dev);
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- /* Disable IDE (needed when sata is enabled) */
- pci_write_config8(dev, 0xf2, 0x60);
-
- enable_hpet(dev);
-}
-
-static void i82801ex_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add the ACPI BAR */
- res = pci_get_resource(dev, ACPI_BAR);
-
- /* Add the GPIO BAR */
- res = pci_get_resource(dev, GPIO_BAR);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void i82801ex_lpc_enable_resources(device_t dev)
-{
- uint8_t acpi_cntl, gpio_cntl;
-
- /* Enable the normal pci resources */
- pci_dev_enable_resources(dev);
-
- /* Enable the ACPI bar */
- acpi_cntl = pci_read_config8(dev, 0x44);
- acpi_cntl |= (1 << 4);
- pci_write_config8(dev, 0x44, acpi_cntl);
-
- /* Enable the GPIO bar */
- gpio_cntl = pci_read_config8(dev, 0x5c);
- gpio_cntl |= (1 << 4);
- pci_write_config8(dev, 0x5c, gpio_cntl);
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = i82801ex_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = i82801ex_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i82801ex_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_LPC,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void pci_init(struct device *dev)
-{
- uint16_t word;
-
- /* Clear system errors */
- word = pci_read_config16(dev, 0x06);
- word |= 0xf900; /* Clear possible errors */
- pci_write_config16(dev, 0x06, word);
-
-#if 0
- /* System error enable */
- uint32_t dword;
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* SERR# Enable */
- dword |= (1<<6); /* Parity Error Response */
- pci_write_config32(dev, 0x04, dword);
-#endif
-
- word = pci_read_config16(dev, 0x1e);
- word |= 0xf800; /* Clear possible errors */
- pci_write_config16(dev, 0x1e, word);
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_PCI,
-};
-
+++ /dev/null
-#include <arch/io.h>
-#include <reset.h>
-
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9 */
- outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void sata_init(struct device *dev)
-{
- printk(BIOS_DEBUG, "SATA init\n");
- /* SATA configuration */
- pci_write_config8(dev, 0x04, 0x07);
- pci_write_config8(dev, 0x09, 0x8f);
-
- /* Set timmings */
- pci_write_config16(dev, 0x40, 0x0a307);
- pci_write_config16(dev, 0x42, 0x0a307);
-
- /* Sync DMA */
- pci_write_config16(dev, 0x48, 0x000f);
- pci_write_config16(dev, 0x4a, 0x1111);
-
- /* 66 mhz */
- pci_write_config16(dev, 0x54, 0xf00f);
-
- /* Combine ide - sata configuration */
- pci_write_config8(dev, 0x90, 0x0);
-
- /* port 0 & 1 enable */
- pci_write_config8(dev, 0x92, 0x33);
-
- /* initialize SATA */
- pci_write_config16(dev, 0xa0, 0x0018);
- pci_write_config32(dev, 0xa4, 0x00000264);
- pci_write_config16(dev, 0xa0, 0x0040);
- pci_write_config32(dev, 0xa4, 0x00220043);
-
-}
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver sata_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_SATA,
-};
-
-static const struct pci_driver sata_driver_nr __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801EB_SATA,
-};
-
+++ /dev/null
-#include <device/device.h>
-#include <device/path.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <arch/io.h>
-#include "i82801ex.h"
-#include "i82801ex_smbus.h"
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static struct pci_operations lops_pci = {
- /* The subsystem id follows the ide controller */
- .set_subsystem = 0,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- .enable = i82801ex_enable,
- .ops_pci = &lops_pci,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_SMB,
-};
-
+++ /dev/null
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x0
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-
-static void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while(byte & 1);
- return loops?0:-1;
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
- return loops?0:-1;
-}
-
-static inline int smbus_wait_until_blk_done(unsigned smbus_io_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_io_base + SMBHSTSTAT);
- } while((byte&(1<<7)) == 0);
- return loops?0:-1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* setup transaction */
- /* disable interrupts */
- outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, smbus_io_base + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- global_status_register &= ~(3 << 5);
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
-
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "i82801ex.h"
-
-static void uhci_init(struct device *dev)
-{
- uint32_t cmd;
-
-#if 1
- printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
- cmd = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND,
- cmd | PCI_COMMAND_MASTER);
-
-
- printk(BIOS_DEBUG, "done.\n");
-#endif
-
-}
-
-static struct pci_operations lops_pci = {
- /* The subsystem id follows the ide controller */
- .set_subsystem = 0,
-};
-
-static struct device_operations uhci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = uhci_init,
- .scan_bus = 0,
- .enable = i82801ex_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver uhci_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_USB1,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_USB2,
-};
-
-static const struct pci_driver usb3_driver __pci_driver = {
- .ops = &uhci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82801ER_USB3,
-};
-
+++ /dev/null
-#include <console/console.h>
-#include <watchdog.h>
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-
-void watchdog_off(void)
-{
- device_t dev;
- unsigned long value,base;
-
- /* turn off the ICH5 watchdog */
- dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
- /* Enable I/O space */
- value = pci_read_config16(dev, 0x04);
- value |= (1 << 10);
- pci_write_config16(dev, 0x04, value);
- /* Get TCO base */
- base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
- /* Disable the watchdog timer */
- value = inw(base + 0x08);
- value |= 1 << 11;
- outw(value, base + 0x08);
- /* Clear TCO timeout status */
- outw(0x0008, base + 0x04);
- outw(0x0002, base + 0x06);
- printk(BIOS_DEBUG, "Watchdog ICH5 disabled\n");
-}
-
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void ide_init(struct device *dev)
+{
+ /* Enable IDE devices and timmings */
+ pci_write_config16(dev, 0x40, 0x0a307); // IDE0
+ pci_write_config16(dev, 0x42, 0x0a307); // IDE1
+ pci_write_config8(dev, 0x48, 0x05);
+ pci_write_config16(dev, 0x4a, 0x0101);
+ pci_write_config16(dev, 0x54, 0x5055);
+ printk(BIOS_DEBUG, "IDE Enabled\n");
+}
+
+static void i82801ex_ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* This value is also visible in uchi[0-2] and smbus functions */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = i82801ex_ide_set_subsystem,
+};
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_IDE,
+};
+
--- /dev/null
+/*
+ * (C) 2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801ex.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x58
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#define SERIRQ_CNTL 0x64
+static void i82801ex_enable_serial_irqs(device_t dev)
+{
+ /* set packet length and toggle silent mode bit */
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+#define PCI_DMA_CFG 0x90
+static void i82801ex_pci_dma_cfg(device_t dev)
+{
+ /* Set PCI DMA CFG to lpc I/F DMA */
+ pci_write_config16(dev, PCI_DMA_CFG, 0xfcff);
+}
+
+#define LPC_EN 0xe6
+static void i82801ex_enable_lpc(device_t dev)
+{
+ /* lpc i/f enable */
+ pci_write_config8(dev, LPC_EN, 0x0d);
+}
+
+typedef struct southbridge_intel_i82801ex_config config_t;
+
+static void set_i82801ex_gpio_use_sel(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_use_sel, gpio_use_sel2;
+ int i;
+
+ gpio_use_sel = 0x1A003180;
+ gpio_use_sel2 = 0x00000007;
+ for(i = 0; i < 64; i++) {
+ int val;
+ switch(config->gpio[i] & ICH5R_GPIO_USE_MASK) {
+ case ICH5R_GPIO_USE_AS_NATIVE: val = 0; break;
+ case ICH5R_GPIO_USE_AS_GPIO: val = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_use_sel &= ~( 1 << i);
+ gpio_use_sel |= (val << i);
+ } else {
+ gpio_use_sel2 &= ~( 1 << (i - 32));
+ gpio_use_sel2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_use_sel, res->base + 0x00);
+ outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_i82801ex_gpio_direction(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_io_sel, gpio_io_sel2;
+ int i;
+
+ gpio_io_sel = 0x0000ffff;
+ gpio_io_sel2 = 0x00000300;
+ for(i = 0; i < 64; i++) {
+ int val;
+ switch(config->gpio[i] & ICH5R_GPIO_SEL_MASK) {
+ case ICH5R_GPIO_SEL_OUTPUT: val = 0; break;
+ case ICH5R_GPIO_SEL_INPUT: val = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_io_sel &= ~( 1 << i);
+ gpio_io_sel |= (val << i);
+ } else {
+ gpio_io_sel2 &= ~( 1 << (i - 32));
+ gpio_io_sel2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_io_sel, res->base + 0x04);
+ outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_i82801ex_gpio_level(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_lvl, gpio_lvl2;
+ uint32_t gpio_blink;
+ int i;
+
+ gpio_lvl = 0x1b3f0000;
+ gpio_blink = 0x00040000;
+ gpio_lvl2 = 0x00030207;
+ for(i = 0; i < 64; i++) {
+ int val, blink;
+ switch(config->gpio[i] & ICH5R_GPIO_LVL_MASK) {
+ case ICH5R_GPIO_LVL_LOW: val = 0; blink = 0; break;
+ case ICH5R_GPIO_LVL_HIGH: val = 1; blink = 0; break;
+ case ICH5R_GPIO_LVL_BLINK: val = 1; blink = 1; break;
+ default:
+ continue;
+ }
+ /* The caller is responsible for not playing with unimplemented bits */
+ if (i < 32) {
+ gpio_lvl &= ~( 1 << i);
+ gpio_blink &= ~( 1 << i);
+ gpio_lvl |= ( val << i);
+ gpio_blink |= (blink << i);
+ } else {
+ gpio_lvl2 &= ~( 1 << (i - 32));
+ gpio_lvl2 |= (val << (i - 32));
+ }
+ }
+ outl(gpio_lvl, res->base + 0x0c);
+ outl(gpio_blink, res->base + 0x18);
+ outl(gpio_lvl2, res->base + 0x38);
+}
+
+static void set_i82801ex_gpio_inv(
+ device_t dev, struct resource *res, config_t *config)
+{
+ uint32_t gpio_inv;
+ int i;
+
+ gpio_inv = 0x00000000;
+ for(i = 0; i < 32; i++) {
+ int val;
+ switch(config->gpio[i] & ICH5R_GPIO_INV_MASK) {
+ case ICH5R_GPIO_INV_OFF: val = 0; break;
+ case ICH5R_GPIO_INV_ON: val = 1; break;
+ default:
+ continue;
+ }
+ gpio_inv &= ~( 1 << i);
+ gpio_inv |= (val << i);
+ }
+ outl(gpio_inv, res->base + 0x2c);
+}
+
+static void i82801ex_pirq_init(device_t dev)
+{
+ config_t *config;
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+
+ if(config->pirq_a_d) {
+ pci_write_config32(dev, 0x60, config->pirq_a_d);
+ }
+ if(config->pirq_e_h) {
+ pci_write_config32(dev, 0x68, config->pirq_e_h);
+ }
+}
+
+
+static void i82801ex_gpio_init(device_t dev)
+{
+ struct resource *res;
+ config_t *config;
+
+ /* Skip if I don't have any configuration */
+ if (!dev->chip_info) {
+ return;
+ }
+ /* The programmer is responsible for ensuring
+ * a valid gpio configuration.
+ */
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+ /* Find the GPIO bar */
+ res = find_resource(dev, GPIO_BAR);
+ if (!res) {
+ return;
+ }
+
+ /* Set the use selects */
+ set_i82801ex_gpio_use_sel(dev, res, config);
+
+ /* Set the IO direction */
+ set_i82801ex_gpio_direction(dev, res, config);
+
+ /* Setup the input inverters */
+ set_i82801ex_gpio_inv(dev, res, config);
+
+ /* Set the value on the GPIO output pins */
+ set_i82801ex_gpio_level(dev, res, config);
+
+}
+
+static void enable_hpet(struct device *dev)
+{
+ const unsigned long hpet_address = 0xfed00000;
+
+ uint32_t dword;
+ uint32_t code = (0 & 0x3);
+
+ dword = pci_read_config32(dev, GEN_CNTL);
+ dword |= (1 << 17); /* enable hpet */
+
+ /* Bits [16:15] Memory Address Range
+ * 00 FED0_0000h - FED0_03FFh
+ * 01 FED0_1000h - FED0_13FFh
+ * 10 FED0_2000h - FED0_23FFh
+ * 11 FED0_3000h - FED0_33FFh
+ */
+
+ dword &= ~(3 << 15); /* clear it */
+ dword |= (code<<15);
+ pci_write_config32(dev, GEN_CNTL, dword);
+
+ printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address | (code <<12) );
+}
+
+static void lpc_init(struct device *dev)
+{
+ uint8_t byte;
+ uint32_t value;
+ int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /* IO APIC initialization */
+ value = pci_read_config32(dev, 0xd0);
+ value |= (1 << 8)|(1<<7)|(1<<1);
+ pci_write_config32(dev, 0xd0, value);
+ value = pci_read_config32(dev, 0xd4);
+ value |= (1<<1);
+ pci_write_config32(dev, 0xd4, value);
+ setup_ioapic(IO_APIC_ADDR, 0); // Don't rename IO APIC ID.
+
+ i82801ex_enable_serial_irqs(dev);
+
+ i82801ex_pci_dma_cfg(dev);
+
+ i82801ex_enable_lpc(dev);
+
+ /* Clear SATA to non raid */
+ pci_write_config8(dev, 0xae, 0x00);
+
+ get_option(&pwr_on, "power_on_after_fail");
+ byte = pci_read_config8(dev, 0xa4);
+ byte &= 0xfe;
+ if (!pwr_on) {
+ byte |= 1;
+ }
+ pci_write_config8(dev, 0xa4, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", pwr_on?"on":"off");
+
+ /* Set up the PIRQ */
+ i82801ex_pirq_init(dev);
+
+ /* Set the state of the gpio lines */
+ i82801ex_gpio_init(dev);
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ /* Disable IDE (needed when sata is enabled) */
+ pci_write_config8(dev, 0xf2, 0x60);
+
+ enable_hpet(dev);
+}
+
+static void i82801ex_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add the ACPI BAR */
+ res = pci_get_resource(dev, ACPI_BAR);
+
+ /* Add the GPIO BAR */
+ res = pci_get_resource(dev, GPIO_BAR);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void i82801ex_lpc_enable_resources(device_t dev)
+{
+ uint8_t acpi_cntl, gpio_cntl;
+
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable the ACPI bar */
+ acpi_cntl = pci_read_config8(dev, 0x44);
+ acpi_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x44, acpi_cntl);
+
+ /* Enable the GPIO bar */
+ gpio_cntl = pci_read_config8(dev, 0x5c);
+ gpio_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x5c, gpio_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = i82801ex_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = i82801ex_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801ex_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_LPC,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void pci_init(struct device *dev)
+{
+ uint16_t word;
+
+ /* Clear system errors */
+ word = pci_read_config16(dev, 0x06);
+ word |= 0xf900; /* Clear possible errors */
+ pci_write_config16(dev, 0x06, word);
+
+#if 0
+ /* System error enable */
+ uint32_t dword;
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* SERR# Enable */
+ dword |= (1<<6); /* Parity Error Response */
+ pci_write_config32(dev, 0x04, dword);
+#endif
+
+ word = pci_read_config16(dev, 0x1e);
+ word |= 0xf800; /* Clear possible errors */
+ pci_write_config16(dev, 0x1e, word);
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_PCI,
+};
+
--- /dev/null
+#include <arch/io.h>
+#include <reset.h>
+
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9 */
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void sata_init(struct device *dev)
+{
+ printk(BIOS_DEBUG, "SATA init\n");
+ /* SATA configuration */
+ pci_write_config8(dev, 0x04, 0x07);
+ pci_write_config8(dev, 0x09, 0x8f);
+
+ /* Set timmings */
+ pci_write_config16(dev, 0x40, 0x0a307);
+ pci_write_config16(dev, 0x42, 0x0a307);
+
+ /* Sync DMA */
+ pci_write_config16(dev, 0x48, 0x000f);
+ pci_write_config16(dev, 0x4a, 0x1111);
+
+ /* 66 mhz */
+ pci_write_config16(dev, 0x54, 0xf00f);
+
+ /* Combine ide - sata configuration */
+ pci_write_config8(dev, 0x90, 0x0);
+
+ /* port 0 & 1 enable */
+ pci_write_config8(dev, 0x92, 0x33);
+
+ /* initialize SATA */
+ pci_write_config16(dev, 0xa0, 0x0018);
+ pci_write_config32(dev, 0xa4, 0x00000264);
+ pci_write_config16(dev, 0xa0, 0x0040);
+ pci_write_config32(dev, 0xa4, 0x00220043);
+
+}
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver sata_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_SATA,
+};
+
+static const struct pci_driver sata_driver_nr __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801EB_SATA,
+};
+
--- /dev/null
+#include <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "i82801ex.h"
+#include "smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static struct pci_operations lops_pci = {
+ /* The subsystem id follows the ide controller */
+ .set_subsystem = 0,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = i82801ex_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_SMB,
+};
+
--- /dev/null
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+
+static void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while(byte & 1);
+ return loops?0:-1;
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while((byte & 1) || (byte & ~((1<<6)|(1<<0))) == 0);
+ return loops?0:-1;
+}
+
+static inline int smbus_wait_until_blk_done(unsigned smbus_io_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while((byte&(1<<7)) == 0);
+ return loops?0:-1;
+}
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ global_status_register &= ~(3 << 5);
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
+
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i82801ex.h"
+
+static void uhci_init(struct device *dev)
+{
+ uint32_t cmd;
+
+#if 1
+ printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
+ cmd = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND,
+ cmd | PCI_COMMAND_MASTER);
+
+
+ printk(BIOS_DEBUG, "done.\n");
+#endif
+
+}
+
+static struct pci_operations lops_pci = {
+ /* The subsystem id follows the ide controller */
+ .set_subsystem = 0,
+};
+
+static struct device_operations uhci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = uhci_init,
+ .scan_bus = 0,
+ .enable = i82801ex_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver uhci_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_USB1,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_USB2,
+};
+
+static const struct pci_driver usb3_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82801ER_USB3,
+};
+
--- /dev/null
+#include <console/console.h>
+#include <watchdog.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+
+void watchdog_off(void)
+{
+ device_t dev;
+ unsigned long value,base;
+
+ /* turn off the ICH5 watchdog */
+ dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
+ /* Enable I/O space */
+ value = pci_read_config16(dev, 0x04);
+ value |= (1 << 10);
+ pci_write_config16(dev, 0x04, value);
+ /* Get TCO base */
+ base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
+ /* Disable the watchdog timer */
+ value = inw(base + 0x08);
+ value |= 1 << 11;
+ outw(value, base + 0x08);
+ /* Clear TCO timeout status */
+ outw(0x0008, base + 0x04);
+ outw(0x0002, base + 0x06);
+ printk(BIOS_DEBUG, "Watchdog ICH5 disabled\n");
+}
+
##
driver-y += i82801gx.c
-driver-y += i82801gx_ac97.c
-driver-y += i82801gx_azalia.c
-driver-y += i82801gx_ide.c
-driver-y += i82801gx_lpc.c
-driver-y += i82801gx_nic.c
-driver-y += i82801gx_pci.c
-driver-y += i82801gx_pcie.c
-driver-y += i82801gx_sata.c
-driver-y += i82801gx_smbus.c
-driver-y += i82801gx_usb.c
-driver-y += i82801gx_usb_ehci.c
+driver-y += ac97.c
+driver-y += azalia.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += nic.c
+driver-y += pci.c
+driver-y += pcie.c
+driver-y += sata.c
+driver-y += smbus.c
+driver-y += usb.c
+driver-y += usb_ehci.c
-ramstage-y += i82801gx_reset.c
-ramstage-y += i82801gx_watchdog.c
+ramstage-y += reset.c
+ramstage-y += watchdog.c
-ramstage-$(CONFIG_HAVE_SMI_HANDLER) += i82801gx_smi.c
-smm-$(CONFIG_HAVE_SMI_HANDLER) += i82801gx_smihandler.c
+ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
+smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c
-romstage-y += i82801gx_early_smbus.c
-romstage-$(CONFIG_USBDEBUG) += i82801gx_usb_debug.c
+romstage-y += early_smbus.c
+romstage-$(CONFIG_USBDEBUG) += usb_debug.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "i82801gx.h"
+
+#define NAMBAR 0x10
+#define MASTER_VOL 0x02
+#define PAGING 0x24
+#define EXT_AUDIO 0x28
+#define FUNC_SEL 0x66
+#define INFO_IO 0x68
+#define CONNECTOR 0x6a
+#define VENDOR_ID1 0x7c
+#define VENDOR_ID2 0x7e
+#define SEC_VENDOR_ID1 0xfc
+#define SEC_VENDOR_ID2 0xfe
+
+#define NABMBAR 0x14
+#define GLOB_CNT 0x2c
+#define GLOB_STA 0x30
+#define CAS 0x34
+
+#define MMBAR 0x10
+#define EXT_MODEM_ID1 0x3c
+#define EXT_MODEM_ID2 0xbc
+
+#define MBAR 0x14
+#define SEC_CODEC 0x40
+
+
+/* FIXME. This table is probably mainboard specific */
+static u16 ac97_function[16*2][4] = {
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
+ { (1 << 5), (2 << 11), (1 << 10), (3 << 13) }
+};
+
+static u16 nabmbar;
+static u16 nambar;
+
+static int ac97_semaphore(void)
+{
+ int timeout;
+ u8 reg8;
+
+ timeout = 0xffff;
+ do {
+ reg8 = inb(nabmbar + CAS);
+ timeout--;
+ } while ((reg8 & 1) && timeout);
+ if (! timeout) {
+ printk(BIOS_DEBUG, "Timeout!\n");
+ }
+
+ return (!timeout);
+}
+
+static void init_cnr(void)
+{
+ // TODO
+}
+
+static void program_sigid(struct device *dev, u32 id)
+{
+ pci_write_config32(dev, 0x2c, id);
+}
+
+static void ac97_audio_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+ int i;
+
+ printk(BIOS_DEBUG, "Initializing AC'97 Audio.\n");
+
+ /* top 16 bits are zero, so don't read them */
+ nabmbar = pci_read_config16(dev, NABMBAR) & 0xfffe;
+ nambar = pci_read_config16(dev, NAMBAR) & 0xfffe;
+
+ reg16 = inw(nabmbar + GLOB_CNT);
+ reg16 |= (1 << 1); /* Remove AC_RESET# */
+ outw(reg16, nabmbar + GLOB_CNT);
+
+ /* Wait 600ms. Ouch. */
+ udelay(600 * 1000);
+
+ init_cnr();
+
+ /* Detect Primary AC'97 Codec */
+ reg32 = inl(nabmbar + GLOB_STA);
+ if ((reg32 & ((1 << 28) | (1 << 9) | (1 << 8))) == 0) {
+ /* Primary Codec not found */
+ printk(BIOS_DEBUG, "No primary codec. Disabling AC'97 Audio.\n");
+ return;
+ }
+
+ ac97_semaphore();
+
+ /* Detect if codec is programmable */
+ outw(0x8000, nambar + MASTER_VOL);
+ ac97_semaphore();
+ if (inw(nambar + MASTER_VOL) != 0x8000) {
+ printk(BIOS_DEBUG, "Codec not programmable. Disabling AC'97 Audio.\n");
+ return;
+ }
+
+ /* Program Vendor IDs */
+ reg32 = inw(nambar + VENDOR_ID1);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(nambar + VENDOR_ID2);
+
+ program_sigid(dev, reg32);
+
+ /* Is Codec AC'97 2.3 compliant? */
+ reg16 = inw(nambar + EXT_AUDIO);
+ /* [11:10] = 10b -> AC'97 2.3 */
+ if ((reg16 & 0x0c00) != 0x0800) {
+ /* No 2.3 Codec. We're done */
+ return;
+ }
+
+ /* Select Page 1 */
+ reg16 = inw(nambar + PAGING);
+ reg16 &= 0xfff0;
+ reg16 |= 0x0001;
+ outw(reg16, nambar + PAGING);
+
+ for (i = 0x0a * 2; i > 0; i--) {
+ outw(i, nambar + FUNC_SEL);
+
+ /* Function could not be selected. Next one */
+ if (inw(nambar + FUNC_SEL) != i)
+ continue;
+
+ reg16 = inw(nambar + INFO_IO);
+
+ /* Function Information present? */
+ if (!(reg16 & (1 << 0)))
+ continue;
+
+ /* Function Information valid? */
+ if (!(reg16 & (1 << 4)))
+ continue;
+
+ /* Program Buffer Delay [9:5] */
+ reg16 &= 0x03e0;
+ reg16 |= ac97_function[i][0];
+
+ /* Program Gain [15:11] */
+ reg16 |= ac97_function[i][1];
+
+ /* Program Inversion [10] */
+ reg16 |= ac97_function[i][2];
+
+ outw(reg16, nambar + INFO_IO);
+
+ /* Program Connector / Jack Location */
+ reg16 = inw(nambar + CONNECTOR);
+ reg16 &= 0x1fff;
+ reg16 |= ac97_function[i][3];
+ outw(reg16, nambar + CONNECTOR);
+ }
+}
+
+static void ac97_modem_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+ u16 mmbar, mbar;
+
+ mmbar = pci_read_config16(dev, MMBAR) & 0xfffe;
+ mbar = pci_read_config16(dev, MBAR) & 0xfffe;
+
+ reg16 = inw(mmbar + EXT_MODEM_ID1);
+ if ((reg16 & 0xc000) != 0xc000 ) {
+ if (reg16 & (1 << 0)) {
+ reg32 = inw(mmbar + VENDOR_ID2);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(mmbar + VENDOR_ID1);
+ program_sigid(dev, reg32);
+ return;
+ }
+ }
+
+ /* Secondary codec? */
+ reg16 = inw(mbar + SEC_CODEC);
+ if ((reg16 & (1 << 9)) == 0)
+ return;
+
+ reg16 = inw(mmbar + EXT_MODEM_ID2);
+ if ((reg16 & 0xc000) == 0x4000) {
+ if (reg16 & (1 << 0)) {
+ reg32 = inw(mmbar + SEC_VENDOR_ID2);
+ reg32 <<= 16;
+ reg32 |= (u16)inw(mmbar + SEC_VENDOR_ID1);
+ program_sigid(dev, reg32);
+ return;
+ }
+ }
+}
+
+static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations ac97_pci_ops = {
+ .set_subsystem = ac97_set_subsystem,
+};
+
+static struct device_operations ac97_audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ac97_audio_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &ac97_pci_ops,
+};
+
+static struct device_operations ac97_modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ac97_modem_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &ac97_pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+/* Note: 82801GU (ICH7-U) doesn't have AC97 audio. */
+static const struct pci_driver i82801gx_ac97_audio __pci_driver = {
+ .ops = &ac97_audio_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27de,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+/* Note: 82801GU (ICH7-U) doesn't have AC97 modem. */
+static const struct pci_driver i82801gx_ac97_modem __pci_driver = {
+ .ops = &ac97_modem_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27dd,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Intel i82801G AC'97 Audio and Modem */
+
+// Intel AC'97 Audio 0:1e.2
+
+Device (AUD0)
+{
+ Name (_ADR, 0x001e0002)
+}
+
+// Intel AC'97 Modem 0:1e.3
+
+Device (MODM)
+{
+ Name (_ADR, 0x001e0003)
+
+ Name (_PRW, Package(){ 5, 4 })
+}
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Intel i82801G HDA */
+
+// Intel High Definition Audio (Azalia) 0:1b.0
+
+Device (HDEF)
+{
+ Name (_ADR, 0x001b0000)
+
+ // Power Resources for Wake
+ Name (_PRW, Package(){
+ 5, // Bit 5 of GPE
+ 4 // Can wake from S4 state.
+ })
+}
+
}
// 0:1b.0 High Definition Audio (Azalia)
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_audio.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/audio.asl"
// PCI Express Ports
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_pcie.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/pcie.asl"
// USB
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_usb.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/usb.asl"
// PCI Bridge
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_pci.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/pci.asl"
// AC97 Audio and Modem
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_ac97.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/ac97.asl"
// LPC Bridge
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_lpc.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/lpc.asl"
// PATA
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_pata.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/pata.asl"
// SATA
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_sata.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/sata.asl"
// SMBus
-#include "../../../southbridge/intel/i82801gx/acpi/ich7_smbus.asl"
+#include "../../../southbridge/intel/i82801gx/acpi/smbus.asl"
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-/* Intel i82801G AC'97 Audio and Modem */
-
-// Intel AC'97 Audio 0:1e.2
-
-Device (AUD0)
-{
- Name (_ADR, 0x001e0002)
-}
-
-// Intel AC'97 Modem 0:1e.3
-
-Device (MODM)
-{
- Name (_ADR, 0x001e0003)
-
- Name (_PRW, Package(){ 5, 4 })
-}
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-/* Intel i82801G HDA */
-
-// Intel High Definition Audio (Azalia) 0:1b.0
-
-Device (HDEF)
-{
- Name (_ADR, 0x001b0000)
-
- // Power Resources for Wake
- Name (_PRW, Package(){
- 5, // Bit 5 of GPE
- 4 // Can wake from S4 state.
- })
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-Device (LNKA)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 1)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTA)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLA, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLA, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTA
- ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
-
- Return (RTLA)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTA)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTA, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKB)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 2)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTB)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLB, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLB, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTB
- ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
-
- Return (RTLB)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTB)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTB, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKC)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 3)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTC)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLC, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLC, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTC
- ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
-
- Return (RTLC)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTC)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTC, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKD)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 4)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTD)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLD, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLD, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTD
- ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
-
- Return (RTLD)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTD)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTD, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKE)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 5)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTE)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLE, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLE, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTE
- ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
-
- Return (RTLE)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTE)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTE, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKF)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 6)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTF)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLF, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLF, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTF
- ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
-
- Return (RTLF)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTF)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTF, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKG)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 7)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTG)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLG, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLG, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTG
- ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
-
- Return (RTLG)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTG)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTG, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
-Device (LNKH)
-{
- Name (_HID, EISAID("PNP0C0F"))
- Name (_UID, 8)
-
- // Disable method
- Method (_DIS, 0, Serialized)
- {
- Store (0x80, PRTH)
- }
-
- // Possible Resource Settings for this Link
- Name (_PRS, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared)
- { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
- })
-
- // Current Resource Settings for this link
- Method (_CRS, 0, Serialized)
- {
- Name (RTLH, ResourceTemplate()
- {
- IRQ(Level, ActiveLow, Shared) {}
- })
- CreateWordField(RTLH, 1, IRQ0)
-
- // Clear the WordField
- Store (Zero, IRQ0)
-
- // Set the bit from PRTH
- ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
-
- Return (RTLH)
- }
-
- // Set Resource Setting for this IRQ link
- Method (_SRS, 1, Serialized)
- {
- CreateWordField(Arg0, 1, IRQ0)
-
- // Which bit is set?
- FindSetRightBit(IRQ0, Local0)
-
- Decrement(Local0)
- Store(Local0, PRTH)
- }
-
- // Status
- Method (_STA, 0, Serialized)
- {
- If(And(PRTH, 0x80)) {
- Return (0x9)
- } Else {
- Return (0xb)
- }
- }
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-// Intel LPC Bus Device - 0:1f.0
-
-Device (LPCB)
-{
- Name(_ADR, 0x001f0000)
-
- OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
- Field (LPC0, AnyAcc, NoLock, Preserve)
- {
- Offset (0x40),
- PMBS, 16, // PMBASE
- Offset (0x60), // Interrupt Routing Registers
- PRTA, 8,
- PRTB, 8,
- PRTC, 8,
- PRTD, 8,
- Offset (0x68),
- PRTE, 8,
- PRTF, 8,
- PRTG, 8,
- PRTH, 8,
-
- Offset (0x80), // IO Decode Ranges
- IOD0, 8,
- IOD1, 8,
-
- Offset (0xf0), // RCBA
- RCEN, 1,
- , 13,
- RCBA, 18,
- }
-
- #include "../../../southbridge/intel/i82801gx/acpi/ich7_irqlinks.asl"
-
- #include "acpi/ec.asl"
-
- Device (DMAC) // DMA Controller
- {
- Name(_HID, EISAID("PNP0200"))
- Name(_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x00, 0x00, 0x01, 0x20)
- IO (Decode16, 0x81, 0x81, 0x01, 0x11)
- IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
- IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
- DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
- })
- }
-
- Device (FWH) // Firmware Hub
- {
- Name (_HID, EISAID("INT0800"))
- Name (_CRS, ResourceTemplate()
- {
- Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
- })
- }
-
- Device (HPET)
- {
- Name (_HID, EISAID("PNP0103"))
- Name (_CID, 0x010CD041)
-
- Name(BUF0, ResourceTemplate()
- {
- Memory32Fixed(ReadOnly, 0xfed00000, 0x400, FED0)
- })
-
- Method (_STA, 0) // Device Status
- {
- If (HPTE) {
- // Note: Ancient versions of Windows don't want
- // to see the HPET in order to work right
- If (LGreaterEqual(OSYS, 2001)) {
- Return (0xf) // Enable and show device
- } Else {
- Return (0xb) // Enable and don't show device
- }
- }
-
- Return (0x0) // Not enabled, don't show.
- }
-
- Method (_CRS, 0, Serialized) // Current resources
- {
- If (HPTE) {
- CreateDWordField(BUF0, \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0)
- If (Lequal(HPAS, 1)) {
- Store(0xfed01000, HPT0)
- }
-
- If (Lequal(HPAS, 2)) {
- Store(0xfed02000, HPT0)
- }
-
- If (Lequal(HPAS, 3)) {
- Store(0xfed03000, HPT0)
- }
- }
-
- Return (BUF0)
- }
- }
-
- Device(PIC) // 8259 Interrupt Controller
- {
- Name(_HID,EISAID("PNP0000"))
- Name(_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x20, 0x20, 0x01, 0x02)
- IO (Decode16, 0x24, 0x24, 0x01, 0x02)
- IO (Decode16, 0x28, 0x28, 0x01, 0x02)
- IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
- IO (Decode16, 0x30, 0x30, 0x01, 0x02)
- IO (Decode16, 0x34, 0x34, 0x01, 0x02)
- IO (Decode16, 0x38, 0x38, 0x01, 0x02)
- IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
- IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
- IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
- IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
- IO (Decode16, 0xac, 0xac, 0x01, 0x02)
- IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
- IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
- IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
- IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
- IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
- IRQNoFlags () { 2 }
- })
- }
-
- Device(MATH) // FPU
- {
- Name (_HID, EISAID("PNP0C04"))
- Name (_CRS, ResourceTemplate()
- {
- IO (Decode16, 0xf0, 0xf0, 0x01, 0x01)
- IRQNoFlags() { 13 }
- })
- }
-
- Device(LDRC) // LPC device: Resource consumption
- {
- Name (_HID, EISAID("PNP0C02"))
- Name (_UID, 2)
- Name (_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO
- IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO
- IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
- IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
- IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
- IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
- IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
- IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
- IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
- IO (Decode16, 0x800, 0x800, 0x1, 0x10) // ACPI I/O trap
- IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80) // ICH7-M ACPI
- IO (Decode16, DEFAULT_GPIOBASE, DEFAULT_GPIOBASE, 0x1, 0x40) // ICH7-M GPIO
- })
- }
-
- Device (RTC) // Real Time Clock
- {
- Name (_HID, EISAID("PNP0B00"))
- Name (_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x70, 0x70, 1, 8)
-// Disable as Windows doesn't like it, and systems don't seem to use it.
-// IRQNoFlags() { 8 }
- })
- }
-
- Device (TIMR) // Intel 8254 timer
- {
- Name(_HID, EISAID("PNP0100"))
- Name(_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x40, 0x40, 0x01, 0x04)
- IO (Decode16, 0x50, 0x50, 0x10, 0x04)
- IRQNoFlags() {0}
- })
- }
-
- #include "acpi/superio.asl"
-
-#ifdef ENABLE_TPM
- Device (TPM) // Trusted Platform Module
- {
- Name(_HID, EISAID("IFX0102"))
- Name(_CID, 0x310cd041)
- Name(_UID, 1)
-
- Method(_STA, 0)
- {
- If (TPMP) {
- Return (0xf)
- }
- Return (0x0)
- }
-
- Name(_CRS, ResourceTemplate() {
- IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
- IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10)
- Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
- IRQ (Edge, Activehigh, Exclusive) { 6 }
- })
- }
-#endif
-
- Device (PS2K) // Keyboard
- {
- Name(_HID, EISAID("PNP0303"))
- Name(_CID, EISAID("PNP030B"))
-
- Name(_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x60, 0x60, 0x01, 0x01)
- IO (Decode16, 0x64, 0x64, 0x01, 0x01)
- IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1
- })
-
- Method (_STA, 0)
- {
- Return (0xf)
- }
- }
-
- Device (PS2M) // Mouse
- {
- Name(_HID, EISAID("PNP0F13"))
- Name(_CRS, ResourceTemplate()
- {
- IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
- })
-
- Method(_STA, 0)
- {
- Return (0xf)
- }
- }
-
-#ifdef ENABLE_FDC
- Device (FDC0) // Floppy controller
- {
- Name (_HID, EisaId ("PNP0700"))
- Method (_STA, 0, NotSerialized)
- {
- Return (0x0f) // FIXME
- }
-
- Name(_CRS, ResourceTemplate()
- {
- IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
- IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
- IRQNoFlags () {6}
- DMA (Compatibility, NotBusMaster, Transfer8) {2}
- })
-
- Name(_PRS, ResourceTemplate()
- {
- IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
- IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
- IRQNoFlags () {6}
- DMA (Compatibility, NotBusMaster, Transfer8) {2}
- })
-
- }
-#endif
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-// Intel PATA Controller 0:1f.1
-
-Device (PATA)
-{
- Name (_ADR, 0x001f0001)
-
- Device (PRID)
- {
- Name (_ADR, 0)
-
- // Get Timing Mode
- Method (_GTM)
- {
- Name(PBUF, Buffer(20) {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00 })
-
- CreateDwordField (PBUF, 0, PIO0)
- CreateDwordField (PBUF, 4, DMA0)
- CreateDwordField (PBUF, 8, PIO1)
- CreateDwordField (PBUF, 12, DMA1)
- CreateDwordField (PBUF, 16, FLAG)
-
- // TODO fill return structure
-
- Return (PBUF)
- }
-
- // Set Timing Mode
- Method (_STM, 3)
- {
- CreateDwordField (Arg0, 0, PIO0)
- CreateDwordField (Arg0, 4, DMA0)
- CreateDwordField (Arg0, 8, PIO1)
- CreateDwordField (Arg0, 12, DMA1)
- CreateDwordField (Arg0, 16, FLAG)
-
- // TODO: Do the deed
- }
-
- Device (DSK0)
- {
- Name (_ADR, 0)
- // TODO: _RMV ?
- // TODO: _GTF ?
- }
-
- Device (DSK1)
- {
- Name (_ADR, 1)
-
- // TODO: _RMV ?
- // TODO: _GTF ?
- }
-
- }
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-// Intel PCI to PCI bridge 0:1e.0
-
-Device (PCIB)
-{
- Name (_ADR, 0x001e0000)
-
- Device (SLT1)
- {
- Name (_ADR, 0x00000000)
- Name (_PRW, Package(){ 11, 4 })
- }
-
- Device (SLT2)
- {
- Name (_ADR, 0x00010000)
- Name (_PRW, Package(){ 11, 4 })
- }
-
- Device (SLT3)
- {
- Name (_ADR, 0x00020000)
- Name (_PRW, Package(){ 11, 4 })
- }
-
- Device (SLT6)
- {
- Name (_ADR, 0x00050000)
- Name (_PRW, Package(){ 11, 4 })
- }
-
- Device (LANC)
- {
- Name (_ADR, 0x00080000)
- Name (_PRW, Package(){ 11, 3 })
- }
-
- Device (LANR)
- {
- Name (_ADR, 0x00000000)
- Name (_PRW, Package(){ 11, 3 })
- }
-
- // TODO: How many slots, where?
-
- // PCI Interrupt Routing.
- // If PICM is set, interrupts are routed over the i8259, otherwise
- // over the IOAPIC. (Really? If they're above 15 they need to be routed
- // fixed over the IOAPIC?)
-
- Method (_PRT)
- {
- #include "acpi/ich7_pci_irqs.asl"
- }
-
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-/* Intel i82801G PCIe support */
-
-// PCI Express Ports
-
-Device (RP01)
-{
- NAME(_ADR, 0x001c0000) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 16 },
- Package() { 0x0000ffff, 1, 0, 17 },
- Package() { 0x0000ffff, 2, 0, 18 },
- Package() { 0x0000ffff, 3, 0, 19 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
- })
-
- }
-
- }
-}
-
-Device (RP02)
-{
- NAME(_ADR, 0x001c0001) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 17 },
- Package() { 0x0000ffff, 1, 0, 18 },
- Package() { 0x0000ffff, 2, 0, 19 },
- Package() { 0x0000ffff, 3, 0, 16 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
- })
-
- }
-
- }
-}
-
-
-Device (RP03)
-{
- NAME(_ADR, 0x001c0002) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 18 },
- Package() { 0x0000ffff, 1, 0, 19 },
- Package() { 0x0000ffff, 2, 0, 16 },
- Package() { 0x0000ffff, 3, 0, 17 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 }
- })
-
- }
-
- }
-}
-
-
-Device (RP04)
-{
- NAME(_ADR, 0x001c0003) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 19 },
- Package() { 0x0000ffff, 1, 0, 16 },
- Package() { 0x0000ffff, 2, 0, 17 },
- Package() { 0x0000ffff, 3, 0, 18 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 }
- })
-
- }
-
- }
-}
-
-
-Device (RP05)
-{
- NAME(_ADR, 0x001c0004) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 16 },
- Package() { 0x0000ffff, 1, 0, 17 },
- Package() { 0x0000ffff, 2, 0, 18 },
- Package() { 0x0000ffff, 3, 0, 19 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
- })
-
- }
-
- }
-}
-
-
-Device (RP06)
-{
- NAME(_ADR, 0x001c0005) // FIXME: Have a macro for PCI Devices -> ACPI notation?
- //#include "pcie_port.asl"
- Method(_PRT)
- {
- If (PICM) {
- Return (Package() {
- Package() { 0x0000ffff, 0, 0, 17 },
- Package() { 0x0000ffff, 1, 0, 18 },
- Package() { 0x0000ffff, 2, 0, 19 },
- Package() { 0x0000ffff, 3, 0, 16 }
- })
- } Else {
- Return (Package() {
- Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
- Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
- Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
- Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
- })
-
- }
-
- }
-}
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-// Intel SATA Controller 0:1f.2
-
-// Note: Some BIOSes put the S-ATA code into an SSDT to make it easily
-// pluggable
-
-Device (SATA)
-{
- Name (_ADR, 0x001f0002)
-
- Device (PRID)
- {
- Name (_ADR, 0)
-
- // Get Timing Mode
- Method (_GTM)
- {
- Name(PBUF, Buffer(20) {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00 })
-
- CreateDwordField (PBUF, 0, PIO0)
- CreateDwordField (PBUF, 4, DMA0)
- CreateDwordField (PBUF, 8, PIO1)
- CreateDwordField (PBUF, 12, DMA1)
- CreateDwordField (PBUF, 16, FLAG)
-
- // TODO fill return structure
-
- Return (PBUF)
- }
-
- // Set Timing Mode
- Method (_STM, 3)
- {
- CreateDwordField (Arg0, 0, PIO0)
- CreateDwordField (Arg0, 4, DMA0)
- CreateDwordField (Arg0, 8, PIO1)
- CreateDwordField (Arg0, 12, DMA1)
- CreateDwordField (Arg0, 16, FLAG)
-
- // TODO: Do the deed
- }
-
- Device (DSK0)
- {
- Name (_ADR, 0)
- // TODO: _RMV ?
- // TODO: _GTF ?
- }
-
- Device (DSK1)
- {
- Name (_ADR, 1)
-
- // TODO: _RMV ?
- // TODO: _GTF ?
- }
-
- }
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-// Intel SMBus Controller 0:1f.3
-
-Device (SBUS)
-{
- Name (_ADR, 0x001f0003)
-
- OperationRegion (SMBP, PCI_Config, 0x00, 0x100)
- Field(SMBP, DWordAcc, NoLock, Preserve)
- {
- Offset(0x40),
- , 2,
- I2CE, 1
- }
-
- OperationRegion (SMBI, SystemIO, 0x400, 0x20)
- Field (SMBI, ByteAcc, NoLock, Preserve)
- {
- HSTS, 8, // Host Status
- , 8,
- HCNT, 8, // Host Control
- HCMD, 8, // Host Command
- TXSA, 8, // Transmit Slave Address
- DAT0, 8, // Host Data 0
- DAT1, 8, // Host Data 1
- HBDB, 8, // Host Block Data Byte
- PECK, 8, // Packet Error Check
- RXSA, 8, // Receive Slave Address
- RXDA, 16, // Receive Slave Data
- AUXS, 8, // Auxiliary Status
- AUXC, 8, // Auxiliary Control
- SLPC, 8, // SMLink Pin Control
- SBPC, 8, // SMBus Pin Control
- SSTS, 8, // Slave Status
- SCMD, 8, // Slave Command
- NADR, 8, // Notify Device Address
- NDLB, 8, // Notify Data Low Byte
- NDLH, 8, // Notify Data High Byte
- }
-
-#ifdef ENABLE_SMBUS_METHODS
- // Kill all SMBus communication
- Method (KILL, 0, Serialized)
- {
- Or (HCNT, 0x02, HCNT) // Send Kill
- Or (HSTS, 0xff, HSTS) // Clean Status
- }
-
- // Check if last operation completed
- // return Failure = 0, Success = 1
- Method (CMPL, 0, Serialized)
- {
- Store (4000, Local0) // Timeout 200ms in 50us steps
- While (Local0) {
- If (And(HSTS, 0x02)) { // Completion Status?
- Return (1) // Operation Completed
- } Else {
- Stall (50)
- Decrement (Local0)
- If (LEqual(Local0, 0)) {
- KILL()
- }
- }
- }
-
- Return (0) // Failure
- }
-
-
- // Wait for SMBus to become ready
- Method (SRDY, 0, Serialized)
- {
- Store (200, Local0) // Timeout 200ms
- While (Local0) {
- If (And(HSTS, 0x40)) { // IN_USE?
- Sleep(1) // Wait 1ms
- Decrement(Local0) // timeout--
- If (LEqual(Local0, 0)) {
- Return (1)
- }
- } Else {
- Store (0, Local0) // We're ready
- }
- }
-
- Store (4000, Local0) // Timeout 200ms (50us * 4000)
- While (Local0) {
- If (And (HSTS, 0x01)) { // Host Busy?
- Stall(50) // Wait 50us
- Decrement(Local0) // timeout--
- If (LEqual(Local0, 0)) {
- KILL()
- }
- } Else {
- Return (0) // Success
- }
- }
-
- Return (1) // Failure
- }
-
- // SMBus Send Byte
- // Arg0: Address
- // Arg1: Data
- // Return: 1 = Success, 0=Failure
-
- Method (SSXB, 2, Serialized)
- {
-
- // Is the SMBus Controller Ready?
- If (SRDY()) {
- Return (0)
- }
-
- // Send Byte
- Store (0, I2CE) // SMBus Enable
- Store (0xbf, HSTS)
- Store (Arg0, TXSA) // Write Address
- Store (Arg1, HCMD) // Write Data
-
- Store (0x48, HCNT) // Start + Byte Data Protocol
-
- If (CMPL()) {
- Or (HSTS, 0xff, HSTS) // Clean up
- Return (1) // Success
- }
-
- Return (0)
- }
-
-
- // SMBus Receive Byte
- // Arg0: Address
- // Return: 0xffff = Failure, Data (8bit) = Success
-
- Method (SRXB, 2, Serialized)
- {
-
- // Is the SMBus Controller Ready?
- If (SRDY()) {
- Return (0xffff)
- }
-
- // Receive Byte
- Store (0, I2CE) // SMBus Enable
- Store (0xbf, HSTS)
- Store (Or (Arg0, 1), TXSA) // Write Address
-
- Store (0x44, HCNT) // Start
-
- If (CMPL()) {
- Or (HSTS, 0xff, HSTS) // Clean up
- Return (DAT0) // Success
- }
-
- Return (0xffff)
- }
-
-
- // SMBus Write Byte
- // Arg0: Address
- // Arg1: Command
- // Arg2: Data
- // Return: 1 = Success, 0=Failure
-
- Method (SWRB, 3, Serialized)
- {
-
- // Is the SMBus Controller Ready?
- If (SRDY()) {
- Return (0)
- }
-
- // Send Byte
- Store (0, I2CE) // SMBus Enable
- Store (0xbf, HSTS)
- Store (Arg0, TXSA) // Write Address
- Store (Arg1, HCMD) // Write Command
- Store (Arg2, DAT0) // Write Data
-
- Store (0x48, HCNT) // Start + Byte Protocol
-
- If (CMPL()) {
- Or (HSTS, 0xff, HSTS) // Clean up
- Return (1) // Success
- }
-
- Return (0)
- }
-
-
- // SMBus Read Byte
- // Arg0: Address
- // Arg1: Command
- // Return: 0xffff = Failure, Data (8bit) = Success
-
- Method (SRDB, 2, Serialized)
- {
-
- // Is the SMBus Controller Ready?
- If (SRDY()) {
- Return (0xffff)
- }
-
- // Receive Byte
- Store (0, I2CE) // SMBus Enable
- Store (0xbf, HSTS)
- Store (Or (Arg0, 1), TXSA) // Write Address
- Store (Arg1, HCMD) // Command
-
- Store (0x48, HCNT) // Start
-
- If (CMPL()) {
- Or (HSTS, 0xff, HSTS) // Clean up
- Return (DAT0) // Success
- }
-
- Return (0xffff)
- }
-#endif
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-/* Intel i82801G USB support */
-
-// USB Controller 0:1d.0
-
-Device (USB1)
-{
- Name(_ADR, 0x001d0000)
-
- OperationRegion(U01P, PCI_Config, 0, 256)
- Field(U01P, DWordAcc, NoLock, Preserve)
- {
- Offset(0xc4),
- U1WE, 2 // USB Wake Enable
- }
-
- Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
-
- Method (_PSW, 1) // Power State Wake method
- {
- // USB Controller can wake OS from Sleep State
- If (Arg0) {
- Store (3, U1WE)
- } Else {
- Store (0, U1WE)
- }
- }
-
- // Leave USB ports on for to allow Wake from USB
-
- Method(_S3D,0) // Highest D State in S3 State
- {
- Return (2)
- }
-
- Method(_S4D,0) // Highest D State in S4 State
- {
- Return (2)
- }
-}
-
-
-// USB Controller 0:1d.1
-
-Device (USB2)
-{
- Name(_ADR, 0x001d0001)
-
- OperationRegion(U02P, PCI_Config, 0, 256)
- Field(U02P, DWordAcc, NoLock, Preserve)
- {
- Offset(0xc4),
- U2WE, 2 // USB Wake Enable
- }
-
- Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
-
- Method (_PSW, 1) // Power State Wake method
- {
- // USB Controller can wake OS from Sleep State
- If (Arg0) {
- Store (3, U2WE)
- } Else {
- Store (0, U2WE)
- }
- }
-
- // Leave USB ports on for to allow Wake from USB
-
- Method(_S3D,0) // Highest D State in S3 State
- {
- Return (2)
- }
-
- Method(_S4D,0) // Highest D State in S4 State
- {
- Return (2)
- }
-
-}
-
-
-// USB Controller 0:1d.2
-
-Device (USB3)
-{
- Name(_ADR, 0x001d0002)
-
- OperationRegion(U03P, PCI_Config, 0, 256)
- Field(U03P, DWordAcc, NoLock, Preserve)
- {
- Offset(0xc4),
- U3WE, 2 // USB Wake Enable
- }
-
- Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
-
- Method (_PSW, 1) // Power State Wake method
- {
- // USB Controller can wake OS from Sleep State
- If (Arg0) {
- Store (3, U3WE)
- } Else {
- Store (0, U3WE)
- }
- }
-
- // Leave USB ports on for to allow Wake from USB
-
- Method(_S3D,0) // Highest D State in S3 State
- {
- Return (2)
- }
-
- Method(_S4D,0) // Highest D State in S4 State
- {
- Return (2)
- }
-
-}
-
-
-// USB Controller 0:1d.3
-
-Device (USB4)
-{
- Name(_ADR, 0x001d0003)
-
- OperationRegion(U04P, PCI_Config, 0, 256)
- Field(U04P, DWordAcc, NoLock, Preserve)
- {
- Offset(0xc4),
- U4WE, 2 // USB Wake Enable
- }
-
- Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
-
- Method (_PSW, 1) // Power State Wake method
- {
- // USB Controller can wake OS from Sleep State
- If (Arg0) {
- Store (3, U4WE)
- } Else {
- Store (0, U4WE)
- }
- }
-
- // Leave USB ports on for to allow Wake from USB
-
- Method(_S3D,0) // Highest D State in S3 State
- {
- Return (2)
- }
-
- Method(_S4D,0) // Highest D State in S4 State
- {
- Return (2)
- }
-
-}
-
-
-// EHCI Controller 0:1d.7
-
-Device (EHC1)
-{
- Name(_ADR, 0x001d0007)
-
- Name (_PRW, Package(){ 13, 4 }) // Power Resources for Wake
-
- // Leave USB ports on for to allow Wake from USB
-
- Method(_S3D,0) // Highest D State in S3 State
- {
- Return (2)
- }
-
- Method(_S4D,0) // Highest D State in S4 State
- {
- Return (2)
- }
-
- Device (HUB7)
- {
- Name (_ADR, 0x00000000)
-
- // How many are there?
- Device (PRT1) { Name (_ADR, 1) } // USB Port 0
- Device (PRT2) { Name (_ADR, 2) } // USB Port 1
- Device (PRT3) { Name (_ADR, 3) } // USB Port 2
- Device (PRT4) { Name (_ADR, 4) } // USB Port 3
- Device (PRT5) { Name (_ADR, 5) } // USB Port 4
- Device (PRT6) { Name (_ADR, 6) } // USB Port 5
- }
-}
-
-
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+Device (LNKA)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 1)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTA)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLA, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLA, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTA
+ ShiftLeft(1, And(PRTA, 0x0f), IRQ0)
+
+ Return (RTLA)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTA)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTA, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKB)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 2)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTB)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLB, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLB, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTB
+ ShiftLeft(1, And(PRTB, 0x0f), IRQ0)
+
+ Return (RTLB)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTB)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTB, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKC)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 3)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTC)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLC, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLC, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTC
+ ShiftLeft(1, And(PRTC, 0x0f), IRQ0)
+
+ Return (RTLC)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTC)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTC, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKD)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 4)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTD)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLD, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLD, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTD
+ ShiftLeft(1, And(PRTD, 0x0f), IRQ0)
+
+ Return (RTLD)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTD)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTD, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKE)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 5)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTE)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLE, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLE, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTE
+ ShiftLeft(1, And(PRTE, 0x0f), IRQ0)
+
+ Return (RTLE)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTE)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTE, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKF)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 6)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTF)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLF, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLF, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTF
+ ShiftLeft(1, And(PRTF, 0x0f), IRQ0)
+
+ Return (RTLF)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTF)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTF, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKG)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 7)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTG)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 10, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLG, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLG, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTG
+ ShiftLeft(1, And(PRTG, 0x0f), IRQ0)
+
+ Return (RTLG)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTG)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTG, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
+Device (LNKH)
+{
+ Name (_HID, EISAID("PNP0C0F"))
+ Name (_UID, 8)
+
+ // Disable method
+ Method (_DIS, 0, Serialized)
+ {
+ Store (0x80, PRTH)
+ }
+
+ // Possible Resource Settings for this Link
+ Name (_PRS, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared)
+ { 1, 3, 4, 5, 6, 7, 11, 12, 14, 15 }
+ })
+
+ // Current Resource Settings for this link
+ Method (_CRS, 0, Serialized)
+ {
+ Name (RTLH, ResourceTemplate()
+ {
+ IRQ(Level, ActiveLow, Shared) {}
+ })
+ CreateWordField(RTLH, 1, IRQ0)
+
+ // Clear the WordField
+ Store (Zero, IRQ0)
+
+ // Set the bit from PRTH
+ ShiftLeft(1, And(PRTH, 0x0f), IRQ0)
+
+ Return (RTLH)
+ }
+
+ // Set Resource Setting for this IRQ link
+ Method (_SRS, 1, Serialized)
+ {
+ CreateWordField(Arg0, 1, IRQ0)
+
+ // Which bit is set?
+ FindSetRightBit(IRQ0, Local0)
+
+ Decrement(Local0)
+ Store(Local0, PRTH)
+ }
+
+ // Status
+ Method (_STA, 0, Serialized)
+ {
+ If(And(PRTH, 0x80)) {
+ Return (0x9)
+ } Else {
+ Return (0xb)
+ }
+ }
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Intel LPC Bus Device - 0:1f.0
+
+Device (LPCB)
+{
+ Name(_ADR, 0x001f0000)
+
+ OperationRegion(LPC0, PCI_Config, 0x00, 0x100)
+ Field (LPC0, AnyAcc, NoLock, Preserve)
+ {
+ Offset (0x40),
+ PMBS, 16, // PMBASE
+ Offset (0x60), // Interrupt Routing Registers
+ PRTA, 8,
+ PRTB, 8,
+ PRTC, 8,
+ PRTD, 8,
+ Offset (0x68),
+ PRTE, 8,
+ PRTF, 8,
+ PRTG, 8,
+ PRTH, 8,
+
+ Offset (0x80), // IO Decode Ranges
+ IOD0, 8,
+ IOD1, 8,
+
+ Offset (0xf0), // RCBA
+ RCEN, 1,
+ , 13,
+ RCBA, 18,
+ }
+
+ #include "../../../southbridge/intel/i82801gx/acpi/irqlinks.asl"
+
+ #include "acpi/ec.asl"
+
+ Device (DMAC) // DMA Controller
+ {
+ Name(_HID, EISAID("PNP0200"))
+ Name(_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x00, 0x00, 0x01, 0x20)
+ IO (Decode16, 0x81, 0x81, 0x01, 0x11)
+ IO (Decode16, 0x93, 0x93, 0x01, 0x0d)
+ IO (Decode16, 0xc0, 0xc0, 0x01, 0x20)
+ DMA (Compatibility, NotBusMaster, Transfer8_16) { 4 }
+ })
+ }
+
+ Device (FWH) // Firmware Hub
+ {
+ Name (_HID, EISAID("INT0800"))
+ Name (_CRS, ResourceTemplate()
+ {
+ Memory32Fixed(ReadOnly, 0xff000000, 0x01000000)
+ })
+ }
+
+ Device (HPET)
+ {
+ Name (_HID, EISAID("PNP0103"))
+ Name (_CID, 0x010CD041)
+
+ Name(BUF0, ResourceTemplate()
+ {
+ Memory32Fixed(ReadOnly, 0xfed00000, 0x400, FED0)
+ })
+
+ Method (_STA, 0) // Device Status
+ {
+ If (HPTE) {
+ // Note: Ancient versions of Windows don't want
+ // to see the HPET in order to work right
+ If (LGreaterEqual(OSYS, 2001)) {
+ Return (0xf) // Enable and show device
+ } Else {
+ Return (0xb) // Enable and don't show device
+ }
+ }
+
+ Return (0x0) // Not enabled, don't show.
+ }
+
+ Method (_CRS, 0, Serialized) // Current resources
+ {
+ If (HPTE) {
+ CreateDWordField(BUF0, \_SB.PCI0.LPCB.HPET.FED0._BAS, HPT0)
+ If (Lequal(HPAS, 1)) {
+ Store(0xfed01000, HPT0)
+ }
+
+ If (Lequal(HPAS, 2)) {
+ Store(0xfed02000, HPT0)
+ }
+
+ If (Lequal(HPAS, 3)) {
+ Store(0xfed03000, HPT0)
+ }
+ }
+
+ Return (BUF0)
+ }
+ }
+
+ Device(PIC) // 8259 Interrupt Controller
+ {
+ Name(_HID,EISAID("PNP0000"))
+ Name(_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x20, 0x20, 0x01, 0x02)
+ IO (Decode16, 0x24, 0x24, 0x01, 0x02)
+ IO (Decode16, 0x28, 0x28, 0x01, 0x02)
+ IO (Decode16, 0x2c, 0x2c, 0x01, 0x02)
+ IO (Decode16, 0x30, 0x30, 0x01, 0x02)
+ IO (Decode16, 0x34, 0x34, 0x01, 0x02)
+ IO (Decode16, 0x38, 0x38, 0x01, 0x02)
+ IO (Decode16, 0x3c, 0x3c, 0x01, 0x02)
+ IO (Decode16, 0xa0, 0xa0, 0x01, 0x02)
+ IO (Decode16, 0xa4, 0xa4, 0x01, 0x02)
+ IO (Decode16, 0xa8, 0xa8, 0x01, 0x02)
+ IO (Decode16, 0xac, 0xac, 0x01, 0x02)
+ IO (Decode16, 0xb0, 0xb0, 0x01, 0x02)
+ IO (Decode16, 0xb4, 0xb4, 0x01, 0x02)
+ IO (Decode16, 0xb8, 0xb8, 0x01, 0x02)
+ IO (Decode16, 0xbc, 0xbc, 0x01, 0x02)
+ IO (Decode16, 0x4d0, 0x4d0, 0x01, 0x02)
+ IRQNoFlags () { 2 }
+ })
+ }
+
+ Device(MATH) // FPU
+ {
+ Name (_HID, EISAID("PNP0C04"))
+ Name (_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0xf0, 0xf0, 0x01, 0x01)
+ IRQNoFlags() { 13 }
+ })
+ }
+
+ Device(LDRC) // LPC device: Resource consumption
+ {
+ Name (_HID, EISAID("PNP0C02"))
+ Name (_UID, 2)
+ Name (_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x2e, 0x2e, 0x1, 0x02) // First SuperIO
+ IO (Decode16, 0x4e, 0x4e, 0x1, 0x02) // Second SuperIO
+ IO (Decode16, 0x61, 0x61, 0x1, 0x01) // NMI Status
+ IO (Decode16, 0x63, 0x63, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x65, 0x65, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x67, 0x67, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0x80, 0x80, 0x1, 0x01) // Port 80 Post
+ IO (Decode16, 0x92, 0x92, 0x1, 0x01) // CPU Reserved
+ IO (Decode16, 0xb2, 0xb2, 0x1, 0x02) // SWSMI
+ IO (Decode16, 0x800, 0x800, 0x1, 0x10) // ACPI I/O trap
+ IO (Decode16, DEFAULT_PMBASE, DEFAULT_PMBASE, 0x1, 0x80) // ICH7-M ACPI
+ IO (Decode16, DEFAULT_GPIOBASE, DEFAULT_GPIOBASE, 0x1, 0x40) // ICH7-M GPIO
+ })
+ }
+
+ Device (RTC) // Real Time Clock
+ {
+ Name (_HID, EISAID("PNP0B00"))
+ Name (_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x70, 0x70, 1, 8)
+// Disable as Windows doesn't like it, and systems don't seem to use it.
+// IRQNoFlags() { 8 }
+ })
+ }
+
+ Device (TIMR) // Intel 8254 timer
+ {
+ Name(_HID, EISAID("PNP0100"))
+ Name(_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x40, 0x40, 0x01, 0x04)
+ IO (Decode16, 0x50, 0x50, 0x10, 0x04)
+ IRQNoFlags() {0}
+ })
+ }
+
+ #include "acpi/superio.asl"
+
+#ifdef ENABLE_TPM
+ Device (TPM) // Trusted Platform Module
+ {
+ Name(_HID, EISAID("IFX0102"))
+ Name(_CID, 0x310cd041)
+ Name(_UID, 1)
+
+ Method(_STA, 0)
+ {
+ If (TPMP) {
+ Return (0xf)
+ }
+ Return (0x0)
+ }
+
+ Name(_CRS, ResourceTemplate() {
+ IO (Decode16, 0x2e, 0x2e, 0x01, 0x02)
+ IO (Decode16, 0x6f0, 0x6f0, 0x01, 0x10)
+ Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
+ IRQ (Edge, Activehigh, Exclusive) { 6 }
+ })
+ }
+#endif
+
+ Device (PS2K) // Keyboard
+ {
+ Name(_HID, EISAID("PNP0303"))
+ Name(_CID, EISAID("PNP030B"))
+
+ Name(_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x60, 0x60, 0x01, 0x01)
+ IO (Decode16, 0x64, 0x64, 0x01, 0x01)
+ IRQ (Edge, ActiveHigh, Exclusive) { 0x01 } // IRQ 1
+ })
+
+ Method (_STA, 0)
+ {
+ Return (0xf)
+ }
+ }
+
+ Device (PS2M) // Mouse
+ {
+ Name(_HID, EISAID("PNP0F13"))
+ Name(_CRS, ResourceTemplate()
+ {
+ IRQ (Edge, ActiveHigh, Exclusive) { 0x0c } // IRQ 12
+ })
+
+ Method(_STA, 0)
+ {
+ Return (0xf)
+ }
+ }
+
+#ifdef ENABLE_FDC
+ Device (FDC0) // Floppy controller
+ {
+ Name (_HID, EisaId ("PNP0700"))
+ Method (_STA, 0, NotSerialized)
+ {
+ Return (0x0f) // FIXME
+ }
+
+ Name(_CRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+ IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+ IRQNoFlags () {6}
+ DMA (Compatibility, NotBusMaster, Transfer8) {2}
+ })
+
+ Name(_PRS, ResourceTemplate()
+ {
+ IO (Decode16, 0x03F0, 0x03F0, 0x01, 0x06)
+ IO (Decode16, 0x03F7, 0x03F7, 0x01, 0x01)
+ IRQNoFlags () {6}
+ DMA (Compatibility, NotBusMaster, Transfer8) {2}
+ })
+
+ }
+#endif
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Intel PATA Controller 0:1f.1
+
+Device (PATA)
+{
+ Name (_ADR, 0x001f0001)
+
+ Device (PRID)
+ {
+ Name (_ADR, 0)
+
+ // Get Timing Mode
+ Method (_GTM)
+ {
+ Name(PBUF, Buffer(20) {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00 })
+
+ CreateDwordField (PBUF, 0, PIO0)
+ CreateDwordField (PBUF, 4, DMA0)
+ CreateDwordField (PBUF, 8, PIO1)
+ CreateDwordField (PBUF, 12, DMA1)
+ CreateDwordField (PBUF, 16, FLAG)
+
+ // TODO fill return structure
+
+ Return (PBUF)
+ }
+
+ // Set Timing Mode
+ Method (_STM, 3)
+ {
+ CreateDwordField (Arg0, 0, PIO0)
+ CreateDwordField (Arg0, 4, DMA0)
+ CreateDwordField (Arg0, 8, PIO1)
+ CreateDwordField (Arg0, 12, DMA1)
+ CreateDwordField (Arg0, 16, FLAG)
+
+ // TODO: Do the deed
+ }
+
+ Device (DSK0)
+ {
+ Name (_ADR, 0)
+ // TODO: _RMV ?
+ // TODO: _GTF ?
+ }
+
+ Device (DSK1)
+ {
+ Name (_ADR, 1)
+
+ // TODO: _RMV ?
+ // TODO: _GTF ?
+ }
+
+ }
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Intel PCI to PCI bridge 0:1e.0
+
+Device (PCIB)
+{
+ Name (_ADR, 0x001e0000)
+
+ Device (SLT1)
+ {
+ Name (_ADR, 0x00000000)
+ Name (_PRW, Package(){ 11, 4 })
+ }
+
+ Device (SLT2)
+ {
+ Name (_ADR, 0x00010000)
+ Name (_PRW, Package(){ 11, 4 })
+ }
+
+ Device (SLT3)
+ {
+ Name (_ADR, 0x00020000)
+ Name (_PRW, Package(){ 11, 4 })
+ }
+
+ Device (SLT6)
+ {
+ Name (_ADR, 0x00050000)
+ Name (_PRW, Package(){ 11, 4 })
+ }
+
+ Device (LANC)
+ {
+ Name (_ADR, 0x00080000)
+ Name (_PRW, Package(){ 11, 3 })
+ }
+
+ Device (LANR)
+ {
+ Name (_ADR, 0x00000000)
+ Name (_PRW, Package(){ 11, 3 })
+ }
+
+ // TODO: How many slots, where?
+
+ // PCI Interrupt Routing.
+ // If PICM is set, interrupts are routed over the i8259, otherwise
+ // over the IOAPIC. (Really? If they're above 15 they need to be routed
+ // fixed over the IOAPIC?)
+
+ Method (_PRT)
+ {
+ #include "acpi/ich7_pci_irqs.asl"
+ }
+
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Intel i82801G PCIe support */
+
+// PCI Express Ports
+
+Device (RP01)
+{
+ NAME(_ADR, 0x001c0000) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 16 },
+ Package() { 0x0000ffff, 1, 0, 17 },
+ Package() { 0x0000ffff, 2, 0, 18 },
+ Package() { 0x0000ffff, 3, 0, 19 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
+ })
+
+ }
+
+ }
+}
+
+Device (RP02)
+{
+ NAME(_ADR, 0x001c0001) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 17 },
+ Package() { 0x0000ffff, 1, 0, 18 },
+ Package() { 0x0000ffff, 2, 0, 19 },
+ Package() { 0x0000ffff, 3, 0, 16 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
+ })
+
+ }
+
+ }
+}
+
+
+Device (RP03)
+{
+ NAME(_ADR, 0x001c0002) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 18 },
+ Package() { 0x0000ffff, 1, 0, 19 },
+ Package() { 0x0000ffff, 2, 0, 16 },
+ Package() { 0x0000ffff, 3, 0, 17 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKC, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKD, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKB, 0 }
+ })
+
+ }
+
+ }
+}
+
+
+Device (RP04)
+{
+ NAME(_ADR, 0x001c0003) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 19 },
+ Package() { 0x0000ffff, 1, 0, 16 },
+ Package() { 0x0000ffff, 2, 0, 17 },
+ Package() { 0x0000ffff, 3, 0, 18 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKD, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKC, 0 }
+ })
+
+ }
+
+ }
+}
+
+
+Device (RP05)
+{
+ NAME(_ADR, 0x001c0004) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 16 },
+ Package() { 0x0000ffff, 1, 0, 17 },
+ Package() { 0x0000ffff, 2, 0, 18 },
+ Package() { 0x0000ffff, 3, 0, 19 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKA, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKC, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKD, 0 }
+ })
+
+ }
+
+ }
+}
+
+
+Device (RP06)
+{
+ NAME(_ADR, 0x001c0005) // FIXME: Have a macro for PCI Devices -> ACPI notation?
+ //#include "pcie_port.asl"
+ Method(_PRT)
+ {
+ If (PICM) {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, 0, 17 },
+ Package() { 0x0000ffff, 1, 0, 18 },
+ Package() { 0x0000ffff, 2, 0, 19 },
+ Package() { 0x0000ffff, 3, 0, 16 }
+ })
+ } Else {
+ Return (Package() {
+ Package() { 0x0000ffff, 0, \_SB.PCI0.LPCB.LNKB, 0 },
+ Package() { 0x0000ffff, 1, \_SB.PCI0.LPCB.LNKC, 0 },
+ Package() { 0x0000ffff, 2, \_SB.PCI0.LPCB.LNKD, 0 },
+ Package() { 0x0000ffff, 3, \_SB.PCI0.LPCB.LNKA, 0 }
+ })
+
+ }
+
+ }
+}
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Intel SATA Controller 0:1f.2
+
+// Note: Some BIOSes put the S-ATA code into an SSDT to make it easily
+// pluggable
+
+Device (SATA)
+{
+ Name (_ADR, 0x001f0002)
+
+ Device (PRID)
+ {
+ Name (_ADR, 0)
+
+ // Get Timing Mode
+ Method (_GTM)
+ {
+ Name(PBUF, Buffer(20) {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00 })
+
+ CreateDwordField (PBUF, 0, PIO0)
+ CreateDwordField (PBUF, 4, DMA0)
+ CreateDwordField (PBUF, 8, PIO1)
+ CreateDwordField (PBUF, 12, DMA1)
+ CreateDwordField (PBUF, 16, FLAG)
+
+ // TODO fill return structure
+
+ Return (PBUF)
+ }
+
+ // Set Timing Mode
+ Method (_STM, 3)
+ {
+ CreateDwordField (Arg0, 0, PIO0)
+ CreateDwordField (Arg0, 4, DMA0)
+ CreateDwordField (Arg0, 8, PIO1)
+ CreateDwordField (Arg0, 12, DMA1)
+ CreateDwordField (Arg0, 16, FLAG)
+
+ // TODO: Do the deed
+ }
+
+ Device (DSK0)
+ {
+ Name (_ADR, 0)
+ // TODO: _RMV ?
+ // TODO: _GTF ?
+ }
+
+ Device (DSK1)
+ {
+ Name (_ADR, 1)
+
+ // TODO: _RMV ?
+ // TODO: _GTF ?
+ }
+
+ }
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Intel SMBus Controller 0:1f.3
+
+Device (SBUS)
+{
+ Name (_ADR, 0x001f0003)
+
+ OperationRegion (SMBP, PCI_Config, 0x00, 0x100)
+ Field(SMBP, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0x40),
+ , 2,
+ I2CE, 1
+ }
+
+ OperationRegion (SMBI, SystemIO, 0x400, 0x20)
+ Field (SMBI, ByteAcc, NoLock, Preserve)
+ {
+ HSTS, 8, // Host Status
+ , 8,
+ HCNT, 8, // Host Control
+ HCMD, 8, // Host Command
+ TXSA, 8, // Transmit Slave Address
+ DAT0, 8, // Host Data 0
+ DAT1, 8, // Host Data 1
+ HBDB, 8, // Host Block Data Byte
+ PECK, 8, // Packet Error Check
+ RXSA, 8, // Receive Slave Address
+ RXDA, 16, // Receive Slave Data
+ AUXS, 8, // Auxiliary Status
+ AUXC, 8, // Auxiliary Control
+ SLPC, 8, // SMLink Pin Control
+ SBPC, 8, // SMBus Pin Control
+ SSTS, 8, // Slave Status
+ SCMD, 8, // Slave Command
+ NADR, 8, // Notify Device Address
+ NDLB, 8, // Notify Data Low Byte
+ NDLH, 8, // Notify Data High Byte
+ }
+
+#ifdef ENABLE_SMBUS_METHODS
+ // Kill all SMBus communication
+ Method (KILL, 0, Serialized)
+ {
+ Or (HCNT, 0x02, HCNT) // Send Kill
+ Or (HSTS, 0xff, HSTS) // Clean Status
+ }
+
+ // Check if last operation completed
+ // return Failure = 0, Success = 1
+ Method (CMPL, 0, Serialized)
+ {
+ Store (4000, Local0) // Timeout 200ms in 50us steps
+ While (Local0) {
+ If (And(HSTS, 0x02)) { // Completion Status?
+ Return (1) // Operation Completed
+ } Else {
+ Stall (50)
+ Decrement (Local0)
+ If (LEqual(Local0, 0)) {
+ KILL()
+ }
+ }
+ }
+
+ Return (0) // Failure
+ }
+
+
+ // Wait for SMBus to become ready
+ Method (SRDY, 0, Serialized)
+ {
+ Store (200, Local0) // Timeout 200ms
+ While (Local0) {
+ If (And(HSTS, 0x40)) { // IN_USE?
+ Sleep(1) // Wait 1ms
+ Decrement(Local0) // timeout--
+ If (LEqual(Local0, 0)) {
+ Return (1)
+ }
+ } Else {
+ Store (0, Local0) // We're ready
+ }
+ }
+
+ Store (4000, Local0) // Timeout 200ms (50us * 4000)
+ While (Local0) {
+ If (And (HSTS, 0x01)) { // Host Busy?
+ Stall(50) // Wait 50us
+ Decrement(Local0) // timeout--
+ If (LEqual(Local0, 0)) {
+ KILL()
+ }
+ } Else {
+ Return (0) // Success
+ }
+ }
+
+ Return (1) // Failure
+ }
+
+ // SMBus Send Byte
+ // Arg0: Address
+ // Arg1: Data
+ // Return: 1 = Success, 0=Failure
+
+ Method (SSXB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0)
+ }
+
+ // Send Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Arg0, TXSA) // Write Address
+ Store (Arg1, HCMD) // Write Data
+
+ Store (0x48, HCNT) // Start + Byte Data Protocol
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (1) // Success
+ }
+
+ Return (0)
+ }
+
+
+ // SMBus Receive Byte
+ // Arg0: Address
+ // Return: 0xffff = Failure, Data (8bit) = Success
+
+ Method (SRXB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0xffff)
+ }
+
+ // Receive Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Or (Arg0, 1), TXSA) // Write Address
+
+ Store (0x44, HCNT) // Start
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (DAT0) // Success
+ }
+
+ Return (0xffff)
+ }
+
+
+ // SMBus Write Byte
+ // Arg0: Address
+ // Arg1: Command
+ // Arg2: Data
+ // Return: 1 = Success, 0=Failure
+
+ Method (SWRB, 3, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0)
+ }
+
+ // Send Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Arg0, TXSA) // Write Address
+ Store (Arg1, HCMD) // Write Command
+ Store (Arg2, DAT0) // Write Data
+
+ Store (0x48, HCNT) // Start + Byte Protocol
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (1) // Success
+ }
+
+ Return (0)
+ }
+
+
+ // SMBus Read Byte
+ // Arg0: Address
+ // Arg1: Command
+ // Return: 0xffff = Failure, Data (8bit) = Success
+
+ Method (SRDB, 2, Serialized)
+ {
+
+ // Is the SMBus Controller Ready?
+ If (SRDY()) {
+ Return (0xffff)
+ }
+
+ // Receive Byte
+ Store (0, I2CE) // SMBus Enable
+ Store (0xbf, HSTS)
+ Store (Or (Arg0, 1), TXSA) // Write Address
+ Store (Arg1, HCMD) // Command
+
+ Store (0x48, HCNT) // Start
+
+ If (CMPL()) {
+ Or (HSTS, 0xff, HSTS) // Clean up
+ Return (DAT0) // Success
+ }
+
+ Return (0xffff)
+ }
+#endif
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* Intel i82801G USB support */
+
+// USB Controller 0:1d.0
+
+Device (USB1)
+{
+ Name(_ADR, 0x001d0000)
+
+ OperationRegion(U01P, PCI_Config, 0, 256)
+ Field(U01P, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0xc4),
+ U1WE, 2 // USB Wake Enable
+ }
+
+ Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
+
+ Method (_PSW, 1) // Power State Wake method
+ {
+ // USB Controller can wake OS from Sleep State
+ If (Arg0) {
+ Store (3, U1WE)
+ } Else {
+ Store (0, U1WE)
+ }
+ }
+
+ // Leave USB ports on for to allow Wake from USB
+
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+}
+
+
+// USB Controller 0:1d.1
+
+Device (USB2)
+{
+ Name(_ADR, 0x001d0001)
+
+ OperationRegion(U02P, PCI_Config, 0, 256)
+ Field(U02P, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0xc4),
+ U2WE, 2 // USB Wake Enable
+ }
+
+ Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
+
+ Method (_PSW, 1) // Power State Wake method
+ {
+ // USB Controller can wake OS from Sleep State
+ If (Arg0) {
+ Store (3, U2WE)
+ } Else {
+ Store (0, U2WE)
+ }
+ }
+
+ // Leave USB ports on for to allow Wake from USB
+
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+
+}
+
+
+// USB Controller 0:1d.2
+
+Device (USB3)
+{
+ Name(_ADR, 0x001d0002)
+
+ OperationRegion(U03P, PCI_Config, 0, 256)
+ Field(U03P, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0xc4),
+ U3WE, 2 // USB Wake Enable
+ }
+
+ Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
+
+ Method (_PSW, 1) // Power State Wake method
+ {
+ // USB Controller can wake OS from Sleep State
+ If (Arg0) {
+ Store (3, U3WE)
+ } Else {
+ Store (0, U3WE)
+ }
+ }
+
+ // Leave USB ports on for to allow Wake from USB
+
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+
+}
+
+
+// USB Controller 0:1d.3
+
+Device (USB4)
+{
+ Name(_ADR, 0x001d0003)
+
+ OperationRegion(U04P, PCI_Config, 0, 256)
+ Field(U04P, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0xc4),
+ U4WE, 2 // USB Wake Enable
+ }
+
+ Name (_PRW, Package(){ 3, 4 }) // Power Resources for Wake
+
+ Method (_PSW, 1) // Power State Wake method
+ {
+ // USB Controller can wake OS from Sleep State
+ If (Arg0) {
+ Store (3, U4WE)
+ } Else {
+ Store (0, U4WE)
+ }
+ }
+
+ // Leave USB ports on for to allow Wake from USB
+
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+
+}
+
+
+// EHCI Controller 0:1d.7
+
+Device (EHC1)
+{
+ Name(_ADR, 0x001d0007)
+
+ Name (_PRW, Package(){ 13, 4 }) // Power Resources for Wake
+
+ // Leave USB ports on for to allow Wake from USB
+
+ Method(_S3D,0) // Highest D State in S3 State
+ {
+ Return (2)
+ }
+
+ Method(_S4D,0) // Highest D State in S4 State
+ {
+ Return (2)
+ }
+
+ Device (HUB7)
+ {
+ Name (_ADR, 0x00000000)
+
+ // How many are there?
+ Device (PRT1) { Name (_ADR, 1) } // USB Port 0
+ Device (PRT2) { Name (_ADR, 2) } // USB Port 1
+ Device (PRT3) { Name (_ADR, 3) } // USB Port 2
+ Device (PRT4) { Name (_ADR, 4) } // USB Port 3
+ Device (PRT5) { Name (_ADR, 5) } // USB Port 4
+ Device (PRT6) { Name (_ADR, 6) } // USB Port 5
+ }
+}
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "i82801gx.h"
+
+#define HDA_ICII_REG 0x68
+#define HDA_ICII_BUSY (1 << 0)
+#define HDA_ICII_VALID (1 << 1)
+
+typedef struct southbridge_intel_i82801gx_config config_t;
+
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 reg32;
+ int count;
+
+ /* Write (val & mask) to port */
+ val &= mask;
+ reg32 = read32(port);
+ reg32 &= ~mask;
+ reg32 |= val;
+ write32(port, reg32);
+
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
+ count = 50;
+ do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
+ reg32 = read32(port);
+ reg32 &= mask;
+ } while ((reg32 != val) && --count);
+
+ /* Timeout occurred */
+ if (!count)
+ return -1;
+ return 0;
+}
+
+static int codec_detect(u32 base)
+{
+ u32 reg32;
+
+ /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 0) == -1)
+ goto no_codec;
+
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 1) == -1)
+ goto no_codec;
+
+ /* Read in Codec location (BAR + 0xe)[2..0]*/
+ reg32 = read32(base + 0xe);
+ reg32 &= 0x0f;
+ if (!reg32)
+ goto no_codec;
+
+ return reg32;
+
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + 0x08, 1, 0);
+ printk(BIOS_DEBUG, "Azalia: No codec!\n");
+ return 0;
+}
+
+const u32 * cim_verb_data = NULL;
+u32 cim_verb_data_size = 0;
+
+static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
+{
+ int idx=0;
+
+ while (idx < (cim_verb_data_size / sizeof(u32))) {
+ u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
+ if (cim_verb_data[idx] != viddid) {
+ idx += verb_size + 3; // skip verb + header
+ continue;
+ }
+ *verb = &cim_verb_data[idx+3];
+ return verb_size;
+ }
+
+ /* Not all codecs need to load another verb */
+ return 0;
+}
+
+/**
+ * Wait 50usec for the codec to indicate it is ready
+ * no response would imply that the codec is non-operative
+ */
+
+static int wait_for_ready(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+
+ while(timeout--) {
+ u32 reg32 = read32(base + HDA_ICII_REG);
+ if (!(reg32 & HDA_ICII_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Wait 50usec for the codec to indicate that it accepted
+ * the previous command. No response would imply that the code
+ * is non-operative
+ */
+
+static int wait_for_valid(u32 base)
+{
+ u32 reg32;
+
+ /* Send the verb to the codec */
+ reg32 = read32(base + 0x68);
+ reg32 |= (1 << 0) | (1 << 1);
+ write32(base + 0x68, reg32);
+
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+ while(timeout--) {
+ reg32 = read32(base + HDA_ICII_REG);
+ if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
+ HDA_ICII_VALID)
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static void codec_init(struct device *dev, u32 base, int addr)
+{
+ u32 reg32;
+ const u32 *verb;
+ u32 verb_size;
+ int i;
+
+ printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
+
+ /* 1 */
+ if (wait_for_ready(base) == -1)
+ return;
+
+ reg32 = (addr << 28) | 0x000f0000;
+ write32(base + 0x60, reg32);
+
+ if (wait_for_valid(base) == -1)
+ return;
+
+ reg32 = read32(base + 0x64);
+
+ /* 2 */
+ printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
+ verb_size = find_verb(dev, reg32, &verb);
+
+ if (!verb_size) {
+ printk(BIOS_DEBUG, "Azalia: No verb!\n");
+ return;
+ }
+ printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
+
+ /* 3 */
+ for (i = 0; i < verb_size; i++) {
+ if (wait_for_ready(base) == -1)
+ return;
+
+ write32(base + 0x60, verb[i]);
+
+ if (wait_for_valid(base) == -1)
+ return;
+ }
+ printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
+}
+
+static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
+{
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (codec_mask & (1 << i))
+ codec_init(dev, base, i);
+ }
+}
+
+static void azalia_init(struct device *dev)
+{
+ u32 base;
+ struct resource *res;
+ u32 codec_mask;
+ u8 reg8;
+ u32 reg32;
+
+#if CONFIG_MMCONF_SUPPORT
+ // ESD
+ reg32 = pci_mmio_read_config32(dev, 0x134);
+ reg32 &= 0xff00ffff;
+ reg32 |= (2 << 16);
+ pci_mmio_write_config32(dev, 0x134, reg32);
+
+ // Link1 description
+ reg32 = pci_mmio_read_config32(dev, 0x140);
+ reg32 &= 0xff00ffff;
+ reg32 |= (2 << 16);
+ pci_mmio_write_config32(dev, 0x140, reg32);
+
+ // Port VC0 Resource Control Register
+ reg32 = pci_mmio_read_config32(dev, 0x114);
+ reg32 &= 0xffffff00;
+ reg32 |= 1;
+ pci_mmio_write_config32(dev, 0x114, reg32);
+
+ // VCi traffic class
+ reg8 = pci_mmio_read_config8(dev, 0x44);
+ reg8 |= (7 << 0); // TC7
+ pci_mmio_write_config8(dev, 0x44, reg8);
+
+ // VCi Resource Control
+ reg32 = pci_mmio_read_config32(dev, 0x120);
+ reg32 |= (1 << 31);
+ reg32 |= (1 << 24); // VCi ID
+ reg32 |= (0x80 << 0); // VCi map
+ pci_mmio_write_config32(dev, 0x120, reg32);
+#else
+#error ICH7 Azalia required CONFIG_MMCONF_SUPPORT
+#endif
+
+ /* Set Bus Master */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
+
+ pci_write_config8(dev, 0x3c, 0x0a); // unused?
+
+ // TODO Actually check if we're AC97 or HDA instead of hardcoding this
+ // here, in devicetree.cb and/or romstage.c.
+ reg8 = pci_read_config8(dev, 0x40);
+ reg8 |= (1 << 3); // Clear Clock Detect Bit
+ pci_write_config8(dev, 0x40, reg8);
+ reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over
+ pci_write_config8(dev, 0x40, reg8);
+ reg8 |= (1 << 2); // Enable clock detection
+ pci_write_config8(dev, 0x40, reg8);
+ mdelay(1);
+ reg8 = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97");
+
+ //
+ reg8 = pci_read_config8(dev, 0x40); // Audio Control
+ reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
+ pci_write_config8(dev, 0x40, reg8);
+
+ reg8 = pci_read_config8(dev, 0x4d); // Docking Status
+ reg8 &= ~(1 << 7); // Docking not supported
+ pci_write_config8(dev, 0x4d, reg8);
+#if 0
+ /* Set routing pin */
+ pci_write_config32(dev, 0xf8, 0x0);
+ pci_write_config8(dev, 0xfc, 0xAA);
+
+ /* Set INTA */
+ pci_write_config8(dev, 0x63, 0x0);
+
+ /* Enable azalia, disable ac97 */
+ // pm_iowrite(0x59, 0xB);
+#endif
+
+ res = find_resource(dev, 0x10);
+ if (!res)
+ return;
+
+ // NOTE this will break as soon as the Azalia get's a bar above
+ // 4G. Is there anything we can do about it?
+ base = (u32)res->base;
+ printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
+ codec_mask = codec_detect(base);
+
+ if (codec_mask) {
+ printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
+ codecs_init(dev, base, codec_mask);
+ }
+}
+
+static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations azalia_pci_ops = {
+ .set_subsystem = azalia_set_subsystem,
+};
+
+static struct device_operations azalia_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = azalia_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &azalia_pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_azalia __pci_driver = {
+ .ops = &azalia_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27d8,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_ids.h>
+#include <device/pci_def.h>
+#include "i82801gx.h"
+#include "smbus.h"
+
+void enable_smbus(void)
+{
+ device_t dev;
+
+ /* Set the SMBus device statically. */
+ dev = PCI_DEV(0x0, 0x1f, 0x3);
+
+ /* Check to make sure we've got the right device. */
+ if (pci_read_config16(dev, 0x2) != 0x27da) {
+ die("SMBus controller not found!");
+ }
+
+ /* Set SMBus I/O base. */
+ pci_write_config32(dev, SMB_BASE,
+ SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+
+ /* Set SMBus enable. */
+ pci_write_config8(dev, HOSTC, HST_EN);
+
+ /* Set SMBus I/O space enable. */
+ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ /* Disable interrupt generation. */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* Clear any lingering errors, so transactions can run. */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+ print_debug("SMBus controller enabled.\n");
+}
+
+int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
+
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "i82801gx.h"
-
-#define NAMBAR 0x10
-#define MASTER_VOL 0x02
-#define PAGING 0x24
-#define EXT_AUDIO 0x28
-#define FUNC_SEL 0x66
-#define INFO_IO 0x68
-#define CONNECTOR 0x6a
-#define VENDOR_ID1 0x7c
-#define VENDOR_ID2 0x7e
-#define SEC_VENDOR_ID1 0xfc
-#define SEC_VENDOR_ID2 0xfe
-
-#define NABMBAR 0x14
-#define GLOB_CNT 0x2c
-#define GLOB_STA 0x30
-#define CAS 0x34
-
-#define MMBAR 0x10
-#define EXT_MODEM_ID1 0x3c
-#define EXT_MODEM_ID2 0xbc
-
-#define MBAR 0x14
-#define SEC_CODEC 0x40
-
-
-/* FIXME. This table is probably mainboard specific */
-static u16 ac97_function[16*2][4] = {
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) },
- { (1 << 5), (2 << 11), (1 << 10), (3 << 13) }
-};
-
-static u16 nabmbar;
-static u16 nambar;
-
-static int ac97_semaphore(void)
-{
- int timeout;
- u8 reg8;
-
- timeout = 0xffff;
- do {
- reg8 = inb(nabmbar + CAS);
- timeout--;
- } while ((reg8 & 1) && timeout);
- if (! timeout) {
- printk(BIOS_DEBUG, "Timeout!\n");
- }
-
- return (!timeout);
-}
-
-static void init_cnr(void)
-{
- // TODO
-}
-
-static void program_sigid(struct device *dev, u32 id)
-{
- pci_write_config32(dev, 0x2c, id);
-}
-
-static void ac97_audio_init(struct device *dev)
-{
- u16 reg16;
- u32 reg32;
- int i;
-
- printk(BIOS_DEBUG, "Initializing AC'97 Audio.\n");
-
- /* top 16 bits are zero, so don't read them */
- nabmbar = pci_read_config16(dev, NABMBAR) & 0xfffe;
- nambar = pci_read_config16(dev, NAMBAR) & 0xfffe;
-
- reg16 = inw(nabmbar + GLOB_CNT);
- reg16 |= (1 << 1); /* Remove AC_RESET# */
- outw(reg16, nabmbar + GLOB_CNT);
-
- /* Wait 600ms. Ouch. */
- udelay(600 * 1000);
-
- init_cnr();
-
- /* Detect Primary AC'97 Codec */
- reg32 = inl(nabmbar + GLOB_STA);
- if ((reg32 & ((1 << 28) | (1 << 9) | (1 << 8))) == 0) {
- /* Primary Codec not found */
- printk(BIOS_DEBUG, "No primary codec. Disabling AC'97 Audio.\n");
- return;
- }
-
- ac97_semaphore();
-
- /* Detect if codec is programmable */
- outw(0x8000, nambar + MASTER_VOL);
- ac97_semaphore();
- if (inw(nambar + MASTER_VOL) != 0x8000) {
- printk(BIOS_DEBUG, "Codec not programmable. Disabling AC'97 Audio.\n");
- return;
- }
-
- /* Program Vendor IDs */
- reg32 = inw(nambar + VENDOR_ID1);
- reg32 <<= 16;
- reg32 |= (u16)inw(nambar + VENDOR_ID2);
-
- program_sigid(dev, reg32);
-
- /* Is Codec AC'97 2.3 compliant? */
- reg16 = inw(nambar + EXT_AUDIO);
- /* [11:10] = 10b -> AC'97 2.3 */
- if ((reg16 & 0x0c00) != 0x0800) {
- /* No 2.3 Codec. We're done */
- return;
- }
-
- /* Select Page 1 */
- reg16 = inw(nambar + PAGING);
- reg16 &= 0xfff0;
- reg16 |= 0x0001;
- outw(reg16, nambar + PAGING);
-
- for (i = 0x0a * 2; i > 0; i--) {
- outw(i, nambar + FUNC_SEL);
-
- /* Function could not be selected. Next one */
- if (inw(nambar + FUNC_SEL) != i)
- continue;
-
- reg16 = inw(nambar + INFO_IO);
-
- /* Function Information present? */
- if (!(reg16 & (1 << 0)))
- continue;
-
- /* Function Information valid? */
- if (!(reg16 & (1 << 4)))
- continue;
-
- /* Program Buffer Delay [9:5] */
- reg16 &= 0x03e0;
- reg16 |= ac97_function[i][0];
-
- /* Program Gain [15:11] */
- reg16 |= ac97_function[i][1];
-
- /* Program Inversion [10] */
- reg16 |= ac97_function[i][2];
-
- outw(reg16, nambar + INFO_IO);
-
- /* Program Connector / Jack Location */
- reg16 = inw(nambar + CONNECTOR);
- reg16 &= 0x1fff;
- reg16 |= ac97_function[i][3];
- outw(reg16, nambar + CONNECTOR);
- }
-}
-
-static void ac97_modem_init(struct device *dev)
-{
- u16 reg16;
- u32 reg32;
- u16 mmbar, mbar;
-
- mmbar = pci_read_config16(dev, MMBAR) & 0xfffe;
- mbar = pci_read_config16(dev, MBAR) & 0xfffe;
-
- reg16 = inw(mmbar + EXT_MODEM_ID1);
- if ((reg16 & 0xc000) != 0xc000 ) {
- if (reg16 & (1 << 0)) {
- reg32 = inw(mmbar + VENDOR_ID2);
- reg32 <<= 16;
- reg32 |= (u16)inw(mmbar + VENDOR_ID1);
- program_sigid(dev, reg32);
- return;
- }
- }
-
- /* Secondary codec? */
- reg16 = inw(mbar + SEC_CODEC);
- if ((reg16 & (1 << 9)) == 0)
- return;
-
- reg16 = inw(mmbar + EXT_MODEM_ID2);
- if ((reg16 & 0xc000) == 0x4000) {
- if (reg16 & (1 << 0)) {
- reg32 = inw(mmbar + SEC_VENDOR_ID2);
- reg32 <<= 16;
- reg32 |= (u16)inw(mmbar + SEC_VENDOR_ID1);
- program_sigid(dev, reg32);
- return;
- }
- }
-}
-
-static void ac97_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations ac97_pci_ops = {
- .set_subsystem = ac97_set_subsystem,
-};
-
-static struct device_operations ac97_audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ac97_audio_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &ac97_pci_ops,
-};
-
-static struct device_operations ac97_modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ac97_modem_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &ac97_pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-/* Note: 82801GU (ICH7-U) doesn't have AC97 audio. */
-static const struct pci_driver i82801gx_ac97_audio __pci_driver = {
- .ops = &ac97_audio_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27de,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-/* Note: 82801GU (ICH7-U) doesn't have AC97 modem. */
-static const struct pci_driver i82801gx_ac97_modem __pci_driver = {
- .ops = &ac97_modem_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27dd,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "i82801gx.h"
-
-#define HDA_ICII_REG 0x68
-#define HDA_ICII_BUSY (1 << 0)
-#define HDA_ICII_VALID (1 << 1)
-
-typedef struct southbridge_intel_i82801gx_config config_t;
-
-static int set_bits(u32 port, u32 mask, u32 val)
-{
- u32 reg32;
- int count;
-
- /* Write (val & mask) to port */
- val &= mask;
- reg32 = read32(port);
- reg32 &= ~mask;
- reg32 |= val;
- write32(port, reg32);
-
- /* Wait for readback of register to
- * match what was just written to it
- */
- count = 50;
- do {
- /* Wait 1ms based on BKDG wait time */
- mdelay(1);
- reg32 = read32(port);
- reg32 &= mask;
- } while ((reg32 != val) && --count);
-
- /* Timeout occurred */
- if (!count)
- return -1;
- return 0;
-}
-
-static int codec_detect(u32 base)
-{
- u32 reg32;
-
- /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 0) == -1)
- goto no_codec;
-
- /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 1) == -1)
- goto no_codec;
-
- /* Read in Codec location (BAR + 0xe)[2..0]*/
- reg32 = read32(base + 0xe);
- reg32 &= 0x0f;
- if (!reg32)
- goto no_codec;
-
- return reg32;
-
-no_codec:
- /* Codec Not found */
- /* Put HDA back in reset (BAR + 0x8) [0] */
- set_bits(base + 0x08, 1, 0);
- printk(BIOS_DEBUG, "Azalia: No codec!\n");
- return 0;
-}
-
-const u32 * cim_verb_data = NULL;
-u32 cim_verb_data_size = 0;
-
-static u32 find_verb(struct device *dev, u32 viddid, const u32 ** verb)
-{
- int idx=0;
-
- while (idx < (cim_verb_data_size / sizeof(u32))) {
- u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
- if (cim_verb_data[idx] != viddid) {
- idx += verb_size + 3; // skip verb + header
- continue;
- }
- *verb = &cim_verb_data[idx+3];
- return verb_size;
- }
-
- /* Not all codecs need to load another verb */
- return 0;
-}
-
-/**
- * Wait 50usec for the codec to indicate it is ready
- * no response would imply that the codec is non-operative
- */
-
-static int wait_for_ready(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
-
- while(timeout--) {
- u32 reg32 = read32(base + HDA_ICII_REG);
- if (!(reg32 & HDA_ICII_BUSY))
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-/**
- * Wait 50usec for the codec to indicate that it accepted
- * the previous command. No response would imply that the code
- * is non-operative
- */
-
-static int wait_for_valid(u32 base)
-{
- u32 reg32;
-
- /* Send the verb to the codec */
- reg32 = read32(base + 0x68);
- reg32 |= (1 << 0) | (1 << 1);
- write32(base + 0x68, reg32);
-
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
- while(timeout--) {
- reg32 = read32(base + HDA_ICII_REG);
- if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
- HDA_ICII_VALID)
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-static void codec_init(struct device *dev, u32 base, int addr)
-{
- u32 reg32;
- const u32 *verb;
- u32 verb_size;
- int i;
-
- printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
-
- /* 1 */
- if (wait_for_ready(base) == -1)
- return;
-
- reg32 = (addr << 28) | 0x000f0000;
- write32(base + 0x60, reg32);
-
- if (wait_for_valid(base) == -1)
- return;
-
- reg32 = read32(base + 0x64);
-
- /* 2 */
- printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
- verb_size = find_verb(dev, reg32, &verb);
-
- if (!verb_size) {
- printk(BIOS_DEBUG, "Azalia: No verb!\n");
- return;
- }
- printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
-
- /* 3 */
- for (i = 0; i < verb_size; i++) {
- if (wait_for_ready(base) == -1)
- return;
-
- write32(base + 0x60, verb[i]);
-
- if (wait_for_valid(base) == -1)
- return;
- }
- printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
-}
-
-static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
-{
- int i;
- for (i = 2; i >= 0; i--) {
- if (codec_mask & (1 << i))
- codec_init(dev, base, i);
- }
-}
-
-static void azalia_init(struct device *dev)
-{
- u32 base;
- struct resource *res;
- u32 codec_mask;
- u8 reg8;
- u32 reg32;
-
-#if CONFIG_MMCONF_SUPPORT
- // ESD
- reg32 = pci_mmio_read_config32(dev, 0x134);
- reg32 &= 0xff00ffff;
- reg32 |= (2 << 16);
- pci_mmio_write_config32(dev, 0x134, reg32);
-
- // Link1 description
- reg32 = pci_mmio_read_config32(dev, 0x140);
- reg32 &= 0xff00ffff;
- reg32 |= (2 << 16);
- pci_mmio_write_config32(dev, 0x140, reg32);
-
- // Port VC0 Resource Control Register
- reg32 = pci_mmio_read_config32(dev, 0x114);
- reg32 &= 0xffffff00;
- reg32 |= 1;
- pci_mmio_write_config32(dev, 0x114, reg32);
-
- // VCi traffic class
- reg8 = pci_mmio_read_config8(dev, 0x44);
- reg8 |= (7 << 0); // TC7
- pci_mmio_write_config8(dev, 0x44, reg8);
-
- // VCi Resource Control
- reg32 = pci_mmio_read_config32(dev, 0x120);
- reg32 |= (1 << 31);
- reg32 |= (1 << 24); // VCi ID
- reg32 |= (0x80 << 0); // VCi map
- pci_mmio_write_config32(dev, 0x120, reg32);
-#else
-#error ICH7 Azalia required CONFIG_MMCONF_SUPPORT
-#endif
-
- /* Set Bus Master */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
-
- pci_write_config8(dev, 0x3c, 0x0a); // unused?
-
- // TODO Actually check if we're AC97 or HDA instead of hardcoding this
- // here, in devicetree.cb and/or romstage.c.
- reg8 = pci_read_config8(dev, 0x40);
- reg8 |= (1 << 3); // Clear Clock Detect Bit
- pci_write_config8(dev, 0x40, reg8);
- reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over
- pci_write_config8(dev, 0x40, reg8);
- reg8 |= (1 << 2); // Enable clock detection
- pci_write_config8(dev, 0x40, reg8);
- mdelay(1);
- reg8 = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97");
-
- //
- reg8 = pci_read_config8(dev, 0x40); // Audio Control
- reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
- pci_write_config8(dev, 0x40, reg8);
-
- reg8 = pci_read_config8(dev, 0x4d); // Docking Status
- reg8 &= ~(1 << 7); // Docking not supported
- pci_write_config8(dev, 0x4d, reg8);
-#if 0
- /* Set routing pin */
- pci_write_config32(dev, 0xf8, 0x0);
- pci_write_config8(dev, 0xfc, 0xAA);
-
- /* Set INTA */
- pci_write_config8(dev, 0x63, 0x0);
-
- /* Enable azalia, disable ac97 */
- // pm_iowrite(0x59, 0xB);
-#endif
-
- res = find_resource(dev, 0x10);
- if (!res)
- return;
-
- // NOTE this will break as soon as the Azalia get's a bar above
- // 4G. Is there anything we can do about it?
- base = (u32)res->base;
- printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
- codec_mask = codec_detect(base);
-
- if (codec_mask) {
- printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
- codecs_init(dev, base, codec_mask);
- }
-}
-
-static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations azalia_pci_ops = {
- .set_subsystem = azalia_set_subsystem,
-};
-
-static struct device_operations azalia_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = azalia_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &azalia_pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_azalia __pci_driver = {
- .ops = &azalia_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27d8,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <device/pci_def.h>
-#include "i82801gx.h"
-#include "i82801gx_smbus.h"
-
-void enable_smbus(void)
-{
- device_t dev;
-
- /* Set the SMBus device statically. */
- dev = PCI_DEV(0x0, 0x1f, 0x3);
-
- /* Check to make sure we've got the right device. */
- if (pci_read_config16(dev, 0x2) != 0x27da) {
- die("SMBus controller not found!");
- }
-
- /* Set SMBus I/O base. */
- pci_write_config32(dev, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
-
- /* Set SMBus enable. */
- pci_write_config8(dev, HOSTC, HST_EN);
-
- /* Set SMBus I/O space enable. */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Disable interrupt generation. */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* Clear any lingering errors, so transactions can run. */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- print_debug("SMBus controller enabled.\n");
-}
-
-int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801gx.h"
-
-typedef struct southbridge_intel_i82801gx_config config_t;
-
-static void ide_init(struct device *dev)
-{
- u16 ideTimingConfig;
- u32 reg32;
- u32 enable_primary, enable_secondary;
-
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- printk(BIOS_DEBUG, "i82801gx_ide: initializing... ");
- if (config == NULL) {
- printk(BIOS_ERR, "\ni82801gx_ide: Not mentioned in devicetree.cb!\n");
- // Trying to set somewhat safe defaults instead of bailing out.
- enable_primary = enable_secondary = 1;
- } else {
- enable_primary = config->ide_enable_primary;
- enable_secondary = config->ide_enable_secondary;
- }
-
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
-
- /* Native Capable, but not enabled. */
- pci_write_config8(dev, 0x09, 0x8a);
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- ideTimingConfig |= IDE_SITRE;
- if (enable_primary) {
- /* Enable primary IDE interface. */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- ideTimingConfig |= (2 << 12); // ISP = 3 clocks
- ideTimingConfig |= (3 << 8); // RCT = 1 clock
- ideTimingConfig |= (1 << 1); // IE0
- ideTimingConfig |= (1 << 0); // TIME0
- printk(BIOS_DEBUG, "IDE0 ");
- }
- pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
-
- ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
- ideTimingConfig &= ~IDE_DECODE_ENABLE;
- ideTimingConfig |= IDE_SITRE;
- if (enable_secondary) {
- /* Enable secondary IDE interface. */
- ideTimingConfig |= IDE_DECODE_ENABLE;
- ideTimingConfig |= (2 << 12); // ISP = 3 clocks
- ideTimingConfig |= (3 << 8); // RCT = 1 clock
- ideTimingConfig |= (1 << 1); // IE0
- ideTimingConfig |= (1 << 0); // TIME0
- printk(BIOS_DEBUG, "IDE1 ");
- }
- pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
-
- /* Set IDE I/O Configuration */
- reg32 = 0;
- /* FIXME: only set FAST_* for ata/100, only ?CBx for ata/66 */
- if (enable_primary)
- reg32 |= SIG_MODE_PRI_NORMAL | FAST_PCB0 | PCB0 | FAST_PCB1 | PCB1;
- if (enable_secondary)
- reg32 |= SIG_MODE_SEC_NORMAL | FAST_SCB0 | SCB0 | FAST_SCB1 | SCB1;
- pci_write_config32(dev, IDE_CONFIG, reg32);
-
- /* Set Interrupt Line */
- /* Interrupt Pin is set by D31IP.PIP */
- pci_write_config32(dev, INTR_LN, 0xff); /* Int 15 */
-
- printk(BIOS_DEBUG, "\n");
-}
-
-static void ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations ide_pci_ops = {
- .set_subsystem = ide_set_subsystem,
-};
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &ide_pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gx_ide __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27df,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <pc80/i8259.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include "i82801gx.h"
-
-#define NMI_OFF 0
-
-#define ENABLE_ACPI_MODE_IN_COREBOOT 0
-#define TEST_SMM_FLASH_LOCKDOWN 0
-
-typedef struct southbridge_intel_i82801gx_config config_t;
-
-static void i82801gx_enable_apic(struct device *dev)
-{
- int i;
- u32 reg32;
- volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
- volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
-
- /* Enable ACPI I/O and power management.
- * Set SCI IRQ to IRQ9
- */
- pci_write_config8(dev, ACPI_CNTL, 0x80);
-
- *ioapic_index = 0;
- *ioapic_data = (1 << 25);
-
- *ioapic_index = 0;
- reg32 = *ioapic_data;
- printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", (reg32 >> 24) & 0x0f);
- if (reg32 != (1 << 25))
- die("APIC Error\n");
-
- printk(BIOS_SPEW, "Dumping IOAPIC registers\n");
- for (i=0; i<3; i++) {
- *ioapic_index = i;
- printk(BIOS_SPEW, " reg 0x%04x:", i);
- reg32 = *ioapic_data;
- printk(BIOS_SPEW, " 0x%08x\n", reg32);
- }
-
- *ioapic_index = 3; /* Select Boot Configuration register. */
- *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
-}
-
-static void i82801gx_enable_serial_irqs(struct device *dev)
-{
- /* Set packet length and toggle silent mode bit for one frame. */
- pci_write_config8(dev, SERIRQ_CNTL,
- (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
-}
-
-/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
- * 0x00 - 0000 = Reserved
- * 0x01 - 0001 = Reserved
- * 0x02 - 0010 = Reserved
- * 0x03 - 0011 = IRQ3
- * 0x04 - 0100 = IRQ4
- * 0x05 - 0101 = IRQ5
- * 0x06 - 0110 = IRQ6
- * 0x07 - 0111 = IRQ7
- * 0x08 - 1000 = Reserved
- * 0x09 - 1001 = IRQ9
- * 0x0A - 1010 = IRQ10
- * 0x0B - 1011 = IRQ11
- * 0x0C - 1100 = IRQ12
- * 0x0D - 1101 = Reserved
- * 0x0E - 1110 = IRQ14
- * 0x0F - 1111 = IRQ15
- * PIRQ[n]_ROUT[7] - PIRQ Routing Control
- * 0x80 - The PIRQ is not routed.
- */
-
-static void i82801gx_pirq_init(device_t dev)
-{
- device_t irq_dev;
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
- pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
- pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
- pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
-
- pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
- pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
- pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
- pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
-
- /* Eric Biederman once said we should let the OS do this.
- * I am not so sure anymore he was right.
- */
-
- for(irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
- u8 int_pin=0, int_line=0;
-
- if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
- continue;
-
- int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
-
- switch (int_pin) {
- case 1: /* INTA# */ int_line = config->pirqa_routing; break;
- case 2: /* INTB# */ int_line = config->pirqb_routing; break;
- case 3: /* INTC# */ int_line = config->pirqc_routing; break;
- case 4: /* INTD# */ int_line = config->pirqd_routing; break;
- }
-
- if (!int_line)
- continue;
-
- pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
- }
-}
-
-static void i82801gx_gpi_routing(device_t dev)
-{
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
- u32 reg32 = 0;
-
- /* An array would be much nicer here, or some
- * other method of doing this.
- */
- reg32 |= (config->gpi0_routing & 0x03) << 0;
- reg32 |= (config->gpi1_routing & 0x03) << 2;
- reg32 |= (config->gpi2_routing & 0x03) << 4;
- reg32 |= (config->gpi3_routing & 0x03) << 6;
- reg32 |= (config->gpi4_routing & 0x03) << 8;
- reg32 |= (config->gpi5_routing & 0x03) << 10;
- reg32 |= (config->gpi6_routing & 0x03) << 12;
- reg32 |= (config->gpi7_routing & 0x03) << 14;
- reg32 |= (config->gpi8_routing & 0x03) << 16;
- reg32 |= (config->gpi9_routing & 0x03) << 18;
- reg32 |= (config->gpi10_routing & 0x03) << 20;
- reg32 |= (config->gpi11_routing & 0x03) << 22;
- reg32 |= (config->gpi12_routing & 0x03) << 24;
- reg32 |= (config->gpi13_routing & 0x03) << 26;
- reg32 |= (config->gpi14_routing & 0x03) << 28;
- reg32 |= (config->gpi15_routing & 0x03) << 30;
-
- pci_write_config32(dev, 0xb8, reg32);
-}
-
-extern u8 acpi_slp_type;
-
-static void i82801gx_power_options(device_t dev)
-{
- u8 reg8;
- u16 reg16, pmbase;
- u32 reg32;
- const char *state;
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- int nmi_option;
-
- /* Which state do we want to goto after g3 (power restored)?
- * 0 == S0 Full On
- * 1 == S5 Soft Off
- *
- * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
- */
- if (get_option(&pwr_on, "power_on_after_fail") < 0)
- pwr_on = MAINBOARD_POWER_ON;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- reg8 &= 0xfe;
- switch (pwr_on) {
- case MAINBOARD_POWER_OFF:
- reg8 |= 1;
- state = "off";
- break;
- case MAINBOARD_POWER_ON:
- reg8 &= ~1;
- state = "on";
- break;
- case MAINBOARD_POWER_KEEP:
- reg8 &= ~1;
- state = "state keep";
- break;
- default:
- state = "undefined";
- }
-
- reg8 |= (3 << 4); /* avoid #S4 assertions */
- reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
-
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- printk(BIOS_INFO, "Set power %s after power failure.\n", state);
-
- /* Set up NMI on errors. */
- reg8 = inb(0x61);
- reg8 &= 0x0f; /* Higher Nibble must be 0 */
- reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
- // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
- reg8 |= (1 << 2); /* PCI SERR# Disable for now */
- outb(reg8, 0x61);
-
- reg8 = inb(0x70);
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- printk(BIOS_INFO, "NMI sources enabled.\n");
- reg8 &= ~(1 << 7); /* Set NMI. */
- } else {
- printk(BIOS_INFO, "NMI sources disabled.\n");
- reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
- }
- outb(reg8, 0x70);
-
- /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
- reg16 = pci_read_config16(dev, GEN_PMCON_1);
- reg16 &= ~(3 << 0); // SMI# rate 1 minute
- reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only
- reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only
- reg16 |= (1 << 5); // CPUSLP_EN Desktop only
- // another laptop wants this?
- // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
- reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
-#if DEBUG_PERIODIC_SMIS
- /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
- * periodic SMIs.
- */
- reg16 |= (3 << 0); // Periodic SMI every 8s
-#endif
- pci_write_config16(dev, GEN_PMCON_1, reg16);
-
- // Set the board's GPI routing.
- i82801gx_gpi_routing(dev);
-
- pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
-
- outl(config->gpe0_en, pmbase + GPE0_EN);
- outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);
-
- /* Set up power management block and determine sleep mode */
- reg32 = inl(pmbase + 0x04); // PM1_CNT
-
- reg32 &= ~(7 << 10); // SLP_TYP
- reg32 |= (1 << 1); // enable C3->C0 transition on bus master
- reg32 |= (1 << 0); // SCI_EN
- outl(reg32, pmbase + 0x04);
-}
-
-static void i82801gx_configure_cstates(device_t dev)
-{
- u8 reg8;
-
- reg8 = pci_read_config8(dev, 0xa9); // Cx state configuration
- reg8 |= (1 << 4) | (1 << 3) | (1 << 2); // Enable Popup & Popdown
- pci_write_config8(dev, 0xa9, reg8);
-
- // Set Deeper Sleep configuration to recommended values
- reg8 = pci_read_config8(dev, 0xaa);
- reg8 &= 0xf0;
- reg8 |= (2 << 2); // Deeper Sleep to Stop CPU: 34-40us
- reg8 |= (2 << 0); // Deeper Sleep to Sleep: 15us
- pci_write_config8(dev, 0xaa, reg8);
-}
-
-static void i82801gx_rtc_init(struct device *dev)
-{
- u8 reg8;
- int rtc_failed;
-
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
- rtc_failed = reg8 & RTC_BATTERY_DEAD;
- if (rtc_failed) {
- reg8 &= ~RTC_BATTERY_DEAD;
- pci_write_config8(dev, GEN_PMCON_3, reg8);
- }
- printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
-
- rtc_init(rtc_failed);
-}
-
-static void enable_hpet(void)
-{
- u32 reg32;
-
- /* Move HPET to default address 0xfed00000 and enable it */
- reg32 = RCBA32(HPTC);
- reg32 |= (1 << 7); // HPET Address Enable
- reg32 &= ~(3 << 0);
- RCBA32(HPTC) = reg32;
-}
-
-static void enable_clock_gating(void)
-{
- u32 reg32;
-
- /* Enable Clock Gating for most devices */
- reg32 = RCBA32(CG);
- reg32 |= (1 << 31); // LPC clock gating
- reg32 |= (1 << 30); // PATA clock gating
- // SATA clock gating
- reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
- reg32 |= (1 << 23); // AC97 clock gating
- reg32 |= (1 << 19); // USB EHCI clock gating
- reg32 |= (1 << 3) | (1 << 1); // DMI clock gating
- reg32 |= (1 << 2); // PCIe clock gating;
- reg32 &= ~(1 << 20); // No static clock gating for USB
- reg32 &= ~( (1 << 29) | (1 << 28) ); // Disable UHCI clock gating
- RCBA32(CG) = reg32;
-}
-
-#if CONFIG_HAVE_SMI_HANDLER
-static void i82801gx_lock_smm(struct device *dev)
-{
- void smm_lock(void);
-#if TEST_SMM_FLASH_LOCKDOWN
- u8 reg8;
-#endif
-
-#if ENABLE_ACPI_MODE_IN_COREBOOT
- printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n");
- outb(0xe1, 0xb2); // Enable ACPI mode
- printk(BIOS_DEBUG, "done.\n");
-#else
- printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
- outb(0x1e, 0xb2); // Disable ACPI mode
- printk(BIOS_DEBUG, "done.\n");
-#endif
- /* Don't allow evil boot loaders, kernels, or
- * userspace applications to deceive us:
- */
- smm_lock();
-
-#if TEST_SMM_FLASH_LOCKDOWN
- /* Now try this: */
- printk(BIOS_DEBUG, "Locking BIOS to RO... ");
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
- (reg8&1)?"rw":"ro");
- reg8 &= ~(1 << 0); /* clear BIOSWE */
- pci_write_config8(dev, 0xdc, reg8);
- reg8 |= (1 << 1); /* set BLE */
- pci_write_config8(dev, 0xdc, reg8);
- printk(BIOS_DEBUG, "ok.\n");
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
- (reg8&1)?"rw":"ro");
-
- printk(BIOS_DEBUG, "Writing:\n");
- *(volatile u8 *)0xfff00000 = 0x00;
- printk(BIOS_DEBUG, "Testing:\n");
- reg8 |= (1 << 0); /* set BIOSWE */
- pci_write_config8(dev, 0xdc, reg8);
-
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
- (reg8&1)?"rw":"ro");
- printk(BIOS_DEBUG, "Done.\n");
-#endif
-}
-#endif
-
-#define SPIBASE 0x3020
-static void i82801gx_spi_init(void)
-{
- u16 spicontrol;
-
- spicontrol = RCBA16(SPIBASE + 2);
- spicontrol &= ~(1 << 0); // SPI Access Request
- RCBA16(SPIBASE + 2) = spicontrol;
-}
-
-static void i82801gx_fixups(struct device *dev)
-{
- /* This needs to happen after PCI enumeration */
- RCBA32(0x1d40) |= 1;
-
- /* USB Transient Disconnect Detect:
- * Prevent a SE0 condition on the USB ports from being
- * interpreted by the UHCI controller as a disconnect
- */
- pci_write_config8(dev, 0xad, 0x3);
-}
-
-static void lpc_init(struct device *dev)
-{
- printk(BIOS_DEBUG, "i82801gx: lpc_init\n");
-
- /* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
-
- /* IO APIC initialization. */
- i82801gx_enable_apic(dev);
-
- i82801gx_enable_serial_irqs(dev);
-
- /* Setup the PIRQ. */
- i82801gx_pirq_init(dev);
-
- /* Setup power options. */
- i82801gx_power_options(dev);
-
- /* Configure Cx state registers */
- i82801gx_configure_cstates(dev);
-
- /* Set the state of the GPIO lines. */
- //gpio_init(dev);
-
- /* Initialize the real time clock. */
- i82801gx_rtc_init(dev);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
- /* Initialize the High Precision Event Timers, if present. */
- enable_hpet();
-
- /* Initialize Clock Gating */
- enable_clock_gating();
-
- setup_i8259();
-
- /* The OS should do this? */
- /* Interrupt 9 should be level triggered (SCI) */
- i8259_configure_irq_trigger(9, 1);
-
-#if CONFIG_HAVE_SMI_HANDLER
- i82801gx_lock_smm(dev);
-#endif
-
- i82801gx_spi_init();
-
- i82801gx_fixups(dev);
-}
-
-static void i82801gx_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations pci_ops = {
- .set_subsystem = set_subsystem,
-};
-
-static struct device_operations device_ops = {
- .read_resources = i82801gx_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- .enable = i82801gx_enable,
- .ops_pci = &pci_ops,
-};
-
-/* 82801GH (ICH7 DH) */
-static const struct pci_driver ich7_dh_lpc __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27b0,
-};
-
-/* 82801GB/GR (ICH7/ICH7R) */
-static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27b8,
-};
-
-/* 82801GBM/GU (ICH7-M/ICH7-U) */
-static const struct pci_driver ich7m_ich7u_lpc __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27b9,
-};
-
-/* 82801GHM (ICH7-M DH) */
-static const struct pci_driver ich7m_dh_lpc __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27bd,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This code should work for all ICH* southbridges with a NIC. */
-
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-static void nic_init(struct device *dev)
-{
- /* Nothing yet */
-}
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-/* Note: 82801GU (ICH7-U) doesn't have a NIC. */
-/* PCI ID loaded from EEPROM. If EEPROM is 0, 0x27dc is used. */
-static const struct pci_driver i82801gx_nic __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27dc,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-typedef struct {
- /* Miscellaneous */
- u16 osys; /* 0x00 - Operating System */
- u8 smif; /* 0x02 - SMI function call ("TRAP") */
- u8 prm0; /* 0x03 - SMI function call parameter */
- u8 prm1; /* 0x04 - SMI function call parameter */
- u8 scif; /* 0x05 - SCI function call (via _L00) */
- u8 prm2; /* 0x06 - SCI function call parameter */
- u8 prm3; /* 0x07 - SCI function call parameter */
- u8 lckf; /* 0x08 - Global Lock function for EC */
- u8 prm4; /* 0x09 - Lock function parameter */
- u8 prm5; /* 0x0a - Lock function parameter */
- u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
- u8 lids; /* 0x0f - LID state (open = 1) */
- u8 pwrs; /* 0x10 - Power state (AC = 1) */
- u8 dbgs; /* 0x11 - Debug state */
- u8 linx; /* 0x12 - Linux OS */
- u8 dckn; /* 0x13 - PCIe docking state */
- /* Thermal policy */
- u8 actt; /* 0x14 - active trip point */
- u8 psvt; /* 0x15 - passive trip point */
- u8 tc1v; /* 0x16 - passive trip point TC1 */
- u8 tc2v; /* 0x17 - passive trip point TC2 */
- u8 tspv; /* 0x18 - passive trip point TSP */
- u8 crtt; /* 0x19 - critical trip point */
- u8 dtse; /* 0x1a - Digital Thermal Sensor enable */
- u8 dts1; /* 0x1b - DT sensor 1 */
- u8 dts2; /* 0x1c - DT sensor 2 */
- u8 rsvd2;
- /* Battery Support */
- u8 bnum; /* 0x1e - number of batteries */
- u8 b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
- u8 b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
- u8 rsvd3[3];
- /* Processor Identification */
- u8 apic; /* 0x28 - APIC enabled */
- u8 mpen; /* 0x29 - MP capable/enabled */
- u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
- u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
- u8 ppcm; /* 0x2c - Max. PPC state */
- u8 rsvd4[5];
- /* Super I/O & CMOS config */
- u8 natp; /* 0x32 - SIO type */
- u8 cmap; /* 0x33 - */
- u8 cmbp; /* 0x34 - */
- u8 lptp; /* 0x35 - LPT port */
- u8 fdcp; /* 0x36 - Floppy Disk Controller */
- u8 rfdv; /* 0x37 - */
- u8 hotk; /* 0x38 - Hot Key */
- u8 rtcf;
- u8 util;
- u8 acin;
- /* Integrated Graphics Device */
- u8 igds; /* 0x3c - IGD state */
- u8 tlst; /* 0x3d - Display Toggle List Pointer */
- u8 cadl; /* 0x3e - currently attached devices */
- u8 padl; /* 0x3f - previously attached devices */
- u16 cste; /* 0x40 - current display state */
- u16 nste; /* 0x42 - next display state */
- u16 sste; /* 0x44 - set display state */
- u8 ndid; /* 0x46 - number of device ids */
- u32 did[5]; /* 0x47 - 5b device id 1..5 */
- u8 rsvd5[0x9];
- /* Backlight Control */
- u8 blcs; /* 0x64 - Backlight Control possible */
- u8 brtl;
- u8 odds;
- u8 rsvd6[0x7];
- /* Ambient Light Sensors*/
- u8 alse; /* 0x6e - ALS enable */
- u8 alaf;
- u8 llow;
- u8 lhih;
- u8 rsvd7[0x6];
- /* EMA */
- u8 emae; /* 0x78 - EMA enable */
- u16 emap;
- u16 emal;
- u8 rsvd8[0x5];
- /* MEF */
- u8 mefe; /* 0x82 - MEF enable */
- u8 rsvd9[0x9];
- /* TPM support */
- u8 tpmp; /* 0x8c - TPM */
- u8 tpme;
- u8 rsvd10[8];
- /* SATA */
- u8 gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
- u8 gtf1[7];
- u8 gtf2[7];
- u8 idem;
- u8 idet;
- u8 rsvd11[7];
- /* IGD OpRegion (not implemented yet) */
- u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
- u8 ibtt;
- u8 ipat;
- u8 itvf;
- u8 itvm;
- u8 ipsc;
- u8 iblc;
- u8 ibia;
- u8 issc;
- u8 i409;
- u8 i509;
- u8 i609;
- u8 i709;
- u8 idmm;
- u8 idms;
- u8 if1e;
- u8 hvco;
- u32 nxd[8];
- u8 rsvd12[8];
- /* Mainboard specific */
- u8 dock; /* 0xf0 - Docking Status */
- u8 bten;
- u8 rsvd13[14];
-} __attribute__((packed)) global_nvs_t;
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801gx.h"
-
-static void pci_init(struct device *dev)
-{
- u16 reg16;
- u8 reg8;
-
- /* Enable Bus Master */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 |= PCI_COMMAND_MASTER;
- pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /* This device has no interrupt */
- pci_write_config8(dev, INTR, 0xff);
-
- /* disable parity error response and SERR */
- reg16 = pci_read_config16(dev, BCTRL);
- reg16 &= ~(1 << 0);
- reg16 &= ~(1 << 1);
- pci_write_config16(dev, BCTRL, reg16);
-
- /* Master Latency Count must be set to 0x04! */
- reg8 = pci_read_config8(dev, SMLT);
- reg8 &= 0x07;
- reg8 |= (0x04 << 3);
- pci_write_config8(dev, SMLT, reg8);
-
- /* Will this improve throughput of bus masters? */
- pci_write_config8(dev, PCI_MIN_GNT, 0x06);
-
- /* Clear errors in status registers */
- reg16 = pci_read_config16(dev, PSTS);
- //reg16 |= 0xf900;
- pci_write_config16(dev, PSTS, reg16);
-
- reg16 = pci_read_config16(dev, SECSTS);
- // reg16 |= 0xf900;
- pci_write_config16(dev, SECSTS, reg16);
-}
-
-#undef PCI_BRIDGE_UPDATE_COMMAND
-static void ich_pci_dev_enable_resources(struct device *dev)
-{
- const struct pci_operations *ops;
- uint16_t command;
-
- /* Set the subsystem vendor and device id for mainboard devices */
- ops = ops_pci(dev);
- if (dev->on_mainboard && ops && ops->set_subsystem) {
- printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n",
- dev_path(dev),
- CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
- CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
- ops->set_subsystem(dev,
- CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
- CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
- }
-
- command = pci_read_config16(dev, PCI_COMMAND);
- command |= dev->command;
-#ifdef PCI_BRIDGE_UPDATE_COMMAND
- /* If we write to PCI_COMMAND, on some systems
- * this will cause the ROM and APICs not being visible
- * anymore.
- */
- printk(BIOS_DEBUG, "%s cmd <- %02x\n", dev_path(dev), command);
- pci_write_config16(dev, PCI_COMMAND, command);
-#else
- printk(BIOS_DEBUG, "%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
-#endif
-}
-
-static void ich_pci_bus_enable_resources(struct device *dev)
-{
- uint16_t ctrl;
- /* enable IO in command register if there is VGA card
- * connected with (even it does not claim IO resource)
- */
- if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
- dev->command |= PCI_COMMAND_IO;
- ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
- ctrl |= dev->link_list->bridge_ctrl;
- ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
- printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
- pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
-
- /* This is the reason we need our own pci_bus_enable_resources */
- ich_pci_dev_enable_resources(dev);
-}
-
-static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* NOTE: This is not the default position! */
- if (!vendor || !device) {
- pci_write_config32(dev, 0x54,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, 0x54,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations pci_ops = {
- .set_subsystem = set_subsystem,
-};
-
-static struct device_operations device_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = ich_pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = &pci_ops,
-};
-
-/* Desktop */
-/* 82801BA/CA/DB/EB/ER/FB/FR/FW/FRW/GB/GR/GDH/HB/IB/6300ESB/i3100 */
-static const struct pci_driver i82801g_pci __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x244e,
-};
-
-/* Mobile / Ultra Mobile */
-/* 82801BAM/CAM/DBL/DBM/FBM/GBM/GHM/GU/HBM/HEM */
-static const struct pci_driver i82801gmu_pci __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x2448,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-static void pci_init(struct device *dev)
-{
- u16 reg16;
- u32 reg32;
-
- printk(BIOS_DEBUG, "Initializing ICH7 PCIe bridge.\n");
-
- /* Enable Bus Master */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 |= PCI_COMMAND_MASTER;
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- /* Set Cache Line Size to 0x10 */
- // This has no effect but the OS might expect it
- pci_write_config8(dev, 0x0c, 0x10);
-
- reg16 = pci_read_config16(dev, 0x3e);
- reg16 &= ~(1 << 0); /* disable parity error response */
- // reg16 &= ~(1 << 1); /* disable SERR */
- reg16 |= (1 << 2); /* ISA enable */
- pci_write_config16(dev, 0x3e, reg16);
-
- /* Enable IO xAPIC on this PCIe port */
- reg32 = pci_read_config32(dev, 0xd8);
- reg32 |= (1 << 7);
- pci_write_config32(dev, 0xd8, reg32);
-
- /* Enable Backbone Clock Gating */
- reg32 = pci_read_config32(dev, 0xe1);
- reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
- pci_write_config32(dev, 0xe1, reg32);
-
-#if CONFIG_MMCONF_SUPPORT
- /* Set VC0 transaction class */
- reg32 = pci_mmio_read_config32(dev, 0x114);
- reg32 &= 0xffffff00;
- reg32 |= 1;
- pci_mmio_write_config32(dev, 0x114, reg32);
-
- /* Mask completion timeouts */
- reg32 = pci_mmio_read_config32(dev, 0x148);
- reg32 |= (1 << 14);
- pci_mmio_write_config32(dev, 0x148, reg32);
-#else
-#error "MMIO needed for ICH7 PCIe"
-#endif
- /* Enable common clock configuration */
- // Are there cases when we don't want that?
- reg16 = pci_read_config16(dev, 0x50);
- reg16 |= (1 << 6);
- pci_write_config16(dev, 0x50, reg16);
-
-#ifdef EVEN_MORE_DEBUG
- reg32 = pci_read_config32(dev, 0x20);
- printk(BIOS_SPEW, " MBL = 0x%08x\n", reg32);
- reg32 = pci_read_config32(dev, 0x24);
- printk(BIOS_SPEW, " PMBL = 0x%08x\n", reg32);
- reg32 = pci_read_config32(dev, 0x28);
- printk(BIOS_SPEW, " PMBU32 = 0x%08x\n", reg32);
- reg32 = pci_read_config32(dev, 0x2c);
- printk(BIOS_SPEW, " PMLU32 = 0x%08x\n", reg32);
-#endif
-
- /* Clear errors in status registers */
- reg16 = pci_read_config16(dev, 0x06);
- //reg16 |= 0xf900;
- pci_write_config16(dev, 0x06, reg16);
-
- reg16 = pci_read_config16(dev, 0x1e);
- //reg16 |= 0xf900;
- pci_write_config16(dev, 0x1e, reg16);
-}
-
-static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- /* NOTE: This is not the default position! */
- if (!vendor || !device) {
- pci_write_config32(dev, 0x94,
- pci_read_config32(dev, 0));
- } else {
- pci_write_config32(dev, 0x94,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations pci_ops = {
- .set_subsystem = pcie_set_subsystem,
-};
-
-static struct device_operations device_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- .ops_pci = &pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port1 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27d0,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port2 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27d2,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port3 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27d4,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port4 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27d6,
-};
-
-/* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port5 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27e0,
-};
-
-/* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
-static const struct pci_driver i82801gx_pcie_port6 __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27e2,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-void soft_reset(void)
-{
- outb(0x04, 0xcf9);
-}
-
-#if 0
-void hard_reset(void)
-{
- /* Try rebooting through port 0xcf9. */
- outb((1 << 2) | (1 << 1), 0xcf9);
-}
-#endif
-
-void hard_reset(void)
-{
- outb(0x02, 0xcf9);
- outb(0x06, 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801gx.h"
-
-typedef struct southbridge_intel_i82801gx_config config_t;
-
-static void sata_init(struct device *dev)
-{
- u32 reg32;
- u16 reg16;
- /* Get the chip configuration */
- config_t *config = dev->chip_info;
-
- printk(BIOS_DEBUG, "i82801gx_sata: initializing...\n");
-
- if (config == NULL) {
- printk(BIOS_ERR, "i82801gx_sata: error: device not in devicetree.cb!\n");
- return;
- }
-
- /* SATA configuration */
-
- /* Enable BARs */
- pci_write_config16(dev, PCI_COMMAND, 0x0007);
-
- if (config->ide_legacy_combined) {
- printk(BIOS_DEBUG, "SATA controller in combined mode.\n");
- /* No AHCI: clear AHCI base */
- pci_write_config32(dev, 0x24, 0x00000000);
- /* And without AHCI BAR no memory decoding */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 &= ~PCI_COMMAND_MEMORY;
- pci_write_config16(dev, PCI_COMMAND, reg16);
-
- pci_write_config8(dev, 0x09, 0x80);
-
- /* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
- IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
- IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
- IDE_PPE0 | IDE_IE0 | IDE_TIME0);
-
- /* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
-
- /* Set IDE I/O Configuration */
- reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
- pci_write_config32(dev, IDE_CONFIG, reg32);
-
- /* Combine IDE - SATA configuration */
- pci_write_config8(dev, 0x90, 0x02);
-
- /* Port 0 & 1 enable */
- pci_write_config8(dev, 0x92, 0x0f);
-
- /* SATA Initialization register */
- pci_write_config32(dev, 0x94, 0x5a000180);
- } else if(config->sata_ahci) {
- printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
- /* Allow both Legacy and Native mode */
- pci_write_config8(dev, 0x09, 0x8f);
-
- /* Set Interrupt Line */
- /* Interrupt Pin is set by D31IP.PIP */
- pci_write_config8(dev, INTR_LN, 0x0a);
-
- /* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
- IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
- IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
- IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
-
- /* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
-
- /* Set IDE I/O Configuration */
- reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
- pci_write_config32(dev, IDE_CONFIG, reg32);
-
- /* Set Sata Controller Mode. */
- pci_write_config8(dev, 0x90, 0x40); // 40=AHCI
-
- /* Port 0 & 1 enable */
- pci_write_config8(dev, 0x92, 0x0f);
-
- /* SATA Initialization register */
- pci_write_config32(dev, 0x94, 0x1a000180);
- } else {
- printk(BIOS_DEBUG, "SATA controller in plain mode.\n");
- /* Set Sata Controller Mode. No Mapping(?) */
- pci_write_config8(dev, 0x90, 0x00);
-
- /* No AHCI: clear AHCI base */
- pci_write_config32(dev, 0x24, 0x00000000);
-
- /* And without AHCI BAR no memory decoding */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
- reg16 &= ~PCI_COMMAND_MEMORY;
- pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /* Native mode capable on both primary and secondary (0xa)
- * or'ed with enabled (0x50) = 0xf
- */
- pci_write_config8(dev, 0x09, 0x8f);
-
- /* Set Interrupt Line */
- /* Interrupt Pin is set by D31IP.PIP */
- pci_write_config8(dev, INTR_LN, 0xff);
-
- /* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
- IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
- IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
- IDE_SITRE | IDE_ISP_3_CLOCKS |
- IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
-
- /* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
-
- /* Set IDE I/O Configuration */
- reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
- pci_write_config32(dev, IDE_CONFIG, reg32);
-
- /* Port 0 & 1 enable XXX */
- pci_write_config8(dev, 0x92, 0x15);
-
- /* SATA Initialization register */
- pci_write_config32(dev, 0x94, 0x1a000180);
- }
-
- /* All configurations need this SATA initialization sequence */
- pci_write_config8(dev, 0xa0, 0x40);
- pci_write_config8(dev, 0xa6, 0x22);
- pci_write_config8(dev, 0xa0, 0x78);
- pci_write_config8(dev, 0xa6, 0x22);
- pci_write_config8(dev, 0xa0, 0x88);
- reg32 = pci_read_config32(dev, 0xa4);
- reg32 &= 0xc0c0c0c0;
- reg32 |= 0x1b1b1212;
- pci_write_config32(dev, 0xa4, reg32);
- pci_write_config8(dev, 0xa0, 0x8c);
- reg32 = pci_read_config32(dev, 0xa4);
- reg32 &= 0xc0c0ff00;
- reg32 |= 0x121200aa;
- pci_write_config32(dev, 0xa4, reg32);
- pci_write_config8(dev, 0xa0, 0x00);
-
- pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
-
- /* Sata Initialization Register */
- reg32 = pci_read_config32(dev, 0x94);
- reg32 |= (1 << 30); // due to some bug
- pci_write_config32(dev, 0x94, reg32);
-}
-
-static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations sata_pci_ops = {
- .set_subsystem = sata_set_subsystem,
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &sata_pci_ops,
-};
-
-/* Desktop Non-AHCI and Non-RAID Mode */
-/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
-static const struct pci_driver i82801gx_sata_normal_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c0,
-};
-
-/* Mobile Non-AHCI and Non-RAID Mode */
-/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_sata_mobile_normal_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c4,
-};
-
-
-/* NOTE: Any of the below are not properly supported yet. */
-
-/* Desktop AHCI Mode */
-/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
-static const struct pci_driver i82801gx_sata_ahci_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c1,
-};
-
-/* Desktop RAID mode */
-/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
-static const struct pci_driver i82801gx_sata_raid_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c3,
-};
-
-/* Mobile AHCI Mode */
-/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
-static const struct pci_driver i82801gx_sata_mobile_ahci_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c5,
-};
-
-/* ICH7M DH Raid Mode */
-/* 82801GHM (ICH7-M DH) */
-static const struct pci_driver i82801gx_sata_ich7dh_raid_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c6,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/path.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "i82801gx.h"
-#include "i82801gx_smbus.h"
-
-#define SMB_BASE 0x20
-static void smbus_init(struct device *dev)
-{
- u32 smb_base;
-
- smb_base = pci_read_config32(dev, SMB_BASE);
- printk(BIOS_DEBUG, "Initializing SMBus device:\n");
- printk(BIOS_DEBUG, " Old SMBUS Base Address: 0x%04x\n", smb_base);
- pci_write_config32(dev, SMB_BASE, 0x00000401);
- smb_base = pci_read_config32(dev, SMB_BASE);
- printk(BIOS_DEBUG, " New SMBUS Base Address: 0x%04x\n", smb_base);
-}
-
-static int lsmbus_read_byte(device_t dev, u8 address)
-{
- u16 device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
- res = find_resource(pbus->dev, 0x20);
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .read_byte = lsmbus_read_byte,
-};
-
-static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations smbus_pci_ops = {
- .set_subsystem = smbus_set_subsystem,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = smbus_init,
- .scan_bus = scan_static_bus,
- .enable = i82801gx_enable,
- .ops_smbus_bus = &lops_smbus_bus,
- .ops_pci = &smbus_pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gx_smbus __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27da,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
- * Copyright (C) 2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-#include "i82801gx.h"
-
-static void smbus_delay(void)
-{
- inb(0x80);
-}
-
-static int smbus_wait_until_ready(u16 smbus_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_base + SMBHSTSTAT);
- } while (byte & 1);
- return loops ? 0 : -1;
-}
-
-static int smbus_wait_until_done(u16 smbus_base)
-{
- unsigned loops = SMBUS_TIMEOUT;
- unsigned char byte;
- do {
- smbus_delay();
- if (--loops == 0)
- break;
- byte = inb(smbus_base + SMBHSTSTAT);
- } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
- return loops ? 0 : -1;
-}
-
-static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready(smbus_base) < 0) {
- return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
- }
- /* Setup transaction */
- /* Disable interrupts */
- outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
- /* Set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
- /* Set the command/address... */
- outb(address & 0xff, smbus_base + SMBHSTCMD);
- /* Set up for a byte data read */
- outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
- (smbus_base + SMBHSTCTL));
- /* Clear any lingering errors, so the transaction will run */
- outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
-
- /* Clear the data byte... */
- outb(0, smbus_base + SMBHSTDAT0);
-
- /* Start the command */
- outb((inb(smbus_base + SMBHSTCTL) | 0x40),
- smbus_base + SMBHSTCTL);
-
- /* Poll for transaction completion */
- if (smbus_wait_until_done(smbus_base) < 0) {
- return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
- }
-
- global_status_register = inb(smbus_base + SMBHSTSTAT);
-
- /* Ignore the "In Use" status... */
- global_status_register &= ~(3 << 5);
-
- /* Read results of transaction */
- byte = inb(smbus_base + SMBHSTDAT0);
- if (global_status_register != (1 << 1)) {
- return SMBUS_ERROR;
- }
- return byte;
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <console/console.h>
-#include <arch/io.h>
-#include <cpu/cpu.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/smm.h>
-#include <string.h>
-#include "i82801gx.h"
-
-extern unsigned char _binary_smm_start;
-extern unsigned char _binary_smm_size;
-
-/* I945 */
-#define SMRAM 0x9d
-#define D_OPEN (1 << 6)
-#define D_CLS (1 << 5)
-#define D_LCK (1 << 4)
-#define G_SMRAME (1 << 3)
-#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
-
-/* While we read PMBASE dynamically in case it changed, let's
- * initialize it with a sane value
- */
-static u16 pmbase = DEFAULT_PMBASE;
-
-/**
- * @brief read and clear PM1_STS
- * @return PM1_STS register
- */
-static u16 reset_pm1_status(void)
-{
- u16 reg16;
-
- reg16 = inw(pmbase + PM1_STS);
- /* set status bits are cleared by writing 1 to them */
- outw(reg16, pmbase + PM1_STS);
-
- return reg16;
-}
-
-static void dump_pm1_status(u16 pm1_sts)
-{
- printk(BIOS_DEBUG, "PM1_STS: ");
- if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
- if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
- if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
- if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
- if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
- if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
- if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
- if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
- printk(BIOS_DEBUG, "\n");
-}
-
-/**
- * @brief read and clear SMI_STS
- * @return SMI_STS register
- */
-static u32 reset_smi_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + SMI_STS);
-
- return reg32;
-}
-
-static void dump_smi_status(u32 smi_sts)
-{
- printk(BIOS_DEBUG, "SMI_STS: ");
- if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
- if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
- if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
- if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
- if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
- if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
- if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
- if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
- if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
- if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
- if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
- if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
- if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
- if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
- if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
- if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
- if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
- if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
- if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
- if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear GPE0_STS
- * @return GPE0_STS register
- */
-static u32 reset_gpe0_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + GPE0_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + GPE0_STS);
-
- return reg32;
-}
-
-static void dump_gpe0_status(u32 gpe0_sts)
-{
- int i;
- printk(BIOS_DEBUG, "GPE0_STS: ");
- for (i=31; i<= 16; i--) {
- if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
- }
- if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
- if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
- if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
- if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
- if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
- if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
- if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
- if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
- if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
- if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
- if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
- if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
- if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
- if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear ALT_GP_SMI_STS
- * @return ALT_GP_SMI_STS register
- */
-static u16 reset_alt_gp_smi_status(void)
-{
- u16 reg16;
-
- reg16 = inl(pmbase + ALT_GP_SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg16, pmbase + ALT_GP_SMI_STS);
-
- return reg16;
-}
-
-static void dump_alt_gp_smi_status(u16 alt_gp_smi_sts)
-{
- int i;
- printk(BIOS_DEBUG, "ALT_GP_SMI_STS: ");
- for (i=15; i<= 0; i--) {
- if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", (i-16));
- }
- printk(BIOS_DEBUG, "\n");
-}
-
-
-
-/**
- * @brief read and clear TCOx_STS
- * @return TCOx_STS registers
- */
-static u32 reset_tco_status(void)
-{
- u32 tcobase = pmbase + 0x60;
- u32 reg32;
-
- reg32 = inl(tcobase + 0x04);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
- if (reg32 & (1 << 18))
- outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
-
- return reg32;
-}
-
-
-static void dump_tco_status(u32 tco_sts)
-{
- printk(BIOS_DEBUG, "TCO_STS: ");
- if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
- if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
- if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
- if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
- if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
- if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
- if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
- if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
- if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
- if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
- if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
- if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
- if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-
-/**
- * @brief Set the EOS bit
- */
-static void smi_set_eos(void)
-{
- u8 reg8;
-
- reg8 = inb(pmbase + SMI_EN);
- reg8 |= EOS;
- outb(reg8, pmbase + SMI_EN);
-}
-
-extern uint8_t smm_relocation_start, smm_relocation_end;
-
-static void smm_relocate(void)
-{
- u32 smi_en;
- u16 pm1_en;
-
- printk(BIOS_DEBUG, "Initializing SMM handler...");
-
- pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), 0x40) & 0xfffc;
- printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);
-
- smi_en = inl(pmbase + SMI_EN);
- if (smi_en & APMC_EN) {
- printk(BIOS_INFO, "SMI# handler already enabled?\n");
- return;
- }
-
- /* copy the SMM relocation code */
- memcpy((void *)0x38000, &smm_relocation_start,
- &smm_relocation_end - &smm_relocation_start);
-
- printk(BIOS_DEBUG, "\n");
- dump_smi_status(reset_smi_status());
- dump_pm1_status(reset_pm1_status());
- dump_gpe0_status(reset_gpe0_status());
- dump_alt_gp_smi_status(reset_alt_gp_smi_status());
- dump_tco_status(reset_tco_status());
-
- /* Enable SMI generation:
- * - on TCO events
- * - on APMC writes (io 0xb2)
- * - on writes to SLP_EN (sleep states)
- * - on writes to GBL_RLS (bios commands)
- * No SMIs:
- * - on microcontroller writes (io 0x62/0x66)
- */
-
- smi_en = 0; /* reset SMI enables */
-
-#if 0
- smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN;
-#endif
- smi_en |= TCO_EN;
- smi_en |= APMC_EN;
-#if DEBUG_PERIODIC_SMIS
- /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
- * periodic SMIs.
- */
- smi_en |= PERIODIC_EN;
-#endif
- smi_en |= SLP_SMI_EN;
- smi_en |= BIOS_EN;
-
- /* The following need to be on for SMIs to happen */
- smi_en |= EOS | GBL_SMI_EN;
-
- outl(smi_en, pmbase + SMI_EN);
-
- pm1_en = 0;
- pm1_en |= PWRBTN_EN;
- pm1_en |= GBL_EN;
- outw(pm1_en, pmbase + PM1_EN);
-
- /**
- * There are several methods of raising a controlled SMI# via
- * software, among them:
- * - Writes to io 0xb2 (APMC)
- * - Writes to the Local Apic ICR with Delivery mode SMI.
- *
- * Using the local apic is a bit more tricky. According to
- * AMD Family 11 Processor BKDG no destination shorthand must be
- * used.
- * The whole SMM initialization is quite a bit hardware specific, so
- * I'm not too worried about the better of the methods at the moment
- */
-
- /* raise an SMI interrupt */
- printk(BIOS_SPEW, " ... raise SMI#\n");
- outb(0x00, 0xb2);
-}
-
-static void smm_install(void)
-{
- /* enable the SMM memory window */
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- D_OPEN | G_SMRAME | C_BASE_SEG);
-
- /* copy the real SMM handler */
- memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
- wbinvd();
-
- /* close the SMM memory window and enable normal SMM */
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- G_SMRAME | C_BASE_SEG);
-}
-
-void smm_init(void)
-{
- /* Put SMM code to 0xa0000 */
- smm_install();
-
- /* Put relocation code to 0x38000 and relocate SMBASE */
- smm_relocate();
-
- /* We're done. Make sure SMIs can happen! */
- smi_set_eos();
-}
-
-void smm_lock(void)
-{
- /* LOCK the SMM memory window and enable normal SMM.
- * After running this function, only a full reset can
- * make the SMM registers writable again.
- */
- printk(BIOS_DEBUG, "Locking SMM.\n");
- pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
- D_LCK | G_SMRAME | C_BASE_SEG);
-}
-
-void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
-{
- /* The GDT or coreboot table is going to live here. But a long time
- * after we relocated the GNVS, so this is not troublesome.
- */
- *(u32 *)0x500 = (u32)gnvs;
- *(u32 *)0x504 = (u32)tcg;
- *(u32 *)0x508 = (u32)smi1;
- outb(0xea, 0xb2);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
- * MA 02110-1301 USA
- */
-
-#include <types.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/smm.h>
-#include <device/pci_def.h>
-#include "i82801gx.h"
-
-#define APM_CNT 0xb2
-#define CST_CONTROL 0x85
-#define PST_CONTROL 0x80
-#define ACPI_DISABLE 0x1e
-#define ACPI_ENABLE 0xe1
-#define GNVS_UPDATE 0xea
-#define APM_STS 0xb3
-
-/* I945 */
-#define SMRAM 0x9d
-#define D_OPEN (1 << 6)
-#define D_CLS (1 << 5)
-#define D_LCK (1 << 4)
-#define G_SMRANE (1 << 3)
-#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
-
-#include "i82801gx_nvs.h"
-
-/* While we read PMBASE dynamically in case it changed, let's
- * initialize it with a sane value
- */
-u16 pmbase = DEFAULT_PMBASE;
-u8 smm_initialized = 0;
-
-/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
- * by coreboot.
- */
-global_nvs_t *gnvs = (global_nvs_t *)0x0;
-void *tcg = (void *)0x0;
-void *smi1 = (void *)0x0;
-
-/**
- * @brief read and clear PM1_STS
- * @return PM1_STS register
- */
-static u16 reset_pm1_status(void)
-{
- u16 reg16;
-
- reg16 = inw(pmbase + PM1_STS);
- /* set status bits are cleared by writing 1 to them */
- outw(reg16, pmbase + PM1_STS);
-
- return reg16;
-}
-
-static void dump_pm1_status(u16 pm1_sts)
-{
- printk(BIOS_SPEW, "PM1_STS: ");
- if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK ");
- if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK ");
- if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR ");
- if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC ");
- if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN ");
- if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL ");
- if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM ");
- if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF ");
- printk(BIOS_SPEW, "\n");
- int reg16 = inw(pmbase + PM1_EN);
- printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
-}
-
-/**
- * @brief read and clear SMI_STS
- * @return SMI_STS register
- */
-static u32 reset_smi_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + SMI_STS);
-
- return reg32;
-}
-
-static void dump_smi_status(u32 smi_sts)
-{
- printk(BIOS_DEBUG, "SMI_STS: ");
- if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
- if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
- if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
- if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
- if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
- if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
- if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
- if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
- if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
- if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
- if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
- if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
- if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
- if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
- if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
- if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
- if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
- if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
- if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
- if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear GPE0_STS
- * @return GPE0_STS register
- */
-static u32 reset_gpe0_status(void)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + GPE0_STS);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32, pmbase + GPE0_STS);
-
- return reg32;
-}
-
-static void dump_gpe0_status(u32 gpe0_sts)
-{
- int i;
- printk(BIOS_DEBUG, "GPE0_STS: ");
- for (i=31; i<= 16; i--) {
- if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
- }
- if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
- if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
- if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
- if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
- if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
- if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
- if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
- if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
- if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
- if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
- if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
- if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
- if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
- if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
- printk(BIOS_DEBUG, "\n");
-}
-
-
-/**
- * @brief read and clear TCOx_STS
- * @return TCOx_STS registers
- */
-static u32 reset_tco_status(void)
-{
- u32 tcobase = pmbase + 0x60;
- u32 reg32;
-
- reg32 = inl(tcobase + 0x04);
- /* set status bits are cleared by writing 1 to them */
- outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
- if (reg32 & (1 << 18))
- outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
-
- return reg32;
-}
-
-
-static void dump_tco_status(u32 tco_sts)
-{
- printk(BIOS_DEBUG, "TCO_STS: ");
- if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
- if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
- if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
- if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
- if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
- if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
- if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
- if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
- if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
- if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
- if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
- if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
- if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
- printk(BIOS_DEBUG, "\n");
-}
-
-/* We are using PCIe accesses for now
- * 1. the chipset can do it
- * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
- */
-#include "../../../northbridge/intel/i945/pcie_config.c"
-
-int southbridge_io_trap_handler(int smif)
-{
- switch (smif) {
- case 0x32:
- printk(BIOS_DEBUG, "OS Init\n");
- /* gnvs->smif:
- * On success, the IO Trap Handler returns 0
- * On failure, the IO Trap Handler returns a value != 0
- */
- gnvs->smif = 0;
- return 1; /* IO trap handled */
- }
-
- /* Not handled */
- return 0;
-}
-
-/**
- * @brief Set the EOS bit
- */
-void southbridge_smi_set_eos(void)
-{
- u8 reg8;
-
- reg8 = inb(pmbase + SMI_EN);
- reg8 |= EOS;
- outb(reg8, pmbase + SMI_EN);
-}
-
-static void busmaster_disable_on_bus(int bus)
-{
- int slot, func;
- unsigned int val;
- unsigned char hdr;
-
- for (slot = 0; slot < 0x20; slot++) {
- for (func = 0; func < 8; func++) {
- u32 reg32;
- device_t dev = PCI_DEV(bus, slot, func);
-
- val = pci_read_config32(dev, PCI_VENDOR_ID);
-
- if (val == 0xffffffff || val == 0x00000000 ||
- val == 0x0000ffff || val == 0xffff0000)
- continue;
-
- /* Disable Bus Mastering for this one device */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 &= ~PCI_COMMAND_MASTER;
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- /* If this is a bridge, then follow it. */
- hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
- hdr &= 0x7f;
- if (hdr == PCI_HEADER_TYPE_BRIDGE ||
- hdr == PCI_HEADER_TYPE_CARDBUS) {
- unsigned int buses;
- buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
- busmaster_disable_on_bus((buses >> 8) & 0xff);
- }
- }
- }
-}
-
-
-static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
-{
- u8 reg8;
- u32 reg32;
- u8 slp_typ;
- /* FIXME: the power state on boot should be read from
- * CMOS or even better from GNVS. Right now it's hard
- * coded at compile time.
- */
- u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
-
- /* First, disable further SMIs */
- reg8 = inb(pmbase + SMI_EN);
- reg8 &= ~SLP_SMI_EN;
- outb(reg8, pmbase + SMI_EN);
-
- /* Figure out SLP_TYP */
- reg32 = inl(pmbase + PM1_CNT);
- printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
- slp_typ = (reg32 >> 10) & 7;
-
- /* Next, do the deed.
- */
-
- switch (slp_typ) {
- case 0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
- case 1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
- case 5:
- printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
- /* Invalidate the cache before going to S3 */
- wbinvd();
- break;
- case 6: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
- case 7:
- printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
-
- outl(0, pmbase + GPE0_EN);
-
- /* Should we keep the power state after a power loss?
- * In case the setting is "ON" or "OFF" we don't have
- * to do anything. But if it's "KEEP" we have to switch
- * to "OFF" before entering S5.
- */
- if (s5pwr == MAINBOARD_POWER_KEEP) {
- reg8 = pcie_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
- reg8 |= 1;
- pcie_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
- }
-
- /* also iterates over all bridges on bus 0 */
- busmaster_disable_on_bus(0);
- break;
- default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
- }
-
- /* Write back to the SLP register to cause the originally intended
- * event again. We need to set BIT13 (SLP_EN) though to make the
- * sleep happen.
- */
- outl(reg32 | SLP_EN, pmbase + PM1_CNT);
-
- /* In most sleep states, the code flow of this function ends at
- * the line above. However, if we entered sleep state S1 and wake
- * up again, we will continue to execute code in this function.
- */
- reg32 = inl(pmbase + PM1_CNT);
- if (reg32 & SCI_EN) {
- /* The OS is not an ACPI OS, so we set the state to S0 */
- reg32 &= ~(SLP_EN | SLP_TYP);
- outl(reg32, pmbase + PM1_CNT);
- }
-}
-
-static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 pmctrl;
- u8 reg8;
-
- /* Emulate B2 register as the FADT / Linux expects it */
-
- reg8 = inb(APM_CNT);
- switch (reg8) {
- case CST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "C-state control\n");
- break;
- case PST_CONTROL:
- /* Calling this function seems to cause
- * some kind of race condition in Linux
- * and causes a kernel oops
- */
- printk(BIOS_DEBUG, "P-state control\n");
- break;
- case ACPI_DISABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl &= ~SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
- break;
- case ACPI_ENABLE:
- pmctrl = inl(pmbase + PM1_CNT);
- pmctrl |= SCI_EN;
- outl(pmctrl, pmbase + PM1_CNT);
- printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
- break;
- case GNVS_UPDATE:
- if (smm_initialized) {
- printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
- return;
- }
- gnvs = *(global_nvs_t **)0x500;
- tcg = *(void **)0x504;
- smi1 = *(void **)0x508;
- smm_initialized = 1;
- printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
- break;
- default:
- printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);
- }
-}
-
-static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 pm1_sts;
-
- pm1_sts = reset_pm1_status();
- dump_pm1_status(pm1_sts);
-
- /* While OSPM is not active, poweroff immediately
- * on a power button event.
- */
- if (pm1_sts & PWRBTN_STS) {
- // power button pressed
- u32 reg32;
- reg32 = (7 << 10) | (1 << 13);
- outl(reg32, pmbase + PM1_CNT);
- }
-}
-
-static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 gpe0_sts;
-
- gpe0_sts = reset_gpe0_status();
- dump_gpe0_status(gpe0_sts);
-}
-
-static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save)
-{
- u16 reg16;
- reg16 = inw(pmbase + ALT_GP_SMI_STS);
- outl(reg16, pmbase + ALT_GP_SMI_STS);
-
- reg16 &= inw(pmbase + ALT_GP_SMI_EN);
-
- if (mainboard_smi_gpi) {
- mainboard_smi_gpi(reg16);
- } else {
- if (reg16)
- printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16);
- }
-}
-
-static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & MCSMI_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Microcontroller SMI.\n");
-}
-
-
-
-static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 tco_sts;
-
- tco_sts = reset_tco_status();
-
- /* Any TCO event? */
- if (!tco_sts)
- return;
-
- if (tco_sts & (1 << 8)) { // BIOSWR
- u8 bios_cntl;
-
- bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
-
- if (bios_cntl & 1) {
- /* BWE is RW, so the SMI was caused by a
- * write to BWE, not by a write to the BIOS
- */
-
- /* This is the place where we notice someone
- * is trying to tinker with the BIOS. We are
- * trying to be nice and just ignore it. A more
- * resolute answer would be to power down the
- * box.
- */
- printk(BIOS_DEBUG, "Switching back to RO\n");
- pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
- } /* No else for now? */
- } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
- /* Handle TCO timeout */
- printk(BIOS_DEBUG, "TCO Timeout.\n");
- } else if (!tco_sts) {
- dump_tco_status(tco_sts);
- }
-}
-
-static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
-{
- u32 reg32;
-
- reg32 = inl(pmbase + SMI_EN);
-
- /* Are periodic SMIs enabled? */
- if ((reg32 & PERIODIC_EN) == 0)
- return;
-
- printk(BIOS_DEBUG, "Periodic SMI.\n");
-}
-
-static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
-{
-#define IOTRAP(x) (trap_sts & (1 << x))
- u32 trap_sts, trap_cycle;
- u32 data, mask = 0;
- int i;
-
- trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
- RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
-
- trap_cycle = RCBA32(0x1e10);
- for (i=16; i<20; i++) {
- if (trap_cycle & (1 << i))
- mask |= (0xff << ((i - 16) << 2));
- }
-
-
- /* IOTRAP(3) SMI function call */
- if (IOTRAP(3)) {
- if (gnvs && gnvs->smif)
- io_trap_handler(gnvs->smif); // call function smif
- return;
- }
-
- /* IOTRAP(2) currently unused
- * IOTRAP(1) currently unused */
-
- /* IOTRAP(0) SMIC */
- if (IOTRAP(0)) {
- if (!(trap_cycle & (1 << 24))) { // It's a write
- printk(BIOS_DEBUG, "SMI1 command\n");
- data = RCBA32(0x1e18);
- data &= mask;
- // if (smi1)
- // southbridge_smi_command(data);
- // return;
- }
- // Fall through to debug
- }
-
- printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc);
- for (i=0; i < 4; i++) if(IOTRAP(i)) printk(BIOS_DEBUG, " TRAPÂ = %d\n", i);
- printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
- printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
- printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
-
- if (!(trap_cycle & (1 << 24))) {
- /* Write Cycle */
- data = RCBA32(0x1e18);
- printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
- }
-#undef IOTRAP
-}
-
-typedef void (*smi_handler_t)(unsigned int node,
- smm_state_save_area_t *state_save);
-
-smi_handler_t southbridge_smi[32] = {
- NULL, // [0] reserved
- NULL, // [1] reserved
- NULL, // [2] BIOS_STS
- NULL, // [3] LEGACY_USB_STS
- southbridge_smi_sleep, // [4] SLP_SMI_STS
- southbridge_smi_apmc, // [5] APM_STS
- NULL, // [6] SWSMI_TMR_STS
- NULL, // [7] reserved
- southbridge_smi_pm1, // [8] PM1_STS
- southbridge_smi_gpe0, // [9] GPE0_STS
- southbridge_smi_gpi, // [10] GPI_STS
- southbridge_smi_mc, // [11] MCSMI_STS
- NULL, // [12] DEVMON_STS
- southbridge_smi_tco, // [13] TCO_STS
- southbridge_smi_periodic, // [14] PERIODIC_STS
- NULL, // [15] SERIRQ_SMI_STS
- NULL, // [16] SMBUS_SMI_STS
- NULL, // [17] LEGACY_USB2_STS
- NULL, // [18] INTEL_USB2_STS
- NULL, // [19] reserved
- NULL, // [20] PCI_EXP_SMI_STS
- southbridge_smi_monitor, // [21] MONITOR_STS
- NULL, // [22] reserved
- NULL, // [23] reserved
- NULL, // [24] reserved
- NULL, // [25] EL_SMI_STS
- NULL, // [26] SPI_STS
- NULL, // [27] reserved
- NULL, // [28] reserved
- NULL, // [29] reserved
- NULL, // [30] reserved
- NULL // [31] reserved
-};
-
-/**
- * @brief Interrupt handler for SMI#
- *
- * @param smm_revision revision of the smm state save map
- */
-
-void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
-{
- int i, dump = 0;
- u32 smi_sts;
-
- /* Update global variable pmbase */
- pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
-
- /* We need to clear the SMI status registers, or we won't see what's
- * happening in the following calls.
- */
- smi_sts = reset_smi_status();
-
- /* Filter all non-enabled SMI events */
- // FIXME Double check, this clears MONITOR
- // smi_sts &= inl(pmbase + SMI_EN);
-
- /* Call SMI sub handler for each of the status bits */
- for (i = 0; i < 31; i++) {
- if (smi_sts & (1 << i)) {
- if (southbridge_smi[i])
- southbridge_smi[i](node, state_save);
- else {
- printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no "
- "handler available.\n", i);
- dump = 1;
- }
- }
- }
-
- if(dump) {
- dump_smi_status(smi_sts);
- }
-
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801gx.h"
-
-static void usb_init(struct device *dev)
-{
- u32 reg32;
- u8 reg8;
-
- /* USB Specification says the device must be Bus Master */
- printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
-
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
-
- // Erratum
- pci_write_config8(dev, 0xca, 0x00);
-
- // Yes. Another Erratum
- reg8 = pci_read_config8(dev, 0xca);
- reg8 |= (1 << 0);
- pci_write_config8(dev, 0xca, reg8);
-
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static void usb_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations usb_pci_ops = {
- .set_subsystem = usb_set_subsystem,
-};
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &usb_pci_ops,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gb_usb1 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c8,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gb_usb2 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27c9,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gb_usb3 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27ca,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gb_usb4 __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27cb,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "i82801gx.h"
-
-/* Required for successful build, but currently empty. */
-void set_debug_port(unsigned int port)
-{
- /* Not needed, the ICH* southbridges hardcode physical USB port 1. */
-}
-
-void i82801gx_enable_usbdebug(unsigned int port)
-{
- u32 dbgctl;
- device_t dev = PCI_DEV(0, 0x1d, 7); /* USB EHCI, D29:F7 */
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-
- /* Force ownership of the Debug Port to the EHCI controller. */
- printk(BIOS_DEBUG, "Enabling OWNER_CNT\n");
- dbgctl = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET);
- dbgctl |= (1 << 30);
- write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "i82801gx.h"
-#include <usbdebug.h>
-#include <arch/io.h>
-
-static void usb_ehci_init(struct device *dev)
-{
- struct resource *res;
- u32 base;
- u32 reg32;
- u8 reg8;
-
- printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- reg32 |= PCI_COMMAND_MASTER;
- reg32 |= PCI_COMMAND_SERR;
- pci_write_config32(dev, PCI_COMMAND, reg32);
-
- reg32 = pci_read_config32(dev, 0xdc);
- reg32 |= (1 << 31) | (1 << 27);
- pci_write_config32(dev, 0xdc, reg32);
-
- reg32 = pci_read_config32(dev, 0xfc);
- reg32 &= ~(3 << 2);
- reg32 |= (2 << 2) | (1 << 29) | (1 << 17);
- pci_write_config32(dev, 0xfc, reg32);
-
- /* Clear any pending port changes */
- res = find_resource(dev, 0x10);
- base = res->base;
- reg32 = read32(base + 0x24) | (1 << 2);
- write32(base + 0x24, reg32);
-
- /* workaround */
- reg8 = pci_read_config8(dev, 0x84);
- reg8 |= (1 << 4);
- pci_write_config8(dev, 0x84, reg8);
-
- printk(BIOS_DEBUG, "done.\n");
-}
-
-static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- u8 access_cntl;
-
- access_cntl = pci_read_config8(dev, 0x80);
-
- /* Enable writes to protected registers. */
- pci_write_config8(dev, 0x80, access_cntl | 1);
-
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-
- /* Restore protection. */
- pci_write_config8(dev, 0x80, access_cntl);
-}
-
-static void usb_ehci_set_resources(struct device *dev)
-{
-#if CONFIG_USBDEBUG
- struct resource *res;
- u32 base;
- u32 usb_debug;
-
- usb_debug = get_ehci_debug();
- set_ehci_debug(0);
-#endif
- pci_dev_set_resources(dev);
-
-#if CONFIG_USBDEBUG
- res = find_resource(dev, 0x10);
- set_ehci_debug(usb_debug);
- if (!res) return;
- base = res->base;
- set_ehci_base(base);
- report_resource_stored(dev, res, "");
-#endif
-}
-
-
-
-static struct pci_operations lops_pci = {
- .set_subsystem = &usb_ehci_set_subsystem,
-};
-
-static struct device_operations usb_ehci_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb_ehci_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_ehci_init,
- .scan_bus = 0,
- .enable = i82801gx_enable,
- .ops_pci = &lops_pci,
-};
-
-/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
-static const struct pci_driver i82801gx_usb_ehci __pci_driver = {
- .ops = &usb_ehci_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x27cc,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <watchdog.h>
-
-void watchdog_off(void)
-{
- device_t dev;
- unsigned long value, base;
-
- /* Turn off the ICH7 watchdog. */
- dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
-
- /* Enable I/O space. */
- value = pci_read_config16(dev, 0x04);
- value |= (1 << 10);
- pci_write_config16(dev, 0x04, value);
-
- /* Get TCO base. */
- base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
-
- /* Disable the watchdog timer. */
- value = inw(base + 0x08);
- value |= 1 << 11;
- outw(value, base + 0x08);
-
- /* Clear TCO timeout status. */
- outw(0x0008, base + 0x04);
- outw(0x0002, base + 0x06);
-
- printk(BIOS_DEBUG, "ICH7 watchdog disabled\n");
-}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801gx.h"
+
+typedef struct southbridge_intel_i82801gx_config config_t;
+
+static void ide_init(struct device *dev)
+{
+ u16 ideTimingConfig;
+ u32 reg32;
+ u32 enable_primary, enable_secondary;
+
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ printk(BIOS_DEBUG, "i82801gx_ide: initializing... ");
+ if (config == NULL) {
+ printk(BIOS_ERR, "\ni82801gx_ide: Not mentioned in devicetree.cb!\n");
+ // Trying to set somewhat safe defaults instead of bailing out.
+ enable_primary = enable_secondary = 1;
+ } else {
+ enable_primary = config->ide_enable_primary;
+ enable_secondary = config->ide_enable_secondary;
+ }
+
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_IO | PCI_COMMAND_MASTER);
+
+ /* Native Capable, but not enabled. */
+ pci_write_config8(dev, 0x09, 0x8a);
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_PRI);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ ideTimingConfig |= IDE_SITRE;
+ if (enable_primary) {
+ /* Enable primary IDE interface. */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ ideTimingConfig |= (2 << 12); // ISP = 3 clocks
+ ideTimingConfig |= (3 << 8); // RCT = 1 clock
+ ideTimingConfig |= (1 << 1); // IE0
+ ideTimingConfig |= (1 << 0); // TIME0
+ printk(BIOS_DEBUG, "IDE0 ");
+ }
+ pci_write_config16(dev, IDE_TIM_PRI, ideTimingConfig);
+
+ ideTimingConfig = pci_read_config16(dev, IDE_TIM_SEC);
+ ideTimingConfig &= ~IDE_DECODE_ENABLE;
+ ideTimingConfig |= IDE_SITRE;
+ if (enable_secondary) {
+ /* Enable secondary IDE interface. */
+ ideTimingConfig |= IDE_DECODE_ENABLE;
+ ideTimingConfig |= (2 << 12); // ISP = 3 clocks
+ ideTimingConfig |= (3 << 8); // RCT = 1 clock
+ ideTimingConfig |= (1 << 1); // IE0
+ ideTimingConfig |= (1 << 0); // TIME0
+ printk(BIOS_DEBUG, "IDE1 ");
+ }
+ pci_write_config16(dev, IDE_TIM_SEC, ideTimingConfig);
+
+ /* Set IDE I/O Configuration */
+ reg32 = 0;
+ /* FIXME: only set FAST_* for ata/100, only ?CBx for ata/66 */
+ if (enable_primary)
+ reg32 |= SIG_MODE_PRI_NORMAL | FAST_PCB0 | PCB0 | FAST_PCB1 | PCB1;
+ if (enable_secondary)
+ reg32 |= SIG_MODE_SEC_NORMAL | FAST_SCB0 | SCB0 | FAST_SCB1 | SCB1;
+ pci_write_config32(dev, IDE_CONFIG, reg32);
+
+ /* Set Interrupt Line */
+ /* Interrupt Pin is set by D31IP.PIP */
+ pci_write_config32(dev, INTR_LN, 0xff); /* Int 15 */
+
+ printk(BIOS_DEBUG, "\n");
+}
+
+static void ide_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations ide_pci_ops = {
+ .set_subsystem = ide_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &ide_pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gx_ide __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27df,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <pc80/i8259.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include "i82801gx.h"
+
+#define NMI_OFF 0
+
+#define ENABLE_ACPI_MODE_IN_COREBOOT 0
+#define TEST_SMM_FLASH_LOCKDOWN 0
+
+typedef struct southbridge_intel_i82801gx_config config_t;
+
+static void i82801gx_enable_apic(struct device *dev)
+{
+ int i;
+ u32 reg32;
+ volatile u32 *ioapic_index = (volatile u32 *)(IO_APIC_ADDR);
+ volatile u32 *ioapic_data = (volatile u32 *)(IO_APIC_ADDR + 0x10);
+
+ /* Enable ACPI I/O and power management.
+ * Set SCI IRQ to IRQ9
+ */
+ pci_write_config8(dev, ACPI_CNTL, 0x80);
+
+ *ioapic_index = 0;
+ *ioapic_data = (1 << 25);
+
+ *ioapic_index = 0;
+ reg32 = *ioapic_data;
+ printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", (reg32 >> 24) & 0x0f);
+ if (reg32 != (1 << 25))
+ die("APIC Error\n");
+
+ printk(BIOS_SPEW, "Dumping IOAPIC registers\n");
+ for (i=0; i<3; i++) {
+ *ioapic_index = i;
+ printk(BIOS_SPEW, " reg 0x%04x:", i);
+ reg32 = *ioapic_data;
+ printk(BIOS_SPEW, " 0x%08x\n", reg32);
+ }
+
+ *ioapic_index = 3; /* Select Boot Configuration register. */
+ *ioapic_data = 1; /* Use Processor System Bus to deliver interrupts. */
+}
+
+static void i82801gx_enable_serial_irqs(struct device *dev)
+{
+ /* Set packet length and toggle silent mode bit for one frame. */
+ pci_write_config8(dev, SERIRQ_CNTL,
+ (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
+}
+
+/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
+ * 0x00 - 0000 = Reserved
+ * 0x01 - 0001 = Reserved
+ * 0x02 - 0010 = Reserved
+ * 0x03 - 0011 = IRQ3
+ * 0x04 - 0100 = IRQ4
+ * 0x05 - 0101 = IRQ5
+ * 0x06 - 0110 = IRQ6
+ * 0x07 - 0111 = IRQ7
+ * 0x08 - 1000 = Reserved
+ * 0x09 - 1001 = IRQ9
+ * 0x0A - 1010 = IRQ10
+ * 0x0B - 1011 = IRQ11
+ * 0x0C - 1100 = IRQ12
+ * 0x0D - 1101 = Reserved
+ * 0x0E - 1110 = IRQ14
+ * 0x0F - 1111 = IRQ15
+ * PIRQ[n]_ROUT[7] - PIRQ Routing Control
+ * 0x80 - The PIRQ is not routed.
+ */
+
+static void i82801gx_pirq_init(device_t dev)
+{
+ device_t irq_dev;
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ pci_write_config8(dev, PIRQA_ROUT, config->pirqa_routing);
+ pci_write_config8(dev, PIRQB_ROUT, config->pirqb_routing);
+ pci_write_config8(dev, PIRQC_ROUT, config->pirqc_routing);
+ pci_write_config8(dev, PIRQD_ROUT, config->pirqd_routing);
+
+ pci_write_config8(dev, PIRQE_ROUT, config->pirqe_routing);
+ pci_write_config8(dev, PIRQF_ROUT, config->pirqf_routing);
+ pci_write_config8(dev, PIRQG_ROUT, config->pirqg_routing);
+ pci_write_config8(dev, PIRQH_ROUT, config->pirqh_routing);
+
+ /* Eric Biederman once said we should let the OS do this.
+ * I am not so sure anymore he was right.
+ */
+
+ for(irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
+ u8 int_pin=0, int_line=0;
+
+ if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
+ continue;
+
+ int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
+
+ switch (int_pin) {
+ case 1: /* INTA# */ int_line = config->pirqa_routing; break;
+ case 2: /* INTB# */ int_line = config->pirqb_routing; break;
+ case 3: /* INTC# */ int_line = config->pirqc_routing; break;
+ case 4: /* INTD# */ int_line = config->pirqd_routing; break;
+ }
+
+ if (!int_line)
+ continue;
+
+ pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, int_line);
+ }
+}
+
+static void i82801gx_gpi_routing(device_t dev)
+{
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+ u32 reg32 = 0;
+
+ /* An array would be much nicer here, or some
+ * other method of doing this.
+ */
+ reg32 |= (config->gpi0_routing & 0x03) << 0;
+ reg32 |= (config->gpi1_routing & 0x03) << 2;
+ reg32 |= (config->gpi2_routing & 0x03) << 4;
+ reg32 |= (config->gpi3_routing & 0x03) << 6;
+ reg32 |= (config->gpi4_routing & 0x03) << 8;
+ reg32 |= (config->gpi5_routing & 0x03) << 10;
+ reg32 |= (config->gpi6_routing & 0x03) << 12;
+ reg32 |= (config->gpi7_routing & 0x03) << 14;
+ reg32 |= (config->gpi8_routing & 0x03) << 16;
+ reg32 |= (config->gpi9_routing & 0x03) << 18;
+ reg32 |= (config->gpi10_routing & 0x03) << 20;
+ reg32 |= (config->gpi11_routing & 0x03) << 22;
+ reg32 |= (config->gpi12_routing & 0x03) << 24;
+ reg32 |= (config->gpi13_routing & 0x03) << 26;
+ reg32 |= (config->gpi14_routing & 0x03) << 28;
+ reg32 |= (config->gpi15_routing & 0x03) << 30;
+
+ pci_write_config32(dev, 0xb8, reg32);
+}
+
+extern u8 acpi_slp_type;
+
+static void i82801gx_power_options(device_t dev)
+{
+ u8 reg8;
+ u16 reg16, pmbase;
+ u32 reg32;
+ const char *state;
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ int nmi_option;
+
+ /* Which state do we want to goto after g3 (power restored)?
+ * 0 == S0 Full On
+ * 1 == S5 Soft Off
+ *
+ * If the option is not existent (Laptops), use MAINBOARD_POWER_ON.
+ */
+ if (get_option(&pwr_on, "power_on_after_fail") < 0)
+ pwr_on = MAINBOARD_POWER_ON;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ reg8 &= 0xfe;
+ switch (pwr_on) {
+ case MAINBOARD_POWER_OFF:
+ reg8 |= 1;
+ state = "off";
+ break;
+ case MAINBOARD_POWER_ON:
+ reg8 &= ~1;
+ state = "on";
+ break;
+ case MAINBOARD_POWER_KEEP:
+ reg8 &= ~1;
+ state = "state keep";
+ break;
+ default:
+ state = "undefined";
+ }
+
+ reg8 |= (3 << 4); /* avoid #S4 assertions */
+ reg8 &= ~(1 << 3); /* minimum asssertion is 1 to 2 RTCCLK */
+
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ printk(BIOS_INFO, "Set power %s after power failure.\n", state);
+
+ /* Set up NMI on errors. */
+ reg8 = inb(0x61);
+ reg8 &= 0x0f; /* Higher Nibble must be 0 */
+ reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
+ // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
+ reg8 |= (1 << 2); /* PCI SERR# Disable for now */
+ outb(reg8, 0x61);
+
+ reg8 = inb(0x70);
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ printk(BIOS_INFO, "NMI sources enabled.\n");
+ reg8 &= ~(1 << 7); /* Set NMI. */
+ } else {
+ printk(BIOS_INFO, "NMI sources disabled.\n");
+ reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
+ }
+ outb(reg8, 0x70);
+
+ /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
+ reg16 = pci_read_config16(dev, GEN_PMCON_1);
+ reg16 &= ~(3 << 0); // SMI# rate 1 minute
+ reg16 |= (1 << 2); // CLKRUN_EN - Mobile/Ultra only
+ reg16 |= (1 << 3); // Speedstep Enable - Mobile/Ultra only
+ reg16 |= (1 << 5); // CPUSLP_EN Desktop only
+ // another laptop wants this?
+ // reg16 &= ~(1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
+ reg16 |= (1 << 10); // BIOS_PCI_EXP_EN - Desktop/Mobile only
+#if DEBUG_PERIODIC_SMIS
+ /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
+ * periodic SMIs.
+ */
+ reg16 |= (3 << 0); // Periodic SMI every 8s
+#endif
+ pci_write_config16(dev, GEN_PMCON_1, reg16);
+
+ // Set the board's GPI routing.
+ i82801gx_gpi_routing(dev);
+
+ pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+
+ outl(config->gpe0_en, pmbase + GPE0_EN);
+ outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);
+
+ /* Set up power management block and determine sleep mode */
+ reg32 = inl(pmbase + 0x04); // PM1_CNT
+
+ reg32 &= ~(7 << 10); // SLP_TYP
+ reg32 |= (1 << 1); // enable C3->C0 transition on bus master
+ reg32 |= (1 << 0); // SCI_EN
+ outl(reg32, pmbase + 0x04);
+}
+
+static void i82801gx_configure_cstates(device_t dev)
+{
+ u8 reg8;
+
+ reg8 = pci_read_config8(dev, 0xa9); // Cx state configuration
+ reg8 |= (1 << 4) | (1 << 3) | (1 << 2); // Enable Popup & Popdown
+ pci_write_config8(dev, 0xa9, reg8);
+
+ // Set Deeper Sleep configuration to recommended values
+ reg8 = pci_read_config8(dev, 0xaa);
+ reg8 &= 0xf0;
+ reg8 |= (2 << 2); // Deeper Sleep to Stop CPU: 34-40us
+ reg8 |= (2 << 0); // Deeper Sleep to Sleep: 15us
+ pci_write_config8(dev, 0xaa, reg8);
+}
+
+static void i82801gx_rtc_init(struct device *dev)
+{
+ u8 reg8;
+ int rtc_failed;
+
+ reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ rtc_failed = reg8 & RTC_BATTERY_DEAD;
+ if (rtc_failed) {
+ reg8 &= ~RTC_BATTERY_DEAD;
+ pci_write_config8(dev, GEN_PMCON_3, reg8);
+ }
+ printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
+
+ rtc_init(rtc_failed);
+}
+
+static void enable_hpet(void)
+{
+ u32 reg32;
+
+ /* Move HPET to default address 0xfed00000 and enable it */
+ reg32 = RCBA32(HPTC);
+ reg32 |= (1 << 7); // HPET Address Enable
+ reg32 &= ~(3 << 0);
+ RCBA32(HPTC) = reg32;
+}
+
+static void enable_clock_gating(void)
+{
+ u32 reg32;
+
+ /* Enable Clock Gating for most devices */
+ reg32 = RCBA32(CG);
+ reg32 |= (1 << 31); // LPC clock gating
+ reg32 |= (1 << 30); // PATA clock gating
+ // SATA clock gating
+ reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
+ reg32 |= (1 << 23); // AC97 clock gating
+ reg32 |= (1 << 19); // USB EHCI clock gating
+ reg32 |= (1 << 3) | (1 << 1); // DMI clock gating
+ reg32 |= (1 << 2); // PCIe clock gating;
+ reg32 &= ~(1 << 20); // No static clock gating for USB
+ reg32 &= ~( (1 << 29) | (1 << 28) ); // Disable UHCI clock gating
+ RCBA32(CG) = reg32;
+}
+
+#if CONFIG_HAVE_SMI_HANDLER
+static void i82801gx_lock_smm(struct device *dev)
+{
+ void smm_lock(void);
+#if TEST_SMM_FLASH_LOCKDOWN
+ u8 reg8;
+#endif
+
+#if ENABLE_ACPI_MODE_IN_COREBOOT
+ printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n");
+ outb(0xe1, 0xb2); // Enable ACPI mode
+ printk(BIOS_DEBUG, "done.\n");
+#else
+ printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
+ outb(0x1e, 0xb2); // Disable ACPI mode
+ printk(BIOS_DEBUG, "done.\n");
+#endif
+ /* Don't allow evil boot loaders, kernels, or
+ * userspace applications to deceive us:
+ */
+ smm_lock();
+
+#if TEST_SMM_FLASH_LOCKDOWN
+ /* Now try this: */
+ printk(BIOS_DEBUG, "Locking BIOS to RO... ");
+ reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
+ (reg8&1)?"rw":"ro");
+ reg8 &= ~(1 << 0); /* clear BIOSWE */
+ pci_write_config8(dev, 0xdc, reg8);
+ reg8 |= (1 << 1); /* set BLE */
+ pci_write_config8(dev, 0xdc, reg8);
+ printk(BIOS_DEBUG, "ok.\n");
+ reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
+ (reg8&1)?"rw":"ro");
+
+ printk(BIOS_DEBUG, "Writing:\n");
+ *(volatile u8 *)0xfff00000 = 0x00;
+ printk(BIOS_DEBUG, "Testing:\n");
+ reg8 |= (1 << 0); /* set BIOSWE */
+ pci_write_config8(dev, 0xdc, reg8);
+
+ reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off",
+ (reg8&1)?"rw":"ro");
+ printk(BIOS_DEBUG, "Done.\n");
+#endif
+}
+#endif
+
+#define SPIBASE 0x3020
+static void i82801gx_spi_init(void)
+{
+ u16 spicontrol;
+
+ spicontrol = RCBA16(SPIBASE + 2);
+ spicontrol &= ~(1 << 0); // SPI Access Request
+ RCBA16(SPIBASE + 2) = spicontrol;
+}
+
+static void i82801gx_fixups(struct device *dev)
+{
+ /* This needs to happen after PCI enumeration */
+ RCBA32(0x1d40) |= 1;
+
+ /* USB Transient Disconnect Detect:
+ * Prevent a SE0 condition on the USB ports from being
+ * interpreted by the UHCI controller as a disconnect
+ */
+ pci_write_config8(dev, 0xad, 0x3);
+}
+
+static void lpc_init(struct device *dev)
+{
+ printk(BIOS_DEBUG, "i82801gx: lpc_init\n");
+
+ /* Set the value for PCI command register. */
+ pci_write_config16(dev, PCI_COMMAND, 0x000f);
+
+ /* IO APIC initialization. */
+ i82801gx_enable_apic(dev);
+
+ i82801gx_enable_serial_irqs(dev);
+
+ /* Setup the PIRQ. */
+ i82801gx_pirq_init(dev);
+
+ /* Setup power options. */
+ i82801gx_power_options(dev);
+
+ /* Configure Cx state registers */
+ i82801gx_configure_cstates(dev);
+
+ /* Set the state of the GPIO lines. */
+ //gpio_init(dev);
+
+ /* Initialize the real time clock. */
+ i82801gx_rtc_init(dev);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+ /* Initialize the High Precision Event Timers, if present. */
+ enable_hpet();
+
+ /* Initialize Clock Gating */
+ enable_clock_gating();
+
+ setup_i8259();
+
+ /* The OS should do this? */
+ /* Interrupt 9 should be level triggered (SCI) */
+ i8259_configure_irq_trigger(9, 1);
+
+#if CONFIG_HAVE_SMI_HANDLER
+ i82801gx_lock_smm(dev);
+#endif
+
+ i82801gx_spi_init();
+
+ i82801gx_fixups(dev);
+}
+
+static void i82801gx_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations pci_ops = {
+ .set_subsystem = set_subsystem,
+};
+
+static struct device_operations device_ops = {
+ .read_resources = i82801gx_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801gx_enable,
+ .ops_pci = &pci_ops,
+};
+
+/* 82801GH (ICH7 DH) */
+static const struct pci_driver ich7_dh_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27b0,
+};
+
+/* 82801GB/GR (ICH7/ICH7R) */
+static const struct pci_driver ich7_ich7r_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27b8,
+};
+
+/* 82801GBM/GU (ICH7-M/ICH7-U) */
+static const struct pci_driver ich7m_ich7u_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27b9,
+};
+
+/* 82801GHM (ICH7-M DH) */
+static const struct pci_driver ich7m_dh_lpc __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27bd,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This code should work for all ICH* southbridges with a NIC. */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+static void nic_init(struct device *dev)
+{
+ /* Nothing yet */
+}
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+/* Note: 82801GU (ICH7-U) doesn't have a NIC. */
+/* PCI ID loaded from EEPROM. If EEPROM is 0, 0x27dc is used. */
+static const struct pci_driver i82801gx_nic __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27dc,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+typedef struct {
+ /* Miscellaneous */
+ u16 osys; /* 0x00 - Operating System */
+ u8 smif; /* 0x02 - SMI function call ("TRAP") */
+ u8 prm0; /* 0x03 - SMI function call parameter */
+ u8 prm1; /* 0x04 - SMI function call parameter */
+ u8 scif; /* 0x05 - SCI function call (via _L00) */
+ u8 prm2; /* 0x06 - SCI function call parameter */
+ u8 prm3; /* 0x07 - SCI function call parameter */
+ u8 lckf; /* 0x08 - Global Lock function for EC */
+ u8 prm4; /* 0x09 - Lock function parameter */
+ u8 prm5; /* 0x0a - Lock function parameter */
+ u32 p80d; /* 0x0b - Debug port (IO 0x80) value */
+ u8 lids; /* 0x0f - LID state (open = 1) */
+ u8 pwrs; /* 0x10 - Power state (AC = 1) */
+ u8 dbgs; /* 0x11 - Debug state */
+ u8 linx; /* 0x12 - Linux OS */
+ u8 dckn; /* 0x13 - PCIe docking state */
+ /* Thermal policy */
+ u8 actt; /* 0x14 - active trip point */
+ u8 psvt; /* 0x15 - passive trip point */
+ u8 tc1v; /* 0x16 - passive trip point TC1 */
+ u8 tc2v; /* 0x17 - passive trip point TC2 */
+ u8 tspv; /* 0x18 - passive trip point TSP */
+ u8 crtt; /* 0x19 - critical trip point */
+ u8 dtse; /* 0x1a - Digital Thermal Sensor enable */
+ u8 dts1; /* 0x1b - DT sensor 1 */
+ u8 dts2; /* 0x1c - DT sensor 2 */
+ u8 rsvd2;
+ /* Battery Support */
+ u8 bnum; /* 0x1e - number of batteries */
+ u8 b0sc, b1sc, b2sc; /* 0x1f-0x21 - stored capacity */
+ u8 b0ss, b1ss, b2ss; /* 0x22-0x24 - stored status */
+ u8 rsvd3[3];
+ /* Processor Identification */
+ u8 apic; /* 0x28 - APIC enabled */
+ u8 mpen; /* 0x29 - MP capable/enabled */
+ u8 pcp0; /* 0x2a - PDC CPU/CORE 0 */
+ u8 pcp1; /* 0x2b - PDC CPU/CORE 1 */
+ u8 ppcm; /* 0x2c - Max. PPC state */
+ u8 rsvd4[5];
+ /* Super I/O & CMOS config */
+ u8 natp; /* 0x32 - SIO type */
+ u8 cmap; /* 0x33 - */
+ u8 cmbp; /* 0x34 - */
+ u8 lptp; /* 0x35 - LPT port */
+ u8 fdcp; /* 0x36 - Floppy Disk Controller */
+ u8 rfdv; /* 0x37 - */
+ u8 hotk; /* 0x38 - Hot Key */
+ u8 rtcf;
+ u8 util;
+ u8 acin;
+ /* Integrated Graphics Device */
+ u8 igds; /* 0x3c - IGD state */
+ u8 tlst; /* 0x3d - Display Toggle List Pointer */
+ u8 cadl; /* 0x3e - currently attached devices */
+ u8 padl; /* 0x3f - previously attached devices */
+ u16 cste; /* 0x40 - current display state */
+ u16 nste; /* 0x42 - next display state */
+ u16 sste; /* 0x44 - set display state */
+ u8 ndid; /* 0x46 - number of device ids */
+ u32 did[5]; /* 0x47 - 5b device id 1..5 */
+ u8 rsvd5[0x9];
+ /* Backlight Control */
+ u8 blcs; /* 0x64 - Backlight Control possible */
+ u8 brtl;
+ u8 odds;
+ u8 rsvd6[0x7];
+ /* Ambient Light Sensors*/
+ u8 alse; /* 0x6e - ALS enable */
+ u8 alaf;
+ u8 llow;
+ u8 lhih;
+ u8 rsvd7[0x6];
+ /* EMA */
+ u8 emae; /* 0x78 - EMA enable */
+ u16 emap;
+ u16 emal;
+ u8 rsvd8[0x5];
+ /* MEF */
+ u8 mefe; /* 0x82 - MEF enable */
+ u8 rsvd9[0x9];
+ /* TPM support */
+ u8 tpmp; /* 0x8c - TPM */
+ u8 tpme;
+ u8 rsvd10[8];
+ /* SATA */
+ u8 gtf0[7]; /* 0x96 - GTF task file buffer for port 0 */
+ u8 gtf1[7];
+ u8 gtf2[7];
+ u8 idem;
+ u8 idet;
+ u8 rsvd11[7];
+ /* IGD OpRegion (not implemented yet) */
+ u32 aslb; /* 0xb4 - IGD OpRegion Base Address */
+ u8 ibtt;
+ u8 ipat;
+ u8 itvf;
+ u8 itvm;
+ u8 ipsc;
+ u8 iblc;
+ u8 ibia;
+ u8 issc;
+ u8 i409;
+ u8 i509;
+ u8 i609;
+ u8 i709;
+ u8 idmm;
+ u8 idms;
+ u8 if1e;
+ u8 hvco;
+ u32 nxd[8];
+ u8 rsvd12[8];
+ /* Mainboard specific */
+ u8 dock; /* 0xf0 - Docking Status */
+ u8 bten;
+ u8 rsvd13[14];
+} __attribute__((packed)) global_nvs_t;
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801gx.h"
+
+static void pci_init(struct device *dev)
+{
+ u16 reg16;
+ u8 reg8;
+
+ /* Enable Bus Master */
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 |= PCI_COMMAND_MASTER;
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+
+ /* This device has no interrupt */
+ pci_write_config8(dev, INTR, 0xff);
+
+ /* disable parity error response and SERR */
+ reg16 = pci_read_config16(dev, BCTRL);
+ reg16 &= ~(1 << 0);
+ reg16 &= ~(1 << 1);
+ pci_write_config16(dev, BCTRL, reg16);
+
+ /* Master Latency Count must be set to 0x04! */
+ reg8 = pci_read_config8(dev, SMLT);
+ reg8 &= 0x07;
+ reg8 |= (0x04 << 3);
+ pci_write_config8(dev, SMLT, reg8);
+
+ /* Will this improve throughput of bus masters? */
+ pci_write_config8(dev, PCI_MIN_GNT, 0x06);
+
+ /* Clear errors in status registers */
+ reg16 = pci_read_config16(dev, PSTS);
+ //reg16 |= 0xf900;
+ pci_write_config16(dev, PSTS, reg16);
+
+ reg16 = pci_read_config16(dev, SECSTS);
+ // reg16 |= 0xf900;
+ pci_write_config16(dev, SECSTS, reg16);
+}
+
+#undef PCI_BRIDGE_UPDATE_COMMAND
+static void ich_pci_dev_enable_resources(struct device *dev)
+{
+ const struct pci_operations *ops;
+ uint16_t command;
+
+ /* Set the subsystem vendor and device id for mainboard devices */
+ ops = ops_pci(dev);
+ if (dev->on_mainboard && ops && ops->set_subsystem) {
+ printk(BIOS_DEBUG, "%s subsystem <- %02x/%02x\n",
+ dev_path(dev),
+ CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
+ CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
+ ops->set_subsystem(dev,
+ CONFIG_MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID,
+ CONFIG_MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID);
+ }
+
+ command = pci_read_config16(dev, PCI_COMMAND);
+ command |= dev->command;
+#ifdef PCI_BRIDGE_UPDATE_COMMAND
+ /* If we write to PCI_COMMAND, on some systems
+ * this will cause the ROM and APICs not being visible
+ * anymore.
+ */
+ printk(BIOS_DEBUG, "%s cmd <- %02x\n", dev_path(dev), command);
+ pci_write_config16(dev, PCI_COMMAND, command);
+#else
+ printk(BIOS_DEBUG, "%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
+#endif
+}
+
+static void ich_pci_bus_enable_resources(struct device *dev)
+{
+ uint16_t ctrl;
+ /* enable IO in command register if there is VGA card
+ * connected with (even it does not claim IO resource)
+ */
+ if (dev->link_list->bridge_ctrl & PCI_BRIDGE_CTL_VGA)
+ dev->command |= PCI_COMMAND_IO;
+ ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
+ ctrl |= dev->link_list->bridge_ctrl;
+ ctrl |= (PCI_BRIDGE_CTL_PARITY + PCI_BRIDGE_CTL_SERR); /* error check */
+ printk(BIOS_DEBUG, "%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
+ pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
+
+ /* This is the reason we need our own pci_bus_enable_resources */
+ ich_pci_dev_enable_resources(dev);
+}
+
+static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* NOTE: This is not the default position! */
+ if (!vendor || !device) {
+ pci_write_config32(dev, 0x54,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, 0x54,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations pci_ops = {
+ .set_subsystem = set_subsystem,
+};
+
+static struct device_operations device_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = ich_pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = &pci_ops,
+};
+
+/* Desktop */
+/* 82801BA/CA/DB/EB/ER/FB/FR/FW/FRW/GB/GR/GDH/HB/IB/6300ESB/i3100 */
+static const struct pci_driver i82801g_pci __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x244e,
+};
+
+/* Mobile / Ultra Mobile */
+/* 82801BAM/CAM/DBL/DBM/FBM/GBM/GHM/GU/HBM/HEM */
+static const struct pci_driver i82801gmu_pci __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x2448,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+static void pci_init(struct device *dev)
+{
+ u16 reg16;
+ u32 reg32;
+
+ printk(BIOS_DEBUG, "Initializing ICH7 PCIe bridge.\n");
+
+ /* Enable Bus Master */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* Set Cache Line Size to 0x10 */
+ // This has no effect but the OS might expect it
+ pci_write_config8(dev, 0x0c, 0x10);
+
+ reg16 = pci_read_config16(dev, 0x3e);
+ reg16 &= ~(1 << 0); /* disable parity error response */
+ // reg16 &= ~(1 << 1); /* disable SERR */
+ reg16 |= (1 << 2); /* ISA enable */
+ pci_write_config16(dev, 0x3e, reg16);
+
+ /* Enable IO xAPIC on this PCIe port */
+ reg32 = pci_read_config32(dev, 0xd8);
+ reg32 |= (1 << 7);
+ pci_write_config32(dev, 0xd8, reg32);
+
+ /* Enable Backbone Clock Gating */
+ reg32 = pci_read_config32(dev, 0xe1);
+ reg32 |= (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0);
+ pci_write_config32(dev, 0xe1, reg32);
+
+#if CONFIG_MMCONF_SUPPORT
+ /* Set VC0 transaction class */
+ reg32 = pci_mmio_read_config32(dev, 0x114);
+ reg32 &= 0xffffff00;
+ reg32 |= 1;
+ pci_mmio_write_config32(dev, 0x114, reg32);
+
+ /* Mask completion timeouts */
+ reg32 = pci_mmio_read_config32(dev, 0x148);
+ reg32 |= (1 << 14);
+ pci_mmio_write_config32(dev, 0x148, reg32);
+#else
+#error "MMIO needed for ICH7 PCIe"
+#endif
+ /* Enable common clock configuration */
+ // Are there cases when we don't want that?
+ reg16 = pci_read_config16(dev, 0x50);
+ reg16 |= (1 << 6);
+ pci_write_config16(dev, 0x50, reg16);
+
+#ifdef EVEN_MORE_DEBUG
+ reg32 = pci_read_config32(dev, 0x20);
+ printk(BIOS_SPEW, " MBL = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x24);
+ printk(BIOS_SPEW, " PMBL = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x28);
+ printk(BIOS_SPEW, " PMBU32 = 0x%08x\n", reg32);
+ reg32 = pci_read_config32(dev, 0x2c);
+ printk(BIOS_SPEW, " PMLU32 = 0x%08x\n", reg32);
+#endif
+
+ /* Clear errors in status registers */
+ reg16 = pci_read_config16(dev, 0x06);
+ //reg16 |= 0xf900;
+ pci_write_config16(dev, 0x06, reg16);
+
+ reg16 = pci_read_config16(dev, 0x1e);
+ //reg16 |= 0xf900;
+ pci_write_config16(dev, 0x1e, reg16);
+}
+
+static void pcie_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ /* NOTE: This is not the default position! */
+ if (!vendor || !device) {
+ pci_write_config32(dev, 0x94,
+ pci_read_config32(dev, 0));
+ } else {
+ pci_write_config32(dev, 0x94,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations pci_ops = {
+ .set_subsystem = pcie_set_subsystem,
+};
+
+static struct device_operations device_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = &pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port1 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27d0,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port2 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27d2,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port3 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27d4,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port4 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27d6,
+};
+
+/* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port5 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27e0,
+};
+
+/* 82801GR/GDH/GHM (ICH7R/ICH7DH/ICH7-M DH) */
+static const struct pci_driver i82801gx_pcie_port6 __pci_driver = {
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27e2,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+void soft_reset(void)
+{
+ outb(0x04, 0xcf9);
+}
+
+#if 0
+void hard_reset(void)
+{
+ /* Try rebooting through port 0xcf9. */
+ outb((1 << 2) | (1 << 1), 0xcf9);
+}
+#endif
+
+void hard_reset(void)
+{
+ outb(0x02, 0xcf9);
+ outb(0x06, 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801gx.h"
+
+typedef struct southbridge_intel_i82801gx_config config_t;
+
+static void sata_init(struct device *dev)
+{
+ u32 reg32;
+ u16 reg16;
+ /* Get the chip configuration */
+ config_t *config = dev->chip_info;
+
+ printk(BIOS_DEBUG, "i82801gx_sata: initializing...\n");
+
+ if (config == NULL) {
+ printk(BIOS_ERR, "i82801gx_sata: error: device not in devicetree.cb!\n");
+ return;
+ }
+
+ /* SATA configuration */
+
+ /* Enable BARs */
+ pci_write_config16(dev, PCI_COMMAND, 0x0007);
+
+ if (config->ide_legacy_combined) {
+ printk(BIOS_DEBUG, "SATA controller in combined mode.\n");
+ /* No AHCI: clear AHCI base */
+ pci_write_config32(dev, 0x24, 0x00000000);
+ /* And without AHCI BAR no memory decoding */
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 &= ~PCI_COMMAND_MEMORY;
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+
+ pci_write_config8(dev, 0x09, 0x80);
+
+ /* Set timings */
+ pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+ pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+ IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+
+ /* Sync DMA */
+ pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+ pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+
+ /* Set IDE I/O Configuration */
+ reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
+ pci_write_config32(dev, IDE_CONFIG, reg32);
+
+ /* Combine IDE - SATA configuration */
+ pci_write_config8(dev, 0x90, 0x02);
+
+ /* Port 0 & 1 enable */
+ pci_write_config8(dev, 0x92, 0x0f);
+
+ /* SATA Initialization register */
+ pci_write_config32(dev, 0x94, 0x5a000180);
+ } else if(config->sata_ahci) {
+ printk(BIOS_DEBUG, "SATA controller in AHCI mode.\n");
+ /* Allow both Legacy and Native mode */
+ pci_write_config8(dev, 0x09, 0x8f);
+
+ /* Set Interrupt Line */
+ /* Interrupt Pin is set by D31IP.PIP */
+ pci_write_config8(dev, INTR_LN, 0x0a);
+
+ /* Set timings */
+ pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+ IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+ pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
+
+ /* Sync DMA */
+ pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+ pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+
+ /* Set IDE I/O Configuration */
+ reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
+ pci_write_config32(dev, IDE_CONFIG, reg32);
+
+ /* Set Sata Controller Mode. */
+ pci_write_config8(dev, 0x90, 0x40); // 40=AHCI
+
+ /* Port 0 & 1 enable */
+ pci_write_config8(dev, 0x92, 0x0f);
+
+ /* SATA Initialization register */
+ pci_write_config32(dev, 0x94, 0x1a000180);
+ } else {
+ printk(BIOS_DEBUG, "SATA controller in plain mode.\n");
+ /* Set Sata Controller Mode. No Mapping(?) */
+ pci_write_config8(dev, 0x90, 0x00);
+
+ /* No AHCI: clear AHCI base */
+ pci_write_config32(dev, 0x24, 0x00000000);
+
+ /* And without AHCI BAR no memory decoding */
+ reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 &= ~PCI_COMMAND_MEMORY;
+ pci_write_config16(dev, PCI_COMMAND, reg16);
+
+ /* Native mode capable on both primary and secondary (0xa)
+ * or'ed with enabled (0x50) = 0xf
+ */
+ pci_write_config8(dev, 0x09, 0x8f);
+
+ /* Set Interrupt Line */
+ /* Interrupt Pin is set by D31IP.PIP */
+ pci_write_config8(dev, INTR_LN, 0xff);
+
+ /* Set timings */
+ pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
+ IDE_PPE0 | IDE_IE0 | IDE_TIME0);
+ pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ IDE_SITRE | IDE_ISP_3_CLOCKS |
+ IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
+
+ /* Sync DMA */
+ pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+ pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+
+ /* Set IDE I/O Configuration */
+ reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
+ pci_write_config32(dev, IDE_CONFIG, reg32);
+
+ /* Port 0 & 1 enable XXX */
+ pci_write_config8(dev, 0x92, 0x15);
+
+ /* SATA Initialization register */
+ pci_write_config32(dev, 0x94, 0x1a000180);
+ }
+
+ /* All configurations need this SATA initialization sequence */
+ pci_write_config8(dev, 0xa0, 0x40);
+ pci_write_config8(dev, 0xa6, 0x22);
+ pci_write_config8(dev, 0xa0, 0x78);
+ pci_write_config8(dev, 0xa6, 0x22);
+ pci_write_config8(dev, 0xa0, 0x88);
+ reg32 = pci_read_config32(dev, 0xa4);
+ reg32 &= 0xc0c0c0c0;
+ reg32 |= 0x1b1b1212;
+ pci_write_config32(dev, 0xa4, reg32);
+ pci_write_config8(dev, 0xa0, 0x8c);
+ reg32 = pci_read_config32(dev, 0xa4);
+ reg32 &= 0xc0c0ff00;
+ reg32 |= 0x121200aa;
+ pci_write_config32(dev, 0xa4, reg32);
+ pci_write_config8(dev, 0xa0, 0x00);
+
+ pci_write_config8(dev, PCI_INTERRUPT_LINE, 0);
+
+ /* Sata Initialization Register */
+ reg32 = pci_read_config32(dev, 0x94);
+ reg32 |= (1 << 30); // due to some bug
+ pci_write_config32(dev, 0x94, reg32);
+}
+
+static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations sata_pci_ops = {
+ .set_subsystem = sata_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &sata_pci_ops,
+};
+
+/* Desktop Non-AHCI and Non-RAID Mode */
+/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
+static const struct pci_driver i82801gx_sata_normal_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c0,
+};
+
+/* Mobile Non-AHCI and Non-RAID Mode */
+/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_sata_mobile_normal_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c4,
+};
+
+
+/* NOTE: Any of the below are not properly supported yet. */
+
+/* Desktop AHCI Mode */
+/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
+static const struct pci_driver i82801gx_sata_ahci_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c1,
+};
+
+/* Desktop RAID mode */
+/* 82801GB/GR/GDH (ICH7/ICH7R/ICH7DH) */
+static const struct pci_driver i82801gx_sata_raid_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c3,
+};
+
+/* Mobile AHCI Mode */
+/* 82801GBM/GHM (ICH7-M/ICH7-M DH) */
+static const struct pci_driver i82801gx_sata_mobile_ahci_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c5,
+};
+
+/* ICH7M DH Raid Mode */
+/* 82801GHM (ICH7-M DH) */
+static const struct pci_driver i82801gx_sata_ich7dh_raid_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c6,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "i82801gx.h"
+#include "smbus.h"
+
+#define SMB_BASE 0x20
+static void smbus_init(struct device *dev)
+{
+ u32 smb_base;
+
+ smb_base = pci_read_config32(dev, SMB_BASE);
+ printk(BIOS_DEBUG, "Initializing SMBus device:\n");
+ printk(BIOS_DEBUG, " Old SMBUS Base Address: 0x%04x\n", smb_base);
+ pci_write_config32(dev, SMB_BASE, 0x00000401);
+ smb_base = pci_read_config32(dev, SMB_BASE);
+ printk(BIOS_DEBUG, " New SMBUS Base Address: 0x%04x\n", smb_base);
+}
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations smbus_pci_ops = {
+ .set_subsystem = smbus_set_subsystem,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = smbus_init,
+ .scan_bus = scan_static_bus,
+ .enable = i82801gx_enable,
+ .ops_smbus_bus = &lops_smbus_bus,
+ .ops_pci = &smbus_pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gx_smbus __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27da,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2005 Yinghai Lu <yinghailu@gmail.com>
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+#include "i82801gx.h"
+
+static void smbus_delay(void)
+{
+ inb(0x80);
+}
+
+static int smbus_wait_until_ready(u16 smbus_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u16 smbus_base)
+{
+ unsigned loops = SMBUS_TIMEOUT;
+ unsigned char byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6) | (1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+static int do_smbus_read_byte(unsigned smbus_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready(smbus_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* Setup transaction */
+ /* Disable interrupts */
+ outb(inb(smbus_base + SMBHSTCTL) & (~1), smbus_base + SMBHSTCTL);
+ /* Set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_base + SMBXMITADD);
+ /* Set the command/address... */
+ outb(address & 0xff, smbus_base + SMBHSTCMD);
+ /* Set up for a byte data read */
+ outb((inb(smbus_base + SMBHSTCTL) & 0xe3) | (0x2 << 2),
+ (smbus_base + SMBHSTCTL));
+ /* Clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_base + SMBHSTSTAT), smbus_base + SMBHSTSTAT);
+
+ /* Clear the data byte... */
+ outb(0, smbus_base + SMBHSTDAT0);
+
+ /* Start the command */
+ outb((inb(smbus_base + SMBHSTCTL) | 0x40),
+ smbus_base + SMBHSTCTL);
+
+ /* Poll for transaction completion */
+ if (smbus_wait_until_done(smbus_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_base + SMBHSTSTAT);
+
+ /* Ignore the "In Use" status... */
+ global_status_register &= ~(3 << 5);
+
+ /* Read results of transaction */
+ byte = inb(smbus_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <console/console.h>
+#include <arch/io.h>
+#include <cpu/cpu.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <string.h>
+#include "i82801gx.h"
+
+extern unsigned char _binary_smm_start;
+extern unsigned char _binary_smm_size;
+
+/* I945 */
+#define SMRAM 0x9d
+#define D_OPEN (1 << 6)
+#define D_CLS (1 << 5)
+#define D_LCK (1 << 4)
+#define G_SMRAME (1 << 3)
+#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+
+/* While we read PMBASE dynamically in case it changed, let's
+ * initialize it with a sane value
+ */
+static u16 pmbase = DEFAULT_PMBASE;
+
+/**
+ * @brief read and clear PM1_STS
+ * @return PM1_STS register
+ */
+static u16 reset_pm1_status(void)
+{
+ u16 reg16;
+
+ reg16 = inw(pmbase + PM1_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outw(reg16, pmbase + PM1_STS);
+
+ return reg16;
+}
+
+static void dump_pm1_status(u16 pm1_sts)
+{
+ printk(BIOS_DEBUG, "PM1_STS: ");
+ if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK ");
+ if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK ");
+ if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR ");
+ if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC ");
+ if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN ");
+ if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL ");
+ if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM ");
+ if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+/**
+ * @brief read and clear SMI_STS
+ * @return SMI_STS register
+ */
+static u32 reset_smi_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + SMI_STS);
+
+ return reg32;
+}
+
+static void dump_smi_status(u32 smi_sts)
+{
+ printk(BIOS_DEBUG, "SMI_STS: ");
+ if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
+ if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
+ if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
+ if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
+ if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
+ if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
+ if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
+ if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
+ if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
+ if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
+ if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
+ if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
+ if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
+ if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
+ if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
+ if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
+ if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
+ if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
+ if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
+ if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear GPE0_STS
+ * @return GPE0_STS register
+ */
+static u32 reset_gpe0_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + GPE0_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + GPE0_STS);
+
+ return reg32;
+}
+
+static void dump_gpe0_status(u32 gpe0_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ for (i=31; i<= 16; i--) {
+ if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
+ }
+ if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
+ if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
+ if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
+ if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
+ if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
+ if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
+ if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
+ if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
+ if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
+ if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
+ if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
+ if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
+ if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
+ if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear ALT_GP_SMI_STS
+ * @return ALT_GP_SMI_STS register
+ */
+static u16 reset_alt_gp_smi_status(void)
+{
+ u16 reg16;
+
+ reg16 = inl(pmbase + ALT_GP_SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg16, pmbase + ALT_GP_SMI_STS);
+
+ return reg16;
+}
+
+static void dump_alt_gp_smi_status(u16 alt_gp_smi_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "ALT_GP_SMI_STS: ");
+ for (i=15; i<= 0; i--) {
+ if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", (i-16));
+ }
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+
+/**
+ * @brief read and clear TCOx_STS
+ * @return TCOx_STS registers
+ */
+static u32 reset_tco_status(void)
+{
+ u32 tcobase = pmbase + 0x60;
+ u32 reg32;
+
+ reg32 = inl(tcobase + 0x04);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
+ if (reg32 & (1 << 18))
+ outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
+
+ return reg32;
+}
+
+
+static void dump_tco_status(u32 tco_sts)
+{
+ printk(BIOS_DEBUG, "TCO_STS: ");
+ if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
+ if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
+ if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
+ if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
+ if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
+ if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
+ if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
+ if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
+ if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
+ if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
+ if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
+ if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
+ if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+
+/**
+ * @brief Set the EOS bit
+ */
+static void smi_set_eos(void)
+{
+ u8 reg8;
+
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 |= EOS;
+ outb(reg8, pmbase + SMI_EN);
+}
+
+extern uint8_t smm_relocation_start, smm_relocation_end;
+
+static void smm_relocate(void)
+{
+ u32 smi_en;
+ u16 pm1_en;
+
+ printk(BIOS_DEBUG, "Initializing SMM handler...");
+
+ pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), 0x40) & 0xfffc;
+ printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase);
+
+ smi_en = inl(pmbase + SMI_EN);
+ if (smi_en & APMC_EN) {
+ printk(BIOS_INFO, "SMI# handler already enabled?\n");
+ return;
+ }
+
+ /* copy the SMM relocation code */
+ memcpy((void *)0x38000, &smm_relocation_start,
+ &smm_relocation_end - &smm_relocation_start);
+
+ printk(BIOS_DEBUG, "\n");
+ dump_smi_status(reset_smi_status());
+ dump_pm1_status(reset_pm1_status());
+ dump_gpe0_status(reset_gpe0_status());
+ dump_alt_gp_smi_status(reset_alt_gp_smi_status());
+ dump_tco_status(reset_tco_status());
+
+ /* Enable SMI generation:
+ * - on TCO events
+ * - on APMC writes (io 0xb2)
+ * - on writes to SLP_EN (sleep states)
+ * - on writes to GBL_RLS (bios commands)
+ * No SMIs:
+ * - on microcontroller writes (io 0x62/0x66)
+ */
+
+ smi_en = 0; /* reset SMI enables */
+
+#if 0
+ smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN;
+#endif
+ smi_en |= TCO_EN;
+ smi_en |= APMC_EN;
+#if DEBUG_PERIODIC_SMIS
+ /* Set DEBUG_PERIODIC_SMIS in i82801gx.h to debug using
+ * periodic SMIs.
+ */
+ smi_en |= PERIODIC_EN;
+#endif
+ smi_en |= SLP_SMI_EN;
+ smi_en |= BIOS_EN;
+
+ /* The following need to be on for SMIs to happen */
+ smi_en |= EOS | GBL_SMI_EN;
+
+ outl(smi_en, pmbase + SMI_EN);
+
+ pm1_en = 0;
+ pm1_en |= PWRBTN_EN;
+ pm1_en |= GBL_EN;
+ outw(pm1_en, pmbase + PM1_EN);
+
+ /**
+ * There are several methods of raising a controlled SMI# via
+ * software, among them:
+ * - Writes to io 0xb2 (APMC)
+ * - Writes to the Local Apic ICR with Delivery mode SMI.
+ *
+ * Using the local apic is a bit more tricky. According to
+ * AMD Family 11 Processor BKDG no destination shorthand must be
+ * used.
+ * The whole SMM initialization is quite a bit hardware specific, so
+ * I'm not too worried about the better of the methods at the moment
+ */
+
+ /* raise an SMI interrupt */
+ printk(BIOS_SPEW, " ... raise SMI#\n");
+ outb(0x00, 0xb2);
+}
+
+static void smm_install(void)
+{
+ /* enable the SMM memory window */
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ D_OPEN | G_SMRAME | C_BASE_SEG);
+
+ /* copy the real SMM handler */
+ memcpy((void *)0xa0000, &_binary_smm_start, (size_t)&_binary_smm_size);
+ wbinvd();
+
+ /* close the SMM memory window and enable normal SMM */
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ G_SMRAME | C_BASE_SEG);
+}
+
+void smm_init(void)
+{
+ /* Put SMM code to 0xa0000 */
+ smm_install();
+
+ /* Put relocation code to 0x38000 and relocate SMBASE */
+ smm_relocate();
+
+ /* We're done. Make sure SMIs can happen! */
+ smi_set_eos();
+}
+
+void smm_lock(void)
+{
+ /* LOCK the SMM memory window and enable normal SMM.
+ * After running this function, only a full reset can
+ * make the SMM registers writable again.
+ */
+ printk(BIOS_DEBUG, "Locking SMM.\n");
+ pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
+ D_LCK | G_SMRAME | C_BASE_SEG);
+}
+
+void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
+{
+ /* The GDT or coreboot table is going to live here. But a long time
+ * after we relocated the GNVS, so this is not troublesome.
+ */
+ *(u32 *)0x500 = (u32)gnvs;
+ *(u32 *)0x504 = (u32)tcg;
+ *(u32 *)0x508 = (u32)smi1;
+ outb(0xea, 0xb2);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/smm.h>
+#include <device/pci_def.h>
+#include "i82801gx.h"
+
+#define APM_CNT 0xb2
+#define CST_CONTROL 0x85
+#define PST_CONTROL 0x80
+#define ACPI_DISABLE 0x1e
+#define ACPI_ENABLE 0xe1
+#define GNVS_UPDATE 0xea
+#define APM_STS 0xb3
+
+/* I945 */
+#define SMRAM 0x9d
+#define D_OPEN (1 << 6)
+#define D_CLS (1 << 5)
+#define D_LCK (1 << 4)
+#define G_SMRANE (1 << 3)
+#define C_BASE_SEG ((0 << 2) | (1 << 1) | (0 << 0))
+
+#include "nvs.h"
+
+/* While we read PMBASE dynamically in case it changed, let's
+ * initialize it with a sane value
+ */
+u16 pmbase = DEFAULT_PMBASE;
+u8 smm_initialized = 0;
+
+/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
+ * by coreboot.
+ */
+global_nvs_t *gnvs = (global_nvs_t *)0x0;
+void *tcg = (void *)0x0;
+void *smi1 = (void *)0x0;
+
+/**
+ * @brief read and clear PM1_STS
+ * @return PM1_STS register
+ */
+static u16 reset_pm1_status(void)
+{
+ u16 reg16;
+
+ reg16 = inw(pmbase + PM1_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outw(reg16, pmbase + PM1_STS);
+
+ return reg16;
+}
+
+static void dump_pm1_status(u16 pm1_sts)
+{
+ printk(BIOS_SPEW, "PM1_STS: ");
+ if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK ");
+ if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK ");
+ if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR ");
+ if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC ");
+ if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN ");
+ if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL ");
+ if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM ");
+ if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF ");
+ printk(BIOS_SPEW, "\n");
+ int reg16 = inw(pmbase + PM1_EN);
+ printk(BIOS_SPEW, "PM1_EN: %x\n", reg16);
+}
+
+/**
+ * @brief read and clear SMI_STS
+ * @return SMI_STS register
+ */
+static u32 reset_smi_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + SMI_STS);
+
+ return reg32;
+}
+
+static void dump_smi_status(u32 smi_sts)
+{
+ printk(BIOS_DEBUG, "SMI_STS: ");
+ if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI ");
+ if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI ");
+ if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR ");
+ if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI ");
+ if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 ");
+ if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 ");
+ if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI ");
+ if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI ");
+ if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC ");
+ if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO ");
+ if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON ");
+ if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI ");
+ if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI ");
+ if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 ");
+ if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 ");
+ if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR ");
+ if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM ");
+ if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI ");
+ if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB ");
+ if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear GPE0_STS
+ * @return GPE0_STS register
+ */
+static u32 reset_gpe0_status(void)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + GPE0_STS);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32, pmbase + GPE0_STS);
+
+ return reg32;
+}
+
+static void dump_gpe0_status(u32 gpe0_sts)
+{
+ int i;
+ printk(BIOS_DEBUG, "GPE0_STS: ");
+ for (i=31; i<= 16; i--) {
+ if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16));
+ }
+ if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 ");
+ if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 ");
+ if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 ");
+ if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME ");
+ if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW ");
+ if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP ");
+ if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI ");
+ if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK ");
+ if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI ");
+ if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 ");
+ if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 ");
+ if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 ");
+ if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG ");
+ if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+
+/**
+ * @brief read and clear TCOx_STS
+ * @return TCOx_STS registers
+ */
+static u32 reset_tco_status(void)
+{
+ u32 tcobase = pmbase + 0x60;
+ u32 reg32;
+
+ reg32 = inl(tcobase + 0x04);
+ /* set status bits are cleared by writing 1 to them */
+ outl(reg32 & ~(1<<18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS
+ if (reg32 & (1 << 18))
+ outl(reg32 & (1<<18), tcobase + 0x04); // clear BOOT_STS
+
+ return reg32;
+}
+
+
+static void dump_tco_status(u32 tco_sts)
+{
+ printk(BIOS_DEBUG, "TCO_STS: ");
+ if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV ");
+ if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT ");
+ if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO ");
+ if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET ");
+ if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR ");
+ if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI ");
+ if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI ");
+ if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR ");
+ if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY ");
+ if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT ");
+ if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT ");
+ if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO ");
+ if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI ");
+ printk(BIOS_DEBUG, "\n");
+}
+
+/* We are using PCIe accesses for now
+ * 1. the chipset can do it
+ * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind
+ */
+#include "../../../northbridge/intel/i945/pcie_config.c"
+
+int southbridge_io_trap_handler(int smif)
+{
+ switch (smif) {
+ case 0x32:
+ printk(BIOS_DEBUG, "OS Init\n");
+ /* gnvs->smif:
+ * On success, the IO Trap Handler returns 0
+ * On failure, the IO Trap Handler returns a value != 0
+ */
+ gnvs->smif = 0;
+ return 1; /* IO trap handled */
+ }
+
+ /* Not handled */
+ return 0;
+}
+
+/**
+ * @brief Set the EOS bit
+ */
+void southbridge_smi_set_eos(void)
+{
+ u8 reg8;
+
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 |= EOS;
+ outb(reg8, pmbase + SMI_EN);
+}
+
+static void busmaster_disable_on_bus(int bus)
+{
+ int slot, func;
+ unsigned int val;
+ unsigned char hdr;
+
+ for (slot = 0; slot < 0x20; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 reg32;
+ device_t dev = PCI_DEV(bus, slot, func);
+
+ val = pci_read_config32(dev, PCI_VENDOR_ID);
+
+ if (val == 0xffffffff || val == 0x00000000 ||
+ val == 0x0000ffff || val == 0xffff0000)
+ continue;
+
+ /* Disable Bus Mastering for this one device */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 &= ~PCI_COMMAND_MASTER;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ /* If this is a bridge, then follow it. */
+ hdr = pci_read_config8(dev, PCI_HEADER_TYPE);
+ hdr &= 0x7f;
+ if (hdr == PCI_HEADER_TYPE_BRIDGE ||
+ hdr == PCI_HEADER_TYPE_CARDBUS) {
+ unsigned int buses;
+ buses = pci_read_config32(dev, PCI_PRIMARY_BUS);
+ busmaster_disable_on_bus((buses >> 8) & 0xff);
+ }
+ }
+ }
+}
+
+
+static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u8 reg8;
+ u32 reg32;
+ u8 slp_typ;
+ /* FIXME: the power state on boot should be read from
+ * CMOS or even better from GNVS. Right now it's hard
+ * coded at compile time.
+ */
+ u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+ /* First, disable further SMIs */
+ reg8 = inb(pmbase + SMI_EN);
+ reg8 &= ~SLP_SMI_EN;
+ outb(reg8, pmbase + SMI_EN);
+
+ /* Figure out SLP_TYP */
+ reg32 = inl(pmbase + PM1_CNT);
+ printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
+ slp_typ = (reg32 >> 10) & 7;
+
+ /* Next, do the deed.
+ */
+
+ switch (slp_typ) {
+ case 0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break;
+ case 1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break;
+ case 5:
+ printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
+ /* Invalidate the cache before going to S3 */
+ wbinvd();
+ break;
+ case 6: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break;
+ case 7:
+ printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n");
+
+ outl(0, pmbase + GPE0_EN);
+
+ /* Should we keep the power state after a power loss?
+ * In case the setting is "ON" or "OFF" we don't have
+ * to do anything. But if it's "KEEP" we have to switch
+ * to "OFF" before entering S5.
+ */
+ if (s5pwr == MAINBOARD_POWER_KEEP) {
+ reg8 = pcie_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
+ reg8 |= 1;
+ pcie_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
+ }
+
+ /* also iterates over all bridges on bus 0 */
+ busmaster_disable_on_bus(0);
+ break;
+ default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break;
+ }
+
+ /* Write back to the SLP register to cause the originally intended
+ * event again. We need to set BIT13 (SLP_EN) though to make the
+ * sleep happen.
+ */
+ outl(reg32 | SLP_EN, pmbase + PM1_CNT);
+
+ /* In most sleep states, the code flow of this function ends at
+ * the line above. However, if we entered sleep state S1 and wake
+ * up again, we will continue to execute code in this function.
+ */
+ reg32 = inl(pmbase + PM1_CNT);
+ if (reg32 & SCI_EN) {
+ /* The OS is not an ACPI OS, so we set the state to S0 */
+ reg32 &= ~(SLP_EN | SLP_TYP);
+ outl(reg32, pmbase + PM1_CNT);
+ }
+}
+
+static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 pmctrl;
+ u8 reg8;
+
+ /* Emulate B2 register as the FADT / Linux expects it */
+
+ reg8 = inb(APM_CNT);
+ switch (reg8) {
+ case CST_CONTROL:
+ /* Calling this function seems to cause
+ * some kind of race condition in Linux
+ * and causes a kernel oops
+ */
+ printk(BIOS_DEBUG, "C-state control\n");
+ break;
+ case PST_CONTROL:
+ /* Calling this function seems to cause
+ * some kind of race condition in Linux
+ * and causes a kernel oops
+ */
+ printk(BIOS_DEBUG, "P-state control\n");
+ break;
+ case ACPI_DISABLE:
+ pmctrl = inl(pmbase + PM1_CNT);
+ pmctrl &= ~SCI_EN;
+ outl(pmctrl, pmbase + PM1_CNT);
+ printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n");
+ break;
+ case ACPI_ENABLE:
+ pmctrl = inl(pmbase + PM1_CNT);
+ pmctrl |= SCI_EN;
+ outl(pmctrl, pmbase + PM1_CNT);
+ printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
+ break;
+ case GNVS_UPDATE:
+ if (smm_initialized) {
+ printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n");
+ return;
+ }
+ gnvs = *(global_nvs_t **)0x500;
+ tcg = *(void **)0x504;
+ smi1 = *(void **)0x508;
+ smm_initialized = 1;
+ printk(BIOS_DEBUG, "SMI#: Setting up structures to %p, %p, %p\n", gnvs, tcg, smi1);
+ break;
+ default:
+ printk(BIOS_DEBUG, "SMI#: Unknown function APM_CNT=%02x\n", reg8);
+ }
+}
+
+static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u16 pm1_sts;
+
+ pm1_sts = reset_pm1_status();
+ dump_pm1_status(pm1_sts);
+
+ /* While OSPM is not active, poweroff immediately
+ * on a power button event.
+ */
+ if (pm1_sts & PWRBTN_STS) {
+ // power button pressed
+ u32 reg32;
+ reg32 = (7 << 10) | (1 << 13);
+ outl(reg32, pmbase + PM1_CNT);
+ }
+}
+
+static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 gpe0_sts;
+
+ gpe0_sts = reset_gpe0_status();
+ dump_gpe0_status(gpe0_sts);
+}
+
+static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u16 reg16;
+ reg16 = inw(pmbase + ALT_GP_SMI_STS);
+ outl(reg16, pmbase + ALT_GP_SMI_STS);
+
+ reg16 &= inw(pmbase + ALT_GP_SMI_EN);
+
+ if (mainboard_smi_gpi) {
+ mainboard_smi_gpi(reg16);
+ } else {
+ if (reg16)
+ printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16);
+ }
+}
+
+static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_EN);
+
+ /* Are periodic SMIs enabled? */
+ if ((reg32 & MCSMI_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Microcontroller SMI.\n");
+}
+
+
+
+static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 tco_sts;
+
+ tco_sts = reset_tco_status();
+
+ /* Any TCO event? */
+ if (!tco_sts)
+ return;
+
+ if (tco_sts & (1 << 8)) { // BIOSWR
+ u8 bios_cntl;
+
+ bios_cntl = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
+
+ if (bios_cntl & 1) {
+ /* BWE is RW, so the SMI was caused by a
+ * write to BWE, not by a write to the BIOS
+ */
+
+ /* This is the place where we notice someone
+ * is trying to tinker with the BIOS. We are
+ * trying to be nice and just ignore it. A more
+ * resolute answer would be to power down the
+ * box.
+ */
+ printk(BIOS_DEBUG, "Switching back to RO\n");
+ pcie_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1));
+ } /* No else for now? */
+ } else if (tco_sts & (1 << 3)) { /* TIMEOUT */
+ /* Handle TCO timeout */
+ printk(BIOS_DEBUG, "TCO Timeout.\n");
+ } else if (!tco_sts) {
+ dump_tco_status(tco_sts);
+ }
+}
+
+static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save)
+{
+ u32 reg32;
+
+ reg32 = inl(pmbase + SMI_EN);
+
+ /* Are periodic SMIs enabled? */
+ if ((reg32 & PERIODIC_EN) == 0)
+ return;
+
+ printk(BIOS_DEBUG, "Periodic SMI.\n");
+}
+
+static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save)
+{
+#define IOTRAP(x) (trap_sts & (1 << x))
+ u32 trap_sts, trap_cycle;
+ u32 data, mask = 0;
+ int i;
+
+ trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register
+ RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR
+
+ trap_cycle = RCBA32(0x1e10);
+ for (i=16; i<20; i++) {
+ if (trap_cycle & (1 << i))
+ mask |= (0xff << ((i - 16) << 2));
+ }
+
+
+ /* IOTRAP(3) SMI function call */
+ if (IOTRAP(3)) {
+ if (gnvs && gnvs->smif)
+ io_trap_handler(gnvs->smif); // call function smif
+ return;
+ }
+
+ /* IOTRAP(2) currently unused
+ * IOTRAP(1) currently unused */
+
+ /* IOTRAP(0) SMIC */
+ if (IOTRAP(0)) {
+ if (!(trap_cycle & (1 << 24))) { // It's a write
+ printk(BIOS_DEBUG, "SMI1 command\n");
+ data = RCBA32(0x1e18);
+ data &= mask;
+ // if (smi1)
+ // southbridge_smi_command(data);
+ // return;
+ }
+ // Fall through to debug
+ }
+
+ printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc);
+ for (i=0; i < 4; i++) if(IOTRAP(i)) printk(BIOS_DEBUG, " TRAPÂ = %d\n", i);
+ printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf);
+ printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask);
+ printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write");
+
+ if (!(trap_cycle & (1 << 24))) {
+ /* Write Cycle */
+ data = RCBA32(0x1e18);
+ printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data);
+ }
+#undef IOTRAP
+}
+
+typedef void (*smi_handler_t)(unsigned int node,
+ smm_state_save_area_t *state_save);
+
+smi_handler_t southbridge_smi[32] = {
+ NULL, // [0] reserved
+ NULL, // [1] reserved
+ NULL, // [2] BIOS_STS
+ NULL, // [3] LEGACY_USB_STS
+ southbridge_smi_sleep, // [4] SLP_SMI_STS
+ southbridge_smi_apmc, // [5] APM_STS
+ NULL, // [6] SWSMI_TMR_STS
+ NULL, // [7] reserved
+ southbridge_smi_pm1, // [8] PM1_STS
+ southbridge_smi_gpe0, // [9] GPE0_STS
+ southbridge_smi_gpi, // [10] GPI_STS
+ southbridge_smi_mc, // [11] MCSMI_STS
+ NULL, // [12] DEVMON_STS
+ southbridge_smi_tco, // [13] TCO_STS
+ southbridge_smi_periodic, // [14] PERIODIC_STS
+ NULL, // [15] SERIRQ_SMI_STS
+ NULL, // [16] SMBUS_SMI_STS
+ NULL, // [17] LEGACY_USB2_STS
+ NULL, // [18] INTEL_USB2_STS
+ NULL, // [19] reserved
+ NULL, // [20] PCI_EXP_SMI_STS
+ southbridge_smi_monitor, // [21] MONITOR_STS
+ NULL, // [22] reserved
+ NULL, // [23] reserved
+ NULL, // [24] reserved
+ NULL, // [25] EL_SMI_STS
+ NULL, // [26] SPI_STS
+ NULL, // [27] reserved
+ NULL, // [28] reserved
+ NULL, // [29] reserved
+ NULL, // [30] reserved
+ NULL // [31] reserved
+};
+
+/**
+ * @brief Interrupt handler for SMI#
+ *
+ * @param smm_revision revision of the smm state save map
+ */
+
+void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save)
+{
+ int i, dump = 0;
+ u32 smi_sts;
+
+ /* Update global variable pmbase */
+ pmbase = pcie_read_config16(PCI_DEV(0, 0x1f, 0), 0x40) & 0xfffc;
+
+ /* We need to clear the SMI status registers, or we won't see what's
+ * happening in the following calls.
+ */
+ smi_sts = reset_smi_status();
+
+ /* Filter all non-enabled SMI events */
+ // FIXME Double check, this clears MONITOR
+ // smi_sts &= inl(pmbase + SMI_EN);
+
+ /* Call SMI sub handler for each of the status bits */
+ for (i = 0; i < 31; i++) {
+ if (smi_sts & (1 << i)) {
+ if (southbridge_smi[i])
+ southbridge_smi[i](node, state_save);
+ else {
+ printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no "
+ "handler available.\n", i);
+ dump = 1;
+ }
+ }
+ }
+
+ if(dump) {
+ dump_smi_status(smi_sts);
+ }
+
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801gx.h"
+
+static void usb_init(struct device *dev)
+{
+ u32 reg32;
+ u8 reg8;
+
+ /* USB Specification says the device must be Bus Master */
+ printk(BIOS_DEBUG, "UHCI: Setting up controller.. ");
+
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
+
+ // Erratum
+ pci_write_config8(dev, 0xca, 0x00);
+
+ // Yes. Another Erratum
+ reg8 = pci_read_config8(dev, 0xca);
+ reg8 |= (1 << 0);
+ pci_write_config8(dev, 0xca, reg8);
+
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static void usb_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations usb_pci_ops = {
+ .set_subsystem = usb_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &usb_pci_ops,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gb_usb1 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c8,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gb_usb2 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27c9,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gb_usb3 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27ca,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gb_usb4 __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27cb,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "i82801gx.h"
+
+/* Required for successful build, but currently empty. */
+void set_debug_port(unsigned int port)
+{
+ /* Not needed, the ICH* southbridges hardcode physical USB port 1. */
+}
+
+void i82801gx_enable_usbdebug(unsigned int port)
+{
+ u32 dbgctl;
+ device_t dev = PCI_DEV(0, 0x1d, 7); /* USB EHCI, D29:F7 */
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+
+ /* Force ownership of the Debug Port to the EHCI controller. */
+ printk(BIOS_DEBUG, "Enabling OWNER_CNT\n");
+ dbgctl = read32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET);
+ dbgctl |= (1 << 30);
+ write32(CONFIG_EHCI_BAR + CONFIG_EHCI_DEBUG_OFFSET, dbgctl);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i82801gx.h"
+#include <usbdebug.h>
+#include <arch/io.h>
+
+static void usb_ehci_init(struct device *dev)
+{
+ struct resource *res;
+ u32 base;
+ u32 reg32;
+ u8 reg8;
+
+ printk(BIOS_DEBUG, "EHCI: Setting up controller.. ");
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 |= PCI_COMMAND_MASTER;
+ reg32 |= PCI_COMMAND_SERR;
+ pci_write_config32(dev, PCI_COMMAND, reg32);
+
+ reg32 = pci_read_config32(dev, 0xdc);
+ reg32 |= (1 << 31) | (1 << 27);
+ pci_write_config32(dev, 0xdc, reg32);
+
+ reg32 = pci_read_config32(dev, 0xfc);
+ reg32 &= ~(3 << 2);
+ reg32 |= (2 << 2) | (1 << 29) | (1 << 17);
+ pci_write_config32(dev, 0xfc, reg32);
+
+ /* Clear any pending port changes */
+ res = find_resource(dev, 0x10);
+ base = res->base;
+ reg32 = read32(base + 0x24) | (1 << 2);
+ write32(base + 0x24, reg32);
+
+ /* workaround */
+ reg8 = pci_read_config8(dev, 0x84);
+ reg8 |= (1 << 4);
+ pci_write_config8(dev, 0x84, reg8);
+
+ printk(BIOS_DEBUG, "done.\n");
+}
+
+static void usb_ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ u8 access_cntl;
+
+ access_cntl = pci_read_config8(dev, 0x80);
+
+ /* Enable writes to protected registers. */
+ pci_write_config8(dev, 0x80, access_cntl | 1);
+
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+
+ /* Restore protection. */
+ pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static void usb_ehci_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+ struct resource *res;
+ u32 base;
+ u32 usb_debug;
+
+ usb_debug = get_ehci_debug();
+ set_ehci_debug(0);
+#endif
+ pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+ res = find_resource(dev, 0x10);
+ set_ehci_debug(usb_debug);
+ if (!res) return;
+ base = res->base;
+ set_ehci_base(base);
+ report_resource_stored(dev, res, "");
+#endif
+}
+
+
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &usb_ehci_set_subsystem,
+};
+
+static struct device_operations usb_ehci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb_ehci_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_ehci_init,
+ .scan_bus = 0,
+ .enable = i82801gx_enable,
+ .ops_pci = &lops_pci,
+};
+
+/* 82801GB/GR/GDH/GBM/GHM/GU (ICH7/ICH7R/ICH7DH/ICH7-M/ICH7-M DH/ICH7-U) */
+static const struct pci_driver i82801gx_usb_ehci __pci_driver = {
+ .ops = &usb_ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x27cc,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <watchdog.h>
+
+void watchdog_off(void)
+{
+ device_t dev;
+ unsigned long value, base;
+
+ /* Turn off the ICH7 watchdog. */
+ dev = dev_find_slot(0, PCI_DEVFN(0x1f, 0));
+
+ /* Enable I/O space. */
+ value = pci_read_config16(dev, 0x04);
+ value |= (1 << 10);
+ pci_write_config16(dev, 0x04, value);
+
+ /* Get TCO base. */
+ base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60;
+
+ /* Disable the watchdog timer. */
+ value = inw(base + 0x08);
+ value |= 1 << 11;
+ outw(value, base + 0x08);
+
+ /* Clear TCO timeout status. */
+ outw(0x0008, base + 0x04);
+ outw(0x0002, base + 0x06);
+
+ printk(BIOS_DEBUG, "ICH7 watchdog disabled\n");
+}
-driver-y += p64h2_ioapic.c
-driver-y += p64h2_pcibridge.c
-#driver-y += p64h2_pci_parity.c
+driver-y += ioapic.c
+driver-y += pcibridge.c
+#driver-y += pci_parity.c
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <assert.h>
+#include "82870.h"
+
+static int num_p64h2_ioapics = 0;
+
+static void p64h2_ioapic_enable(device_t dev)
+{
+ /* We have to enable MEM and Bus Master for IOAPIC */
+ uint16_t command = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+
+
+ pci_write_config16(dev, PCI_COMMAND, command);
+}
+
+/**
+ * Configure one of the IOAPICs in a P64H2.
+ *
+ * Note that a PCI bus scan will detect both IOAPICs, so this function
+ * will be called twice for each P64H2 in the system.
+ *
+ * @param dev PCI bus/device/function of P64H2 IOAPIC.
+ * NOTE: There are two IOAPICs per P64H2, at D28:F0 and D30:F0.
+ */
+static void p64h2_ioapic_init(device_t dev)
+{
+ uint32_t memoryBase;
+ int apic_index, apic_id;
+
+ volatile uint32_t* pIndexRegister; /* io apic io memory space command address */
+ volatile uint32_t* pWindowRegister; /* io apic io memory space data address */
+
+ apic_index = num_p64h2_ioapics;
+ num_p64h2_ioapics++;
+
+ // A note on IOAPIC addresses:
+ // 0 and 1 are used for the local APICs of the dual virtual
+ // (hyper-threaded) CPUs of physical CPU 0 (devicetree.cb).
+ // 6 and 7 are used for the local APICs of the dual virtual
+ // (hyper-threaded) CPUs of physical CPU 1 (devicetree.cb).
+ // 2 is used for the IOAPIC in the 82801 southbridge (hard-coded in i82801xx_lpc.c)
+
+ // Map APIC index into APIC ID
+ // IDs 3, 4, 5, and 8+ are available (see above note)
+
+ if (apic_index < 3)
+ apic_id = apic_index + 3;
+ else
+ apic_id = apic_index + 5;
+
+ ASSERT(apic_id < 16); // ID is only 4 bits
+
+ // Read the MBAR address for setting up the IOAPIC in memory space
+ // NOTE: this address was assigned during enumeration of the bus
+
+ memoryBase = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+ pIndexRegister = (volatile uint32_t*) memoryBase;
+ pWindowRegister = (volatile uint32_t*)(memoryBase + 0x10);
+
+ printk(BIOS_DEBUG, "IOAPIC %d at %02x:%02x.%01x MBAR = %p DataAddr = %p\n",
+ apic_id, dev->bus->secondary, PCI_SLOT(dev->path.pci.devfn),
+ PCI_FUNC(dev->path.pci.devfn), pIndexRegister, pWindowRegister);
+
+ apic_id <<= 24; // Convert ID to bitmask
+
+ *pIndexRegister = 0; // Select APIC ID register
+ *pWindowRegister = (*pWindowRegister & ~(0xF<<24)) | apic_id; // Set the ID
+
+ if ((*pWindowRegister & (0xF<<24)) != apic_id)
+ die("p64h2_ioapic_init failed");
+
+ *pIndexRegister = 3; // Select Boot Configuration register
+ *pWindowRegister |= 1; // Use Processor System Bus to deliver interrupts
+
+ if (!(*pWindowRegister & 1))
+ die("p64h2_ioapic_init failed");
+}
+
+static struct device_operations ioapic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = p64h2_ioapic_init,
+ .scan_bus = 0,
+ .enable = p64h2_ioapic_enable,
+};
+
+static const struct pci_driver ioapic_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82870_1E0,
+
+};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <assert.h>
-#include "82870.h"
-
-static int num_p64h2_ioapics = 0;
-
-static void p64h2_ioapic_enable(device_t dev)
-{
- /* We have to enable MEM and Bus Master for IOAPIC */
- uint16_t command = PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-
-
- pci_write_config16(dev, PCI_COMMAND, command);
-}
-
-/**
- * Configure one of the IOAPICs in a P64H2.
- *
- * Note that a PCI bus scan will detect both IOAPICs, so this function
- * will be called twice for each P64H2 in the system.
- *
- * @param dev PCI bus/device/function of P64H2 IOAPIC.
- * NOTE: There are two IOAPICs per P64H2, at D28:F0 and D30:F0.
- */
-static void p64h2_ioapic_init(device_t dev)
-{
- uint32_t memoryBase;
- int apic_index, apic_id;
-
- volatile uint32_t* pIndexRegister; /* io apic io memory space command address */
- volatile uint32_t* pWindowRegister; /* io apic io memory space data address */
-
- apic_index = num_p64h2_ioapics;
- num_p64h2_ioapics++;
-
- // A note on IOAPIC addresses:
- // 0 and 1 are used for the local APICs of the dual virtual
- // (hyper-threaded) CPUs of physical CPU 0 (devicetree.cb).
- // 6 and 7 are used for the local APICs of the dual virtual
- // (hyper-threaded) CPUs of physical CPU 1 (devicetree.cb).
- // 2 is used for the IOAPIC in the 82801 southbridge (hard-coded in i82801xx_lpc.c)
-
- // Map APIC index into APIC ID
- // IDs 3, 4, 5, and 8+ are available (see above note)
-
- if (apic_index < 3)
- apic_id = apic_index + 3;
- else
- apic_id = apic_index + 5;
-
- ASSERT(apic_id < 16); // ID is only 4 bits
-
- // Read the MBAR address for setting up the IOAPIC in memory space
- // NOTE: this address was assigned during enumeration of the bus
-
- memoryBase = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
- pIndexRegister = (volatile uint32_t*) memoryBase;
- pWindowRegister = (volatile uint32_t*)(memoryBase + 0x10);
-
- printk(BIOS_DEBUG, "IOAPIC %d at %02x:%02x.%01x MBAR = %p DataAddr = %p\n",
- apic_id, dev->bus->secondary, PCI_SLOT(dev->path.pci.devfn),
- PCI_FUNC(dev->path.pci.devfn), pIndexRegister, pWindowRegister);
-
- apic_id <<= 24; // Convert ID to bitmask
-
- *pIndexRegister = 0; // Select APIC ID register
- *pWindowRegister = (*pWindowRegister & ~(0xF<<24)) | apic_id; // Set the ID
-
- if ((*pWindowRegister & (0xF<<24)) != apic_id)
- die("p64h2_ioapic_init failed");
-
- *pIndexRegister = 3; // Select Boot Configuration register
- *pWindowRegister |= 1; // Use Processor System Bus to deliver interrupts
-
- if (!(*pWindowRegister & 1))
- die("p64h2_ioapic_init failed");
-}
-
-static struct device_operations ioapic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = p64h2_ioapic_init,
- .scan_bus = 0,
- .enable = p64h2_ioapic_enable,
-};
-
-static const struct pci_driver ioapic_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82870_1E0,
-
-};
+++ /dev/null
-#include <pci.h>
-#include <arch/io.h>
-#include <printk.h>
-#
-
-void p64h2_pci_parity_enable(void)
-{
- uint8_t reg;
-
- /* 2SERREN - SERR enable for PCI bridge secondary device */
- /* 2PEREN - Parity error for PCI bridge secondary device */
- pcibios_read_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, ®);
- reg |= ((1 << 1) + (1 << 0));
- pcibios_write_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, reg);
-
- /* 2SERREN - SERR enable for PCI bridge secondary device */
- /* 2PEREN - Parity error for PCI bridge secondary device */
- pcibios_read_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, ®);
- reg |= ((1 << 1) + (1 << 0));
- pcibios_write_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, reg);
-
- return;
-}
-
-
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include "82870.h"
-
-static void p64h2_pcix_init(device_t dev)
-{
- u32 dword;
- u8 byte;
-
- /* The purpose of changes to HCCR, ACNF, and MTT is to speed
- * up the PCI bus for cards having high speed transfers.
- */
- dword = 0xc2040002;
- pci_write_config32(dev, HCCR, dword);
- dword = 0x0000c3bf;
- pci_write_config32(dev, ACNF, dword);
- byte = 0x08;
- pci_write_config8(dev, MTT, byte);
-
-}
-static struct device_operations pcix_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = p64h2_pcix_init,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
-};
-
-static const struct pci_driver pcix_driver __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = PCI_DEVICE_ID_INTEL_82870_1F0,
-};
-
--- /dev/null
+#include <pci.h>
+#include <arch/io.h>
+#include <printk.h>
+#
+
+void p64h2_pci_parity_enable(void)
+{
+ uint8_t reg;
+
+ /* 2SERREN - SERR enable for PCI bridge secondary device */
+ /* 2PEREN - Parity error for PCI bridge secondary device */
+ pcibios_read_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, ®);
+ reg |= ((1 << 1) + (1 << 0));
+ pcibios_write_config_byte(1, ((29 << 3) + (0 << 0)), 0x3e, reg);
+
+ /* 2SERREN - SERR enable for PCI bridge secondary device */
+ /* 2PEREN - Parity error for PCI bridge secondary device */
+ pcibios_read_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, ®);
+ reg |= ((1 << 1) + (1 << 0));
+ pcibios_write_config_byte(1, ((31 << 3) + (0 << 0)), 0x3e, reg);
+
+ return;
+}
+
+
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include "82870.h"
+
+static void p64h2_pcix_init(device_t dev)
+{
+ u32 dword;
+ u8 byte;
+
+ /* The purpose of changes to HCCR, ACNF, and MTT is to speed
+ * up the PCI bus for cards having high speed transfers.
+ */
+ dword = 0xc2040002;
+ pci_write_config32(dev, HCCR, dword);
+ dword = 0x0000c3bf;
+ pci_write_config32(dev, ACNF, dword);
+ byte = 0x08;
+ pci_write_config8(dev, MTT, byte);
+
+}
+static struct device_operations pcix_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = p64h2_pcix_init,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+};
+
+static const struct pci_driver pcix_driver __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_82870_1F0,
+};
+
-driver-y += pxhd_bridge.c
+driver-y += bridge.c
--- /dev/null
+/*
+ * (C) 2003-2004 Linux Networx
+ */
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pcix.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/ioapic.h>
+#include <delay.h>
+#include "pxhd.h"
+
+static void pxhd_enable(device_t dev)
+{
+ device_t bridge;
+ uint16_t value;
+ if ((dev->path.pci.devfn & 1) == 0) {
+ /* Can we enable/disable the bridges? */
+ return;
+ }
+ bridge = dev_find_slot(dev->bus->secondary, dev->path.pci.devfn & ~1);
+ if (!bridge) {
+ printk(BIOS_ERR, "Cannot find bridge for ioapic: %s\n",
+ dev_path(dev));
+ return;
+ }
+ value = pci_read_config16(bridge, 0x40);
+ value &= ~(1 << 13);
+ if (!dev->enabled) {
+ value |= (1 << 13);
+ }
+ pci_write_config16(bridge, 0x40, value);
+}
+
+
+#define NMI_OFF 0
+
+static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max)
+{
+ int bus_100Mhz = 0;
+
+ dev->link_list->dev = dev;
+
+ get_option(&bus_100Mhz, "pxhd_bus_speed_100");
+ if(bus_100Mhz) {
+ uint16_t word;
+
+ printk(BIOS_DEBUG, "setting pxhd bus to 100 Mhz\n");
+ /* set to pcix 100 mhz */
+ word = pci_read_config16(dev, 0x40);
+ word &= ~(3 << 14);
+ word |= (1 << 14);
+ word &= ~(3 << 9);
+ word |= (2 << 9);
+ pci_write_config16(dev, 0x40, word);
+
+ /* reset the bus to make the new frequencies effective */
+ pci_bus_reset(dev->link_list);
+ }
+ return pcix_scan_bridge(dev, max);
+}
+static void pcix_init(device_t dev)
+{
+ /* Bridge control ISA enable */
+ pci_write_config8(dev, 0x3e, 0x07);
+
+ // FIXME Please review lots of dead code here.
+#if 0
+ int nmi_option;
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+
+ /* Enable memory write and invalidate ??? */
+ byte = pci_read_config8(dev, 0x04);
+ byte |= 0x10;
+ pci_write_config8(dev, 0x04, byte);
+
+ /* Set drive strength */
+ word = pci_read_config16(dev, 0xe0);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe0, word);
+ word = pci_read_config16(dev, 0xe4);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe4, word);
+
+ /* Set impedance */
+ word = pci_read_config16(dev, 0xe8);
+ word = 0x0404;
+ pci_write_config16(dev, 0xe8, word);
+
+ /* Set discard unrequested prefetch data */
+ word = pci_read_config16(dev, 0x4c);
+ word |= 1;
+ pci_write_config16(dev, 0x4c, word);
+
+ /* Set split transaction limits */
+ word = pci_read_config16(dev, 0xa8);
+ pci_write_config16(dev, 0xaa, word);
+ word = pci_read_config16(dev, 0xac);
+ pci_write_config16(dev, 0xae, word);
+
+ /* Set up error reporting, enable all */
+ /* system error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8);
+ pci_write_config32(dev, 0x04, dword);
+
+ /* system and error parity enable */
+ dword = pci_read_config32(dev, 0x3c);
+ dword |= (3<<16);
+ pci_write_config32(dev, 0x3c, dword);
+
+ /* NMI enable */
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if(nmi_option) {
+ dword = pci_read_config32(dev, 0x44);
+ dword |= (1<<0);
+ pci_write_config32(dev, 0x44, dword);
+ }
+
+ /* Set up CRC flood enable */
+ dword = pci_read_config32(dev, 0xc0);
+ if(dword) { /* do device A only */
+ dword = pci_read_config32(dev, 0xc4);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc4, dword);
+ dword = pci_read_config32(dev, 0xc8);
+ dword |= (1<<1);
+ pci_write_config32(dev, 0xc8, dword);
+ }
+
+ return;
+#endif
+}
+
+static struct device_operations pcix_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcix_init,
+ .scan_bus = pxhd_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver pcix_driver __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0329,
+};
+
+static const struct pci_driver pcix_driver2 __pci_driver = {
+ .ops = &pcix_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x032a,
+};
+
+static void ioapic_init(device_t dev)
+{
+ uint32_t value, ioapic_base;
+ /* Enable bus mastering so IOAPICs work */
+ value = pci_read_config16(dev, PCI_COMMAND);
+ value |= PCI_COMMAND_MASTER;
+ pci_write_config16(dev, PCI_COMMAND, value);
+
+ ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+
+ setup_ioapic(ioapic_base, 0); // Don't rename IOAPIC ID
+}
+
+static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations intel_ops_pci = {
+ .set_subsystem = intel_set_subsystem,
+};
+
+static struct device_operations ioapic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ioapic_init,
+ .scan_bus = 0,
+ .enable = pxhd_enable,
+ .ops_pci = &intel_ops_pci,
+};
+
+static const struct pci_driver ioapic_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0326,
+
+};
+
+static const struct pci_driver ioapic2_driver __pci_driver = {
+ .ops = &ioapic_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x0327,
+
+};
+
+struct chip_operations southbridge_intel_pxhd_ops = {
+ CHIP_NAME("Intel PXHD Southbridge")
+ .enable_dev = pxhd_enable,
+};
+++ /dev/null
-/*
- * (C) 2003-2004 Linux Networx
- */
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/pcix.h>
-#include <pc80/mc146818rtc.h>
-#include <arch/ioapic.h>
-#include <delay.h>
-#include "pxhd.h"
-
-static void pxhd_enable(device_t dev)
-{
- device_t bridge;
- uint16_t value;
- if ((dev->path.pci.devfn & 1) == 0) {
- /* Can we enable/disable the bridges? */
- return;
- }
- bridge = dev_find_slot(dev->bus->secondary, dev->path.pci.devfn & ~1);
- if (!bridge) {
- printk(BIOS_ERR, "Cannot find bridge for ioapic: %s\n",
- dev_path(dev));
- return;
- }
- value = pci_read_config16(bridge, 0x40);
- value &= ~(1 << 13);
- if (!dev->enabled) {
- value |= (1 << 13);
- }
- pci_write_config16(bridge, 0x40, value);
-}
-
-
-#define NMI_OFF 0
-
-static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max)
-{
- int bus_100Mhz = 0;
-
- dev->link_list->dev = dev;
-
- get_option(&bus_100Mhz, "pxhd_bus_speed_100");
- if(bus_100Mhz) {
- uint16_t word;
-
- printk(BIOS_DEBUG, "setting pxhd bus to 100 Mhz\n");
- /* set to pcix 100 mhz */
- word = pci_read_config16(dev, 0x40);
- word &= ~(3 << 14);
- word |= (1 << 14);
- word &= ~(3 << 9);
- word |= (2 << 9);
- pci_write_config16(dev, 0x40, word);
-
- /* reset the bus to make the new frequencies effective */
- pci_bus_reset(dev->link_list);
- }
- return pcix_scan_bridge(dev, max);
-}
-static void pcix_init(device_t dev)
-{
- /* Bridge control ISA enable */
- pci_write_config8(dev, 0x3e, 0x07);
-
- // FIXME Please review lots of dead code here.
-#if 0
- int nmi_option;
- uint32_t dword;
- uint16_t word;
- uint8_t byte;
-
- /* Enable memory write and invalidate ??? */
- byte = pci_read_config8(dev, 0x04);
- byte |= 0x10;
- pci_write_config8(dev, 0x04, byte);
-
- /* Set drive strength */
- word = pci_read_config16(dev, 0xe0);
- word = 0x0404;
- pci_write_config16(dev, 0xe0, word);
- word = pci_read_config16(dev, 0xe4);
- word = 0x0404;
- pci_write_config16(dev, 0xe4, word);
-
- /* Set impedance */
- word = pci_read_config16(dev, 0xe8);
- word = 0x0404;
- pci_write_config16(dev, 0xe8, word);
-
- /* Set discard unrequested prefetch data */
- word = pci_read_config16(dev, 0x4c);
- word |= 1;
- pci_write_config16(dev, 0x4c, word);
-
- /* Set split transaction limits */
- word = pci_read_config16(dev, 0xa8);
- pci_write_config16(dev, 0xaa, word);
- word = pci_read_config16(dev, 0xac);
- pci_write_config16(dev, 0xae, word);
-
- /* Set up error reporting, enable all */
- /* system error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8);
- pci_write_config32(dev, 0x04, dword);
-
- /* system and error parity enable */
- dword = pci_read_config32(dev, 0x3c);
- dword |= (3<<16);
- pci_write_config32(dev, 0x3c, dword);
-
- /* NMI enable */
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if(nmi_option) {
- dword = pci_read_config32(dev, 0x44);
- dword |= (1<<0);
- pci_write_config32(dev, 0x44, dword);
- }
-
- /* Set up CRC flood enable */
- dword = pci_read_config32(dev, 0xc0);
- if(dword) { /* do device A only */
- dword = pci_read_config32(dev, 0xc4);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc4, dword);
- dword = pci_read_config32(dev, 0xc8);
- dword |= (1<<1);
- pci_write_config32(dev, 0xc8, dword);
- }
-
- return;
-#endif
-}
-
-static struct device_operations pcix_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcix_init,
- .scan_bus = pxhd_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = 0,
-};
-
-static const struct pci_driver pcix_driver __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x0329,
-};
-
-static const struct pci_driver pcix_driver2 __pci_driver = {
- .ops = &pcix_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x032a,
-};
-
-static void ioapic_init(device_t dev)
-{
- uint32_t value, ioapic_base;
- /* Enable bus mastering so IOAPICs work */
- value = pci_read_config16(dev, PCI_COMMAND);
- value |= PCI_COMMAND_MASTER;
- pci_write_config16(dev, PCI_COMMAND, value);
-
- ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
-
- setup_ioapic(ioapic_base, 0); // Don't rename IOAPIC ID
-}
-
-static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations intel_ops_pci = {
- .set_subsystem = intel_set_subsystem,
-};
-
-static struct device_operations ioapic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ioapic_init,
- .scan_bus = 0,
- .enable = pxhd_enable,
- .ops_pci = &intel_ops_pci,
-};
-
-static const struct pci_driver ioapic_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x0326,
-
-};
-
-static const struct pci_driver ioapic2_driver __pci_driver = {
- .ops = &ioapic_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
- .device = 0x0327,
-
-};
-
-struct chip_operations southbridge_intel_pxhd_ops = {
- CHIP_NAME("Intel PXHD Southbridge")
- .enable_dev = pxhd_enable,
-};
driver-y += ck804.c
-driver-y += ck804_usb.c
-driver-y += ck804_lpc.c
-driver-y += ck804_smbus.c
-driver-y += ck804_ide.c
-driver-y += ck804_sata.c
-driver-y += ck804_usb2.c
-driver-y += ck804_ac97.c
-driver-y += ck804_nic.c
-driver-y += ck804_pci.c
-driver-y += ck804_pcie.c
-driver-y += ck804_ht.c
+driver-y += usb.c
+driver-y += lpc.c
+driver-y += smbus.c
+driver-y += ide.c
+driver-y += sata.c
+driver-y += usb2.c
+driver-y += ac97.c
+driver-y += nic.c
+driver-y += pci.c
+driver-y += pcie.c
+driver-y += ht.c
-ramstage-y += ck804_reset.c
+ramstage-y += reset.c
-ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += ck804_fadt.c
+ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
-romstage-y += ck804_enable_usbdebug.c
-romstage-y += ck804_early_smbus.c
+romstage-y += enable_usbdebug.c
+romstage-y += early_smbus.c
chipset_bootblock_inc += $(src)/southbridge/nvidia/ck804/romstrap.inc
chipset_bootblock_lds += $(src)/southbridge/nvidia/ck804/romstrap.lds
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static struct device_operations ac97audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ // .enable = ck804_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver ac97audio_driver __pci_driver = {
+ .ops = &ac97audio_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_ACI,
+};
+
+static struct device_operations ac97modem_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ // .enable = ck804_enable,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver ac97modem_driver __pci_driver = {
+ .ops = &ac97modem_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_MCI,
+};
#include <arch/io.h>
#include <arch/romcc_io.h>
-#include "southbridge/nvidia/ck804/ck804_enable_rom.c"
+#include "southbridge/nvidia/ck804/enable_rom.c"
static void bootblock_southbridge_init(void)
{
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static struct device_operations ac97audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- // .enable = ck804_enable,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver ac97audio_driver __pci_driver = {
- .ops = &ac97audio_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_ACI,
-};
-
-static struct device_operations ac97modem_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- // .enable = ck804_enable,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver ac97modem_driver __pci_driver = {
- .ops = &ac97modem_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_MCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-
-static int set_ht_link_ck804(uint8_t ht_c_num)
-{
- unsigned vendorid = 0x10de;
- unsigned val = 0x01610169;
- return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
-}
-
-static void setup_ss_table(unsigned index, unsigned where, unsigned control,
- const unsigned int *register_values, int max)
-{
- int i;
- unsigned val;
-
- val = inl(control);
- val &= 0xfffffffe;
- outl(val, control);
-
- outl(0, index);
-
- for (i = 0; i < max; i++) {
- unsigned long reg;
- reg = register_values[i];
- outl(reg, where);
- }
- val = inl(control);
- val |= 1;
- outl(val, control);
-}
-
-#define ANACTRL_IO_BASE 0x7000
-#define ANACTRL_REG_POS 0x68
-
-#define SYSCTRL_IO_BASE 0x6000
-#define SYSCTRL_REG_POS 0x64
-
-/*
- * Values for CONFIG_CK804_PCI_E_X and CONFIG_CK804B_PCI_E_X.
- * Apparently some sort of lane configuration.
- *
- * 16 1 1 2 :0
- * 8 8 2 2 :1
- * 8 8 4 :2
- * 8 4 4 4 :3
- * 16 4 :4
- */
-
-#if CONFIG_CK804_NUM > 1
-#define CK804B_ANACTRL_IO_BASE (ANACTRL_IO_BASE + 0x8000)
-#define CK804B_SYSCTRL_IO_BASE (SYSCTRL_IO_BASE + 0x8000)
-#ifndef CK804B_BUSN
-#define CK804B_BUSN 0x80
-#endif
-#endif
-
-#define CK804_CHIP_REV 3
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
-#define CK804B_DEVN_BASE 1
-#else
-#define CK804B_DEVN_BASE CK804_DEVN_BASE
-#endif
-
-static void ck804_early_set_port(void)
-{
- static const unsigned int ctrl_devport_conf[] = {
- PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
-#if CONFIG_CK804_NUM > 1
- PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), CK804B_ANACTRL_IO_BASE,
-#endif
-
- PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
-#if CONFIG_CK804_NUM > 1
- PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), CK804B_SYSCTRL_IO_BASE,
-#endif
- };
-
- setup_resource_map(ctrl_devport_conf, ARRAY_SIZE(ctrl_devport_conf));
-}
-
-static void ck804_early_clear_port(void)
-{
- static const unsigned int ctrl_devport_conf_clear[] = {
- PCI_ADDR(0, (CK804_DEVN_BASE + 0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
-#if CONFIG_CK804_NUM > 1
- PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
-#endif
- PCI_ADDR(0, (CK804_DEVN_BASE + 0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
-#if CONFIG_CK804_NUM > 1
- PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
-#endif
- };
-
- setup_resource_map(ctrl_devport_conf_clear, ARRAY_SIZE(ctrl_devport_conf_clear));
-}
-
-static void ck804_early_setup(void)
-{
- static const unsigned int ctrl_conf[] = {
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0x8c), 0xffff0000, 0x00009880,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0x90), 0xffff000f, 0x000074a0,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0xac), 0xffffff00, 0x00000000,
-
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0x8c), 0xffff0000, 0x00009880,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0x90), 0xffff000f, 0x000074a0,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
-#endif
-
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x48), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x74), 0xfffff00f, 0x000009d0,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x8c), 0xffff0000, 0x0000007f,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xcc), 0xfffffff8, 0x00000003,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd0), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd4), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd8), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xdc), 0x7f000000, 0x00000000,
-
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x48), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x74), 0xfffff00f, 0x000009d0,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x8c), 0xffff0000, 0x0000007f,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xcc), 0xfffffff8, 0x00000003,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd0), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd4), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd8), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xdc), 0x7f000000, 0x00000000,
-#endif
-
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xf0), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xf8), 0xffffffcf, 0x00000010,
-
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xf0), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xf8), 0xffffffcf, 0x00000010,
-#endif
-
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x40), 0xfff8ffff, 0x00030000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x74), 0xffffffc0, 0x00000000,
-
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x40), 0xfff8ffff, 0x00030000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x74), 0xffffffc0, 0x00000000,
-#endif
-
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0x78), 0xc0ffffff, 0x19000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xe0), 0xfffffeff, 0x00000100,
-
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0x78), 0xc0ffffff, 0x20000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe0), 0xfffffeff, 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe8), 0xffffff00, 0x000000ff,
-#endif
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, ~(0xffff), 0x0f008,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, ~((0xff) | (0xff << 16)), (0x41 << 16) | (0x32),
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7c, ~(0xff << 16), (0xa0 << 16),
-
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
-#endif
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
-#endif
-
- /* Activate master port on primary SATA controller. */
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xe0), ~(0xf0000000), 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
-#if CONFIG_CK804_NUM > 1
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
-#endif
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
-#endif
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
-#endif
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804_PCI_E_X << 4) | (1 << 8),
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804B_PCI_E_X << 4) | (1 << 8),
-#endif
-
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 8, ~(0xff), ((0 << 4) | (0 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 9, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
-#if CONFIG_CK804_USE_NIC
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE +0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
- RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1 , 0, 0xe4), ~(1 << 23), (1 << 23),
-#endif
-
-#if CONFIG_CK804_USE_ACI
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x0d, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x1a, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
-#endif
-
-#if CONFIG_CK804_NUM > 1
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0, ~(3 << 2), (0 << 2),
-#endif
-
-#if CONFIG_CK804_NUM > 1
-#if CONFIG_CK804_USE_NIC
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE +0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
- RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
- RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe4), ~(1 << 23), (1 << 23),
-#endif
-#endif
-
-#ifdef CK804_MB_SETUP
- CK804_MB_SETUP
-#endif
- };
-
- setup_resource_map_x(ctrl_conf, ARRAY_SIZE(ctrl_conf));
-
- setup_ss_table(ANACTRL_IO_BASE + 0x40, ANACTRL_IO_BASE + 0x44, ANACTRL_IO_BASE + 0x48, pcie_ss_tbl, 64);
- setup_ss_table(ANACTRL_IO_BASE + 0xb0, ANACTRL_IO_BASE + 0xb4, ANACTRL_IO_BASE + 0xb8, sata_ss_tbl, 64);
- setup_ss_table(ANACTRL_IO_BASE + 0xc0, ANACTRL_IO_BASE + 0xc4, ANACTRL_IO_BASE + 0xc8, cpu_ss_tbl, 64);
-
-#if CONFIG_CK804_NUM > 1
- setup_ss_table(CK804B_ANACTRL_IO_BASE + 0x40, CK804B_ANACTRL_IO_BASE + 0x44, CK804B_ANACTRL_IO_BASE + 0x48, pcie_ss_tbl, 64);
- setup_ss_table(CK804B_ANACTRL_IO_BASE + 0xb0, CK804B_ANACTRL_IO_BASE + 0xb4, CK804B_ANACTRL_IO_BASE + 0xb8, sata_ss_tbl, 64);
- setup_ss_table(CK804B_ANACTRL_IO_BASE + 0xc0, CK804B_ANACTRL_IO_BASE + 0xc4, CK804B_ANACTRL_IO_BASE + 0xc8, cpu_ss_tbl, 64);
-#endif
-
-#if 0
- dump_io_resources(ANACTRL_IO_BASE);
- dump_io_resources(SYSCTRL_IO_BASE);
-#endif
-}
-
-static int ck804_early_setup_x(void)
-{
- ck804_early_set_port();
- ck804_early_setup();
- ck804_early_clear_port();
- return set_ht_link_ck804(4);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
-
- /* link reset */
- outb(0x02, 0x0cf9);
- outb(0x06, 0x0cf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-static int set_ht_link_ck804(uint8_t ht_c_num)
-{
- unsigned vendorid = 0x10de;
- unsigned val = 0x01610169;
- return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
-}
-
-static void setup_ss_table(unsigned index, unsigned where, unsigned control,
- const unsigned int *register_values, int max)
-{
- int i;
- unsigned val;
-
- val = inl(control);
- val &= 0xfffffffe;
- outl(val, control);
-
- outl(0, index);
-
- for (i = 0; i < max; i++) {
- unsigned long reg;
- reg = register_values[i];
- outl(reg, where);
- }
- val = inl(control);
- val |= 1;
- outl(val, control);
-}
-
-#define ANACTRL_IO_BASE 0x3000
-#define ANACTRL_REG_POS 0x68
-
-#define SYSCTRL_IO_BASE 0x2000
-#define SYSCTRL_REG_POS 0x64
-
-/*
- * Values for CONFIG_CK804_PCI_E_X and CONFIG_CK804B_PCI_E_X.
- * Apparently some sort of lane configuration.
- *
- * 16 1 1 2 :0
- * 8 8 2 2 :1
- * 8 8 4 :2
- * 8 4 4 4 :3
- * 16 4 :4
- */
-
-#define CK804_CHIP_REV 3
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
-#define CK804B_DEVN_BASE 1
-#else
-#define CK804B_DEVN_BASE CK804_DEVN_BASE
-#endif
-
-static void ck804_early_set_port(unsigned ck804_num, unsigned *busn,
- unsigned *io_base)
-{
- static const unsigned int ctrl_devport_conf[] = {
- PCI_ADDR(0, 0x1, 0, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
- PCI_ADDR(0, 0x1, 0, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
- };
-
- int j;
- for (j = 0; j < ck804_num; j++) {
- u32 dev;
- if (busn[j] == 0) //sb chain
- dev = PCI_DEV(busn[j], CK804_DEVN_BASE, 0);
- else
- dev = PCI_DEV(busn[j], CK804B_DEVN_BASE, 0);
- setup_resource_map_offset(ctrl_devport_conf,
- ARRAY_SIZE(ctrl_devport_conf), dev,
- io_base[j]);
- }
-}
-
-static void ck804_early_clear_port(unsigned ck804_num, unsigned *busn,
- unsigned *io_base)
-{
- static const unsigned int ctrl_devport_conf_clear[] = {
- PCI_ADDR(0, 0x1, 0, ANACTRL_REG_POS), ~(0x0000ff01), 0,
- PCI_ADDR(0, 0x1, 0, SYSCTRL_REG_POS), ~(0x0000ff01), 0,
- };
-
- int j;
- for (j = 0; j < ck804_num; j++) {
- u32 dev;
- if (busn[j] == 0) //sb chain
- dev = PCI_DEV(busn[j], CK804_DEVN_BASE, 0);
- else
- dev = PCI_DEV(busn[j], CK804B_DEVN_BASE, 0);
- setup_resource_map_offset(ctrl_devport_conf_clear,
- ARRAY_SIZE(ctrl_devport_conf_clear), dev,
- io_base[j]);
- }
-}
-
-static void ck804_early_setup(unsigned ck804_num, unsigned *busn,
- unsigned *io_base)
-{
- static const unsigned int ctrl_conf_master[] = {
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x8c), 0xffff0000, 0x00009880,
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x90), 0xffff000f, 0x000074a0,
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xac), 0xffffff00, 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xfffff00f, 0x000009d0,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8c), 0xffff0000, 0x0000007f,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xcc), 0xfffffff8, 0x00000003,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd0), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd4), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd8), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xdc), 0x7f000000, 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf0), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf8), 0xffffffcf, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0xfff8ffff, 0x00030000,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x74), 0xffffffc0, 0x00000000,
-
-#ifdef CK804_MB_SETUP
- CK804_MB_SETUP
-#endif
-
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xc0ffffff, 0x19000000,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe0), 0xfffffeff, 0x00000100,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, ~(0xffff), 0x0f008,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, ~((0xff) | (0xff << 16)), (0x41 << 16) | (0x32),
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7c, ~(0xff << 16), (0xa0 << 16),
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
-
- /* Activate master port on primary SATA controller. */
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xe0), ~(0xf0000000), 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804_PCI_E_X << 4) | (1 << 8),
-
-//SYSCTRL
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 8, ~(0xff), ((0 << 4) | (0 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 9, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
-#if CONFIG_CK804_USE_NIC
- RES_PCI_IO, PCI_ADDR(0, 0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe4), ~(1 << 23), (1 << 23),
-#endif
-
-#if CONFIG_CK804_USE_ACI
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x0d, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x1a, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
-#endif
-
- };
-
- static const unsigned int ctrl_conf_multiple[] = {
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0, ~(3 << 2), (0 << 2),
- };
-
- static const unsigned int ctrl_conf_slave[] = {
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x8c), 0xffff0000, 0x00009880,
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x90), 0xffff000f, 0x000074a0,
- RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
-
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xfffff00f, 0x000009d0,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8c), 0xffff0000, 0x0000007f,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xcc), 0xfffffff8, 0x00000003,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd0), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd4), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd8), 0xff000000, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xdc), 0x7f000000, 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf0), 0xfffffffd, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf8), 0xffffffcf, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0xfff8ffff, 0x00030000,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x74), 0xffffffc0, 0x00000000,
-
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xc0ffffff, 0x20000000,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe0), 0xfffffeff, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe8), 0xffffff00, 0x000000ff,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
-
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x50), ~(0x1f000013), 0x15000013,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x64), ~(0x00000001), 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), ~(0x02000000), 0x02000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x70), ~(0x000f0000), 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x7c), ~(0x00000010), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
-
-/* This line doesn't exist in the non-CAR version. */
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804B_PCI_E_X << 4) | (1 << 8),
-
-#if CONFIG_CK804_USE_NIC
- RES_PCI_IO, PCI_ADDR(0, 0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe4), ~(1 << 23), (1 << 23),
-#endif
- };
-
- int j;
- for (j = 0; j < ck804_num; j++) {
- if (busn[j] == 0) {
- setup_resource_map_x_offset(ctrl_conf_master,
- ARRAY_SIZE(ctrl_conf_master),
- PCI_DEV(0, CK804_DEVN_BASE, 0), io_base[0]);
- if (ck804_num > 1)
- setup_resource_map_x_offset(ctrl_conf_multiple,
- ARRAY_SIZE(ctrl_conf_multiple),
- PCI_DEV(0, CK804_DEVN_BASE, 0), 0);
-
- continue;
- }
-
- setup_resource_map_x_offset(ctrl_conf_slave,
- ARRAY_SIZE(ctrl_conf_slave),
- PCI_DEV(busn[j], CK804B_DEVN_BASE, 0), io_base[j]);
- }
-
- for (j = 0; j < ck804_num; j++) {
- /* PCI-E (XSPLL) SS table 0x40, x044, 0x48 */
- /* SATA (SPPLL) SS table 0xb0, 0xb4, 0xb8 */
- /* CPU (PPLL) SS table 0xc0, 0xc4, 0xc8 */
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0x40,
- io_base[j] + ANACTRL_IO_BASE + 0x44,
- io_base[j] + ANACTRL_IO_BASE + 0x48,
- pcie_ss_tbl, 64);
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0xb0,
- io_base[j] + ANACTRL_IO_BASE + 0xb4,
- io_base[j] + ANACTRL_IO_BASE + 0xb8,
- sata_ss_tbl, 64);
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0xc0,
- io_base[j] + ANACTRL_IO_BASE + 0xc4,
- io_base[j] + ANACTRL_IO_BASE + 0xc8,
- cpu_ss_tbl, 64);
- }
-}
-
-static int ck804_early_setup_x(void)
-{
- unsigned busn[4], io_base[4];
- int i, ck804_num = 0;
-
- for (i = 0; i < 4; i++) {
- uint32_t id;
- device_t dev;
- if (i == 0) // SB chain
- dev = PCI_DEV(i * 0x40, CK804_DEVN_BASE, 0);
- else
- dev = PCI_DEV(i * 0x40, CK804B_DEVN_BASE, 0);
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if (id == 0x005e10de) {
- busn[ck804_num] = i * 0x40;
- io_base[ck804_num] = i * 0x4000;
- ck804_num++;
- }
- }
-
- ck804_early_set_port(ck804_num, busn, io_base);
- ck804_early_setup(ck804_num, busn, io_base);
- ck804_early_clear_port(ck804_num, busn, io_base);
-
- return set_ht_link_ck804(4);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
-
- /* link reset */
- outb(0x02, 0x0cf9);
- outb(0x06, 0x0cf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-static const unsigned int pcie_ss_tbl[] = {
- 0x0C504103f,
- 0x0C504103f,
- 0x0C504103f,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C504b049,
- 0x0C504b049,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5042040,
- 0x0C5042040,
-};
-
-static const unsigned int sata_ss_tbl[] = {
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
-};
-
-static const unsigned int cpu_ss_tbl[] = {
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <console/console.h>
-#include <device/pci_def.h>
-#include <device/pci_ids.h>
-
-#include "ck804_smbus.h"
-#include "ck804_early_smbus.h"
-
-#define SMBUS_BAR_BASE 0x20
-#define SMBUS_IO_BASE 0x1000
-#define SMBUS_IO_SIZE 0x0040
-
-#define SMBUS_BAR(x) (SMBUS_BAR_BASE + 4 * (x))
-#define SMBUS_BASE(x) (SMBUS_IO_BASE + SMBUS_IO_SIZE * (x))
-
-void enable_smbus(void)
-{
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_NVIDIA,
- PCI_DEVICE_ID_NVIDIA_CK804_SMB), 0);
- if (dev == PCI_DEV_INVALID)
- die("SMBus controller not found\n");
-
- /* Set SMBus I/O base. */
- pci_write_config32(dev, SMBUS_BAR(0), SMBUS_BASE(0) | 1);
- pci_write_config32(dev, SMBUS_BAR(1), SMBUS_BASE(1) | 1);
-
- /* Set SMBus I/O space enable. */
- pci_write_config16(dev, 0x4, 0x01);
-
- /* Clear any lingering errors, so the transaction will run. */
- outb(inb(SMBUS_BASE(0) + SMBHSTSTAT), SMBUS_BASE(0) + SMBHSTSTAT);
- outb(inb(SMBUS_BASE(1) + SMBHSTSTAT), SMBUS_BASE(1) + SMBHSTSTAT);
-
- print_debug("SMBus controller enabled\n");
-}
-
-int ck804_smbus_read_byte(unsigned bus, unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS_BASE(bus), device, address);
-}
-
-int ck804_smbus_write_byte(unsigned bus, unsigned device, unsigned address,
- unsigned char val)
-{
- return do_smbus_write_byte(SMBUS_BASE(bus), device, address, val);
-}
-
-int smbus_read_byte(unsigned device, unsigned address)
-{
- return ck804_smbus_read_byte(0, device, address);
-}
-
-int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- return ck804_smbus_write_byte(0, device, address, val);
-}
+++ /dev/null
-int ck804_smbus_read_byte(unsigned int, unsigned int, unsigned);
-int ck804_smbus_write_byte(unsigned int, unsigned int, unsigned int, unsigned char);
-void enable_smbus(void);
-int smbus_read_byte(unsigned int, unsigned int);
-int smbus_write_byte(unsigned int, unsigned int, unsigned char);
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-static void ck804_enable_rom(void)
-{
- unsigned char byte;
- device_t addr;
-
- /* Enable 4MB ROM access at 0xFFC00000 - 0xFFFFFFFF. */
- /* Locate the ck804 LPC. */
- addr = PCI_DEV(0, (CK804_DEVN_BASE + 1), 0);
-
- /* Set the 4MB enable bit. */
- byte = pci_read_config8(addr, 0x88);
- byte |= 0x80;
- pci_write_config8(addr, 0x88, byte);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "ck804.h"
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
-#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-void set_debug_port(unsigned int port)
-{
- u32 dword;
- device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Write the port number to 0x74[15:12]. */
- dword = pci_read_config32(dev, 0x74);
- dword &= ~(0xf << 12);
- dword |= (port << 12);
- pci_write_config32(dev, 0x74, dword);
-}
-
-void ck804_enable_usbdebug(unsigned int port)
-{
- device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Mark the requested physical USB port (1-15) as the Debug Port. */
- set_debug_port(port);
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-}
+++ /dev/null
-/*
- * ACPI - create the Fixed ACPI Description Tables (FADT)
- * (C) Copyright 2005 Stefan Reinauer <stepan@openbios.org>
- */
-
-#include <string.h>
-#include <console/console.h>
-#include <arch/acpi.h>
-
-extern unsigned pm_base; /* pm_base should be set in sb acpi */
-
-void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
-{
- acpi_header_t *header = &(fadt->header);
-
- printk(BIOS_DEBUG, "pm_base: 0x%04x\n", pm_base);
-
- /* Prepare the header */
- memset((void *)fadt, 0, sizeof(acpi_fadt_t));
- memcpy(header->signature, "FACP", 4);
-#ifdef LONG_FADT
- header->length = 244;
- header->revision = 3;
-#else
- header->length = 0x74;
- header->revision = 1;
-#endif
- memcpy(header->oem_id, "CORE ", 6);
- memcpy(header->oem_table_id, "CB-FADT ", 8);
- memcpy(header->asl_compiler_id, "IASL", 4);
- header->asl_compiler_revision = 0;
-
- fadt->firmware_ctrl = (u32)facs;
- fadt->dsdt = (u32)dsdt;
- // 3=Workstation,4=Enterprise Server, 7=Performance Server
- fadt->preferred_pm_profile = 0;
- fadt->sci_int = 9;
- // disable system management mode by setting to 0:
- fadt->smi_cmd = 0;
- fadt->acpi_enable = 0;
- fadt->acpi_disable = 0;
- fadt->s4bios_req = 0x0;
- fadt->pstate_cnt = 0x0;
-
- fadt->pm1a_evt_blk = pm_base;
- fadt->pm1b_evt_blk = 0x0000;
- fadt->pm1a_cnt_blk = pm_base + 0x04;
- fadt->pm1b_cnt_blk = 0x0000;
- fadt->pm2_cnt_blk = pm_base + 0x1c;
- fadt->pm_tmr_blk = pm_base + 0x08;
- fadt->gpe0_blk = pm_base + 0x20;
- fadt->gpe1_blk = 0x0000;
-
- fadt->pm1_evt_len = 4;
- fadt->pm1_cnt_len = 2;
- fadt->pm2_cnt_len = 1;
- fadt->pm_tmr_len = 4;
- fadt->gpe0_blk_len = 8;
- fadt->gpe1_blk_len = 0;
- fadt->gpe1_base = 0;
- fadt->cst_cnt = 0;
- fadt->p_lvl2_lat = 0xffff;
- fadt->p_lvl3_lat = 0xffff;
- fadt->flush_size = 0;
- fadt->flush_stride = 0;
- fadt->duty_offset = 1;
- fadt->duty_width = 0;
- fadt->day_alrm = 0x7d;
- fadt->mon_alrm = 0x7e;
- fadt->century = 0x32;
- fadt->iapc_boot_arch = 0;
- fadt->flags = 0xa5;
-
-#ifdef LONG_FADT
- fadt->res2 = 0;
-
- fadt->reset_reg.space_id = 1;
- fadt->reset_reg.bit_width = 8;
- fadt->reset_reg.bit_offset = 0;
- fadt->reset_reg.resv = 0;
- fadt->reset_reg.addrl = 0xcf9;
- fadt->reset_reg.addrh = 0x0;
-
- fadt->reset_value = 6;
- fadt->x_firmware_ctl_l = facs;
- fadt->x_firmware_ctl_h = 0;
- fadt->x_dsdt_l = dsdt;
- fadt->x_dsdt_h = 0;
-
- fadt->x_pm1a_evt_blk.space_id = 1;
- fadt->x_pm1a_evt_blk.bit_width = 32;
- fadt->x_pm1a_evt_blk.bit_offset = 0;
- fadt->x_pm1a_evt_blk.resv = 0;
- fadt->x_pm1a_evt_blk.addrl = pm_base;
- fadt->x_pm1a_evt_blk.addrh = 0x0;
-
- fadt->x_pm1b_evt_blk.space_id = 1;
- fadt->x_pm1b_evt_blk.bit_width = 4;
- fadt->x_pm1b_evt_blk.bit_offset = 0;
- fadt->x_pm1b_evt_blk.resv = 0;
- fadt->x_pm1b_evt_blk.addrl = 0x0;
- fadt->x_pm1b_evt_blk.addrh = 0x0;
-
- fadt->x_pm1a_cnt_blk.space_id = 1;
- fadt->x_pm1a_cnt_blk.bit_width = 16;
- fadt->x_pm1a_cnt_blk.bit_offset = 0;
- fadt->x_pm1a_cnt_blk.resv = 0;
- fadt->x_pm1a_cnt_blk.addrl = pm_base + 4;
- fadt->x_pm1a_cnt_blk.addrh = 0x0;
-
- fadt->x_pm1b_cnt_blk.space_id = 1;
- fadt->x_pm1b_cnt_blk.bit_width = 2;
- fadt->x_pm1b_cnt_blk.bit_offset = 0;
- fadt->x_pm1b_cnt_blk.resv = 0;
- fadt->x_pm1b_cnt_blk.addrl = 0x0;
- fadt->x_pm1b_cnt_blk.addrh = 0x0;
-
- fadt->x_pm2_cnt_blk.space_id = 1;
- fadt->x_pm2_cnt_blk.bit_width = 0;
- fadt->x_pm2_cnt_blk.bit_offset = 0;
- fadt->x_pm2_cnt_blk.resv = 0;
- fadt->x_pm2_cnt_blk.addrl = 0x0;
- fadt->x_pm2_cnt_blk.addrh = 0x0;
-
- fadt->x_pm_tmr_blk.space_id = 1;
- fadt->x_pm_tmr_blk.bit_width = 32;
- fadt->x_pm_tmr_blk.bit_offset = 0;
- fadt->x_pm_tmr_blk.resv = 0;
- fadt->x_pm_tmr_blk.addrl = pm_base + 0x08;
- fadt->x_pm_tmr_blk.addrh = 0x0;
-
- fadt->x_gpe0_blk.space_id = 1;
- fadt->x_gpe0_blk.bit_width = 32;
- fadt->x_gpe0_blk.bit_offset = 0;
- fadt->x_gpe0_blk.resv = 0;
- fadt->x_gpe0_blk.addrl = pm_base + 0x20;
- fadt->x_gpe0_blk.addrh = 0x0;
-
- fadt->x_gpe1_blk.space_id = 1;
- fadt->x_gpe1_blk.bit_width = 64;
- fadt->x_gpe1_blk.bit_offset = 16;
- fadt->x_gpe1_blk.resv = 0;
- fadt->x_gpe1_blk.addrl = pm_base + 0xb0;
- fadt->x_gpe1_blk.addrh = 0x0;
-#endif
- header->checksum = acpi_checksum((void *)fadt, header->length);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static struct device_operations ht_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver ht_driver __pci_driver = {
- .ops = &ht_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_HT,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_nvidia_ck804_config *conf;
- uint32_t dword;
- uint16_t word;
- uint8_t byte;
-
- conf = dev->chip_info;
-
- word = pci_read_config16(dev, 0x50);
- /* Ensure prefetch is disabled. */
- word &= ~((1 << 15) | (1 << 13));
- if (conf->ide1_enable) {
- /* Enable secondary IDE interface. */
- word |= (1 << 0);
- printk(BIOS_DEBUG, "IDE1 \t");
- }
- if (conf->ide0_enable) {
- /* Enable primary IDE interface. */
- word |= (1 << 1);
- printk(BIOS_DEBUG, "IDE0\n");
- }
-
- word |= (1 << 12);
- word |= (1 << 14);
-
- pci_write_config16(dev, 0x50, word);
-
- byte = 0x20; /* Latency: 64 --> 32 */
- pci_write_config8(dev, 0xd, byte);
-
- dword = pci_read_config32(dev, 0xf8);
- dword |= 12;
- pci_write_config32(dev, 0xf8, dword);
-
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);
-#endif
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
- // .enable = ck804_enable,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_IDE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2003 SuSE Linux AG
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include <cpu/x86/lapic.h>
-#include <stdlib.h>
-#include "ck804.h"
-
-#define CK804_CHIP_REV 2
-
-#define NMI_OFF 0
-
-// 0x7a or e3
-#define PREVIOUS_POWER_STATE 0x7A
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-#define SLOW_CPU_OFF 0
-#define SLOW_CPU__ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-static void lpc_common_init(device_t dev)
-{
- uint8_t byte;
- uint32_t dword;
-
- /* I/O APIC initialization */
- byte = pci_read_config8(dev, 0x74);
- byte |= (1 << 0); /* Enable APIC. */
- pci_write_config8(dev, 0x74, byte);
- dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); /* 0x14 */
-
- setup_ioapic(dword, 0); // Don't rename IOAPIC ID
-
-#if 1
- dword = pci_read_config32(dev, 0xe4);
- dword |= (1 << 23);
- pci_write_config32(dev, 0xe4, dword);
-#endif
-}
-
-static void lpc_slave_init(device_t dev)
-{
- lpc_common_init(dev);
-}
-
-static void rom_dummy_write(device_t dev)
-{
- uint8_t old, new;
- uint8_t *p;
-
- old = pci_read_config8(dev, 0x88);
- new = old | 0xc0;
- if (new != old)
- pci_write_config8(dev, 0x88, new);
- /* Enable write. */
- old = pci_read_config8(dev, 0x6d);
- new = old | 0x01;
- if (new != old)
- pci_write_config8(dev, 0x6d, new);
-
- /* Dummy write. */
- p = (uint8_t *) 0xffffffe0;
- old = 0;
- *p = old;
- old = *p;
-
- /* Disable write. */
- old = pci_read_config8(dev, 0x6d);
- new = old & 0xfe;
- if (new != old)
- pci_write_config8(dev, 0x6d, new);
-}
-
-static void enable_hpet(struct device *dev)
-{
- unsigned long hpet_address;
-
- pci_write_config32(dev, 0x44, 0xfed00001);
- hpet_address = pci_read_config32(dev, 0x44) & 0xfffffffe;
- printk(BIOS_DEBUG, "Enabling HPET @0x%lx\n", hpet_address);
-}
-
-unsigned pm_base=0;
-
-static void lpc_init(device_t dev)
-{
- uint8_t byte, byte_old;
- int on, nmi_option;
-
- lpc_common_init(dev);
-
- pm_base = pci_read_config32(dev, 0x60) & 0xff00;
- printk(BIOS_INFO, "%s: pm_base = %x \n", __func__, pm_base);
-
-#if CK804_CHIP_REV==1
- if (dev->bus->secondary != 1)
- return;
-#endif
-
-#if 0
- /* Posted memory write enable */
- byte = pci_read_config8(dev, 0x46);
- pci_write_config8(dev, 0x46, byte | (1 << 0));
-#endif
-
- /* power after power fail */
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
- byte &= ~0x40;
- if (!on)
- byte |= 0x40;
- pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
-
- /* Throttle the CPU speed down for testing. */
- on = SLOW_CPU_OFF;
- get_option(&on, "slow_cpu");
- if (on) {
- uint16_t pm10_bar;
- uint32_t dword;
- pm10_bar = (pci_read_config16(dev, 0x60) & 0xff00);
- outl(((on << 1) + 0x10), (pm10_bar + 0x10));
- dword = inl(pm10_bar + 0x10);
- on = 8 - on;
- printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
- (on * 12) + (on >> 1), (on & 1) * 5);
- }
-#if 0
-// default is enabled
- /* Enable Port 92 fast reset. */
- byte = pci_read_config8(dev, 0xe8);
- byte |= ~(1 << 3);
- pci_write_config8(dev, 0xe8, byte);
-#endif
-
- /* Enable Error reporting. */
- /* Set up sync flood detected. */
- byte = pci_read_config8(dev, 0x47);
- byte |= (1 << 1);
- pci_write_config8(dev, 0x47, byte);
-
- /* Set up NMI on errors. */
- byte = inb(0x70); /* RTC70 */
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* Set NMI. */
- } else {
- byte |= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW. */
- }
- if (byte != byte_old)
- outb(byte, 0x70);
-
- /* Initialize the real time clock (RTC). */
- rtc_init(0);
-
- /* Initialize ISA DMA. */
- isa_dma_init();
-
- /* Initialize the High Precision Event Timers (HPET). */
- enable_hpet(dev);
-
- rom_dummy_write(dev);
-}
-
-static void ck804_lpc_read_resources(device_t dev)
-{
- struct resource *res;
- unsigned long index;
-
- /* Get the normal PCI resources of this device. */
- /* We got one for APIC, or one more for TRAP. */
- pci_dev_read_resources(dev);
-
- /* Get resource for ACPI, SYSTEM_CONTROL, ANALOG_CONTROL. */
- for (index = 0x60; index <= 0x68; index += 4) /* We got another 3. */
- pci_get_resource(dev, index);
- compact_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-/**
- * Enable resources for children devices.
- *
- * This function is called by the global enable_resources() indirectly via the
- * device_operation::enable_resources() method of devices.
- *
- */
-static void ck804_lpc_enable_childrens_resources(device_t dev)
-{
- struct bus *link;
- uint32_t reg, reg_var[4];
- int i, var_num = 0;
-
- reg = pci_read_config32(dev, 0xa0);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child; child = child->sibling) {
- if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for (res = child->resource_list; res; res = res->next) {
- unsigned long base, end; // don't need long long
- if (!(res->flags & IORESOURCE_IO))
- continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "ck804 lpc decode:%s, base=0x%08lx, end=0x%08lx\n", dev_path(child), base, end);
- switch (base) {
- case 0x3f8: // COM1
- reg |= (1 << 0);
- break;
- case 0x2f8: // COM2
- reg |= (1 << 1);
- break;
- case 0x378: // Parallel 1
- reg |= (1 << 24);
- break;
- case 0x3f0: // FD0
- reg |= (1 << 20);
- break;
- case 0x220: // Audio 0
- reg |= (1 << 8);
- break;
- case 0x300: // Midi 0
- reg |= (1 << 12);
- break;
- }
- if (base == 0x290 || base >= 0x400) {
- if (var_num >= 4)
- continue; // only 4 var ; compact them ?
- reg |= (1 << (28 + var_num));
- reg_var[var_num++] = (base & 0xffff) | ((end & 0xffff) << 16);
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0xa0, reg);
- for (i = 0; i < var_num; i++)
- pci_write_config32(dev, 0xa8 + i * 4, reg_var[i]);
-}
-
-static void ck804_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- ck804_lpc_enable_childrens_resources(dev);
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = ck804_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = ck804_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
- // .enable = ck804_enable,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_LPC,
-};
-
-static const struct pci_driver lpc_driver_pro __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_PRO,
-};
-
-#if CK804_CHIP_REV == 1
-static const struct pci_driver lpc_driver_slave __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
-};
-#else
-static struct device_operations lpc_slave_ops = {
- .read_resources = ck804_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_slave_init,
- // .enable = ck804_enable,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver lpc_driver_slave __pci_driver = {
- .ops = &lpc_slave_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
-};
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "ck804.h"
-
-static void nic_init(struct device *dev)
-{
- uint32_t dword, old, mac_h, mac_l;
- int eeprom_valid = 0;
- struct southbridge_nvidia_ck804_config *conf;
- static uint32_t nic_index = 0;
- unsigned long base;
- struct resource *res;
-
- res = find_resource(dev, 0x10);
- base = (unsigned long)res->base;
-
-#define NvRegPhyInterface 0xC0
-#define PHY_RGMII 0x10000000
-
- write32(base + NvRegPhyInterface, PHY_RGMII);
-
- old = dword = pci_read_config32(dev, 0x30);
- dword &= ~(0xf);
- dword |= 0xf;
- if (old != dword)
- pci_write_config32(dev, 0x30, dword);
-
- conf = dev->chip_info;
-
- if (conf->mac_eeprom_smbus != 0) {
- /* Read MAC address from EEPROM at first. */
- struct device *dev_eeprom;
- dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus,
- conf->mac_eeprom_addr);
-
- if (dev_eeprom) {
- /* If that is valid we will use that. */
- unsigned char dat[6];
- int i, status;
- for (i = 0; i < 6; i++) {
- status = smbus_read_byte(dev_eeprom, i);
- if (status < 0)
- break;
- dat[i] = status & 0xff;
- }
- if (status >= 0) {
- mac_l = 0;
- for (i = 3; i >= 0; i--) {
- mac_l <<= 8;
- mac_l += dat[i];
- }
- if (mac_l != 0xffffffff) {
- mac_l += nic_index;
- mac_h = 0;
- for (i = 5; i >= 4; i--) {
- mac_h <<= 8;
- mac_h += dat[i];
- }
- eeprom_valid = 1;
- }
- }
- }
- }
-
- /* If that is invalid we will read that from romstrap. */
- if (!eeprom_valid) {
- unsigned long mac_pos;
- mac_pos = 0xffffffd0; /* See romstrap.inc and romstrap.lds. */
- mac_l = read32(mac_pos) + nic_index;
- mac_h = read32(mac_pos + 4);
- }
-#if 1
- /* Set that into NIC MMIO. */
-#define NvRegMacAddrA 0xA8
-#define NvRegMacAddrB 0xAC
- write32(base + NvRegMacAddrA, mac_l);
- write32(base + NvRegMacAddrB, mac_h);
-#else
- /* Set that into NIC. */
- pci_write_config32(dev, 0xa8, mac_l);
- pci_write_config32(dev, 0xac, mac_h);
-#endif
-
- nic_index++;
-
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev); /* It will init Option ROM. */
-#endif
-}
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
- // .enable = ck804_enable,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC,
-};
-
-static const struct pci_driver nic_bridge_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/resource.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static void pci_init(struct device *dev)
-{
- uint32_t dword;
- device_t pci_domain_dev;
- struct resource *mem, *pref;
-
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* System error enable */
- dword |= (1 << 30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
-#if 0
- word = pci_read_config16(dev, 0x48);
- word |= (1 << 0); /* MRL2MRM */
- word |= (1 << 2); /* MR2MRM */
- pci_write_config16(dev, 0x48, word);
-#endif
-
-#if 1
- dword = pci_read_config32(dev, 0x4c);
- dword |= 0x00440000; /* TABORT_SER_ENABLE Park Last Enable. */
- pci_write_config32(dev, 0x4c, dword);
-#endif
-
- pci_domain_dev = dev->bus->dev;
- while (pci_domain_dev) {
- if (pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN)
- break;
- pci_domain_dev = pci_domain_dev->bus->dev;
- }
-
- if (!pci_domain_dev)
- return; /* Impossible */
-
- pref = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(2,0));
- mem = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(1,0));
-
- if (!mem)
- return; /* Impossible */
-
- if (!pref || pref->base > mem->base) {
- dword = mem->base & (0xffff0000UL);
- printk(BIOS_DEBUG, "PCI DOMAIN mem base = 0x%010Lx\n", mem->base);
- } else {
- dword = pref->base & (0xffff0000UL);
- printk(BIOS_DEBUG, "PCI DOMAIN pref base = 0x%010Lx\n", pref->base);
- }
-
- printk(BIOS_DEBUG, "[0x50] <-- 0x%08x\n", dword);
- pci_write_config32(dev, 0x50, dword); /* TOM */
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
- // .enable = ck804_enable,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static void pcie_init(struct device *dev)
-{
- uint32_t dword;
-
- /* Enable PCI error detecting. */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1 << 8); /* System error enable */
- dword |= (1 << 30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-}
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pci_scan_bridge,
- // .enable = ck804_enable,
-};
-
-static const struct pci_driver pcie_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI_E,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFFF) << 20) | \
- (((DEV) & 0x1F) << 15) | \
- (((FN) & 0x7) << 12))
-
-typedef unsigned device_t;
-
-static void pci_write_config32(device_t dev, unsigned where, unsigned value)
-{
- unsigned addr;
- addr = (dev >> 4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outl(value, 0xCFC);
-}
-
-static unsigned pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = (dev >> 4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- return inl(0xCFC);
-}
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9. */
- outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
- outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-#ifndef CK804_SATA_RESET_FOR_ATAPI
-#define CK804_SATA_RESET_FOR_ATAPI 0
-#endif
-
-#if CK804_SATA_RESET_FOR_ATAPI
-static void sata_com_reset(struct device *dev, unsigned reset)
-// reset = 1 : reset
-// reset = 0 : clear
-{
- uint32_t *base;
- uint32_t dword;
- int loop;
-
- base = (uint32_t *) pci_read_config32(dev, 0x24);
-
- printk(BIOS_DEBUG, "base = %08lx\n", base);
-
- if (reset) {
- *(base + 4) = 0xffffffff;
- *(base + 0x44) = 0xffffffff;
- }
-
- dword = *(base + 8);
- dword &= ~(0xf);
- dword |= reset;
-
- *(base + 8) = dword;
- *(base + 0x48) = dword;
-
-#if 0
- udelay(1000);
- dword &= ~(0xf);
- *(base + 8) = dword;
- *(base + 0x48) = dword;
-#endif
-
- if (reset)
- return;
-
- dword = *(base + 0);
- printk(BIOS_DEBUG, "*(base+0)=%08x\n", dword);
- if (dword == 0x113) {
- loop = 200000; // 2
- do {
- dword = *(base + 4);
- if ((dword & 0x10000) != 0)
- break;
- udelay(10);
- } while (--loop > 0);
- printk(BIOS_DEBUG, "loop=%d, *(base+4)=%08x\n", loop, dword);
- }
-
- dword = *(base + 0x40);
- printk(BIOS_DEBUG, "*(base+0x40)=%08x\n", dword);
- if (dword == 0x113) {
- loop = 200000; //2
- do {
- dword = *(base + 0x44);
- if ((dword & 0x10000) != 0)
- break;
- udelay(10);
- } while (--loop > 0);
- printk(BIOS_DEBUG, "loop=%d, *(base+0x44)=%08x\n", loop, dword);
- }
-}
-#endif
-
-static void sata_init(struct device *dev)
-{
- uint32_t dword;
- struct southbridge_nvidia_ck804_config *conf;
-
- conf = dev->chip_info;
-
- dword = pci_read_config32(dev, 0x50);
- /* Ensure prefetch is disabled. */
- dword &= ~((1 << 15) | (1 << 13));
- if (conf->sata1_enable) {
- /* Enable secondary SATA interface. */
- dword |= (1 << 0);
- printk(BIOS_DEBUG, "SATA S \t");
- }
- if (conf->sata0_enable) {
- /* Enable primary SATA interface. */
- dword |= (1 << 1);
- printk(BIOS_DEBUG, "SATA P \n");
- }
-#if 0
- /* Write back */
- dword |= (1 << 12);
- dword |= (1 << 14);
-#endif
-
-#if 0
- /* ADMA */
- dword |= (1 << 16);
- dword |= (1 << 17);
-#endif
-
-#if 1
- /* DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT. */
- dword &= ~(0x1f << 24);
- dword |= (0x15 << 24);
-#endif
- pci_write_config32(dev, 0x50, dword);
-
-#if 0
- /* SLUMBER_DURING_D3 */
- dword = pci_read_config32(dev, 0x7c);
- dword &= ~(1 << 4);
- pci_write_config32(dev, 0x7c, dword);
-
- dword = pci_read_config32(dev, 0xd0);
- dword &= ~(0xff << 24);
- dword |= (0x68 << 24);
- pci_write_config32(dev, 0xd0, dword);
-
- dword = pci_read_config32(dev, 0xe0);
- dword &= ~(0xff << 24);
- dword |= (0x68 << 24);
- pci_write_config32(dev, 0xe0, dword);
-#endif
-
- dword = pci_read_config32(dev, 0xf8);
- dword |= 2;
- pci_write_config32(dev, 0xf8, dword);
-
-#if CK804_SATA_RESET_FOR_ATAPI
- dword = pci_read_config32(dev, 0xac);
- dword &= ~((1 << 13) | (1 << 14));
- dword |= (1 << 13) | (0 << 14);
- pci_write_config32(dev, 0xac, dword);
-
- sata_com_reset(dev, 1); /* For discover some s-atapi device. */
-#endif
-
-}
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- // .enable = ck804_enable,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA0,
-};
-
-static const struct pci_driver sata1_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA1,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include "ck804.h"
-#include "ck804_smbus.h"
-
-static int lsmbus_recv_byte(device_t dev)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-static int lsmbus_read_byte(device_t dev, uint8_t address)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-static struct device_operations smbus_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = scan_static_bus,
- // .enable = ck804_enable,
- .ops_pci = &ck804_pci_ops,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_SM,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x1
-#define SMBHSTPRTCL 0x0
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x2
-#define SMBHSTDAT0 0x4
-#define SMBHSTDAT1 0x5
-
-/*
- * Between 1-10 seconds, We should never timeout normally.
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100 * 1000 * 10)
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-#if 0
-/* Not needed, upon write to PRTCL, the status will be auto-cleared. */
-static int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f;
- if (val == 0)
- return 0;
- outb(val, smbus_io_base + SMBHSTSTAT);
- } while (--loops);
- return -2;
-}
-#endif
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(smbus_io_base + SMBHSTSTAT);
- if ((val & 0xff) != 0)
- return 0;
- } while (--loops);
- return -3;
-}
-
-#ifndef __PRE_RAM__
-static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
-{
- unsigned char global_status_register, byte;
-
-#if 0
- /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
- if (smbus_wait_until_ready(smbus_io_base) < 0)
- return -2;
-#endif
-
- /* Set the device I'm talking to. */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* Set the command/address. */
- outb(0, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* Byte data recv */
- outb(0x05, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* Poll for transaction completion. */
- if (smbus_wait_until_done(smbus_io_base) < 0)
- return -3;
-
- /* Lose check */
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
-
- /* Read results of transaction. */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- /* Lose check, otherwise it should be 0. */
- if (global_status_register != 0x80)
- return -1;
-
- return byte;
-}
-
-static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device,
- unsigned char val)
-{
- unsigned global_status_register;
-
-#if 0
- /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
- if (smbus_wait_until_ready(smbus_io_base) < 0)
- return -2;
-#endif
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* Set the device I'm talking to. */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- outb(0, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* Set up for a byte data write. */
- outb(0x04, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* Poll for transaction completion. */
- if (smbus_wait_until_done(smbus_io_base) < 0)
- return -3;
-
- /* Lose check */
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
-
- if (global_status_register != 0x80)
- return -1;
-
- return 0;
-}
-#endif
-
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device,
- unsigned address)
-{
- unsigned char global_status_register, byte;
-
-#if 0
- /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
- if (smbus_wait_until_ready(smbus_io_base) < 0)
- return -2;
-#endif
-
- /* Set the device I'm talking to. */
- outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* Set the command/address. */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* Byte data read */
- outb(0x07, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* Poll for transaction completion. */
- if (smbus_wait_until_done(smbus_io_base) < 0)
- return -3;
-
- /* Lose check */
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
-
- /* Read results of transaction. */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- /* Lose check, otherwise it should be 0. */
- if (global_status_register != 0x80)
- return -1;
-
- return byte;
-}
-
-static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device,
- unsigned address, unsigned char val)
-{
- unsigned global_status_register;
-
-#if 0
- /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
- if (smbus_wait_until_ready(smbus_io_base) < 0)
- return -2;
-#endif
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* Set the device I'm talking to. */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* Set up for a byte data write. */
- outb(0x06, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* Poll for transaction completion. */
- if (smbus_wait_until_done(smbus_io_base) < 0)
- return -3;
-
- /* Lose check */
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
-
- if (global_status_register != 0x80)
- return -1;
-
- return 0;
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static void usb1_init(struct device *dev)
-{
- struct southbridge_nvidia_ck804_config const *conf = dev->chip_info;
- if (conf->usb1_hc_reset) {
- /*
- * Somehow the warm reset does not really reset the USB
- * controller. Later, during boot, when the Bus Master bit is
- * set, the USB controller trashes the memory, causing weird
- * misbehavior. Was detected on Sun Ultra40, where mptable
- * was damaged.
- */
- uint32_t bar0 = pci_read_config32(dev, 0x10);
- uint32_t *regs = (uint32_t *) (bar0 & ~0xfff);
-
- /* OHCI USB HCCommandStatus Register, HostControllerReset bit */
- regs[2] |= 1;
- }
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb1_init,
- // .enable = ck804_enable,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver usb_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_USB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "ck804.h"
-
-static void usb2_init(struct device *dev)
-{
- uint32_t dword;
- dword = pci_read_config32(dev, 0xf8);
- dword |= 40;
- pci_write_config32(dev, 0xf8, dword);
-}
-
-static struct device_operations usb2_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb2_init,
- // .enable = ck804_enable,
- .scan_bus = 0,
- .ops_pci = &ck804_pci_ops,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb2_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_CK804_USB2,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+
+static int set_ht_link_ck804(uint8_t ht_c_num)
+{
+ unsigned vendorid = 0x10de;
+ unsigned val = 0x01610169;
+ return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
+}
+
+static void setup_ss_table(unsigned index, unsigned where, unsigned control,
+ const unsigned int *register_values, int max)
+{
+ int i;
+ unsigned val;
+
+ val = inl(control);
+ val &= 0xfffffffe;
+ outl(val, control);
+
+ outl(0, index);
+
+ for (i = 0; i < max; i++) {
+ unsigned long reg;
+ reg = register_values[i];
+ outl(reg, where);
+ }
+ val = inl(control);
+ val |= 1;
+ outl(val, control);
+}
+
+#define ANACTRL_IO_BASE 0x7000
+#define ANACTRL_REG_POS 0x68
+
+#define SYSCTRL_IO_BASE 0x6000
+#define SYSCTRL_REG_POS 0x64
+
+/*
+ * Values for CONFIG_CK804_PCI_E_X and CONFIG_CK804B_PCI_E_X.
+ * Apparently some sort of lane configuration.
+ *
+ * 16 1 1 2 :0
+ * 8 8 2 2 :1
+ * 8 8 4 :2
+ * 8 4 4 4 :3
+ * 16 4 :4
+ */
+
+#if CONFIG_CK804_NUM > 1
+#define CK804B_ANACTRL_IO_BASE (ANACTRL_IO_BASE + 0x8000)
+#define CK804B_SYSCTRL_IO_BASE (SYSCTRL_IO_BASE + 0x8000)
+#ifndef CK804B_BUSN
+#define CK804B_BUSN 0x80
+#endif
+#endif
+
+#define CK804_CHIP_REV 3
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
+#define CK804B_DEVN_BASE 1
+#else
+#define CK804B_DEVN_BASE CK804_DEVN_BASE
+#endif
+
+static void ck804_early_set_port(void)
+{
+ static const unsigned int ctrl_devport_conf[] = {
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
+#if CONFIG_CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), CK804B_ANACTRL_IO_BASE,
+#endif
+
+ PCI_ADDR(0, (CK804_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
+#if CONFIG_CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), CK804B_SYSCTRL_IO_BASE,
+#endif
+ };
+
+ setup_resource_map(ctrl_devport_conf, ARRAY_SIZE(ctrl_devport_conf));
+}
+
+static void ck804_early_clear_port(void)
+{
+ static const unsigned int ctrl_devport_conf_clear[] = {
+ PCI_ADDR(0, (CK804_DEVN_BASE + 0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
+#if CONFIG_CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, ANACTRL_REG_POS), ~(0x0000ff00), 0,
+#endif
+ PCI_ADDR(0, (CK804_DEVN_BASE + 0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
+#if CONFIG_CK804_NUM > 1
+ PCI_ADDR(CK804B_BUSN, (CK804B_DEVN_BASE+0x1), 0, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
+#endif
+ };
+
+ setup_resource_map(ctrl_devport_conf_clear, ARRAY_SIZE(ctrl_devport_conf_clear));
+}
+
+static void ck804_early_setup(void)
+{
+ static const unsigned int ctrl_conf[] = {
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 2, 0xac), 0xffffff00, 0x00000000,
+
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
+#endif
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE, 0, 0xdc), 0x7f000000, 0x00000000,
+
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE, 0, 0xdc), 0x7f000000, 0x00000000,
+#endif
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xf8), 0xffffffcf, 0x00000010,
+
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xf8), 0xffffffcf, 0x00000010,
+#endif
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 9, 0, 0x74), 0xffffffc0, 0x00000000,
+
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 9, 0, 0x74), 0xffffffc0, 0x00000000,
+#endif
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0x78), 0xc0ffffff, 0x19000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1, 0, 0xe0), 0xfffffeff, 0x00000100,
+
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0x78), 0xc0ffffff, 0x20000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe0), 0xfffffeff, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe8), 0xffffff00, 0x000000ff,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, ~(0xffff), 0x0f008,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, ~((0xff) | (0xff << 16)), (0x41 << 16) | (0x32),
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7c, ~(0xff << 16), (0xa0 << 16),
+
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+#endif
+
+ /* Activate master port on primary SATA controller. */
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 7, 0, 0xe0), ~(0xf0000000), 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
+#if CONFIG_CK804_NUM > 1
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
+#endif
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804_PCI_E_X << 4) | (1 << 8),
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_32, CK804B_ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804B_PCI_E_X << 4) | (1 << 8),
+#endif
+
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 8, ~(0xff), ((0 << 4) | (0 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 9, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+#if CONFIG_CK804_USE_NIC
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE +0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+ RES_PCI_IO, PCI_ADDR(0, CK804_DEVN_BASE + 1 , 0, 0xe4), ~(1 << 23), (1 << 23),
+#endif
+
+#if CONFIG_CK804_USE_ACI
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x0d, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x1a, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
+#endif
+
+#if CONFIG_CK804_NUM > 1
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0, ~(3 << 2), (0 << 2),
+#endif
+
+#if CONFIG_CK804_NUM > 1
+#if CONFIG_CK804_USE_NIC
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE +0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, CK804B_SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+ RES_PCI_IO, PCI_ADDR(CK804B_BUSN, CK804B_DEVN_BASE + 1, 0, 0xe4), ~(1 << 23), (1 << 23),
+#endif
+#endif
+
+#ifdef CK804_MB_SETUP
+ CK804_MB_SETUP
+#endif
+ };
+
+ setup_resource_map_x(ctrl_conf, ARRAY_SIZE(ctrl_conf));
+
+ setup_ss_table(ANACTRL_IO_BASE + 0x40, ANACTRL_IO_BASE + 0x44, ANACTRL_IO_BASE + 0x48, pcie_ss_tbl, 64);
+ setup_ss_table(ANACTRL_IO_BASE + 0xb0, ANACTRL_IO_BASE + 0xb4, ANACTRL_IO_BASE + 0xb8, sata_ss_tbl, 64);
+ setup_ss_table(ANACTRL_IO_BASE + 0xc0, ANACTRL_IO_BASE + 0xc4, ANACTRL_IO_BASE + 0xc8, cpu_ss_tbl, 64);
+
+#if CONFIG_CK804_NUM > 1
+ setup_ss_table(CK804B_ANACTRL_IO_BASE + 0x40, CK804B_ANACTRL_IO_BASE + 0x44, CK804B_ANACTRL_IO_BASE + 0x48, pcie_ss_tbl, 64);
+ setup_ss_table(CK804B_ANACTRL_IO_BASE + 0xb0, CK804B_ANACTRL_IO_BASE + 0xb4, CK804B_ANACTRL_IO_BASE + 0xb8, sata_ss_tbl, 64);
+ setup_ss_table(CK804B_ANACTRL_IO_BASE + 0xc0, CK804B_ANACTRL_IO_BASE + 0xc4, CK804B_ANACTRL_IO_BASE + 0xc8, cpu_ss_tbl, 64);
+#endif
+
+#if 0
+ dump_io_resources(ANACTRL_IO_BASE);
+ dump_io_resources(SYSCTRL_IO_BASE);
+#endif
+}
+
+static int ck804_early_setup_x(void)
+{
+ ck804_early_set_port();
+ ck804_early_setup();
+ ck804_early_clear_port();
+ return set_ht_link_ck804(4);
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+static int set_ht_link_ck804(uint8_t ht_c_num)
+{
+ unsigned vendorid = 0x10de;
+ unsigned val = 0x01610169;
+ return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
+}
+
+static void setup_ss_table(unsigned index, unsigned where, unsigned control,
+ const unsigned int *register_values, int max)
+{
+ int i;
+ unsigned val;
+
+ val = inl(control);
+ val &= 0xfffffffe;
+ outl(val, control);
+
+ outl(0, index);
+
+ for (i = 0; i < max; i++) {
+ unsigned long reg;
+ reg = register_values[i];
+ outl(reg, where);
+ }
+ val = inl(control);
+ val |= 1;
+ outl(val, control);
+}
+
+#define ANACTRL_IO_BASE 0x3000
+#define ANACTRL_REG_POS 0x68
+
+#define SYSCTRL_IO_BASE 0x2000
+#define SYSCTRL_REG_POS 0x64
+
+/*
+ * Values for CONFIG_CK804_PCI_E_X and CONFIG_CK804B_PCI_E_X.
+ * Apparently some sort of lane configuration.
+ *
+ * 16 1 1 2 :0
+ * 8 8 2 2 :1
+ * 8 8 4 :2
+ * 8 4 4 4 :3
+ * 16 4 :4
+ */
+
+#define CK804_CHIP_REV 3
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+#if CONFIG_SB_HT_CHAIN_UNITID_OFFSET_ONLY == 1
+#define CK804B_DEVN_BASE 1
+#else
+#define CK804B_DEVN_BASE CK804_DEVN_BASE
+#endif
+
+static void ck804_early_set_port(unsigned ck804_num, unsigned *busn,
+ unsigned *io_base)
+{
+ static const unsigned int ctrl_devport_conf[] = {
+ PCI_ADDR(0, 0x1, 0, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
+ PCI_ADDR(0, 0x1, 0, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
+ };
+
+ int j;
+ for (j = 0; j < ck804_num; j++) {
+ u32 dev;
+ if (busn[j] == 0) //sb chain
+ dev = PCI_DEV(busn[j], CK804_DEVN_BASE, 0);
+ else
+ dev = PCI_DEV(busn[j], CK804B_DEVN_BASE, 0);
+ setup_resource_map_offset(ctrl_devport_conf,
+ ARRAY_SIZE(ctrl_devport_conf), dev,
+ io_base[j]);
+ }
+}
+
+static void ck804_early_clear_port(unsigned ck804_num, unsigned *busn,
+ unsigned *io_base)
+{
+ static const unsigned int ctrl_devport_conf_clear[] = {
+ PCI_ADDR(0, 0x1, 0, ANACTRL_REG_POS), ~(0x0000ff01), 0,
+ PCI_ADDR(0, 0x1, 0, SYSCTRL_REG_POS), ~(0x0000ff01), 0,
+ };
+
+ int j;
+ for (j = 0; j < ck804_num; j++) {
+ u32 dev;
+ if (busn[j] == 0) //sb chain
+ dev = PCI_DEV(busn[j], CK804_DEVN_BASE, 0);
+ else
+ dev = PCI_DEV(busn[j], CK804B_DEVN_BASE, 0);
+ setup_resource_map_offset(ctrl_devport_conf_clear,
+ ARRAY_SIZE(ctrl_devport_conf_clear), dev,
+ io_base[j]);
+ }
+}
+
+static void ck804_early_setup(unsigned ck804_num, unsigned *busn,
+ unsigned *io_base)
+{
+ static const unsigned int ctrl_conf_master[] = {
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xac), 0xffffff00, 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xdc), 0x7f000000, 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf8), 0xffffffcf, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x74), 0xffffffc0, 0x00000000,
+
+#ifdef CK804_MB_SETUP
+ CK804_MB_SETUP
+#endif
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xc0ffffff, 0x19000000,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe0), 0xfffffeff, 0x00000100,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, ~(0xffff), 0x0f008,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, ~((0xff) | (0xff << 16)), (0x41 << 16) | (0x32),
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7c, ~(0xff << 16), (0xa0 << 16),
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+
+ /* Activate master port on primary SATA controller. */
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 7, 0, 0xe0), ~(0xf0000000), 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804_PCI_E_X << 4) | (1 << 8),
+
+//SYSCTRL
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 8, ~(0xff), ((0 << 4) | (0 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 9, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+#if CONFIG_CK804_USE_NIC
+ RES_PCI_IO, PCI_ADDR(0, 0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe4), ~(1 << 23), (1 << 23),
+#endif
+
+#if CONFIG_CK804_USE_ACI
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x0d, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0x1a, ~(0xff), ((0 << 4) | (2 << 2) | (0 << 0)),
+#endif
+
+ };
+
+ static const unsigned int ctrl_conf_multiple[] = {
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 0, ~(3 << 2), (0 << 2),
+ };
+
+ static const unsigned int ctrl_conf_slave[] = {
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x8c), 0xffff0000, 0x00009880,
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0x90), 0xffff000f, 0x000074a0,
+ RES_PCI_IO, PCI_ADDR(0, 1, 2, 0xa0), 0xfffff0ff, 0x00000a00,
+
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xfffff00f, 0x000009d0,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8c), 0xffff0000, 0x0000007f,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xcc), 0xfffffff8, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd0), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd4), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xd8), 0xff000000, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xdc), 0x7f000000, 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf0), 0xfffffffd, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xf8), 0xffffffcf, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0xfff8ffff, 0x00030000,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x4c), 0xfe00ffff, 0x00440000,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x74), 0xffffffc0, 0x00000000,
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xc0ffffff, 0x20000000,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe0), 0xfffffeff, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe8), 0xffffff00, 0x000000ff,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x20, 0xe00fffff, 0x11000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc3f0ffff, 0x24040000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0x8c3f04df, 0x51407120,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x84, 0xffffff8f, 0x00000010,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x94, 0xff00ffff, 0x00c00000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, 0xf7ffffff, 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xfcffff0f, 0x020000b0,
+
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x50), ~(0x1f000013), 0x15000013,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x64), ~(0x00000001), 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), ~(0x02000000), 0x02000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x70), ~(0x000f0000), 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xa0), ~(0x000001ff), 0x00000150,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xac), ~(0xffff8f00), 0x02aa8b00,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x7c), ~(0x00000010), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xc8), ~(0x0fff0fff), 0x000a000a,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xd0), ~(0xf0000000), 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xe0), ~(0xf0000000), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x04, ~((0x3ff << 0) | (0x3ff << 10)), (0x21 << 0) | (0x22 << 10),
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, ~(0xfffff), (0x1c << 10) | 0x1b,
+
+/* This line doesn't exist in the non-CAR version. */
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, ~(1 << 3), 0x00000000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xcc, ~((7 << 4) | (1 << 8)), (CONFIG_CK804B_PCI_E_X << 4) | (1 << 8),
+
+#if CONFIG_CK804_USE_NIC
+ RES_PCI_IO, PCI_ADDR(0, 0xa, 0, 0xf8), 0xffffffbf, 0x00000040,
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 19, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (0 << 0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0 + 3, ~(0xff), ((0 << 4) | (1 << 2) | (1 << 0)),
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xe4), ~(1 << 23), (1 << 23),
+#endif
+ };
+
+ int j;
+ for (j = 0; j < ck804_num; j++) {
+ if (busn[j] == 0) {
+ setup_resource_map_x_offset(ctrl_conf_master,
+ ARRAY_SIZE(ctrl_conf_master),
+ PCI_DEV(0, CK804_DEVN_BASE, 0), io_base[0]);
+ if (ck804_num > 1)
+ setup_resource_map_x_offset(ctrl_conf_multiple,
+ ARRAY_SIZE(ctrl_conf_multiple),
+ PCI_DEV(0, CK804_DEVN_BASE, 0), 0);
+
+ continue;
+ }
+
+ setup_resource_map_x_offset(ctrl_conf_slave,
+ ARRAY_SIZE(ctrl_conf_slave),
+ PCI_DEV(busn[j], CK804B_DEVN_BASE, 0), io_base[j]);
+ }
+
+ for (j = 0; j < ck804_num; j++) {
+ /* PCI-E (XSPLL) SS table 0x40, x044, 0x48 */
+ /* SATA (SPPLL) SS table 0xb0, 0xb4, 0xb8 */
+ /* CPU (PPLL) SS table 0xc0, 0xc4, 0xc8 */
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0x40,
+ io_base[j] + ANACTRL_IO_BASE + 0x44,
+ io_base[j] + ANACTRL_IO_BASE + 0x48,
+ pcie_ss_tbl, 64);
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0xb0,
+ io_base[j] + ANACTRL_IO_BASE + 0xb4,
+ io_base[j] + ANACTRL_IO_BASE + 0xb8,
+ sata_ss_tbl, 64);
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE + 0xc0,
+ io_base[j] + ANACTRL_IO_BASE + 0xc4,
+ io_base[j] + ANACTRL_IO_BASE + 0xc8,
+ cpu_ss_tbl, 64);
+ }
+}
+
+static int ck804_early_setup_x(void)
+{
+ unsigned busn[4], io_base[4];
+ int i, ck804_num = 0;
+
+ for (i = 0; i < 4; i++) {
+ uint32_t id;
+ device_t dev;
+ if (i == 0) // SB chain
+ dev = PCI_DEV(i * 0x40, CK804_DEVN_BASE, 0);
+ else
+ dev = PCI_DEV(i * 0x40, CK804B_DEVN_BASE, 0);
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if (id == 0x005e10de) {
+ busn[ck804_num] = i * 0x40;
+ io_base[ck804_num] = i * 0x4000;
+ ck804_num++;
+ }
+ }
+
+ ck804_early_set_port(ck804_num, busn, io_base);
+ ck804_early_setup(ck804_num, busn, io_base);
+ ck804_early_clear_port(ck804_num, busn, io_base);
+
+ return set_ht_link_ck804(4);
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+static const unsigned int pcie_ss_tbl[] = {
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C504b049,
+ 0x0C504b049,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5042040,
+ 0x0C5042040,
+};
+
+static const unsigned int sata_ss_tbl[] = {
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+};
+
+static const unsigned int cpu_ss_tbl[] = {
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <console/console.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+
+#include "smbus.h"
+#include "early_smbus.h"
+
+#define SMBUS_BAR_BASE 0x20
+#define SMBUS_IO_BASE 0x1000
+#define SMBUS_IO_SIZE 0x0040
+
+#define SMBUS_BAR(x) (SMBUS_BAR_BASE + 4 * (x))
+#define SMBUS_BASE(x) (SMBUS_IO_BASE + SMBUS_IO_SIZE * (x))
+
+void enable_smbus(void)
+{
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_NVIDIA,
+ PCI_DEVICE_ID_NVIDIA_CK804_SMB), 0);
+ if (dev == PCI_DEV_INVALID)
+ die("SMBus controller not found\n");
+
+ /* Set SMBus I/O base. */
+ pci_write_config32(dev, SMBUS_BAR(0), SMBUS_BASE(0) | 1);
+ pci_write_config32(dev, SMBUS_BAR(1), SMBUS_BASE(1) | 1);
+
+ /* Set SMBus I/O space enable. */
+ pci_write_config16(dev, 0x4, 0x01);
+
+ /* Clear any lingering errors, so the transaction will run. */
+ outb(inb(SMBUS_BASE(0) + SMBHSTSTAT), SMBUS_BASE(0) + SMBHSTSTAT);
+ outb(inb(SMBUS_BASE(1) + SMBHSTSTAT), SMBUS_BASE(1) + SMBHSTSTAT);
+
+ print_debug("SMBus controller enabled\n");
+}
+
+int ck804_smbus_read_byte(unsigned bus, unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS_BASE(bus), device, address);
+}
+
+int ck804_smbus_write_byte(unsigned bus, unsigned device, unsigned address,
+ unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS_BASE(bus), device, address, val);
+}
+
+int smbus_read_byte(unsigned device, unsigned address)
+{
+ return ck804_smbus_read_byte(0, device, address);
+}
+
+int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return ck804_smbus_write_byte(0, device, address, val);
+}
--- /dev/null
+int ck804_smbus_read_byte(unsigned int, unsigned int, unsigned);
+int ck804_smbus_write_byte(unsigned int, unsigned int, unsigned int, unsigned char);
+void enable_smbus(void);
+int smbus_read_byte(unsigned int, unsigned int);
+int smbus_write_byte(unsigned int, unsigned int, unsigned char);
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+static void ck804_enable_rom(void)
+{
+ unsigned char byte;
+ device_t addr;
+
+ /* Enable 4MB ROM access at 0xFFC00000 - 0xFFFFFFFF. */
+ /* Locate the ck804 LPC. */
+ addr = PCI_DEV(0, (CK804_DEVN_BASE + 1), 0);
+
+ /* Set the 4MB enable bit. */
+ byte = pci_read_config8(addr, 0x88);
+ byte |= 0x80;
+ pci_write_config8(addr, 0x88, byte);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "ck804.h"
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE != 0x20
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+#define CK804_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+void set_debug_port(unsigned int port)
+{
+ u32 dword;
+ device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Write the port number to 0x74[15:12]. */
+ dword = pci_read_config32(dev, 0x74);
+ dword &= ~(0xf << 12);
+ dword |= (port << 12);
+ pci_write_config32(dev, 0x74, dword);
+}
+
+void ck804_enable_usbdebug(unsigned int port)
+{
+ device_t dev = PCI_DEV(0, CK804_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Mark the requested physical USB port (1-15) as the Debug Port. */
+ set_debug_port(port);
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+}
--- /dev/null
+/*
+ * ACPI - create the Fixed ACPI Description Tables (FADT)
+ * (C) Copyright 2005 Stefan Reinauer <stepan@openbios.org>
+ */
+
+#include <string.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+
+extern unsigned pm_base; /* pm_base should be set in sb acpi */
+
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+
+ printk(BIOS_DEBUG, "pm_base: 0x%04x\n", pm_base);
+
+ /* Prepare the header */
+ memset((void *)fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+#ifdef LONG_FADT
+ header->length = 244;
+ header->revision = 3;
+#else
+ header->length = 0x74;
+ header->revision = 1;
+#endif
+ memcpy(header->oem_id, "CORE ", 6);
+ memcpy(header->oem_table_id, "CB-FADT ", 8);
+ memcpy(header->asl_compiler_id, "IASL", 4);
+ header->asl_compiler_revision = 0;
+
+ fadt->firmware_ctrl = (u32)facs;
+ fadt->dsdt = (u32)dsdt;
+ // 3=Workstation,4=Enterprise Server, 7=Performance Server
+ fadt->preferred_pm_profile = 0;
+ fadt->sci_int = 9;
+ // disable system management mode by setting to 0:
+ fadt->smi_cmd = 0;
+ fadt->acpi_enable = 0;
+ fadt->acpi_disable = 0;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0x0;
+
+ fadt->pm1a_evt_blk = pm_base;
+ fadt->pm1b_evt_blk = 0x0000;
+ fadt->pm1a_cnt_blk = pm_base + 0x04;
+ fadt->pm1b_cnt_blk = 0x0000;
+ fadt->pm2_cnt_blk = pm_base + 0x1c;
+ fadt->pm_tmr_blk = pm_base + 0x08;
+ fadt->gpe0_blk = pm_base + 0x20;
+ fadt->gpe1_blk = 0x0000;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 1;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 8;
+ fadt->gpe1_blk_len = 0;
+ fadt->gpe1_base = 0;
+ fadt->cst_cnt = 0;
+ fadt->p_lvl2_lat = 0xffff;
+ fadt->p_lvl3_lat = 0xffff;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 1;
+ fadt->duty_width = 0;
+ fadt->day_alrm = 0x7d;
+ fadt->mon_alrm = 0x7e;
+ fadt->century = 0x32;
+ fadt->iapc_boot_arch = 0;
+ fadt->flags = 0xa5;
+
+#ifdef LONG_FADT
+ fadt->res2 = 0;
+
+ fadt->reset_reg.space_id = 1;
+ fadt->reset_reg.bit_width = 8;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0xcf9;
+ fadt->reset_reg.addrh = 0x0;
+
+ fadt->reset_value = 6;
+ fadt->x_firmware_ctl_l = facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = 32;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = pm_base;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = 4;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = 0x0;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = 16;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = pm_base + 4;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = 2;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = 0x0;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = 0;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = 0x0;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = 32;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = pm_base + 0x08;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = 32;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = pm_base + 0x20;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = 64;
+ fadt->x_gpe1_blk.bit_offset = 16;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = pm_base + 0xb0;
+ fadt->x_gpe1_blk.addrh = 0x0;
+#endif
+ header->checksum = acpi_checksum((void *)fadt, header->length);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_HT,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_nvidia_ck804_config *conf;
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+
+ conf = dev->chip_info;
+
+ word = pci_read_config16(dev, 0x50);
+ /* Ensure prefetch is disabled. */
+ word &= ~((1 << 15) | (1 << 13));
+ if (conf->ide1_enable) {
+ /* Enable secondary IDE interface. */
+ word |= (1 << 0);
+ printk(BIOS_DEBUG, "IDE1 \t");
+ }
+ if (conf->ide0_enable) {
+ /* Enable primary IDE interface. */
+ word |= (1 << 1);
+ printk(BIOS_DEBUG, "IDE0\n");
+ }
+
+ word |= (1 << 12);
+ word |= (1 << 14);
+
+ pci_write_config16(dev, 0x50, word);
+
+ byte = 0x20; /* Latency: 64 --> 32 */
+ pci_write_config8(dev, 0xd, byte);
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 12;
+ pci_write_config32(dev, 0xf8, dword);
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+ // .enable = ck804_enable,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_IDE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2003 SuSE Linux AG
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <cpu/x86/lapic.h>
+#include <stdlib.h>
+#include "ck804.h"
+
+#define CK804_CHIP_REV 2
+
+#define NMI_OFF 0
+
+// 0x7a or e3
+#define PREVIOUS_POWER_STATE 0x7A
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define SLOW_CPU_OFF 0
+#define SLOW_CPU__ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+static void lpc_common_init(device_t dev)
+{
+ uint8_t byte;
+ uint32_t dword;
+
+ /* I/O APIC initialization */
+ byte = pci_read_config8(dev, 0x74);
+ byte |= (1 << 0); /* Enable APIC. */
+ pci_write_config8(dev, 0x74, byte);
+ dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); /* 0x14 */
+
+ setup_ioapic(dword, 0); // Don't rename IOAPIC ID
+
+#if 1
+ dword = pci_read_config32(dev, 0xe4);
+ dword |= (1 << 23);
+ pci_write_config32(dev, 0xe4, dword);
+#endif
+}
+
+static void lpc_slave_init(device_t dev)
+{
+ lpc_common_init(dev);
+}
+
+static void rom_dummy_write(device_t dev)
+{
+ uint8_t old, new;
+ uint8_t *p;
+
+ old = pci_read_config8(dev, 0x88);
+ new = old | 0xc0;
+ if (new != old)
+ pci_write_config8(dev, 0x88, new);
+ /* Enable write. */
+ old = pci_read_config8(dev, 0x6d);
+ new = old | 0x01;
+ if (new != old)
+ pci_write_config8(dev, 0x6d, new);
+
+ /* Dummy write. */
+ p = (uint8_t *) 0xffffffe0;
+ old = 0;
+ *p = old;
+ old = *p;
+
+ /* Disable write. */
+ old = pci_read_config8(dev, 0x6d);
+ new = old & 0xfe;
+ if (new != old)
+ pci_write_config8(dev, 0x6d, new);
+}
+
+static void enable_hpet(struct device *dev)
+{
+ unsigned long hpet_address;
+
+ pci_write_config32(dev, 0x44, 0xfed00001);
+ hpet_address = pci_read_config32(dev, 0x44) & 0xfffffffe;
+ printk(BIOS_DEBUG, "Enabling HPET @0x%lx\n", hpet_address);
+}
+
+unsigned pm_base=0;
+
+static void lpc_init(device_t dev)
+{
+ uint8_t byte, byte_old;
+ int on, nmi_option;
+
+ lpc_common_init(dev);
+
+ pm_base = pci_read_config32(dev, 0x60) & 0xff00;
+ printk(BIOS_INFO, "%s: pm_base = %x \n", __func__, pm_base);
+
+#if CK804_CHIP_REV==1
+ if (dev->bus->secondary != 1)
+ return;
+#endif
+
+#if 0
+ /* Posted memory write enable */
+ byte = pci_read_config8(dev, 0x46);
+ pci_write_config8(dev, 0x46, byte | (1 << 0));
+#endif
+
+ /* power after power fail */
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
+ byte &= ~0x40;
+ if (!on)
+ byte |= 0x40;
+ pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
+
+ /* Throttle the CPU speed down for testing. */
+ on = SLOW_CPU_OFF;
+ get_option(&on, "slow_cpu");
+ if (on) {
+ uint16_t pm10_bar;
+ uint32_t dword;
+ pm10_bar = (pci_read_config16(dev, 0x60) & 0xff00);
+ outl(((on << 1) + 0x10), (pm10_bar + 0x10));
+ dword = inl(pm10_bar + 0x10);
+ on = 8 - on;
+ printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
+ (on * 12) + (on >> 1), (on & 1) * 5);
+ }
+#if 0
+// default is enabled
+ /* Enable Port 92 fast reset. */
+ byte = pci_read_config8(dev, 0xe8);
+ byte |= ~(1 << 3);
+ pci_write_config8(dev, 0xe8, byte);
+#endif
+
+ /* Enable Error reporting. */
+ /* Set up sync flood detected. */
+ byte = pci_read_config8(dev, 0x47);
+ byte |= (1 << 1);
+ pci_write_config8(dev, 0x47, byte);
+
+ /* Set up NMI on errors. */
+ byte = inb(0x70); /* RTC70 */
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* Set NMI. */
+ } else {
+ byte |= (1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW. */
+ }
+ if (byte != byte_old)
+ outb(byte, 0x70);
+
+ /* Initialize the real time clock (RTC). */
+ rtc_init(0);
+
+ /* Initialize ISA DMA. */
+ isa_dma_init();
+
+ /* Initialize the High Precision Event Timers (HPET). */
+ enable_hpet(dev);
+
+ rom_dummy_write(dev);
+}
+
+static void ck804_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+ unsigned long index;
+
+ /* Get the normal PCI resources of this device. */
+ /* We got one for APIC, or one more for TRAP. */
+ pci_dev_read_resources(dev);
+
+ /* Get resource for ACPI, SYSTEM_CONTROL, ANALOG_CONTROL. */
+ for (index = 0x60; index <= 0x68; index += 4) /* We got another 3. */
+ pci_get_resource(dev, index);
+ compact_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+/**
+ * Enable resources for children devices.
+ *
+ * This function is called by the global enable_resources() indirectly via the
+ * device_operation::enable_resources() method of devices.
+ *
+ */
+static void ck804_lpc_enable_childrens_resources(device_t dev)
+{
+ struct bus *link;
+ uint32_t reg, reg_var[4];
+ int i, var_num = 0;
+
+ reg = pci_read_config32(dev, 0xa0);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child; child = child->sibling) {
+ if (child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for (res = child->resource_list; res; res = res->next) {
+ unsigned long base, end; // don't need long long
+ if (!(res->flags & IORESOURCE_IO))
+ continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "ck804 lpc decode:%s, base=0x%08lx, end=0x%08lx\n", dev_path(child), base, end);
+ switch (base) {
+ case 0x3f8: // COM1
+ reg |= (1 << 0);
+ break;
+ case 0x2f8: // COM2
+ reg |= (1 << 1);
+ break;
+ case 0x378: // Parallel 1
+ reg |= (1 << 24);
+ break;
+ case 0x3f0: // FD0
+ reg |= (1 << 20);
+ break;
+ case 0x220: // Audio 0
+ reg |= (1 << 8);
+ break;
+ case 0x300: // Midi 0
+ reg |= (1 << 12);
+ break;
+ }
+ if (base == 0x290 || base >= 0x400) {
+ if (var_num >= 4)
+ continue; // only 4 var ; compact them ?
+ reg |= (1 << (28 + var_num));
+ reg_var[var_num++] = (base & 0xffff) | ((end & 0xffff) << 16);
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0xa0, reg);
+ for (i = 0; i < var_num; i++)
+ pci_write_config32(dev, 0xa8 + i * 4, reg_var[i]);
+}
+
+static void ck804_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ ck804_lpc_enable_childrens_resources(dev);
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = ck804_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = ck804_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ // .enable = ck804_enable,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_LPC,
+};
+
+static const struct pci_driver lpc_driver_pro __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PRO,
+};
+
+#if CK804_CHIP_REV == 1
+static const struct pci_driver lpc_driver_slave __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
+};
+#else
+static struct device_operations lpc_slave_ops = {
+ .read_resources = ck804_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_slave_init,
+ // .enable = ck804_enable,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver lpc_driver_slave __pci_driver = {
+ .ops = &lpc_slave_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SLAVE,
+};
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "ck804.h"
+
+static void nic_init(struct device *dev)
+{
+ uint32_t dword, old, mac_h, mac_l;
+ int eeprom_valid = 0;
+ struct southbridge_nvidia_ck804_config *conf;
+ static uint32_t nic_index = 0;
+ unsigned long base;
+ struct resource *res;
+
+ res = find_resource(dev, 0x10);
+ base = (unsigned long)res->base;
+
+#define NvRegPhyInterface 0xC0
+#define PHY_RGMII 0x10000000
+
+ write32(base + NvRegPhyInterface, PHY_RGMII);
+
+ old = dword = pci_read_config32(dev, 0x30);
+ dword &= ~(0xf);
+ dword |= 0xf;
+ if (old != dword)
+ pci_write_config32(dev, 0x30, dword);
+
+ conf = dev->chip_info;
+
+ if (conf->mac_eeprom_smbus != 0) {
+ /* Read MAC address from EEPROM at first. */
+ struct device *dev_eeprom;
+ dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus,
+ conf->mac_eeprom_addr);
+
+ if (dev_eeprom) {
+ /* If that is valid we will use that. */
+ unsigned char dat[6];
+ int i, status;
+ for (i = 0; i < 6; i++) {
+ status = smbus_read_byte(dev_eeprom, i);
+ if (status < 0)
+ break;
+ dat[i] = status & 0xff;
+ }
+ if (status >= 0) {
+ mac_l = 0;
+ for (i = 3; i >= 0; i--) {
+ mac_l <<= 8;
+ mac_l += dat[i];
+ }
+ if (mac_l != 0xffffffff) {
+ mac_l += nic_index;
+ mac_h = 0;
+ for (i = 5; i >= 4; i--) {
+ mac_h <<= 8;
+ mac_h += dat[i];
+ }
+ eeprom_valid = 1;
+ }
+ }
+ }
+ }
+
+ /* If that is invalid we will read that from romstrap. */
+ if (!eeprom_valid) {
+ unsigned long mac_pos;
+ mac_pos = 0xffffffd0; /* See romstrap.inc and romstrap.lds. */
+ mac_l = read32(mac_pos) + nic_index;
+ mac_h = read32(mac_pos + 4);
+ }
+#if 1
+ /* Set that into NIC MMIO. */
+#define NvRegMacAddrA 0xA8
+#define NvRegMacAddrB 0xAC
+ write32(base + NvRegMacAddrA, mac_l);
+ write32(base + NvRegMacAddrB, mac_h);
+#else
+ /* Set that into NIC. */
+ pci_write_config32(dev, 0xa8, mac_l);
+ pci_write_config32(dev, 0xac, mac_h);
+#endif
+
+ nic_index++;
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev); /* It will init Option ROM. */
+#endif
+}
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+ // .enable = ck804_enable,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC,
+};
+
+static const struct pci_driver nic_bridge_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/resource.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void pci_init(struct device *dev)
+{
+ uint32_t dword;
+ device_t pci_domain_dev;
+ struct resource *mem, *pref;
+
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* System error enable */
+ dword |= (1 << 30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+#if 0
+ word = pci_read_config16(dev, 0x48);
+ word |= (1 << 0); /* MRL2MRM */
+ word |= (1 << 2); /* MR2MRM */
+ pci_write_config16(dev, 0x48, word);
+#endif
+
+#if 1
+ dword = pci_read_config32(dev, 0x4c);
+ dword |= 0x00440000; /* TABORT_SER_ENABLE Park Last Enable. */
+ pci_write_config32(dev, 0x4c, dword);
+#endif
+
+ pci_domain_dev = dev->bus->dev;
+ while (pci_domain_dev) {
+ if (pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN)
+ break;
+ pci_domain_dev = pci_domain_dev->bus->dev;
+ }
+
+ if (!pci_domain_dev)
+ return; /* Impossible */
+
+ pref = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(2,0));
+ mem = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(1,0));
+
+ if (!mem)
+ return; /* Impossible */
+
+ if (!pref || pref->base > mem->base) {
+ dword = mem->base & (0xffff0000UL);
+ printk(BIOS_DEBUG, "PCI DOMAIN mem base = 0x%010Lx\n", mem->base);
+ } else {
+ dword = pref->base & (0xffff0000UL);
+ printk(BIOS_DEBUG, "PCI DOMAIN pref base = 0x%010Lx\n", pref->base);
+ }
+
+ printk(BIOS_DEBUG, "[0x50] <-- 0x%08x\n", dword);
+ pci_write_config32(dev, 0x50, dword); /* TOM */
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ // .enable = ck804_enable,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void pcie_init(struct device *dev)
+{
+ uint32_t dword;
+
+ /* Enable PCI error detecting. */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1 << 8); /* System error enable */
+ dword |= (1 << 30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+}
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+ // .enable = ck804_enable,
+};
+
+static const struct pci_driver pcie_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_PCI_E,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev >> 4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev >> 4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9. */
+ outb((0 << 3) | (0 << 2) | (1 << 1), 0xcf9);
+ outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+#ifndef CK804_SATA_RESET_FOR_ATAPI
+#define CK804_SATA_RESET_FOR_ATAPI 0
+#endif
+
+#if CK804_SATA_RESET_FOR_ATAPI
+static void sata_com_reset(struct device *dev, unsigned reset)
+// reset = 1 : reset
+// reset = 0 : clear
+{
+ uint32_t *base;
+ uint32_t dword;
+ int loop;
+
+ base = (uint32_t *) pci_read_config32(dev, 0x24);
+
+ printk(BIOS_DEBUG, "base = %08lx\n", base);
+
+ if (reset) {
+ *(base + 4) = 0xffffffff;
+ *(base + 0x44) = 0xffffffff;
+ }
+
+ dword = *(base + 8);
+ dword &= ~(0xf);
+ dword |= reset;
+
+ *(base + 8) = dword;
+ *(base + 0x48) = dword;
+
+#if 0
+ udelay(1000);
+ dword &= ~(0xf);
+ *(base + 8) = dword;
+ *(base + 0x48) = dword;
+#endif
+
+ if (reset)
+ return;
+
+ dword = *(base + 0);
+ printk(BIOS_DEBUG, "*(base+0)=%08x\n", dword);
+ if (dword == 0x113) {
+ loop = 200000; // 2
+ do {
+ dword = *(base + 4);
+ if ((dword & 0x10000) != 0)
+ break;
+ udelay(10);
+ } while (--loop > 0);
+ printk(BIOS_DEBUG, "loop=%d, *(base+4)=%08x\n", loop, dword);
+ }
+
+ dword = *(base + 0x40);
+ printk(BIOS_DEBUG, "*(base+0x40)=%08x\n", dword);
+ if (dword == 0x113) {
+ loop = 200000; //2
+ do {
+ dword = *(base + 0x44);
+ if ((dword & 0x10000) != 0)
+ break;
+ udelay(10);
+ } while (--loop > 0);
+ printk(BIOS_DEBUG, "loop=%d, *(base+0x44)=%08x\n", loop, dword);
+ }
+}
+#endif
+
+static void sata_init(struct device *dev)
+{
+ uint32_t dword;
+ struct southbridge_nvidia_ck804_config *conf;
+
+ conf = dev->chip_info;
+
+ dword = pci_read_config32(dev, 0x50);
+ /* Ensure prefetch is disabled. */
+ dword &= ~((1 << 15) | (1 << 13));
+ if (conf->sata1_enable) {
+ /* Enable secondary SATA interface. */
+ dword |= (1 << 0);
+ printk(BIOS_DEBUG, "SATA S \t");
+ }
+ if (conf->sata0_enable) {
+ /* Enable primary SATA interface. */
+ dword |= (1 << 1);
+ printk(BIOS_DEBUG, "SATA P \n");
+ }
+#if 0
+ /* Write back */
+ dword |= (1 << 12);
+ dword |= (1 << 14);
+#endif
+
+#if 0
+ /* ADMA */
+ dword |= (1 << 16);
+ dword |= (1 << 17);
+#endif
+
+#if 1
+ /* DO NOT relay OK and PAGE_FRNDLY_DTXFR_CNT. */
+ dword &= ~(0x1f << 24);
+ dword |= (0x15 << 24);
+#endif
+ pci_write_config32(dev, 0x50, dword);
+
+#if 0
+ /* SLUMBER_DURING_D3 */
+ dword = pci_read_config32(dev, 0x7c);
+ dword &= ~(1 << 4);
+ pci_write_config32(dev, 0x7c, dword);
+
+ dword = pci_read_config32(dev, 0xd0);
+ dword &= ~(0xff << 24);
+ dword |= (0x68 << 24);
+ pci_write_config32(dev, 0xd0, dword);
+
+ dword = pci_read_config32(dev, 0xe0);
+ dword &= ~(0xff << 24);
+ dword |= (0x68 << 24);
+ pci_write_config32(dev, 0xe0, dword);
+#endif
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 2;
+ pci_write_config32(dev, 0xf8, dword);
+
+#if CK804_SATA_RESET_FOR_ATAPI
+ dword = pci_read_config32(dev, 0xac);
+ dword &= ~((1 << 13) | (1 << 14));
+ dword |= (1 << 13) | (0 << 14);
+ pci_write_config32(dev, 0xac, dword);
+
+ sata_com_reset(dev, 1); /* For discover some s-atapi device. */
+#endif
+
+}
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ // .enable = ck804_enable,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA0,
+};
+
+static const struct pci_driver sata1_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SATA1,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include "ck804.h"
+#include "smbus.h"
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ // .enable = ck804_enable,
+ .ops_pci = &ck804_pci_ops,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_SM,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x1
+#define SMBHSTPRTCL 0x0
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x2
+#define SMBHSTDAT0 0x4
+#define SMBHSTDAT1 0x5
+
+/*
+ * Between 1-10 seconds, We should never timeout normally.
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100 * 1000 * 10)
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+#if 0
+/* Not needed, upon write to PRTCL, the status will be auto-cleared. */
+static int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0)
+ return 0;
+ outb(val, smbus_io_base + SMBHSTSTAT);
+ } while (--loops);
+ return -2;
+}
+#endif
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ if ((val & 0xff) != 0)
+ return 0;
+ } while (--loops);
+ return -3;
+}
+
+#ifndef __PRE_RAM__
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ unsigned char global_status_register, byte;
+
+#if 0
+ /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
+ if (smbus_wait_until_ready(smbus_io_base) < 0)
+ return -2;
+#endif
+
+ /* Set the device I'm talking to. */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* Set the command/address. */
+ outb(0, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* Byte data recv */
+ outb(0x05, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* Poll for transaction completion. */
+ if (smbus_wait_until_done(smbus_io_base) < 0)
+ return -3;
+
+ /* Lose check */
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
+
+ /* Read results of transaction. */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ /* Lose check, otherwise it should be 0. */
+ if (global_status_register != 0x80)
+ return -1;
+
+ return byte;
+}
+
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device,
+ unsigned char val)
+{
+ unsigned global_status_register;
+
+#if 0
+ /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
+ if (smbus_wait_until_ready(smbus_io_base) < 0)
+ return -2;
+#endif
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* Set the device I'm talking to. */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(0, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* Set up for a byte data write. */
+ outb(0x04, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* Poll for transaction completion. */
+ if (smbus_wait_until_done(smbus_io_base) < 0)
+ return -3;
+
+ /* Lose check */
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
+
+ if (global_status_register != 0x80)
+ return -1;
+
+ return 0;
+}
+#endif
+
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device,
+ unsigned address)
+{
+ unsigned char global_status_register, byte;
+
+#if 0
+ /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
+ if (smbus_wait_until_ready(smbus_io_base) < 0)
+ return -2;
+#endif
+
+ /* Set the device I'm talking to. */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* Set the command/address. */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* Byte data read */
+ outb(0x07, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* Poll for transaction completion. */
+ if (smbus_wait_until_done(smbus_io_base) < 0)
+ return -3;
+
+ /* Lose check */
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
+
+ /* Read results of transaction. */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ /* Lose check, otherwise it should be 0. */
+ if (global_status_register != 0x80)
+ return -1;
+
+ return byte;
+}
+
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device,
+ unsigned address, unsigned char val)
+{
+ unsigned global_status_register;
+
+#if 0
+ /* Not needed, upon write to PRTCL, the status will be auto-cleared. */
+ if (smbus_wait_until_ready(smbus_io_base) < 0)
+ return -2;
+#endif
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* Set the device I'm talking to. */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* Set up for a byte data write. */
+ outb(0x06, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* Poll for transaction completion. */
+ if (smbus_wait_until_done(smbus_io_base) < 0)
+ return -3;
+
+ /* Lose check */
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80;
+
+ if (global_status_register != 0x80)
+ return -1;
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void usb1_init(struct device *dev)
+{
+ struct southbridge_nvidia_ck804_config const *conf = dev->chip_info;
+ if (conf->usb1_hc_reset) {
+ /*
+ * Somehow the warm reset does not really reset the USB
+ * controller. Later, during boot, when the Bus Master bit is
+ * set, the USB controller trashes the memory, causing weird
+ * misbehavior. Was detected on Sun Ultra40, where mptable
+ * was damaged.
+ */
+ uint32_t bar0 = pci_read_config32(dev, 0x10);
+ uint32_t *regs = (uint32_t *) (bar0 & ~0xfff);
+
+ /* OHCI USB HCCommandStatus Register, HostControllerReset bit */
+ regs[2] |= 1;
+ }
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb1_init,
+ // .enable = ck804_enable,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_USB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "ck804.h"
+
+static void usb2_init(struct device *dev)
+{
+ uint32_t dword;
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 40;
+ pci_write_config32(dev, 0xf8, dword);
+}
+
+static struct device_operations usb2_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb2_init,
+ // .enable = ck804_enable,
+ .scan_bus = 0,
+ .ops_pci = &ck804_pci_ops,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_CK804_USB2,
+};
driver-y += mcp55.c
-driver-y += mcp55_azalia.c
-driver-y += mcp55_ht.c
-driver-y += mcp55_ide.c
-driver-y += mcp55_lpc.c
-driver-y += mcp55_nic.c
-driver-y += mcp55_pci.c
-driver-y += mcp55_pcie.c
-driver-y += mcp55_sata.c
-driver-y += mcp55_smbus.c
-driver-y += mcp55_usb2.c
-driver-y += mcp55_usb.c
+driver-y += azalia.c
+driver-y += ht.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += nic.c
+driver-y += pci.c
+driver-y += pcie.c
+driver-y += sata.c
+driver-y += smbus.c
+driver-y += usb2.c
+driver-y += usb.c
-driver-$(CONFIG_GENERATE_ACPI_TABLES) += mcp55_fadt.c
+driver-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
-ramstage-y += mcp55_reset.c
+ramstage-y += reset.c
-romstage-y += mcp55_enable_usbdebug.c
+romstage-y += enable_usbdebug.c
chipset_bootblock_inc += $(src)/southbridge/nvidia/mcp55/romstrap.inc
chipset_bootblock_lds += $(src)/southbridge/nvidia/mcp55/romstrap.lds
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Advanced Micro Devices, Inc.
+ * Copyright (C) 2008-2010 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "mcp55.h"
+
+#define HDA_ICII_REG 0x68
+#define HDA_ICII_BUSY (1 << 0)
+#define HDA_ICII_VALID (1 << 1)
+
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 reg32;
+ int count;
+
+ /* Write (val & mask) to port */
+ val &= mask;
+ reg32 = read32(port);
+ reg32 &= ~mask;
+ reg32 |= val;
+ write32(port, reg32);
+
+ /* Wait for readback of register to
+ * match what was just written to it
+ */
+ count = 50;
+ do {
+ /* Wait 1ms based on BKDG wait time */
+ mdelay(1);
+ reg32 = read32(port);
+ reg32 &= mask;
+ } while ((reg32 != val) && --count);
+
+ /* Timeout occurred */
+ if (!count)
+ return -1;
+ return 0;
+}
+
+static int codec_detect(u32 base)
+{
+ u32 reg32;
+
+ /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 0) == -1)
+ goto no_codec;
+
+ /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
+ if (set_bits(base + 0x08, 1, 1) == -1)
+ goto no_codec;
+
+ /* Read in Codec location (BAR + 0xe)[2..0]*/
+ reg32 = read32(base + 0xe);
+ reg32 &= 0x0f;
+ if (!reg32)
+ goto no_codec;
+
+ return reg32;
+
+no_codec:
+ /* Codec Not found */
+ /* Put HDA back in reset (BAR + 0x8) [0] */
+ set_bits(base + 0x08, 1, 0);
+ printk(BIOS_DEBUG, "Azalia: No codec!\n");
+ return 0;
+}
+
+u32 * cim_verb_data = NULL;
+u32 cim_verb_data_size = 0;
+
+static u32 find_verb(struct device *dev, u32 viddid, u32 ** verb)
+{
+ int idx=0;
+
+ while (idx < (cim_verb_data_size / sizeof(u32))) {
+ u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
+ if (cim_verb_data[idx] != viddid) {
+ idx += verb_size + 3; // skip verb + header
+ continue;
+ }
+ *verb = &cim_verb_data[idx+3];
+ return verb_size;
+ }
+
+ /* Not all codecs need to load another verb */
+ return 0;
+}
+
+/**
+ * Wait 50usec for the codec to indicate it is ready
+ * no response would imply that the codec is non-operative
+ */
+
+static int wait_for_ready(u32 base)
+{
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+
+ while(timeout--) {
+ u32 reg32 = read32(base + HDA_ICII_REG);
+ if (!(reg32 & HDA_ICII_BUSY))
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+/**
+ * Wait 50usec for the codec to indicate that it accepted
+ * the previous command. No response would imply that the code
+ * is non-operative
+ */
+
+static int wait_for_valid(u32 base)
+{
+ u32 reg32;
+
+ /* Send the verb to the codec */
+ reg32 = read32(base + 0x68);
+ reg32 |= (1 << 0) | (1 << 1);
+ write32(base + 0x68, reg32);
+
+ /* Use a 50 usec timeout - the Linux kernel uses the
+ * same duration */
+
+ int timeout = 50;
+ while(timeout--) {
+ reg32 = read32(base + HDA_ICII_REG);
+ if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
+ HDA_ICII_VALID)
+ return 0;
+ udelay(1);
+ }
+
+ return -1;
+}
+
+static void codec_init(struct device *dev, u32 base, int addr)
+{
+ u32 reg32;
+ u32 *verb;
+ u32 verb_size;
+ int i;
+
+ printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
+
+ /* 1 */
+ if (wait_for_ready(base) == -1)
+ return;
+
+ reg32 = (addr << 28) | 0x000f0000;
+ write32(base + 0x60, reg32);
+
+ if (wait_for_valid(base) == -1)
+ return;
+
+ reg32 = read32(base + 0x64);
+
+ /* 2 */
+ printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
+ verb_size = find_verb(dev, reg32, &verb);
+
+ if (!verb_size) {
+ printk(BIOS_DEBUG, "Azalia: No verb!\n");
+ return;
+ }
+ printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
+
+ /* 3 */
+ for (i = 0; i < verb_size; i++) {
+ if (wait_for_ready(base) == -1)
+ return;
+
+ write32(base + 0x60, verb[i]);
+
+ if (wait_for_valid(base) == -1)
+ return;
+ }
+ printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
+}
+
+static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
+{
+ int i;
+ for (i = 2; i >= 0; i--) {
+ if (codec_mask & (1 << i))
+ codec_init(dev, base, i);
+ }
+}
+
+static void azalia_init(struct device *dev)
+{
+ u32 base;
+ struct resource *res;
+ u32 codec_mask;
+ u8 reg8;
+ u32 reg32;
+
+ /* Set Bus Master */
+ reg32 = pci_read_config32(dev, PCI_COMMAND);
+ pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
+
+ pci_write_config8(dev, 0x3c, 0x0a); // unused?
+
+ reg8 = pci_read_config8(dev, 0x40);
+ reg8 |= (1 << 3); // Clear Clock Detect Bit
+ pci_write_config8(dev, 0x40, reg8);
+ reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over
+ pci_write_config8(dev, 0x40, reg8);
+ reg8 |= (1 << 2); // Enable clock detection
+ pci_write_config8(dev, 0x40, reg8);
+ mdelay(1);
+ reg8 = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97");
+
+ //
+ reg8 = pci_read_config8(dev, 0x40); // Audio Control
+ reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
+ pci_write_config8(dev, 0x40, reg8);
+
+ reg8 = pci_read_config8(dev, 0x4d); // Docking Status
+ reg8 &= ~(1 << 7); // Docking not supported
+ pci_write_config8(dev, 0x4d, reg8);
+
+ res = find_resource(dev, 0x10);
+ if (!res)
+ return;
+
+ // NOTE this will break as soon as the Azalia get's a bar above
+ // 4G. Is there anything we can do about it?
+ base = (u32)res->base;
+ printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
+ codec_mask = codec_detect(base);
+
+ if (codec_mask) {
+ printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
+ codecs_init(dev, base, codec_mask);
+ }
+}
+
+static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ if (!vendor || !device) {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_read_config32(dev, PCI_VENDOR_ID));
+ } else {
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ }
+}
+
+static struct pci_operations azalia_pci_ops = {
+ .set_subsystem = azalia_set_subsystem,
+};
+
+static struct device_operations azalia_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = azalia_init,
+ .scan_bus = 0,
+// .enable = mcp55_enable,
+ .ops_pci = &azalia_pci_ops,
+};
+
+static const struct pci_driver azalia __pci_driver = {
+ .ops = &azalia_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_AZA,
+};
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "southbridge/nvidia/mcp55/mcp55_enable_rom.c"
+#include "southbridge/nvidia/mcp55/enable_rom.c"
static void bootblock_southbridge_init(void)
{
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+#include "mcp55.h"
+
+static unsigned get_sbdn(unsigned bus)
+{
+ device_t dev;
+
+ /* Find the device.
+ */
+ dev = pci_locate_device_on_bus(
+ PCI_ID(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP55_HT),
+ bus);
+
+ return (dev>>15) & 0x1f;
+
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
+{
+ /* default value for mcp55 is good */
+ /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#ifdef UNUSED_CODE
+int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val);
+
+static int set_ht_link_mcp55(uint8_t ht_c_num)
+{
+ unsigned vendorid = 0x10de;
+ unsigned val = 0x01610109;
+ /* Nvidia mcp55 hardcode, hw can not set it automatically */
+ return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
+}
+
+static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max)
+{
+ int i;
+
+ unsigned val;
+
+ val = inl(control);
+ val &= 0xfffffffe;
+ outl(val, control);
+
+ outl(0, index); //index
+ for(i = 0; i < max; i++) {
+ unsigned long reg;
+ reg = register_values[i];
+ outl(reg, where);
+ }
+
+ val = inl(control);
+ val |= 1;
+ outl(val, control);
+
+}
+#endif
+
+/* SIZE 0x100 */
+#define ANACTRL_IO_BASE 0x2800
+#define ANACTRL_REG_POS 0x68
+
+/* SIZE 0x100 */
+#define SYSCTRL_IO_BASE 0x2400
+#define SYSCTRL_REG_POS 0x64
+
+/* SIZE 0x100 */
+#define ACPICTRL_IO_BASE 0x2000
+#define ACPICTRL_REG_POS 0x60
+
+/*
+ 16 1 1 1 1 8 :0
+ 16 0 4 0 0 8 :1
+ 16 0 4 2 2 4 :2
+ 4 4 4 4 4 8 :3
+ 8 8 4 0 0 8 :4
+ 8 0 4 4 4 8 :5
+*/
+
+#define MCP55_CHIP_REV 3
+
+static void mcp55_early_set_port(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base)
+{
+
+ static const unsigned int ctrl_devport_conf[] = {
+ PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
+ PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
+ PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), ACPICTRL_IO_BASE,
+ };
+
+ int j;
+ for(j = 0; j < mcp55_num; j++ ) {
+ setup_resource_map_offset(ctrl_devport_conf,
+ ARRAY_SIZE(ctrl_devport_conf),
+ PCI_DEV(busn[j], devn[j], 0) , io_base[j]);
+ }
+}
+
+static void mcp55_early_clear_port(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base)
+{
+
+ static const unsigned int ctrl_devport_conf_clear[] = {
+ PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), 0,
+ PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
+ PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), 0,
+ };
+
+ int j;
+ for(j = 0; j < mcp55_num; j++ ) {
+ setup_resource_map_offset(ctrl_devport_conf_clear,
+ ARRAY_SIZE(ctrl_devport_conf_clear),
+ PCI_DEV(busn[j], devn[j], 0) , io_base[j]);
+ }
+
+
+}
+
+static void mcp55_early_pcie_setup(unsigned busnx, unsigned devnx, unsigned anactrl_io_base, unsigned pci_e_x)
+{
+ uint32_t tgio_ctrl;
+ uint32_t pll_ctrl;
+ uint32_t dword;
+ int i;
+ device_t dev;
+ dev = PCI_DEV(busnx, devnx+1, 1);
+ dword = pci_read_config32(dev, 0xe4);
+ dword |= 0x3f0; // disable it at first
+ pci_write_config32(dev, 0xe4, dword);
+
+ for(i=0; i<3; i++) {
+ tgio_ctrl = inl(anactrl_io_base + 0xcc);
+ tgio_ctrl &= ~(3<<9);
+ tgio_ctrl |= (i<<9);
+ outl(tgio_ctrl, anactrl_io_base + 0xcc);
+ pll_ctrl = inl(anactrl_io_base + 0x30);
+ pll_ctrl |= (1<<31);
+ outl(pll_ctrl, anactrl_io_base + 0x30);
+ do {
+ pll_ctrl = inl(anactrl_io_base + 0x30);
+ } while (!(pll_ctrl & 1));
+ }
+ tgio_ctrl = inl(anactrl_io_base + 0xcc);
+ tgio_ctrl &= ~((7<<4)|(1<<8));
+ tgio_ctrl |= (pci_e_x<<4)|(1<<8);
+ outl(tgio_ctrl, anactrl_io_base + 0xcc);
+
+ // wait 100us
+ udelay(100);
+
+ dword = pci_read_config32(dev, 0xe4);
+ dword &= ~(0x3f0); // enable
+ pci_write_config32(dev, 0xe4, dword);
+
+ // need to wait 100ms
+ mdelay(100);
+}
+
+static void mcp55_early_setup(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base, unsigned *pci_e_x)
+{
+
+ static const unsigned int ctrl_conf_1[] = {
+ RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x10, 0x0007ffff, 0xff78000,
+ RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xa4, 0xffedffff, 0x0012000,
+ RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xac, 0xfffffdff, 0x0000200,
+ RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xb4, 0xfffffffd, 0x0000002,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc0f0f08f, 0x26020230,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x34, 0x00000000, 0x22222222,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, 0x7FFFFFFF, 0x00000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x2C, 0x7FFFFFFF, 0x80000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000200,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000400,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, 0xFFFF0FF5, 0x0000F000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, 0xFF00FF00, 0x00100010,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7C, 0xFF0FF0FF, 0x00500500,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0xFFFFFFE7, 0x00000000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFCFFFFF, 0x00300000,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x90, 0xFFFF00FF, 0x0000FF00,
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x9C, 0xFF00FFFF, 0x00070000,
+
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xFFFFDCED, 0x00002002,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x78), 0xFFFFFF8E, 0x00000011,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x80), 0xFFFF0000, 0x00009923,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x88), 0xFFFFFFFE, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8C), 0xFFFF0000, 0x0000007F,
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xDC), 0xFFFEFFFF, 0x00010000,
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFFFF7B, 0x00000084,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xF8), 0xFFFFFFCF, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xC4), 0xFFFFFFFE, 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF0), 0x7FFFFFFD, 0x00000002,
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF8), 0xFFFFFFCF, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), 0xFFFFFF00, 0x000000FF,
+ RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode
+
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x68), 0xFFFFFF00, 0x000000FF,
+ RES_PCI_IO, PCI_ADDR(0, 9, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode
+ };
+
+ static const unsigned int ctrl_conf_1_1[] = {
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x50), 0xFFFFFFFC, 0x00000003,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x64), 0xFFFFFFFE, 0x00000001,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x70), 0xFFF0FFFF, 0x00040000,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xAC), 0xFFFFF0FF, 0x00000100,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x7C), 0xFFFFFFEF, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xC8), 0xFF00FF00, 0x000A000A,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xD0), 0xF0FFFFFF, 0x03000000,
+ RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xE0), 0xF0FFFFFF, 0x03000000,
+ };
+
+
+ static const unsigned int ctrl_conf_mcp55_only[] = {
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE0), 0xFFFFFEFF, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), 0xFFFFFFFB, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE8), 0xFFA9C8FF, 0x00003000,
+
+ RES_PCI_IO, PCI_ADDR(0, 4, 0, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 4, 0, 0xF8), 0xFFFFFFCF, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 2, 0, 0x40), 0x00000000, 0xCB8410DE,
+
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x40), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x64), 0xF87FFFFF, 0x05000000,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x78), 0xFFC07FFF, 0x00360000,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x68), 0xFE00D03F, 0x013F2C00,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x70), 0xFFF7FFFF, 0x00080000,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x7C), 0xFFFFF00F, 0x00000570,
+ RES_PCI_IO, PCI_ADDR(0, 2, 1, 0xF8), 0xFFFFFFCF, 0x00000010,
+
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x04), 0xFFFFFEFB, 0x00000104,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x3C), 0xF5FFFFFF, 0x0A000000,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x40), 0x00C8FFFF, 0x07330000,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x48), 0xFFFFFFF8, 0x00000005,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x4C), 0xFE02FFFF, 0x004C0000,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x74), 0xFFFFFFC0, 0x00000000,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC0), 0x00000000, 0xCB8410DE,
+ RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC4), 0xFFFFFFF8, 0x00000007,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000,
+
+#if CONFIG_MCP55_USE_AZA
+ RES_PCI_IO, PCI_ADDR(0, 6, 1, 0x40), 0x00000000, 0xCB8410DE,
+
+// RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), ~(1<<14), 1<<14,
+#endif
+// play a while with GPIO in MCP55
+#ifdef MCP55_MB_SETUP
+ MCP55_MB_SETUP
+#endif
+
+#if CONFIG_MCP55_USE_AZA
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 21, ~(3<<2), (2<<2),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 22, ~(3<<2), (2<<2),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 46, ~(3<<2), (2<<2),
+#endif
+
+
+ };
+
+ static const unsigned int ctrl_conf_master_only[] = {
+
+ RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x80, 0xEFFFFFF, 0x01000000,
+
+ //Master MCP55 ????YHLU
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 0, ~(3<<2), (0<<2),
+
+ };
+
+ static const unsigned int ctrl_conf_2[] = {
+ /* I didn't put pcie related stuff here */
+
+ RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xFFFFF00F, 0x000009D0,
+ RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFF7FFF, 0x00008000,
+
+ RES_PORT_IO_32, SYSCTRL_IO_BASE + 0x48, 0xFFFEFFFF, 0x00010000,
+
+ RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFFFFF00, 0x00000012,
+
+
+#if CONFIG_MCP55_USE_NIC
+ RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xe4), ~((1<<22)|(1<<20)), (1<<22)|(1<<20),
+
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
+ RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(1<<0)),
+#endif
+
+ };
+
+
+ int j, i;
+
+ for(j=0; j<mcp55_num; j++) {
+ mcp55_early_pcie_setup(busn[j], devn[j], io_base[j] + ANACTRL_IO_BASE, pci_e_x[j]);
+
+ setup_resource_map_x_offset(ctrl_conf_1, ARRAY_SIZE(ctrl_conf_1),
+ PCI_DEV(busn[j], devn[j], 0), io_base[j]);
+ for(i=0; i<3; i++) { // three SATA
+ setup_resource_map_x_offset(ctrl_conf_1_1, ARRAY_SIZE(ctrl_conf_1_1),
+ PCI_DEV(busn[j], devn[j], i), io_base[j]);
+ }
+ if(busn[j] == 0) {
+ setup_resource_map_x_offset(ctrl_conf_mcp55_only, ARRAY_SIZE(ctrl_conf_mcp55_only),
+ PCI_DEV(busn[j], devn[j], 0), io_base[j]);
+ }
+
+ if( (busn[j] == 0) && (mcp55_num>1) ) {
+ setup_resource_map_x_offset(ctrl_conf_master_only, ARRAY_SIZE(ctrl_conf_master_only),
+ PCI_DEV(busn[j], devn[j], 0), io_base[j]);
+ }
+
+ setup_resource_map_x_offset(ctrl_conf_2, ARRAY_SIZE(ctrl_conf_2),
+ PCI_DEV(busn[j], devn[j], 0), io_base[j]);
+
+ }
+
+#if 0
+ for(j=0; j< mcp55_num; j++) {
+ // PCI-E (XSPLL) SS table 0x40, x044, 0x48
+ // SATA (SPPLL) SS table 0xb0, 0xb4, 0xb8
+ // CPU (PPLL) SS table 0xc0, 0xc4, 0xc8
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0x40, io_base[j] + ANACTRL_IO_BASE+0x44,
+ io_base[j] + ANACTRL_IO_BASE+0x48, pcie_ss_tbl, 64);
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xb0, io_base[j] + ANACTRL_IO_BASE+0xb4,
+ io_base[j] + ANACTRL_IO_BASE+0xb8, sata_ss_tbl, 64);
+ setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xc0, io_base[j] + ANACTRL_IO_BASE+0xc4,
+ io_base[j] + ANACTRL_IO_BASE+0xc8, cpu_ss_tbl, 64);
+ }
+#endif
+
+}
+
+#ifndef HT_CHAIN_NUM_MAX
+
+#define HT_CHAIN_NUM_MAX 4
+#define HT_CHAIN_BUSN_D 0x40
+#define HT_CHAIN_IOBASE_D 0x4000
+
+#endif
+
+static int mcp55_early_setup_x(void)
+{
+ /*find out how many mcp55 we have */
+ unsigned busn[HT_CHAIN_NUM_MAX] = {0};
+ unsigned devn[HT_CHAIN_NUM_MAX] = {0};
+ unsigned io_base[HT_CHAIN_NUM_MAX] = {0};
+ /*
+ FIXME: May have problem if there is different MCP55 HTX card with different PCI_E lane allocation
+ Need to use same trick about pci1234 to verify node/link connection
+ */
+ unsigned pci_e_x[HT_CHAIN_NUM_MAX] = {CONFIG_MCP55_PCI_E_X_0, CONFIG_MCP55_PCI_E_X_1, CONFIG_MCP55_PCI_E_X_2, CONFIG_MCP55_PCI_E_X_3 };
+ int mcp55_num = 0;
+ unsigned busnx;
+ unsigned devnx;
+ int ht_c_index;
+
+ /* FIXME: multi pci segment handling */
+
+ /* Any system that only have IO55 without MCP55? */
+ for(ht_c_index = 0; ht_c_index<HT_CHAIN_NUM_MAX; ht_c_index++) {
+ busnx = ht_c_index * HT_CHAIN_BUSN_D;
+ for(devnx=0;devnx<0x20;devnx++) {
+ uint32_t id;
+ device_t dev;
+ dev = PCI_DEV(busnx, devnx, 0);
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if(id == 0x036910de) {
+ busn[mcp55_num] = busnx;
+ devn[mcp55_num] = devnx;
+ io_base[mcp55_num] = ht_c_index * HT_CHAIN_IOBASE_D; // we may have ht chain other than MCP55
+ mcp55_num++;
+ if(mcp55_num == CONFIG_MCP55_NUM) goto out;
+ break; // only one MCP55 on one chain
+ }
+ }
+ }
+
+out:
+ print_debug("mcp55_num:"); print_debug_hex8(mcp55_num); print_debug("\n");
+
+ mcp55_early_set_port(mcp55_num, busn, devn, io_base);
+ mcp55_early_setup(mcp55_num, busn, devn, io_base, pci_e_x);
+
+ mcp55_early_clear_port(mcp55_num, busn, devn, io_base);
+
+// set_ht_link_mcp55(HT_CHAIN_NUM_MAX);
+
+ return 0;
+
+}
+
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+static const unsigned int pcie_ss_tbl[] = {
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C504b049,
+ 0x0C504b049,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5042040,
+ 0x0C5042040,
+};
+static const unsigned int sata_ss_tbl[] = {
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+};
+
+static const unsigned int cpu_ss_tbl[] = {
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+};
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "smbus.h"
+
+#define SMBUS0_IO_BASE 0x1000
+#define SMBUS1_IO_BASE (0x1000+(1<<8))
+/*SIZE 0x40 */
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(0x10de, 0x0368), 0);
+
+ if (dev == PCI_DEV_INVALID)
+ die("SMBus controller not found\n");
+
+ /* set smbus iobase */
+ pci_write_config32(dev, 0x20, SMBUS0_IO_BASE | 1);
+ pci_write_config32(dev, 0x24, SMBUS1_IO_BASE | 1);
+ /* Set smbus iospace enable */
+ pci_write_config16(dev, 0x4, 0x01);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS0_IO_BASE + SMBHSTSTAT), SMBUS0_IO_BASE + SMBHSTSTAT);
+ outb(inb(SMBUS1_IO_BASE + SMBHSTSTAT), SMBUS1_IO_BASE + SMBHSTSTAT);
+}
+
+static inline int smbus_recv_byte(unsigned device)
+{
+ return do_smbus_recv_byte(SMBUS0_IO_BASE, device);
+}
+
+static inline int smbus_send_byte(unsigned device, unsigned char val)
+{
+ return do_smbus_send_byte(SMBUS0_IO_BASE, device, val);
+}
+
+static inline int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS0_IO_BASE, device, address);
+}
+
+static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val);
+}
+
+static inline int smbusx_recv_byte(unsigned smb_index, unsigned device)
+{
+ return do_smbus_recv_byte(SMBUS0_IO_BASE + (smb_index<<8), device);
+}
+
+static inline int smbusx_send_byte(unsigned smb_index, unsigned device, unsigned char val)
+{
+ return do_smbus_send_byte(SMBUS0_IO_BASE + (smb_index<<8), device, val);
+}
+
+static inline int smbusx_read_byte(unsigned smb_index, unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS0_IO_BASE + (smb_index<<8), device, address);
+}
+
+static inline int smbusx_write_byte(unsigned smb_index, unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS0_IO_BASE + (smb_index<<8), device, address, val);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include "mcp55.h"
+
+static void mcp55_enable_rom(void)
+{
+ uint8_t byte;
+ uint16_t word;
+ device_t addr;
+
+ /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
+#if 0
+ /* default MCP55 LPC single */
+ addr = pci_locate_device(PCI_ID(0x10de, 0x0367), 0);
+#else
+// addr = pci_locate_device(PCI_ID(0x10de, 0x0360), 0);
+ addr = PCI_DEV(0, (MCP55_DEVN_BASE+1), 0);
+#endif
+
+ /* Set the 4MB enable bit bit */
+ byte = pci_read_config8(addr, 0x88);
+ byte |= 0xff; //256K
+ pci_write_config8(addr, 0x88, byte);
+ byte = pci_read_config8(addr, 0x8c);
+ byte |= 0xff; //1M
+ pci_write_config8(addr, 0x8c, byte);
+ word = pci_read_config16(addr, 0x90);
+ word |= 0x7fff; //15M
+ pci_write_config16(addr, 0x90, word);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "mcp55.h"
+
+void set_debug_port(unsigned int port)
+{
+ u32 dword;
+ device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Write the port number to 0x74[15:12]. */
+ dword = pci_read_config32(dev, 0x74);
+ dword &= ~(0xf << 12);
+ dword |= (port << 12);
+ pci_write_config32(dev, 0x74, dword);
+}
+
+void mcp55_enable_usbdebug(unsigned int port)
+{
+ device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Mark the requested physical USB port (1-15) as the Debug Port. */
+ set_debug_port(port);
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Harald Gutmann <harald.gutmann@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <string.h>
+#include <arch/acpi.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci_ids.h>
+
+extern unsigned pm_base;
+
+/* Create the Fixed ACPI Description Tables (FADT) for this board. */
+void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+ device_t dev;
+ int is_mcp55 = 0;
+ dev = dev_find_device(PCI_VENDOR_ID_NVIDIA,
+ PCI_DEVICE_ID_NVIDIA_MCP55_LPC, 0);
+ if (dev)
+ is_mcp55 = 1;
+
+ memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+ header->length = sizeof(acpi_fadt_t);
+ header->revision = 1;
+ memcpy(header->oem_id, "GBT", 6);
+ memcpy(header->oem_table_id, "COREBOOT ", 8);
+ memcpy(header->asl_compiler_id, "CORE", 4);
+ header->asl_compiler_revision = 42;
+
+ printk(BIOS_INFO, "ACPI: pm_base: %u...\n", pm_base);
+
+ fadt->firmware_ctrl = (u32)facs;
+ fadt->dsdt = (u32)dsdt;
+ fadt->preferred_pm_profile = 1; //check
+ fadt->sci_int = 9;
+ /* disable system management mode by setting to 0 */
+ fadt->smi_cmd = 0x0; //pm_base+0x42e; (value from proprietary acpi fadt)
+ fadt->acpi_enable = 0xa1;
+ fadt->acpi_disable = 0xa0;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0x0;
+
+ fadt->pm1a_evt_blk = pm_base;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = pm_base + 0x4;
+ fadt->pm1b_cnt_blk = 0x0;
+ fadt->pm2_cnt_blk = pm_base + 0x1c;
+ fadt->pm_tmr_blk = pm_base + 0x8;
+ fadt->gpe0_blk = pm_base + 0x20;
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 1;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 8;
+ if (is_mcp55) {
+ fadt->gpe1_blk = pm_base + 0x4a0;
+ fadt->gpe1_base = 0x20;
+ fadt->gpe1_blk_len = 0x10;
+ }
+ else {
+ fadt->gpe1_blk = 0x0;
+ fadt->gpe1_base = 0x0;
+ fadt->gpe1_blk_len = 0x0;
+ }
+
+ fadt->cst_cnt = 0;
+ fadt->p_lvl2_lat = 0x65;
+ fadt->p_lvl3_lat = 0x3e9;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 1;
+ fadt->duty_width = 3;
+ fadt->day_alrm = 0x7d;
+ fadt->mon_alrm = 0x7e;
+ fadt->century = 0x32;
+
+ fadt->iapc_boot_arch = 0x0;
+
+ fadt->flags = 0x4a5;
+ fadt->reset_reg.space_id = 0;
+ fadt->reset_reg.bit_width = 0;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0x0;
+ fadt->reset_reg.addrh = 0x0;
+
+ fadt->reset_value = 0;
+ fadt->x_firmware_ctl_l = (u32)facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = (u32)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum = acpi_checksum((void *) fadt, header->length);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static struct device_operations ht_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = 0,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver ht_driver __pci_driver = {
+ .ops = &ht_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_HT,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_nvidia_mcp55_config *conf;
+ /* Enable ide devices so the linux ide driver will work */
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+ conf = dev->chip_info;
+
+ word = pci_read_config16(dev, 0x50);
+ /* Ensure prefetch is disabled */
+ word &= ~((1 << 15) | (1 << 13));
+ if (conf->ide1_enable) {
+ /* Enable secondary ide interface */
+ word |= (1<<0);
+ printk(BIOS_DEBUG, "IDE1 \t");
+ }
+ if (conf->ide0_enable) {
+ /* Enable primary ide interface */
+ word |= (1<<1);
+ printk(BIOS_DEBUG, "IDE0\n");
+ }
+
+ word |= (1<<12);
+ word |= (1<<14);
+
+ pci_write_config16(dev, 0x50, word);
+
+
+ byte = 0x20 ; // Latency: 64-->32
+ pci_write_config8(dev, 0xd, byte);
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 12;
+ pci_write_config32(dev, 0xf8, dword);
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+// .enable = mcp55_enable,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_IDE,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2003 SuSE Linux AG
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <cpu/x86/lapic.h>
+#include <stdlib.h>
+#include "mcp55.h"
+
+#define NMI_OFF 0
+
+// 0x7a or e3
+#define PREVIOUS_POWER_STATE 0x7A
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define SLOW_CPU_OFF 0
+#define SLOW_CPU__ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+static void lpc_common_init(device_t dev, int master)
+{
+ uint8_t byte;
+ uint32_t ioapic_base;
+
+ /* IO APIC initialization */
+ byte = pci_read_config8(dev, 0x74);
+ byte |= (1<<0); // enable APIC
+ pci_write_config8(dev, 0x74, byte);
+ ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
+
+ if (master)
+ setup_ioapic(ioapic_base, 0);
+ else
+ clear_ioapic(ioapic_base);
+}
+
+static void lpc_slave_init(device_t dev)
+{
+ lpc_common_init(dev, 0);
+}
+
+static void enable_hpet(struct device *dev)
+{
+ unsigned long hpet_address;
+
+ pci_write_config32(dev,0x44, 0xfed00001);
+ hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe;
+ printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address);
+}
+
+static void lpc_init(device_t dev)
+{
+ uint8_t byte;
+ uint8_t byte_old;
+ int on;
+ int nmi_option;
+
+ lpc_common_init(dev, 1);
+
+#if 0
+ /* posted memory write enable */
+ byte = pci_read_config8(dev, 0x46);
+ pci_write_config8(dev, 0x46, byte | (1<<0));
+#endif
+ /* power after power fail */
+
+#if 1
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
+ byte &= ~0x40;
+ if (!on) {
+ byte |= 0x40;
+ }
+ pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
+#endif
+ /* Throttle the CPU speed down for testing */
+ on = SLOW_CPU_OFF;
+ get_option(&on, "slow_cpu");
+ if(on) {
+ uint16_t pm10_bar;
+ uint32_t dword;
+ pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
+ outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
+ dword = inl(pm10_bar + 0x10);
+ on = 8-on;
+ printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
+ (on*12)+(on>>1),(on&1)*5);
+ }
+
+#if 0
+// default is enabled
+ /* Enable Port 92 fast reset */
+ byte = pci_read_config8(dev, 0xe8);
+ byte |= ~(1 << 3);
+ pci_write_config8(dev, 0xe8, byte);
+#endif
+
+ /* Enable Error reporting */
+ /* Set up sync flood detected */
+ byte = pci_read_config8(dev, 0x47);
+ byte |= (1 << 1);
+ pci_write_config8(dev, 0x47, byte);
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); // RTC70
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ } else {
+ byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
+ }
+ if( byte != byte_old) {
+ outb(byte, 0x70);
+ }
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ /* Initialize the High Precision Event Timers */
+ enable_hpet(dev);
+
+}
+
+static void mcp55_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal PCI resources of this device. */
+ /* We got one for APIC, or one more for TRAP. */
+ pci_dev_read_resources(dev);
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+/**
+ * @brief Enable resources for children devices
+ *
+ * @param dev the device whos children's resources are to be enabled
+ *
+ */
+static void mcp55_lpc_enable_childrens_resources(device_t dev)
+{
+ uint32_t reg, reg_var[4];
+ int i;
+ int var_num = 0;
+ struct bus *link;
+
+ reg = pci_read_config32(dev, 0xa0);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child; child = child->sibling) {
+ if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for(res = child->resource_list; res; res = res->next) {
+ unsigned long base, end; // don't need long long
+ if(!(res->flags & IORESOURCE_IO)) continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "mcp55 lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
+ switch(base) {
+ case 0x3f8: // COM1
+ reg |= (1<<0); break;
+ case 0x2f8: // COM2
+ reg |= (1<<1); break;
+ case 0x378: // Parallal 1
+ reg |= (1<<24); break;
+ case 0x3f0: // FD0
+ reg |= (1<<20); break;
+ case 0x220: // Aduio 0
+ reg |= (1<<8); break;
+ case 0x300: // Midi 0
+ reg |= (1<<12); break;
+ }
+ if( (base == 0x290) || (base >= 0x400)) {
+ if(var_num>=4) continue; // only 4 var ; compact them ?
+ reg |= (1<<(28+var_num));
+ reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0xa0, reg);
+ for(i=0;i<var_num;i++) {
+ pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
+ }
+
+
+}
+
+static void mcp55_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ mcp55_lpc_enable_childrens_resources(dev);
+}
+
+static struct device_operations lpc_ops = {
+ .read_resources = mcp55_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = mcp55_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+// .enable = mcp55_enable,
+ .ops_pci = &mcp55_pci_ops,
+};
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC,
+};
+
+static const struct pci_driver lpc_driver_pro __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PRO,
+};
+
+static const struct pci_driver lpc_driver_lpc2 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_2,
+};
+static const struct pci_driver lpc_driver_lpc3 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_3,
+};
+static const struct pci_driver lpc_driver_lpc4 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_4,
+};
+static const struct pci_driver lpc_driver_lpc5 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_5,
+};
+static const struct pci_driver lpc_driver_lpc6 __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_6,
+};
+
+static struct device_operations lpc_slave_ops = {
+ .read_resources = mcp55_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_slave_init,
+// .enable = mcp55_enable,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver lpc_driver_slave __pci_driver = {
+ .ops = &lpc_slave_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_SLAVE,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Advanced Micro Devices, Inc.
- * Copyright (C) 2008-2010 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "mcp55.h"
-
-#define HDA_ICII_REG 0x68
-#define HDA_ICII_BUSY (1 << 0)
-#define HDA_ICII_VALID (1 << 1)
-
-static int set_bits(u32 port, u32 mask, u32 val)
-{
- u32 reg32;
- int count;
-
- /* Write (val & mask) to port */
- val &= mask;
- reg32 = read32(port);
- reg32 &= ~mask;
- reg32 |= val;
- write32(port, reg32);
-
- /* Wait for readback of register to
- * match what was just written to it
- */
- count = 50;
- do {
- /* Wait 1ms based on BKDG wait time */
- mdelay(1);
- reg32 = read32(port);
- reg32 &= mask;
- } while ((reg32 != val) && --count);
-
- /* Timeout occurred */
- if (!count)
- return -1;
- return 0;
-}
-
-static int codec_detect(u32 base)
-{
- u32 reg32;
-
- /* Set Bit0 to 0 to enter reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 0) == -1)
- goto no_codec;
-
- /* Set Bit 0 to 1 to exit reset state (BAR + 0x8)[0] */
- if (set_bits(base + 0x08, 1, 1) == -1)
- goto no_codec;
-
- /* Read in Codec location (BAR + 0xe)[2..0]*/
- reg32 = read32(base + 0xe);
- reg32 &= 0x0f;
- if (!reg32)
- goto no_codec;
-
- return reg32;
-
-no_codec:
- /* Codec Not found */
- /* Put HDA back in reset (BAR + 0x8) [0] */
- set_bits(base + 0x08, 1, 0);
- printk(BIOS_DEBUG, "Azalia: No codec!\n");
- return 0;
-}
-
-u32 * cim_verb_data = NULL;
-u32 cim_verb_data_size = 0;
-
-static u32 find_verb(struct device *dev, u32 viddid, u32 ** verb)
-{
- int idx=0;
-
- while (idx < (cim_verb_data_size / sizeof(u32))) {
- u32 verb_size = 4 * cim_verb_data[idx+2]; // in u32
- if (cim_verb_data[idx] != viddid) {
- idx += verb_size + 3; // skip verb + header
- continue;
- }
- *verb = &cim_verb_data[idx+3];
- return verb_size;
- }
-
- /* Not all codecs need to load another verb */
- return 0;
-}
-
-/**
- * Wait 50usec for the codec to indicate it is ready
- * no response would imply that the codec is non-operative
- */
-
-static int wait_for_ready(u32 base)
-{
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
-
- while(timeout--) {
- u32 reg32 = read32(base + HDA_ICII_REG);
- if (!(reg32 & HDA_ICII_BUSY))
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-/**
- * Wait 50usec for the codec to indicate that it accepted
- * the previous command. No response would imply that the code
- * is non-operative
- */
-
-static int wait_for_valid(u32 base)
-{
- u32 reg32;
-
- /* Send the verb to the codec */
- reg32 = read32(base + 0x68);
- reg32 |= (1 << 0) | (1 << 1);
- write32(base + 0x68, reg32);
-
- /* Use a 50 usec timeout - the Linux kernel uses the
- * same duration */
-
- int timeout = 50;
- while(timeout--) {
- reg32 = read32(base + HDA_ICII_REG);
- if ((reg32 & (HDA_ICII_VALID | HDA_ICII_BUSY)) ==
- HDA_ICII_VALID)
- return 0;
- udelay(1);
- }
-
- return -1;
-}
-
-static void codec_init(struct device *dev, u32 base, int addr)
-{
- u32 reg32;
- u32 *verb;
- u32 verb_size;
- int i;
-
- printk(BIOS_DEBUG, "Azalia: Initializing codec #%d\n", addr);
-
- /* 1 */
- if (wait_for_ready(base) == -1)
- return;
-
- reg32 = (addr << 28) | 0x000f0000;
- write32(base + 0x60, reg32);
-
- if (wait_for_valid(base) == -1)
- return;
-
- reg32 = read32(base + 0x64);
-
- /* 2 */
- printk(BIOS_DEBUG, "Azalia: codec viddid: %08x\n", reg32);
- verb_size = find_verb(dev, reg32, &verb);
-
- if (!verb_size) {
- printk(BIOS_DEBUG, "Azalia: No verb!\n");
- return;
- }
- printk(BIOS_DEBUG, "Azalia: verb_size: %d\n", verb_size);
-
- /* 3 */
- for (i = 0; i < verb_size; i++) {
- if (wait_for_ready(base) == -1)
- return;
-
- write32(base + 0x60, verb[i]);
-
- if (wait_for_valid(base) == -1)
- return;
- }
- printk(BIOS_DEBUG, "Azalia: verb loaded.\n");
-}
-
-static void codecs_init(struct device *dev, u32 base, u32 codec_mask)
-{
- int i;
- for (i = 2; i >= 0; i--) {
- if (codec_mask & (1 << i))
- codec_init(dev, base, i);
- }
-}
-
-static void azalia_init(struct device *dev)
-{
- u32 base;
- struct resource *res;
- u32 codec_mask;
- u8 reg8;
- u32 reg32;
-
- /* Set Bus Master */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
- pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
-
- pci_write_config8(dev, 0x3c, 0x0a); // unused?
-
- reg8 = pci_read_config8(dev, 0x40);
- reg8 |= (1 << 3); // Clear Clock Detect Bit
- pci_write_config8(dev, 0x40, reg8);
- reg8 &= ~(1 << 3); // Keep CLKDETCLR from clearing the bit over and over
- pci_write_config8(dev, 0x40, reg8);
- reg8 |= (1 << 2); // Enable clock detection
- pci_write_config8(dev, 0x40, reg8);
- mdelay(1);
- reg8 = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "Azalia: codec type: %s\n", (reg8 & (1 << 1))?"Azalia":"AC97");
-
- //
- reg8 = pci_read_config8(dev, 0x40); // Audio Control
- reg8 |= 1; // Select Azalia mode. This needs to be controlled via devicetree.cb
- pci_write_config8(dev, 0x40, reg8);
-
- reg8 = pci_read_config8(dev, 0x4d); // Docking Status
- reg8 &= ~(1 << 7); // Docking not supported
- pci_write_config8(dev, 0x4d, reg8);
-
- res = find_resource(dev, 0x10);
- if (!res)
- return;
-
- // NOTE this will break as soon as the Azalia get's a bar above
- // 4G. Is there anything we can do about it?
- base = (u32)res->base;
- printk(BIOS_DEBUG, "Azalia: base = %08x\n", (u32)base);
- codec_mask = codec_detect(base);
-
- if (codec_mask) {
- printk(BIOS_DEBUG, "Azalia: codec_mask = %02x\n", codec_mask);
- codecs_init(dev, base, codec_mask);
- }
-}
-
-static void azalia_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- pci_read_config32(dev, PCI_VENDOR_ID));
- } else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
- }
-}
-
-static struct pci_operations azalia_pci_ops = {
- .set_subsystem = azalia_set_subsystem,
-};
-
-static struct device_operations azalia_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = azalia_init,
- .scan_bus = 0,
-// .enable = mcp55_enable,
- .ops_pci = &azalia_pci_ops,
-};
-
-static const struct pci_driver azalia __pci_driver = {
- .ops = &azalia_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_AZA,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-#include "mcp55.h"
-
-static unsigned get_sbdn(unsigned bus)
-{
- device_t dev;
-
- /* Find the device.
- */
- dev = pci_locate_device_on_bus(
- PCI_ID(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP55_HT),
- bus);
-
- return (dev>>15) & 0x1f;
-
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
- /* link reset */
- outb(0x02, 0x0cf9);
- outb(0x06, 0x0cf9);
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
-{
- /* default value for mcp55 is good */
- /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-
-#ifdef UNUSED_CODE
-int set_ht_link_buffer_counts_chain(uint8_t ht_c_num, unsigned vendorid, unsigned val);
-
-static int set_ht_link_mcp55(uint8_t ht_c_num)
-{
- unsigned vendorid = 0x10de;
- unsigned val = 0x01610109;
- /* Nvidia mcp55 hardcode, hw can not set it automatically */
- return set_ht_link_buffer_counts_chain(ht_c_num, vendorid, val);
-}
-
-static void setup_ss_table(unsigned index, unsigned where, unsigned control, const unsigned int *register_values, int max)
-{
- int i;
-
- unsigned val;
-
- val = inl(control);
- val &= 0xfffffffe;
- outl(val, control);
-
- outl(0, index); //index
- for(i = 0; i < max; i++) {
- unsigned long reg;
- reg = register_values[i];
- outl(reg, where);
- }
-
- val = inl(control);
- val |= 1;
- outl(val, control);
-
-}
-#endif
-
-/* SIZE 0x100 */
-#define ANACTRL_IO_BASE 0x2800
-#define ANACTRL_REG_POS 0x68
-
-/* SIZE 0x100 */
-#define SYSCTRL_IO_BASE 0x2400
-#define SYSCTRL_REG_POS 0x64
-
-/* SIZE 0x100 */
-#define ACPICTRL_IO_BASE 0x2000
-#define ACPICTRL_REG_POS 0x60
-
-/*
- 16 1 1 1 1 8 :0
- 16 0 4 0 0 8 :1
- 16 0 4 2 2 4 :2
- 4 4 4 4 4 8 :3
- 8 8 4 0 0 8 :4
- 8 0 4 4 4 8 :5
-*/
-
-#define MCP55_CHIP_REV 3
-
-static void mcp55_early_set_port(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base)
-{
-
- static const unsigned int ctrl_devport_conf[] = {
- PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), ANACTRL_IO_BASE,
- PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), SYSCTRL_IO_BASE,
- PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), ACPICTRL_IO_BASE,
- };
-
- int j;
- for(j = 0; j < mcp55_num; j++ ) {
- setup_resource_map_offset(ctrl_devport_conf,
- ARRAY_SIZE(ctrl_devport_conf),
- PCI_DEV(busn[j], devn[j], 0) , io_base[j]);
- }
-}
-
-static void mcp55_early_clear_port(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base)
-{
-
- static const unsigned int ctrl_devport_conf_clear[] = {
- PCI_ADDR(0, 1, 1, ANACTRL_REG_POS), ~(0x0000ff00), 0,
- PCI_ADDR(0, 1, 1, SYSCTRL_REG_POS), ~(0x0000ff00), 0,
- PCI_ADDR(0, 1, 1, ACPICTRL_REG_POS), ~(0x0000ff00), 0,
- };
-
- int j;
- for(j = 0; j < mcp55_num; j++ ) {
- setup_resource_map_offset(ctrl_devport_conf_clear,
- ARRAY_SIZE(ctrl_devport_conf_clear),
- PCI_DEV(busn[j], devn[j], 0) , io_base[j]);
- }
-
-
-}
-
-static void mcp55_early_pcie_setup(unsigned busnx, unsigned devnx, unsigned anactrl_io_base, unsigned pci_e_x)
-{
- uint32_t tgio_ctrl;
- uint32_t pll_ctrl;
- uint32_t dword;
- int i;
- device_t dev;
- dev = PCI_DEV(busnx, devnx+1, 1);
- dword = pci_read_config32(dev, 0xe4);
- dword |= 0x3f0; // disable it at first
- pci_write_config32(dev, 0xe4, dword);
-
- for(i=0; i<3; i++) {
- tgio_ctrl = inl(anactrl_io_base + 0xcc);
- tgio_ctrl &= ~(3<<9);
- tgio_ctrl |= (i<<9);
- outl(tgio_ctrl, anactrl_io_base + 0xcc);
- pll_ctrl = inl(anactrl_io_base + 0x30);
- pll_ctrl |= (1<<31);
- outl(pll_ctrl, anactrl_io_base + 0x30);
- do {
- pll_ctrl = inl(anactrl_io_base + 0x30);
- } while (!(pll_ctrl & 1));
- }
- tgio_ctrl = inl(anactrl_io_base + 0xcc);
- tgio_ctrl &= ~((7<<4)|(1<<8));
- tgio_ctrl |= (pci_e_x<<4)|(1<<8);
- outl(tgio_ctrl, anactrl_io_base + 0xcc);
-
- // wait 100us
- udelay(100);
-
- dword = pci_read_config32(dev, 0xe4);
- dword &= ~(0x3f0); // enable
- pci_write_config32(dev, 0xe4, dword);
-
- // need to wait 100ms
- mdelay(100);
-}
-
-static void mcp55_early_setup(unsigned mcp55_num, unsigned *busn, unsigned *devn, unsigned *io_base, unsigned *pci_e_x)
-{
-
- static const unsigned int ctrl_conf_1[] = {
- RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x10, 0x0007ffff, 0xff78000,
- RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xa4, 0xffedffff, 0x0012000,
- RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xac, 0xfffffdff, 0x0000200,
- RES_PORT_IO_32, ACPICTRL_IO_BASE + 0xb4, 0xfffffffd, 0x0000002,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x24, 0xc0f0f08f, 0x26020230,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x34, 0x00000000, 0x22222222,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x08, 0x7FFFFFFF, 0x00000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x2C, 0x7FFFFFFF, 0x80000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000200,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0xCC, 0xFFFFF9FF, 0x00000400,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x30, 0x8FFFFFFF, 0x40000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x74, 0xFFFF0FF5, 0x0000F000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x78, 0xFF00FF00, 0x00100010,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x7C, 0xFF0FF0FF, 0x00500500,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x80, 0xFFFFFFE7, 0x00000000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFCFFFFF, 0x00300000,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x90, 0xFFFF00FF, 0x0000FF00,
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x9C, 0xFF00FFFF, 0x00070000,
-
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x48), 0xFFFFDCED, 0x00002002,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x78), 0xFFFFFF8E, 0x00000011,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x80), 0xFFFF0000, 0x00009923,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x88), 0xFFFFFFFE, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x8C), 0xFFFF0000, 0x0000007F,
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0xDC), 0xFFFEFFFF, 0x00010000,
-
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFFFF7B, 0x00000084,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0xF8), 0xFFFFFFCF, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xC4), 0xFFFFFFFE, 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF0), 0x7FFFFFFD, 0x00000002,
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xF8), 0xFFFFFFCF, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0x68), 0xFFFFFF00, 0x000000FF,
- RES_PCI_IO, PCI_ADDR(0, 8, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode
-
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0x68), 0xFFFFFF00, 0x000000FF,
- RES_PCI_IO, PCI_ADDR(0, 9, 0, 0xF8), 0xFFFFFFBF, 0x00000040,//Enable bridge mode
- };
-
- static const unsigned int ctrl_conf_1_1[] = {
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x50), 0xFFFFFFFC, 0x00000003,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x64), 0xFFFFFFFE, 0x00000001,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x70), 0xFFF0FFFF, 0x00040000,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xAC), 0xFFFFF0FF, 0x00000100,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0x7C), 0xFFFFFFEF, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xC8), 0xFF00FF00, 0x000A000A,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xD0), 0xF0FFFFFF, 0x03000000,
- RES_PCI_IO, PCI_ADDR(0, 5, 0, 0xE0), 0xF0FFFFFF, 0x03000000,
- };
-
-
- static const unsigned int ctrl_conf_mcp55_only[] = {
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE0), 0xFFFFFEFF, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), 0xFFFFFFFB, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE8), 0xFFA9C8FF, 0x00003000,
-
- RES_PCI_IO, PCI_ADDR(0, 4, 0, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 4, 0, 0xF8), 0xFFFFFFCF, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 2, 0, 0x40), 0x00000000, 0xCB8410DE,
-
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x40), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x64), 0xF87FFFFF, 0x05000000,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x78), 0xFFC07FFF, 0x00360000,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x68), 0xFE00D03F, 0x013F2C00,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x70), 0xFFF7FFFF, 0x00080000,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0x7C), 0xFFFFF00F, 0x00000570,
- RES_PCI_IO, PCI_ADDR(0, 2, 1, 0xF8), 0xFFFFFFCF, 0x00000010,
-
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x04), 0xFFFFFEFB, 0x00000104,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x3C), 0xF5FFFFFF, 0x0A000000,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x40), 0x00C8FFFF, 0x07330000,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x48), 0xFFFFFFF8, 0x00000005,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x4C), 0xFE02FFFF, 0x004C0000,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0x74), 0xFFFFFFC0, 0x00000000,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC0), 0x00000000, 0xCB8410DE,
- RES_PCI_IO, PCI_ADDR(0, 6, 0, 0xC4), 0xFFFFFFF8, 0x00000007,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x78), 0xC0FFFFFF, 0x19000000,
-
-#if CONFIG_MCP55_USE_AZA
- RES_PCI_IO, PCI_ADDR(0, 6, 1, 0x40), 0x00000000, 0xCB8410DE,
-
-// RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xE4), ~(1<<14), 1<<14,
-#endif
-// play a while with GPIO in MCP55
-#ifdef MCP55_MB_SETUP
- MCP55_MB_SETUP
-#endif
-
-#if CONFIG_MCP55_USE_AZA
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 21, ~(3<<2), (2<<2),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 22, ~(3<<2), (2<<2),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 46, ~(3<<2), (2<<2),
-#endif
-
-
- };
-
- static const unsigned int ctrl_conf_master_only[] = {
-
- RES_PORT_IO_32, ACPICTRL_IO_BASE + 0x80, 0xEFFFFFF, 0x01000000,
-
- //Master MCP55 ????YHLU
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 0, ~(3<<2), (0<<2),
-
- };
-
- static const unsigned int ctrl_conf_2[] = {
- /* I didn't put pcie related stuff here */
-
- RES_PCI_IO, PCI_ADDR(0, 0, 0, 0x74), 0xFFFFF00F, 0x000009D0,
- RES_PCI_IO, PCI_ADDR(0, 1, 0, 0x74), 0xFFFF7FFF, 0x00008000,
-
- RES_PORT_IO_32, SYSCTRL_IO_BASE + 0x48, 0xFFFEFFFF, 0x00010000,
-
- RES_PORT_IO_32, ANACTRL_IO_BASE + 0x60, 0xFFFFFF00, 0x00000012,
-
-
-#if CONFIG_MCP55_USE_NIC
- RES_PCI_IO, PCI_ADDR(0, 1, 1, 0xe4), ~((1<<22)|(1<<20)), (1<<22)|(1<<20),
-
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(0<<0)),
- RES_PORT_IO_8, SYSCTRL_IO_BASE + 0xc0+ 4, ~(0xff), ((0<<4)|(1<<2)|(1<<0)),
-#endif
-
- };
-
-
- int j, i;
-
- for(j=0; j<mcp55_num; j++) {
- mcp55_early_pcie_setup(busn[j], devn[j], io_base[j] + ANACTRL_IO_BASE, pci_e_x[j]);
-
- setup_resource_map_x_offset(ctrl_conf_1, ARRAY_SIZE(ctrl_conf_1),
- PCI_DEV(busn[j], devn[j], 0), io_base[j]);
- for(i=0; i<3; i++) { // three SATA
- setup_resource_map_x_offset(ctrl_conf_1_1, ARRAY_SIZE(ctrl_conf_1_1),
- PCI_DEV(busn[j], devn[j], i), io_base[j]);
- }
- if(busn[j] == 0) {
- setup_resource_map_x_offset(ctrl_conf_mcp55_only, ARRAY_SIZE(ctrl_conf_mcp55_only),
- PCI_DEV(busn[j], devn[j], 0), io_base[j]);
- }
-
- if( (busn[j] == 0) && (mcp55_num>1) ) {
- setup_resource_map_x_offset(ctrl_conf_master_only, ARRAY_SIZE(ctrl_conf_master_only),
- PCI_DEV(busn[j], devn[j], 0), io_base[j]);
- }
-
- setup_resource_map_x_offset(ctrl_conf_2, ARRAY_SIZE(ctrl_conf_2),
- PCI_DEV(busn[j], devn[j], 0), io_base[j]);
-
- }
-
-#if 0
- for(j=0; j< mcp55_num; j++) {
- // PCI-E (XSPLL) SS table 0x40, x044, 0x48
- // SATA (SPPLL) SS table 0xb0, 0xb4, 0xb8
- // CPU (PPLL) SS table 0xc0, 0xc4, 0xc8
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0x40, io_base[j] + ANACTRL_IO_BASE+0x44,
- io_base[j] + ANACTRL_IO_BASE+0x48, pcie_ss_tbl, 64);
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xb0, io_base[j] + ANACTRL_IO_BASE+0xb4,
- io_base[j] + ANACTRL_IO_BASE+0xb8, sata_ss_tbl, 64);
- setup_ss_table(io_base[j] + ANACTRL_IO_BASE+0xc0, io_base[j] + ANACTRL_IO_BASE+0xc4,
- io_base[j] + ANACTRL_IO_BASE+0xc8, cpu_ss_tbl, 64);
- }
-#endif
-
-}
-
-#ifndef HT_CHAIN_NUM_MAX
-
-#define HT_CHAIN_NUM_MAX 4
-#define HT_CHAIN_BUSN_D 0x40
-#define HT_CHAIN_IOBASE_D 0x4000
-
-#endif
-
-static int mcp55_early_setup_x(void)
-{
- /*find out how many mcp55 we have */
- unsigned busn[HT_CHAIN_NUM_MAX] = {0};
- unsigned devn[HT_CHAIN_NUM_MAX] = {0};
- unsigned io_base[HT_CHAIN_NUM_MAX] = {0};
- /*
- FIXME: May have problem if there is different MCP55 HTX card with different PCI_E lane allocation
- Need to use same trick about pci1234 to verify node/link connection
- */
- unsigned pci_e_x[HT_CHAIN_NUM_MAX] = {CONFIG_MCP55_PCI_E_X_0, CONFIG_MCP55_PCI_E_X_1, CONFIG_MCP55_PCI_E_X_2, CONFIG_MCP55_PCI_E_X_3 };
- int mcp55_num = 0;
- unsigned busnx;
- unsigned devnx;
- int ht_c_index;
-
- /* FIXME: multi pci segment handling */
-
- /* Any system that only have IO55 without MCP55? */
- for(ht_c_index = 0; ht_c_index<HT_CHAIN_NUM_MAX; ht_c_index++) {
- busnx = ht_c_index * HT_CHAIN_BUSN_D;
- for(devnx=0;devnx<0x20;devnx++) {
- uint32_t id;
- device_t dev;
- dev = PCI_DEV(busnx, devnx, 0);
- id = pci_read_config32(dev, PCI_VENDOR_ID);
- if(id == 0x036910de) {
- busn[mcp55_num] = busnx;
- devn[mcp55_num] = devnx;
- io_base[mcp55_num] = ht_c_index * HT_CHAIN_IOBASE_D; // we may have ht chain other than MCP55
- mcp55_num++;
- if(mcp55_num == CONFIG_MCP55_NUM) goto out;
- break; // only one MCP55 on one chain
- }
- }
- }
-
-out:
- print_debug("mcp55_num:"); print_debug_hex8(mcp55_num); print_debug("\n");
-
- mcp55_early_set_port(mcp55_num, busn, devn, io_base);
- mcp55_early_setup(mcp55_num, busn, devn, io_base, pci_e_x);
-
- mcp55_early_clear_port(mcp55_num, busn, devn, io_base);
-
-// set_ht_link_mcp55(HT_CHAIN_NUM_MAX);
-
- return 0;
-
-}
-
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-static const unsigned int pcie_ss_tbl[] = {
- 0x0C504103f,
- 0x0C504103f,
- 0x0C504103f,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C504b049,
- 0x0C504b049,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5042040,
- 0x0C5042040,
-};
-static const unsigned int sata_ss_tbl[] = {
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
-};
-
-static const unsigned int cpu_ss_tbl[] = {
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
-};
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "mcp55_smbus.h"
-
-#define SMBUS0_IO_BASE 0x1000
-#define SMBUS1_IO_BASE (0x1000+(1<<8))
-/*SIZE 0x40 */
-
-static void enable_smbus(void)
-{
- device_t dev;
- dev = pci_locate_device(PCI_ID(0x10de, 0x0368), 0);
-
- if (dev == PCI_DEV_INVALID)
- die("SMBus controller not found\n");
-
- /* set smbus iobase */
- pci_write_config32(dev, 0x20, SMBUS0_IO_BASE | 1);
- pci_write_config32(dev, 0x24, SMBUS1_IO_BASE | 1);
- /* Set smbus iospace enable */
- pci_write_config16(dev, 0x4, 0x01);
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS0_IO_BASE + SMBHSTSTAT), SMBUS0_IO_BASE + SMBHSTSTAT);
- outb(inb(SMBUS1_IO_BASE + SMBHSTSTAT), SMBUS1_IO_BASE + SMBHSTSTAT);
-}
-
-static inline int smbus_recv_byte(unsigned device)
-{
- return do_smbus_recv_byte(SMBUS0_IO_BASE, device);
-}
-
-static inline int smbus_send_byte(unsigned device, unsigned char val)
-{
- return do_smbus_send_byte(SMBUS0_IO_BASE, device, val);
-}
-
-static inline int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS0_IO_BASE, device, address);
-}
-
-static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val);
-}
-
-static inline int smbusx_recv_byte(unsigned smb_index, unsigned device)
-{
- return do_smbus_recv_byte(SMBUS0_IO_BASE + (smb_index<<8), device);
-}
-
-static inline int smbusx_send_byte(unsigned smb_index, unsigned device, unsigned char val)
-{
- return do_smbus_send_byte(SMBUS0_IO_BASE + (smb_index<<8), device, val);
-}
-
-static inline int smbusx_read_byte(unsigned smb_index, unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS0_IO_BASE + (smb_index<<8), device, address);
-}
-
-static inline int smbusx_write_byte(unsigned smb_index, unsigned device, unsigned address, unsigned char val)
-{
- return do_smbus_write_byte(SMBUS0_IO_BASE + (smb_index<<8), device, address, val);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include "mcp55.h"
-
-static void mcp55_enable_rom(void)
-{
- uint8_t byte;
- uint16_t word;
- device_t addr;
-
- /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
-#if 0
- /* default MCP55 LPC single */
- addr = pci_locate_device(PCI_ID(0x10de, 0x0367), 0);
-#else
-// addr = pci_locate_device(PCI_ID(0x10de, 0x0360), 0);
- addr = PCI_DEV(0, (MCP55_DEVN_BASE+1), 0);
-#endif
-
- /* Set the 4MB enable bit bit */
- byte = pci_read_config8(addr, 0x88);
- byte |= 0xff; //256K
- pci_write_config8(addr, 0x88, byte);
- byte = pci_read_config8(addr, 0x8c);
- byte |= 0xff; //1M
- pci_write_config8(addr, 0x8c, byte);
- word = pci_read_config16(addr, 0x90);
- word |= 0x7fff; //15M
- pci_write_config16(addr, 0x90, word);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "mcp55.h"
-
-void set_debug_port(unsigned int port)
-{
- u32 dword;
- device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Write the port number to 0x74[15:12]. */
- dword = pci_read_config32(dev, 0x74);
- dword &= ~(0xf << 12);
- dword |= (port << 12);
- pci_write_config32(dev, 0x74, dword);
-}
-
-void mcp55_enable_usbdebug(unsigned int port)
-{
- device_t dev = PCI_DEV(0, MCP55_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Mark the requested physical USB port (1-15) as the Debug Port. */
- set_debug_port(port);
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- * Copyright (C) 2009 Harald Gutmann <harald.gutmann@gmx.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <string.h>
-#include <arch/acpi.h>
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci_ids.h>
-
-extern unsigned pm_base;
-
-/* Create the Fixed ACPI Description Tables (FADT) for this board. */
-void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
-{
- acpi_header_t *header = &(fadt->header);
- device_t dev;
- int is_mcp55 = 0;
- dev = dev_find_device(PCI_VENDOR_ID_NVIDIA,
- PCI_DEVICE_ID_NVIDIA_MCP55_LPC, 0);
- if (dev)
- is_mcp55 = 1;
-
- memset((void *) fadt, 0, sizeof(acpi_fadt_t));
- memcpy(header->signature, "FACP", 4);
- header->length = sizeof(acpi_fadt_t);
- header->revision = 1;
- memcpy(header->oem_id, "GBT", 6);
- memcpy(header->oem_table_id, "COREBOOT ", 8);
- memcpy(header->asl_compiler_id, "CORE", 4);
- header->asl_compiler_revision = 42;
-
- printk(BIOS_INFO, "ACPI: pm_base: %u...\n", pm_base);
-
- fadt->firmware_ctrl = (u32)facs;
- fadt->dsdt = (u32)dsdt;
- fadt->preferred_pm_profile = 1; //check
- fadt->sci_int = 9;
- /* disable system management mode by setting to 0 */
- fadt->smi_cmd = 0x0; //pm_base+0x42e; (value from proprietary acpi fadt)
- fadt->acpi_enable = 0xa1;
- fadt->acpi_disable = 0xa0;
- fadt->s4bios_req = 0x0;
- fadt->pstate_cnt = 0x0;
-
- fadt->pm1a_evt_blk = pm_base;
- fadt->pm1b_evt_blk = 0x0;
- fadt->pm1a_cnt_blk = pm_base + 0x4;
- fadt->pm1b_cnt_blk = 0x0;
- fadt->pm2_cnt_blk = pm_base + 0x1c;
- fadt->pm_tmr_blk = pm_base + 0x8;
- fadt->gpe0_blk = pm_base + 0x20;
-
- fadt->pm1_evt_len = 4;
- fadt->pm1_cnt_len = 2;
- fadt->pm2_cnt_len = 1;
- fadt->pm_tmr_len = 4;
- fadt->gpe0_blk_len = 8;
- if (is_mcp55) {
- fadt->gpe1_blk = pm_base + 0x4a0;
- fadt->gpe1_base = 0x20;
- fadt->gpe1_blk_len = 0x10;
- }
- else {
- fadt->gpe1_blk = 0x0;
- fadt->gpe1_base = 0x0;
- fadt->gpe1_blk_len = 0x0;
- }
-
- fadt->cst_cnt = 0;
- fadt->p_lvl2_lat = 0x65;
- fadt->p_lvl3_lat = 0x3e9;
- fadt->flush_size = 0;
- fadt->flush_stride = 0;
- fadt->duty_offset = 1;
- fadt->duty_width = 3;
- fadt->day_alrm = 0x7d;
- fadt->mon_alrm = 0x7e;
- fadt->century = 0x32;
-
- fadt->iapc_boot_arch = 0x0;
-
- fadt->flags = 0x4a5;
- fadt->reset_reg.space_id = 0;
- fadt->reset_reg.bit_width = 0;
- fadt->reset_reg.bit_offset = 0;
- fadt->reset_reg.resv = 0;
- fadt->reset_reg.addrl = 0x0;
- fadt->reset_reg.addrh = 0x0;
-
- fadt->reset_value = 0;
- fadt->x_firmware_ctl_l = (u32)facs;
- fadt->x_firmware_ctl_h = 0;
- fadt->x_dsdt_l = (u32)dsdt;
- fadt->x_dsdt_h = 0;
-
- fadt->x_pm1a_evt_blk.space_id = 1;
- fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1a_evt_blk.bit_offset = 0;
- fadt->x_pm1a_evt_blk.resv = 0;
- fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
- fadt->x_pm1a_evt_blk.addrh = 0x0;
-
- fadt->x_pm1b_evt_blk.space_id = 1;
- fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1b_evt_blk.bit_offset = 0;
- fadt->x_pm1b_evt_blk.resv = 0;
- fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
- fadt->x_pm1b_evt_blk.addrh = 0x0;
-
- fadt->x_pm1a_cnt_blk.space_id = 1;
- fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1a_cnt_blk.bit_offset = 0;
- fadt->x_pm1a_cnt_blk.resv = 0;
- fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
- fadt->x_pm1a_cnt_blk.addrh = 0x0;
-
- fadt->x_pm1b_cnt_blk.space_id = 1;
- fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1b_cnt_blk.bit_offset = 0;
- fadt->x_pm1b_cnt_blk.resv = 0;
- fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
- fadt->x_pm1b_cnt_blk.addrh = 0x0;
-
- fadt->x_pm2_cnt_blk.space_id = 1;
- fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
- fadt->x_pm2_cnt_blk.bit_offset = 0;
- fadt->x_pm2_cnt_blk.resv = 0;
- fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
- fadt->x_pm2_cnt_blk.addrh = 0x0;
-
- fadt->x_pm_tmr_blk.space_id = 1;
- fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
- fadt->x_pm_tmr_blk.bit_offset = 0;
- fadt->x_pm_tmr_blk.resv = 0;
- fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
- fadt->x_pm_tmr_blk.addrh = 0x0;
-
- fadt->x_gpe0_blk.space_id = 1;
- fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
- fadt->x_gpe0_blk.bit_offset = 0;
- fadt->x_gpe0_blk.resv = 0;
- fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
- fadt->x_gpe0_blk.addrh = 0x0;
-
- fadt->x_gpe1_blk.space_id = 1;
- fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
- fadt->x_gpe1_blk.bit_offset = 0;
- fadt->x_gpe1_blk.resv = 0;
- fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
- fadt->x_gpe1_blk.addrh = 0x0;
-
- header->checksum = acpi_checksum((void *) fadt, header->length);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static struct device_operations ht_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .scan_bus = 0,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver ht_driver __pci_driver = {
- .ops = &ht_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_HT,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_nvidia_mcp55_config *conf;
- /* Enable ide devices so the linux ide driver will work */
- uint32_t dword;
- uint16_t word;
- uint8_t byte;
- conf = dev->chip_info;
-
- word = pci_read_config16(dev, 0x50);
- /* Ensure prefetch is disabled */
- word &= ~((1 << 15) | (1 << 13));
- if (conf->ide1_enable) {
- /* Enable secondary ide interface */
- word |= (1<<0);
- printk(BIOS_DEBUG, "IDE1 \t");
- }
- if (conf->ide0_enable) {
- /* Enable primary ide interface */
- word |= (1<<1);
- printk(BIOS_DEBUG, "IDE0\n");
- }
-
- word |= (1<<12);
- word |= (1<<14);
-
- pci_write_config16(dev, 0x50, word);
-
-
- byte = 0x20 ; // Latency: 64-->32
- pci_write_config8(dev, 0xd, byte);
-
- dword = pci_read_config32(dev, 0xf8);
- dword |= 12;
- pci_write_config32(dev, 0xf8, dword);
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);
-#endif
-
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
-// .enable = mcp55_enable,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_IDE,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2003 SuSE Linux AG
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include <cpu/x86/lapic.h>
-#include <stdlib.h>
-#include "mcp55.h"
-
-#define NMI_OFF 0
-
-// 0x7a or e3
-#define PREVIOUS_POWER_STATE 0x7A
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-#define SLOW_CPU_OFF 0
-#define SLOW_CPU__ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-static void lpc_common_init(device_t dev, int master)
-{
- uint8_t byte;
- uint32_t ioapic_base;
-
- /* IO APIC initialization */
- byte = pci_read_config8(dev, 0x74);
- byte |= (1<<0); // enable APIC
- pci_write_config8(dev, 0x74, byte);
- ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
-
- if (master)
- setup_ioapic(ioapic_base, 0);
- else
- clear_ioapic(ioapic_base);
-}
-
-static void lpc_slave_init(device_t dev)
-{
- lpc_common_init(dev, 0);
-}
-
-static void enable_hpet(struct device *dev)
-{
- unsigned long hpet_address;
-
- pci_write_config32(dev,0x44, 0xfed00001);
- hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe;
- printk(BIOS_DEBUG, "enabling HPET @0x%lx\n", hpet_address);
-}
-
-static void lpc_init(device_t dev)
-{
- uint8_t byte;
- uint8_t byte_old;
- int on;
- int nmi_option;
-
- lpc_common_init(dev, 1);
-
-#if 0
- /* posted memory write enable */
- byte = pci_read_config8(dev, 0x46);
- pci_write_config8(dev, 0x46, byte | (1<<0));
-#endif
- /* power after power fail */
-
-#if 1
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
- byte &= ~0x40;
- if (!on) {
- byte |= 0x40;
- }
- pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
-#endif
- /* Throttle the CPU speed down for testing */
- on = SLOW_CPU_OFF;
- get_option(&on, "slow_cpu");
- if(on) {
- uint16_t pm10_bar;
- uint32_t dword;
- pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
- outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
- dword = inl(pm10_bar + 0x10);
- on = 8-on;
- printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
- (on*12)+(on>>1),(on&1)*5);
- }
-
-#if 0
-// default is enabled
- /* Enable Port 92 fast reset */
- byte = pci_read_config8(dev, 0xe8);
- byte |= ~(1 << 3);
- pci_write_config8(dev, 0xe8, byte);
-#endif
-
- /* Enable Error reporting */
- /* Set up sync flood detected */
- byte = pci_read_config8(dev, 0x47);
- byte |= (1 << 1);
- pci_write_config8(dev, 0x47, byte);
-
- /* Set up NMI on errors */
- byte = inb(0x70); // RTC70
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- } else {
- byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
- }
- if( byte != byte_old) {
- outb(byte, 0x70);
- }
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- /* Initialize the High Precision Event Timers */
- enable_hpet(dev);
-
-}
-
-static void mcp55_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal PCI resources of this device. */
- /* We got one for APIC, or one more for TRAP. */
- pci_dev_read_resources(dev);
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-/**
- * @brief Enable resources for children devices
- *
- * @param dev the device whos children's resources are to be enabled
- *
- */
-static void mcp55_lpc_enable_childrens_resources(device_t dev)
-{
- uint32_t reg, reg_var[4];
- int i;
- int var_num = 0;
- struct bus *link;
-
- reg = pci_read_config32(dev, 0xa0);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child; child = child->sibling) {
- if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for(res = child->resource_list; res; res = res->next) {
- unsigned long base, end; // don't need long long
- if(!(res->flags & IORESOURCE_IO)) continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "mcp55 lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
- switch(base) {
- case 0x3f8: // COM1
- reg |= (1<<0); break;
- case 0x2f8: // COM2
- reg |= (1<<1); break;
- case 0x378: // Parallal 1
- reg |= (1<<24); break;
- case 0x3f0: // FD0
- reg |= (1<<20); break;
- case 0x220: // Aduio 0
- reg |= (1<<8); break;
- case 0x300: // Midi 0
- reg |= (1<<12); break;
- }
- if( (base == 0x290) || (base >= 0x400)) {
- if(var_num>=4) continue; // only 4 var ; compact them ?
- reg |= (1<<(28+var_num));
- reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0xa0, reg);
- for(i=0;i<var_num;i++) {
- pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
- }
-
-
-}
-
-static void mcp55_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- mcp55_lpc_enable_childrens_resources(dev);
-}
-
-static struct device_operations lpc_ops = {
- .read_resources = mcp55_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = mcp55_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
-// .enable = mcp55_enable,
- .ops_pci = &mcp55_pci_ops,
-};
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC,
-};
-
-static const struct pci_driver lpc_driver_pro __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PRO,
-};
-
-static const struct pci_driver lpc_driver_lpc2 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_2,
-};
-static const struct pci_driver lpc_driver_lpc3 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_3,
-};
-static const struct pci_driver lpc_driver_lpc4 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_4,
-};
-static const struct pci_driver lpc_driver_lpc5 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_5,
-};
-static const struct pci_driver lpc_driver_lpc6 __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_LPC_6,
-};
-
-static struct device_operations lpc_slave_ops = {
- .read_resources = mcp55_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_slave_init,
-// .enable = mcp55_enable,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver lpc_driver_slave __pci_driver = {
- .ops = &lpc_slave_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_SLAVE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "mcp55.h"
-
-static int phy_read(u32 base, unsigned phy_addr, unsigned phy_reg)
-{
- u32 dword;
- unsigned loop = 0x100;
- write32(base+0x190, 0x8000); //Clear MDIO lock bit
- mdelay(1);
- dword = read32(base+0x190);
- if(dword & (1<<15)) return -1;
-
- write32(base+0x180, 1);
- write32(base + 0x190, (phy_addr<<5) | (phy_reg));
- do{
- dword = read32(base + 0x190);
- if(--loop==0) return -4;
- } while ((dword & (1<<15)) );
-
- dword = read32(base + 0x180);
- if(dword & 1) return -3;
-
- dword = read32(base + 0x194);
-
- return dword;
-
-}
-
-static void phy_detect(u32 base)
-{
- u32 dword;
- int i;
- int val;
- unsigned id;
- dword = read32(base+0x188);
- dword &= ~(1<<20);
- write32(base+0x188, dword);
-
- phy_read(base, 0, 1);
-
- for(i=1; i<=32; i++) {
- int phyaddr = i & 0x1f;
- val = phy_read(base, phyaddr, 1);
- if(val<0) continue;
- if((val & 0xffff) == 0xfffff) continue;
- if((val & 0xffff) == 0) continue;
- if(!(val & 1)) {
- break; // Ethernet PHY
- }
- val = phy_read(base, phyaddr, 3);
- if (val < 0 || val == 0xffff) continue;
- id = val & 0xfc00;
- val = phy_read(base, phyaddr, 2);
- if (val < 0 || val == 0xffff) continue;
- id |= ((val & 0xffff)<<16);
- printk(BIOS_DEBUG, "MCP55 MAC PHY ID 0x%08x PHY ADDR %d\n", id, i);
-// if((id == 0xe0180000) || (id==0x0032cc00))
- break;
- }
-
- if(i>32) {
- printk(BIOS_DEBUG, "MCP55 MAC PHY not found\n");
- }
-}
-
-static void nic_init(struct device *dev)
-{
- u32 mac_h, mac_l;
- int eeprom_valid = 0;
- struct southbridge_nvidia_mcp55_config *conf;
-
- static u32 nic_index = 0;
-
- u32 base;
- struct resource *res;
-
- res = find_resource(dev, 0x10);
-
- if(!res) return;
-
- base = res->base;
-
- phy_detect(base);
-
-#define NvRegPhyInterface 0xC0
-#define PHY_RGMII 0x10000000
-
- write32(base + NvRegPhyInterface, PHY_RGMII);
-
- conf = dev->chip_info;
-
- if(conf->mac_eeprom_smbus != 0) {
-// read MAC address from EEPROM at first
- struct device *dev_eeprom;
- dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr);
-
- if(dev_eeprom) {
- // if that is valid we will use that
- unsigned char dat[6];
- int status;
- int i;
- for(i=0;i<6;i++) {
- status = smbus_read_byte(dev_eeprom, i);
- if(status < 0) break;
- dat[i] = status & 0xff;
- }
- if(status >= 0) {
- mac_l = 0;
- for(i=3;i>=0;i--) {
- mac_l <<= 8;
- mac_l += dat[i];
- }
- if(mac_l != 0xffffffff) {
- mac_l += nic_index;
- mac_h = 0;
- for(i=5;i>=4;i--) {
- mac_h <<= 8;
- mac_h += dat[i];
- }
- eeprom_valid = 1;
- }
- }
- }
- }
-// if that is invalid we will read that from romstrap
- if(!eeprom_valid) {
- unsigned long mac_pos;
- mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
- mac_l = read32(mac_pos) + nic_index; // overflow?
- mac_h = read32(mac_pos + 4);
-
- }
-#if 1
-// set that into NIC MMIO
-#define NvRegMacAddrA 0xA8
-#define NvRegMacAddrB 0xAC
- write32(base + NvRegMacAddrA, mac_l);
- write32(base + NvRegMacAddrB, mac_h);
-#else
-// set that into NIC
- pci_write_config32(dev, 0xa8, mac_l);
- pci_write_config32(dev, 0xac, mac_h);
-#endif
-
- nic_index++;
-
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);// it will init option rom
-#endif
-
-}
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
-// .enable = mcp55_enable,
- .ops_pci = &mcp55_pci_ops,
-};
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_NIC,
-};
-static const struct pci_driver nic_bridge_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_NIC_BRIDGE,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/resource.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static void pci_init(struct device *dev)
-{
-
- uint32_t dword;
- uint16_t word;
- device_t pci_domain_dev;
- struct resource *mem, *pref;
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (1<<30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
-#if 1
- //only need (a01,xx]
- word = pci_read_config16(dev, 0x48);
- word |= (1<<0); /* MRL2MRM */
- word |= (1<<2); /* MR2MRM */
- pci_write_config16(dev, 0x48, word);
-#endif
-
-#if 1
- dword = pci_read_config32(dev, 0x4c);
- dword |= 0x00440000; /*TABORT_SER_ENABLE Park Last Enable.*/
- pci_write_config32(dev, 0x4c, dword);
-#endif
-
- pci_domain_dev = dev->bus->dev;
- while (pci_domain_dev) {
- if (pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN)
- break;
- pci_domain_dev = pci_domain_dev->bus->dev;
- }
-
- if (!pci_domain_dev)
- return; /* Impossible */
-
- pref = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(2,0));
- mem = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(1,0));
-
- if (!mem)
- return; /* Impossible */
-
- if (!pref || pref->base > mem->base) {
- dword = mem->base & (0xffff0000UL);
- printk(BIOS_DEBUG, "PCI DOMAIN mem base = 0x%010Lx\n", mem->base);
- } else {
- dword = pref->base & (0xffff0000UL);
- printk(BIOS_DEBUG, "PCI DOMAIN pref base = 0x%010Lx\n", pref->base);
- }
-
- printk(BIOS_DEBUG, "[0x50] <-- 0x%08x\n", dword);
- pci_write_config32(dev, 0x50, dword); /* TOM */
-}
-
-static struct device_operations pci_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pci_init,
- .scan_bus = pci_scan_bridge,
-// .enable = mcp55_enable,
- .reset_bus = pci_bus_reset,
-};
-
-static const struct pci_driver pci_driver __pci_driver = {
- .ops = &pci_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCI,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static void pcie_init(struct device *dev)
-{
-
- /* Enable pci error detecting */
- uint32_t dword;
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (1<<30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
-}
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pci_scan_bridge,
-// .enable = mcp55_enable,
-};
-
-static const struct pci_driver pciebc_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_B_C,
-};
-static const struct pci_driver pciee_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_E,
-};
-static const struct pci_driver pciea_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_A,
-};
-static const struct pci_driver pcief_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_F,
-};
-static const struct pci_driver pcied_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_D,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFFF) << 20) | \
- (((DEV) & 0x1F) << 15) | \
- (((FN) & 0x7) << 12))
-
-typedef unsigned device_t;
-
-static void pci_write_config32(device_t dev, unsigned where, unsigned value)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outl(value, 0xCFC);
-}
-
-static unsigned pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- return inl(0xCFC);
-}
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
- outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
- outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static void sata_init(struct device *dev)
-{
- uint32_t dword;
-
- struct southbridge_nvidia_mcp55_config *conf;
- conf = dev->chip_info;
-
- dword = pci_read_config32(dev, 0x50);
- /* Ensure prefetch is disabled */
- dword &= ~((1 << 15) | (1 << 13));
- if(conf) {
- if (conf->sata1_enable) {
- /* Enable secondary SATA interface */
- dword |= (1<<0);
- printk(BIOS_DEBUG, "SATA S \t");
- }
- if (conf->sata0_enable) {
- /* Enable primary SATA interface */
- dword |= (1<<1);
- printk(BIOS_DEBUG, "SATA P \n");
- }
- } else {
- dword |= (1<<1) | (1<<0);
- printk(BIOS_DEBUG, "SATA P and S \n");
- }
-
-
-#if 1
- dword &= ~(0x1f<<24);
- dword |= (0x15<<24);
-#endif
- pci_write_config32(dev, 0x50, dword);
-
- dword = pci_read_config32(dev, 0xf8);
- dword |= 2;
- pci_write_config32(dev, 0xf8, dword);
-
-
-}
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-// .enable = mcp55_enable,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_SATA0,
-};
-
-static const struct pci_driver sata1_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_SATA1,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <device/smbus.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include "mcp55.h"
-#include "mcp55_smbus.h"
-
-static int lsmbus_recv_byte(device_t dev)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_recv_byte(res->base, device);
-}
-
-static int lsmbus_send_byte(device_t dev, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_send_byte(res->base, device, val);
-}
-
-static int lsmbus_read_byte(device_t dev, uint8_t address)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_read_byte(res->base, device, address);
-}
-
-static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
-{
- unsigned device;
- struct resource *res;
- struct bus *pbus;
-
- device = dev->path.i2c.device;
- pbus = get_pbus_smbus(dev);
-
- res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
-
- return do_smbus_write_byte(res->base, device, address, val);
-}
-static struct smbus_bus_operations lops_smbus_bus = {
- .recv_byte = lsmbus_recv_byte,
- .send_byte = lsmbus_send_byte,
- .read_byte = lsmbus_read_byte,
- .write_byte = lsmbus_write_byte,
-};
-
-#if CONFIG_GENERATE_ACPI_TABLES == 1
-unsigned pm_base;
-#endif
-
-static void mcp55_sm_read_resources(device_t dev)
-{
- unsigned long index;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev);
-
- for (index = 0x60; index <= 0x68; index+=4) { // We got another 3.
- pci_get_resource(dev, index);
- }
- compact_resources(dev);
-}
-
-static void mcp55_sm_init(device_t dev)
-{
-#if CONFIG_GENERATE_ACPI_TABLES == 1
- struct resource *res;
-
- res = find_resource(dev, 0x60);
-
- if (res)
- pm_base = res->base;
-#endif
-}
-
-static struct device_operations smbus_ops = {
- .read_resources = mcp55_sm_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = mcp55_sm_init,
- .scan_bus = scan_static_bus,
-// .enable = mcp55_enable,
- .ops_pci = &mcp55_pci_ops,
- .ops_smbus_bus = &lops_smbus_bus,
-};
-static const struct pci_driver smbus_driver __pci_driver = {
- .ops = &smbus_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_SM2,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x1
-#define SMBHSTPRTCL 0x0
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x2
-#define SMBHSTDAT0 0x4
-#define SMBHSTDAT1 0x5
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100*1000*10)
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
-
- val = inb(smbus_io_base + SMBHSTSTAT);
- if ( (val & 0xff) != 0) {
- return 0;
- }
- } while(--loops);
- return -3;
-}
-static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* byte data recv */
- outb(0x05, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTCMD);
-
- if (global_status_register != 0x80) { // lose check, otherwise it should be 0
- return -1;
- }
- return byte;
-}
-static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
-{
- unsigned global_status_register;
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* set the command... */
- outb(val, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* set up for a byte data write */
- outb(0x04, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
-
- if (global_status_register != 0x80) {
- return -1;
- }
- return 0;
-}
-static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
- smbus_delay();
- /* set the command/address... */
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- smbus_delay();
- /* byte data read */
- outb(0x07, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTDAT0);
-
- if (global_status_register != 0x80) { // lose check, otherwise it should be 0
- return -1;
- }
- return byte;
-}
-
-
-static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
-{
- unsigned global_status_register;
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* set up for a byte data write */
- outb(0x06, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
-
- if (global_status_register != 0x80) {
- return -1;
- }
- return 0;
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
-// .enable = mcp55_enable,
- .scan_bus = 0,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver usb_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_USB,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "mcp55.h"
-#include <usbdebug.h>
-
-extern struct ehci_debug_info dbg_info;
-
-static void usb2_init(struct device *dev)
-{
- uint32_t dword;
- dword = pci_read_config32(dev, 0xf8);
- dword |= 40;
- pci_write_config32(dev, 0xf8, dword);
-}
-
-static void usb2_set_resources(struct device *dev)
-{
-#if CONFIG_USBDEBUG
- struct resource *res;
- unsigned base;
- unsigned old_debug;
-
- old_debug = get_ehci_debug();
- set_ehci_debug(0);
-#endif
- pci_dev_set_resources(dev);
-
-#if CONFIG_USBDEBUG
- res = find_resource(dev, 0x10);
- set_ehci_debug(old_debug);
- if (!res) return;
- base = res->base;
- set_ehci_base(base);
- report_resource_stored(dev, res, "");
-#endif
-
-}
-
-static struct device_operations usb2_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb2_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb2_init,
-// .enable = mcp55_enable,
- .scan_bus = 0,
- .ops_pci = &mcp55_pci_ops,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb2_ops,
- .vendor = PCI_VENDOR_ID_NVIDIA,
- .device = PCI_DEVICE_ID_NVIDIA_MCP55_USB2,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "mcp55.h"
+
+static int phy_read(u32 base, unsigned phy_addr, unsigned phy_reg)
+{
+ u32 dword;
+ unsigned loop = 0x100;
+ write32(base+0x190, 0x8000); //Clear MDIO lock bit
+ mdelay(1);
+ dword = read32(base+0x190);
+ if(dword & (1<<15)) return -1;
+
+ write32(base+0x180, 1);
+ write32(base + 0x190, (phy_addr<<5) | (phy_reg));
+ do{
+ dword = read32(base + 0x190);
+ if(--loop==0) return -4;
+ } while ((dword & (1<<15)) );
+
+ dword = read32(base + 0x180);
+ if(dword & 1) return -3;
+
+ dword = read32(base + 0x194);
+
+ return dword;
+
+}
+
+static void phy_detect(u32 base)
+{
+ u32 dword;
+ int i;
+ int val;
+ unsigned id;
+ dword = read32(base+0x188);
+ dword &= ~(1<<20);
+ write32(base+0x188, dword);
+
+ phy_read(base, 0, 1);
+
+ for(i=1; i<=32; i++) {
+ int phyaddr = i & 0x1f;
+ val = phy_read(base, phyaddr, 1);
+ if(val<0) continue;
+ if((val & 0xffff) == 0xfffff) continue;
+ if((val & 0xffff) == 0) continue;
+ if(!(val & 1)) {
+ break; // Ethernet PHY
+ }
+ val = phy_read(base, phyaddr, 3);
+ if (val < 0 || val == 0xffff) continue;
+ id = val & 0xfc00;
+ val = phy_read(base, phyaddr, 2);
+ if (val < 0 || val == 0xffff) continue;
+ id |= ((val & 0xffff)<<16);
+ printk(BIOS_DEBUG, "MCP55 MAC PHY ID 0x%08x PHY ADDR %d\n", id, i);
+// if((id == 0xe0180000) || (id==0x0032cc00))
+ break;
+ }
+
+ if(i>32) {
+ printk(BIOS_DEBUG, "MCP55 MAC PHY not found\n");
+ }
+}
+
+static void nic_init(struct device *dev)
+{
+ u32 mac_h, mac_l;
+ int eeprom_valid = 0;
+ struct southbridge_nvidia_mcp55_config *conf;
+
+ static u32 nic_index = 0;
+
+ u32 base;
+ struct resource *res;
+
+ res = find_resource(dev, 0x10);
+
+ if(!res) return;
+
+ base = res->base;
+
+ phy_detect(base);
+
+#define NvRegPhyInterface 0xC0
+#define PHY_RGMII 0x10000000
+
+ write32(base + NvRegPhyInterface, PHY_RGMII);
+
+ conf = dev->chip_info;
+
+ if(conf->mac_eeprom_smbus != 0) {
+// read MAC address from EEPROM at first
+ struct device *dev_eeprom;
+ dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr);
+
+ if(dev_eeprom) {
+ // if that is valid we will use that
+ unsigned char dat[6];
+ int status;
+ int i;
+ for(i=0;i<6;i++) {
+ status = smbus_read_byte(dev_eeprom, i);
+ if(status < 0) break;
+ dat[i] = status & 0xff;
+ }
+ if(status >= 0) {
+ mac_l = 0;
+ for(i=3;i>=0;i--) {
+ mac_l <<= 8;
+ mac_l += dat[i];
+ }
+ if(mac_l != 0xffffffff) {
+ mac_l += nic_index;
+ mac_h = 0;
+ for(i=5;i>=4;i--) {
+ mac_h <<= 8;
+ mac_h += dat[i];
+ }
+ eeprom_valid = 1;
+ }
+ }
+ }
+ }
+// if that is invalid we will read that from romstrap
+ if(!eeprom_valid) {
+ unsigned long mac_pos;
+ mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
+ mac_l = read32(mac_pos) + nic_index; // overflow?
+ mac_h = read32(mac_pos + 4);
+
+ }
+#if 1
+// set that into NIC MMIO
+#define NvRegMacAddrA 0xA8
+#define NvRegMacAddrB 0xAC
+ write32(base + NvRegMacAddrA, mac_l);
+ write32(base + NvRegMacAddrB, mac_h);
+#else
+// set that into NIC
+ pci_write_config32(dev, 0xa8, mac_l);
+ pci_write_config32(dev, 0xac, mac_h);
+#endif
+
+ nic_index++;
+
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);// it will init option rom
+#endif
+
+}
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+// .enable = mcp55_enable,
+ .ops_pci = &mcp55_pci_ops,
+};
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_NIC,
+};
+static const struct pci_driver nic_bridge_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_NIC_BRIDGE,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/resource.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static void pci_init(struct device *dev)
+{
+
+ uint32_t dword;
+ uint16_t word;
+ device_t pci_domain_dev;
+ struct resource *mem, *pref;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+#if 1
+ //only need (a01,xx]
+ word = pci_read_config16(dev, 0x48);
+ word |= (1<<0); /* MRL2MRM */
+ word |= (1<<2); /* MR2MRM */
+ pci_write_config16(dev, 0x48, word);
+#endif
+
+#if 1
+ dword = pci_read_config32(dev, 0x4c);
+ dword |= 0x00440000; /*TABORT_SER_ENABLE Park Last Enable.*/
+ pci_write_config32(dev, 0x4c, dword);
+#endif
+
+ pci_domain_dev = dev->bus->dev;
+ while (pci_domain_dev) {
+ if (pci_domain_dev->path.type == DEVICE_PATH_PCI_DOMAIN)
+ break;
+ pci_domain_dev = pci_domain_dev->bus->dev;
+ }
+
+ if (!pci_domain_dev)
+ return; /* Impossible */
+
+ pref = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(2,0));
+ mem = probe_resource(pci_domain_dev, IOINDEX_SUBTRACTIVE(1,0));
+
+ if (!mem)
+ return; /* Impossible */
+
+ if (!pref || pref->base > mem->base) {
+ dword = mem->base & (0xffff0000UL);
+ printk(BIOS_DEBUG, "PCI DOMAIN mem base = 0x%010Lx\n", mem->base);
+ } else {
+ dword = pref->base & (0xffff0000UL);
+ printk(BIOS_DEBUG, "PCI DOMAIN pref base = 0x%010Lx\n", pref->base);
+ }
+
+ printk(BIOS_DEBUG, "[0x50] <-- 0x%08x\n", dword);
+ pci_write_config32(dev, 0x50, dword); /* TOM */
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+// .enable = mcp55_enable,
+ .reset_bus = pci_bus_reset,
+};
+
+static const struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCI,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static void pcie_init(struct device *dev)
+{
+
+ /* Enable pci error detecting */
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+}
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+// .enable = mcp55_enable,
+};
+
+static const struct pci_driver pciebc_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_B_C,
+};
+static const struct pci_driver pciee_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_E,
+};
+static const struct pci_driver pciea_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_A,
+};
+static const struct pci_driver pcief_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_F,
+};
+static const struct pci_driver pcied_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_PCIE_D,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static void sata_init(struct device *dev)
+{
+ uint32_t dword;
+
+ struct southbridge_nvidia_mcp55_config *conf;
+ conf = dev->chip_info;
+
+ dword = pci_read_config32(dev, 0x50);
+ /* Ensure prefetch is disabled */
+ dword &= ~((1 << 15) | (1 << 13));
+ if(conf) {
+ if (conf->sata1_enable) {
+ /* Enable secondary SATA interface */
+ dword |= (1<<0);
+ printk(BIOS_DEBUG, "SATA S \t");
+ }
+ if (conf->sata0_enable) {
+ /* Enable primary SATA interface */
+ dword |= (1<<1);
+ printk(BIOS_DEBUG, "SATA P \n");
+ }
+ } else {
+ dword |= (1<<1) | (1<<0);
+ printk(BIOS_DEBUG, "SATA P and S \n");
+ }
+
+
+#if 1
+ dword &= ~(0x1f<<24);
+ dword |= (0x15<<24);
+#endif
+ pci_write_config32(dev, 0x50, dword);
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 2;
+ pci_write_config32(dev, 0xf8, dword);
+
+
+}
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = mcp55_enable,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_SATA0,
+};
+
+static const struct pci_driver sata1_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_SATA1,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include "mcp55.h"
+#include "smbus.h"
+
+static int lsmbus_recv_byte(device_t dev)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_recv_byte(res->base, device);
+}
+
+static int lsmbus_send_byte(device_t dev, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_send_byte(res->base, device, val);
+}
+
+static int lsmbus_read_byte(device_t dev, uint8_t address)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static int lsmbus_write_byte(device_t dev, uint8_t address, uint8_t val)
+{
+ unsigned device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.i2c.device;
+ pbus = get_pbus_smbus(dev);
+
+ res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
+
+ return do_smbus_write_byte(res->base, device, address, val);
+}
+static struct smbus_bus_operations lops_smbus_bus = {
+ .recv_byte = lsmbus_recv_byte,
+ .send_byte = lsmbus_send_byte,
+ .read_byte = lsmbus_read_byte,
+ .write_byte = lsmbus_write_byte,
+};
+
+#if CONFIG_GENERATE_ACPI_TABLES == 1
+unsigned pm_base;
+#endif
+
+static void mcp55_sm_read_resources(device_t dev)
+{
+ unsigned long index;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ for (index = 0x60; index <= 0x68; index+=4) { // We got another 3.
+ pci_get_resource(dev, index);
+ }
+ compact_resources(dev);
+}
+
+static void mcp55_sm_init(device_t dev)
+{
+#if CONFIG_GENERATE_ACPI_TABLES == 1
+ struct resource *res;
+
+ res = find_resource(dev, 0x60);
+
+ if (res)
+ pm_base = res->base;
+#endif
+}
+
+static struct device_operations smbus_ops = {
+ .read_resources = mcp55_sm_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = mcp55_sm_init,
+ .scan_bus = scan_static_bus,
+// .enable = mcp55_enable,
+ .ops_pci = &mcp55_pci_ops,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+static const struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_SM2,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x1
+#define SMBHSTPRTCL 0x0
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x2
+#define SMBHSTDAT0 0x4
+#define SMBHSTDAT1 0x5
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ if ( (val & 0xff) != 0) {
+ return 0;
+ }
+ } while(--loops);
+ return -3;
+}
+static int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* byte data recv */
+ outb(0x05, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ if (global_status_register != 0x80) { // lose check, otherwise it should be 0
+ return -1;
+ }
+ return byte;
+}
+static int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
+{
+ unsigned global_status_register;
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x04, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
+static int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
+ smbus_delay();
+ /* set the command/address... */
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+ /* byte data read */
+ outb(0x07, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+
+ if (global_status_register != 0x80) { // lose check, otherwise it should be 0
+ return -1;
+ }
+ return byte;
+}
+
+
+static int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+ unsigned global_status_register;
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x06, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+// .enable = mcp55_enable,
+ .scan_bus = 0,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_USB,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "mcp55.h"
+#include <usbdebug.h>
+
+extern struct ehci_debug_info dbg_info;
+
+static void usb2_init(struct device *dev)
+{
+ uint32_t dword;
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 40;
+ pci_write_config32(dev, 0xf8, dword);
+}
+
+static void usb2_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+ struct resource *res;
+ unsigned base;
+ unsigned old_debug;
+
+ old_debug = get_ehci_debug();
+ set_ehci_debug(0);
+#endif
+ pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+ res = find_resource(dev, 0x10);
+ set_ehci_debug(old_debug);
+ if (!res) return;
+ base = res->base;
+ set_ehci_base(base);
+ report_resource_stored(dev, res, "");
+#endif
+
+}
+
+static struct device_operations usb2_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb2_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb2_init,
+// .enable = mcp55_enable,
+ .scan_bus = 0,
+ .ops_pci = &mcp55_pci_ops,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_NVIDIA,
+ .device = PCI_DEVICE_ID_NVIDIA_MCP55_USB2,
+};
driver-y += sis761.c
driver-y += sis966.c
-driver-y += sis966_lpc.c
-driver-y += sis966_ide.c
-driver-y += sis966_usb.c
-driver-y += sis966_usb2.c
-driver-y += sis966_nic.c
-driver-y += sis966_sata.c
-driver-y += sis966_pcie.c
-driver-y += sis966_aza.c
-ramstage-y += sis966_reset.c
-romstage-y += sis966_enable_usbdebug.c
+driver-y += lpc.c
+driver-y += ide.c
+driver-y += usb.c
+driver-y += usb2.c
+driver-y += nic.c
+driver-y += sata.c
+driver-y += pcie.c
+driver-y += aza.c
+ramstage-y += reset.c
+romstage-y += enable_usbdebug.c
chipset_bootblock_inc += $(src)/southbridge/sis/sis966/romstrap.inc
chipset_bootblock_lds += $(src)/southbridge/sis/sis966/romstrap.lds
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "sis966.h"
+
+u8 SiS_SiS7502_init[7][3]={
+{0x04, 0xFF, 0x07},
+{0x2C, 0xFF, 0x39},
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x91},
+{0x2F, 0xFF, 0x01},
+{0x04, 0xFF, 0x06},
+{0x00, 0x00, 0x00} //End of table
+};
+
+static int set_bits(u32 port, u32 mask, u32 val)
+{
+ u32 dword;
+ int count;
+
+ val &= mask;
+ dword = read32(port);
+ dword &= ~mask;
+ dword |= val;
+ write32(port, dword);
+
+ count = 50;
+ do {
+ dword = read32(port);
+ dword &= mask;
+ udelay(100);
+ } while ((dword != val) && --count);
+
+ if(!count) return -1;
+
+ udelay(500);
+ return 0;
+
+}
+
+static u32 send_verb(u32 base, u32 verb)
+{
+ u32 dword;
+
+ dword = read32(base + 0x68);
+ dword=dword|(unsigned long)0x0002;
+ write32(base + 0x68, dword);
+ do {
+ dword = read32(base + 0x68);
+ } while ((dword & 1)!=0);
+ write32(base + 0x60, verb);
+ udelay(500);
+ dword = read32(base + 0x68);
+ dword =(dword |0x1);
+ write32(base + 0x68, dword);
+ do {
+ udelay(100);
+ dword = read32(base + 0x68);
+ } while ((dword & 3) != 2);
+
+ dword = read32(base + 0x64);
+ return dword;
+}
+
+
+static int codec_detect(u32 base)
+{
+ u32 dword;
+ int idx=0;
+
+ /* 1 */ // controller reset
+ printk(BIOS_DEBUG, "controller reset\n");
+
+ set_bits(base + 0x08, 1, 1);
+
+ do{
+ dword = read32(base + 0x08)&0x1;
+ if(idx++>1000) { printk(BIOS_DEBUG, "controller reset fail !!! \n"); break;}
+ } while (dword !=1);
+
+ dword=send_verb(base,0x000F0000); // get codec VendorId and DeviceId
+
+ if(dword==0) {
+ printk(BIOS_DEBUG, "No codec!\n");
+ return 0;
+ }
+
+ printk(BIOS_DEBUG, "Codec ID = %x\n", dword);
+
+ dword=0x1;
+ return dword;
+
+}
+
+
+static u32 verb_data[] = {
+
+//14
+ 0x01471c10,
+ 0x01471d40,
+ 0x01471e01,
+ 0x01471f01,
+//15
+ 0x01571c12,
+ 0x01571d10,
+ 0x01571e01,
+ 0x01571f01,
+//16
+ 0x01671c11,
+ 0x01671d60,
+ 0x01671e01,
+ 0x01671f01,
+//17
+ 0x01771c14,
+ 0x01771d20,
+ 0x01771e01,
+ 0x01771f01,
+//18
+ 0x01871c40,
+ 0x01871d98,
+ 0x01871ea1,
+ 0x01871f01,
+//19
+ 0x01971c50,
+ 0x01971d98,
+ 0x01971ea1,
+ 0x01971f02,
+//1a
+ 0x01a71c4f,
+ 0x01a71d30,
+ 0x01a71e81,
+ 0x01a71f01,
+//1b
+ 0x01b71c20,
+ 0x01b71d40,
+ 0x01b71e01,
+ 0x01b71f02,
+//1c
+ 0x01c71cf0,
+ 0x01c71d01,
+ 0x01c71e33,
+ 0x01c71f59,
+//1d
+ 0x01d71c01,
+ 0x01d71de6,
+ 0x01d71e05,
+ 0x01d71f40,
+//1e
+ 0x01e71c30,
+ 0x01e71d11,
+ 0x01e71e44,
+ 0x01e71f01,
+//1f
+ 0x01f71c60,
+ 0x01f71d61,
+ 0x01f71ec4,
+ 0x01f71f01,
+};
+
+static unsigned find_verb(u32 viddid, u32 **verb)
+{
+ if((viddid == 0x10ec0883) || (viddid == 0x10ec0882) || (viddid == 0x10ec0880)) return 0;
+ *verb = (u32 *)verb_data;
+ return sizeof(verb_data)/sizeof(u32);
+}
+
+
+static void codec_init(u32 base, int addr)
+{
+ u32 dword;
+ u32 *verb;
+ unsigned verb_size;
+ int i;
+
+ /* 1 */
+ do {
+ dword = read32(base + 0x68);
+ } while (dword & 1);
+
+ dword = (addr<<28) | 0x000f0000;
+ write32(base + 0x60, dword);
+
+ do {
+ dword = read32(base + 0x68);
+ } while ((dword & 3)!=2);
+
+ dword = read32(base + 0x64);
+
+ /* 2 */
+ printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
+ verb_size = find_verb(dword, &verb);
+
+ if(!verb_size) {
+ printk(BIOS_DEBUG, "No verb!\n");
+ return;
+ }
+
+ printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
+ /* 3 */
+ for(i=0; i<verb_size; i++) {
+ send_verb(base,verb[i]);
+ }
+ printk(BIOS_DEBUG, "verb loaded!\n");
+}
+
+static void codecs_init(u32 base, u32 codec_mask)
+{
+ codec_init(base, 0);
+ return;
+}
+
+static void aza_init(struct device *dev)
+{
+ u32 base;
+ struct resource *res;
+ u32 codec_mask;
+
+ print_debug("AZALIA_INIT:---------->\n");
+
+//-------------- enable AZA (SiS7502) -------------------------
+{
+ u8 temp8;
+ int i=0;
+ while(SiS_SiS7502_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_SiS7502_init[i][0]);
+ temp8 &= SiS_SiS7502_init[i][1];
+ temp8 |= SiS_SiS7502_init[i][2];
+ pci_write_config8(dev, SiS_SiS7502_init[i][0], temp8);
+ i++;
+ };
+}
+//-----------------------------------------------------------
+
+
+ // put audio to D0 state
+ pci_write_config8(dev, 0x54,0x00);
+
+#if DEBUG_AZA
+{
+ int i;
+
+ print_debug("****** Azalia PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+#endif
+
+ res = find_resource(dev, 0x10);
+ if(!res)
+ return;
+
+ base = res->base;
+ printk(BIOS_DEBUG, "base = 0x%08x\n", base);
+
+ codec_mask = codec_detect(base);
+
+ if(codec_mask) {
+ printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
+ codecs_init(base, codec_mask);
+ }
+
+ print_debug("AZALIA_INIT:<----------\n");
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations aza_audio_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = sis966_enable,
+ .init = aza_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver azaaudio_driver __pci_driver = {
+ .ops = &aza_audio_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_HD_AUDIO,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <reset.h>
+
+static unsigned get_sbdn(unsigned bus)
+{
+ device_t dev;
+
+ /* Find the device. */
+ dev = pci_locate_device_on_bus(
+ PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761),
+ bus);
+
+ return (dev>>15) & 0x1f;
+}
+
+void hard_reset(void)
+{
+ set_bios_reset();
+
+ /* full reset */
+ outb(0x0a, 0x0cf9);
+ outb(0x0e, 0x0cf9);
+}
+
+static void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
+{
+ /* default value for sis966 is good */
+ /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
+}
+
+void soft_reset(void)
+{
+ set_bios_reset();
+
+ /* link reset */
+ outb(0x02, 0x0cf9);
+ outb(0x06, 0x0cf9);
+
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+void sis966_early_pcie_setup(unsigned busnx, unsigned devnx, unsigned anactrl_io_base, unsigned pci_e_x)
+{
+ uint32_t tgio_ctrl;
+ uint32_t pll_ctrl;
+ uint32_t dword;
+ int i;
+ device_t dev;
+ dev = PCI_DEV(busnx, devnx+1, 1);
+ dword = pci_read_config32(dev, 0xe4);
+ dword |= 0x3f0; // disable it at first
+ pci_write_config32(dev, 0xe4, dword);
+
+ for(i=0; i<3; i++) {
+ tgio_ctrl = inl(anactrl_io_base + 0xcc);
+ tgio_ctrl &= ~(3<<9);
+ tgio_ctrl |= (i<<9);
+ outl(tgio_ctrl, anactrl_io_base + 0xcc);
+ pll_ctrl = inl(anactrl_io_base + 0x30);
+ pll_ctrl |= (1<<31);
+ outl(pll_ctrl, anactrl_io_base + 0x30);
+ do {
+ pll_ctrl = inl(anactrl_io_base + 0x30);
+ } while (!(pll_ctrl & 1));
+ }
+ tgio_ctrl = inl(anactrl_io_base + 0xcc);
+ tgio_ctrl &= ~((7<<4)|(1<<8));
+ tgio_ctrl |= (pci_e_x<<4)|(1<<8);
+ outl(tgio_ctrl, anactrl_io_base + 0xcc);
+
+// wait 100us
+ udelay(100);
+
+ dword = pci_read_config32(dev, 0xe4);
+ dword &= ~(0x3f0); // enable
+ pci_write_config32(dev, 0xe4, dword);
+
+// need to wait 100ms
+ mdelay(100);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+static const unsigned int pcie_ss_tbl[] = {
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C504103f,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5042040,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C504b049,
+ 0x0C504b049,
+ 0x0C504a048,
+ 0x0C504a048,
+ 0x0C5049047,
+ 0x0C5049047,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5048046,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5047045,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5046044,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5045043,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5044042,
+ 0x0C5043041,
+ 0x0C5043041,
+ 0x0C5042040,
+ 0x0C5042040,
+};
+static const unsigned int sata_ss_tbl[] = {
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904b049,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c904a048,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9049047,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9048046,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9047045,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9046044,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9045043,
+ 0x0c9044042,
+ 0x0c9044042,
+ 0x0c9044042,
+};
+
+static const unsigned int cpu_ss_tbl[] = {
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5034032,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5035033,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5036034,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5037035,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5038036,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503b039,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C503a038,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+ 0x0C5039037,
+};
+
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "smbus.h"
+
+#define SMBUS0_IO_BASE 0x8D0
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+int smbus_wait_until_ready(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(smbus_io_base + SMBHSTSTAT);
+ val &= 0x1f;
+ if (val == 0) {
+ return 0;
+ }
+ outb(val,smbus_io_base + SMBHSTSTAT);
+ } while(--loops);
+ return -2;
+}
+
+int smbus_wait_until_done(unsigned smbus_io_base)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(smbus_io_base + 0x00);
+ if ( (val & 0xff) != 0x02) {
+ return 0;
+ }
+ } while(--loops);
+ return -3;
+}
+
+int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* byte data recv */
+ outb(0x05, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTCMD);
+
+ if (global_status_register != 0x80) { // lose check, otherwise it should be 0
+ return -1;
+ }
+ return byte;
+}
+
+int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
+{
+ unsigned global_status_register;
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the command... */
+ outb(val, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x04, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
+
+static inline int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ outb(0xff, smbus_io_base + 0x00);
+ smbus_delay();
+ outb(0x20, smbus_io_base + 0x03);
+ smbus_delay();
+
+ outb(((device & 0x7f) << 1)|1 , smbus_io_base + 0x04);
+ smbus_delay();
+ outb(address & 0xff, smbus_io_base + 0x05);
+ smbus_delay();
+ outb(0x12, smbus_io_base + 0x03);
+ smbus_delay();
+
+int i,j;
+for(i=0;i<0x1000;i++)
+{
+ if (inb(smbus_io_base + 0x00) != 0x08)
+ { smbus_delay();
+ for(j=0;j<0xFFFF;j++);
+ }
+};
+
+ global_status_register = inb(smbus_io_base + 0x00);
+ byte = inb(smbus_io_base + 0x08);
+
+ if (global_status_register != 0x08) { // lose check, otherwise it should be 0
+ print_debug("Fail");print_debug("\r\t");
+ return -1;
+ }
+ print_debug("Success");print_debug("\r\t");
+ return byte;
+}
+
+
+static inline int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
+{
+ unsigned global_status_register;
+
+ outb(val, smbus_io_base + SMBHSTDAT0);
+ smbus_delay();
+
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
+ smbus_delay();
+
+ outb(address & 0xff, smbus_io_base + SMBHSTCMD);
+ smbus_delay();
+
+ /* set up for a byte data write */
+ outb(0x06, smbus_io_base + SMBHSTPRTCL);
+ smbus_delay();
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return -3;
+ }
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
+
+ if (global_status_register != 0x80) {
+ return -1;
+ }
+ return 0;
+}
+
+
+
+static const uint8_t SiS_LPC_init[34][3]={
+{0x04, 0xF8, 0x07}, //Reg 0x04
+{0x45, 0x00, 0x00}, //Reg 0x45 //Enable Rom Flash
+{0x46, 0x00, 0x3D}, //Reg 0x46
+{0x47, 0x00, 0xDD}, //Reg 0x47
+{0x48, 0x00, 0x12}, //Reg 0x48
+{0x64, 0x00, 0xFF}, //Reg 0x64
+{0x65, 0x00, 0xC1}, //Reg 0x65
+{0x68, 0x00, 0x89}, //Reg 0x68 //SB.ASM, START POST
+{0x69, 0x00, 0x80}, //Reg 0x69
+{0x6B, 0x00, 0x00}, //Reg 0x6B //SBBB.ASM
+{0x6C, 0xFF, 0x97}, //Reg 0x6C //SBBB.ASM
+{0x6E, 0x00, 0x00}, //Reg 0x6E //SBBB.ASM But in Early Post sets 0x04.
+{0x6F, 0xFF, 0x14}, //Reg 0x6F //SBBB.ASM
+{0x77, 0x00, 0x0E}, //Reg 0x77 //SBOEM.ASM, EARLY POST
+{0x78, 0x00, 0x20}, //Reg 0x78
+{0x7B, 0x00, 0x88}, //Reg 0x7B
+{0x7F, 0x00, 0x40}, //Reg 0x7F //SBOEM.ASM, EARLY POST
+{0xC1, 0x00, 0xF0}, //Reg 0xC1
+{0xC2, 0x00, 0x01}, //Reg 0xC2
+{0xC3, 0x00, 0x00}, //Reg 0xC3 //NBAGPBB.ASM
+{0xC9, 0x00, 0x80}, //Reg 0xC9
+{0xCF, 0x00, 0x45}, //Reg 0xCF
+{0xD0, 0x00, 0x02}, //Reg 0xD0
+{0xD4, 0x00, 0x44}, //Reg 0xD4
+{0xD5, 0x00, 0x62}, //Reg 0xD5
+{0xD6, 0x00, 0x32}, //Reg 0xD6
+{0xD8, 0x00, 0x45}, //Reg 0xD8
+{0xDA, 0x00, 0xDA}, //Reg 0xDA
+{0xDB, 0x00, 0x61}, //Reg 0xDB
+{0xDC, 0x00, 0xAA}, //Reg 0xDC
+{0xDD, 0x00, 0xAA}, //Reg 0xDD
+{0xDE, 0x00, 0xAA}, //Reg 0xDE
+{0xDF, 0x00, 0xAA}, //Reg 0xDF
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_NBPCIE_init[43][3]={
+{0x3D, 0x00, 0x00}, //Reg 0x3D
+{0x1C, 0xFE, 0x01}, //Reg 0x1C
+{0x1D, 0xFE, 0x01}, //Reg 0x1D
+{0x24, 0xFE, 0x01}, //Reg 0x24
+{0x26, 0xFE, 0x01}, //Reg 0x26
+{0x40, 0xFF, 0x10}, //Reg 0x40
+{0x43, 0xFF, 0x78}, //Reg 0x43
+{0x44, 0xFF, 0x02}, //Reg 0x44
+{0x45, 0xFF, 0x10}, //Reg 0x45
+{0x48, 0xFF, 0x52}, //Reg 0x48
+{0x49, 0xFF, 0xE3}, //Reg 0x49
+{0x5A, 0x00, 0x00}, //Reg 0x4A
+{0x4B, 0x00, 0x16}, //Reg 0x4B
+{0x4C, 0x00, 0x80}, //Reg 0x4C
+{0x4D, 0x00, 0x02}, //Reg 0x4D
+{0x4E, 0x00, 0x00}, //Reg 0x4E
+{0x5C, 0x00, 0x52}, //Reg 0x5C
+{0x5E, 0x00, 0x10}, //Reg 0x5E
+{0x34, 0x00, 0xD0}, //Reg 0x34
+{0xD0, 0x00, 0x01}, //Reg 0xD0
+{0x4F, 0x00, 0x80}, //Reg 0x4F
+{0xA1, 0x00, 0xF4}, //Reg 0xA1
+{0xA2, 0x7F, 0x00}, //Reg 0xA2
+{0xBD, 0x00, 0xA0}, //Reg 0xBD
+{0xD1, 0xFF, 0x00}, //Reg 0xD1
+{0xD3, 0xFE, 0x01}, //Reg 0xD3
+{0xD4, 0x18, 0x20}, //Reg 0xD4
+{0xD5, 0xF0, 0x00}, //Reg 0xD5
+{0xDD, 0xFF, 0x00}, //Reg 0xDD
+{0xDE, 0xEC, 0x10}, //Reg 0xDE
+{0xDF, 0xFF, 0x00}, //Reg 0xDF
+{0xE0, 0xF7, 0x00}, //Reg 0xE0
+{0xE3, 0xEF, 0x10}, //Reg 0xE3
+{0xE4, 0x7F, 0x80}, //Reg 0xE4
+{0xE5, 0xFF, 0x00}, //Reg 0xE5
+{0xE6, 0x06, 0x00}, //Reg 0xE6
+{0xE7, 0xFF, 0x00}, //Reg 0xE7
+{0xF5, 0x00, 0x00}, //Reg 0xF5
+{0xF6, 0x3F, 0x00}, //Reg 0xF6
+{0xF7, 0xFF, 0x00}, //Reg 0xF7
+{0xFD, 0xFF, 0x00}, //Reg 0xFD
+{0x4F, 0x00, 0x00}, //Reg 0x4F
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_ACPI_init[10][3]={
+{0x1B, 0xBF, 0x40}, //Reg 0x1B
+{0x84, 0x00, 0x0E}, //Reg 0x84
+{0x85, 0x00, 0x29}, //Reg 0x85
+{0x86, 0x00, 0xCB}, //Reg 0x86
+{0x87, 0x00, 0x55}, //Reg 0x87
+{0x6B, 0x00, 0x00}, //Reg 0x6B
+{0x6C, 0x68, 0x97}, //Reg 0x6C
+{0x6E, 0x00, 0x00}, //Reg 0x6E
+{0x6F, 0xFF, 0x14}, //Reg 0x6F
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_SBPCIE_init[13][3]={
+{0x48, 0x00 ,0x07}, //Reg 0x48
+{0x49, 0x00 ,0x06}, //Reg 0x49
+{0x4A, 0x00 ,0x0C}, //Reg 0x4A
+{0x4B, 0x00 ,0x00}, //Reg 0x4B
+{0x4E, 0x00 ,0x20}, //Reg 0x4E
+{0x1C, 0x00 ,0xF1}, //Reg 0x1C
+{0x1D, 0x00 ,0x01}, //Reg 0x1D
+{0x24, 0x00 ,0x01}, //Reg 0x24
+{0x26, 0x00 ,0x01}, //Reg 0x26
+{0xF6, 0x00 ,0x02}, //Reg 0xF6
+{0xF7, 0x00 ,0xC8}, //Reg 0xF7
+{0x5B, 0x00 ,0x40}, //Reg 0x5B
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_NB_init[56][3]={
+{0x04, 0x00 ,0x07}, //Reg 0x04
+{0x05, 0x00 ,0x00}, //Reg 0x05 // alex
+{0x0D, 0x00 ,0x20}, //Reg 0x0D
+{0x2C, 0x00 ,0x39}, //Reg 0x2C
+{0x2D, 0x00 ,0x10}, //Reg 0x2D
+{0x2E, 0x00 ,0x61}, //Reg 0x2E
+{0x2F, 0x00 ,0x07}, //Reg 0x2F
+{0x34, 0x00 ,0xA0}, //Reg 0x34
+{0x40, 0x00 ,0x36}, //Reg 0x40
+{0x42, 0x00 ,0xB9}, //Reg 0x42
+{0x43, 0x00 ,0x8B}, //Reg 0x43
+{0x44, 0x00 ,0x05}, //Reg 0x44
+{0x45, 0x00 ,0xFF}, //Reg 0x45
+{0x46, 0x00 ,0x90}, //Reg 0x46
+{0x47, 0x00 ,0xA0}, //Reg 0x47
+//{0x4C, 0xFF ,0x09}, //Reg 0x4C // SiS307 enable
+{0x4E, 0x00 ,0x00}, //Reg 0x4E
+{0x4F, 0x00 ,0x02}, //Reg 0x4F
+{0x5B, 0x00 ,0x44}, //Reg 0x5B
+{0x5D, 0x00 ,0x00}, //Reg 0x5D
+{0x5E, 0x00 ,0x25}, //Reg 0x5E
+{0x61, 0x00 ,0xB0}, //Reg 0x61
+{0x65, 0x00 ,0xB0}, //Reg 0x65
+{0x68, 0x00 ,0x4C}, //Reg 0x68
+{0x69, 0x00 ,0xD0}, //Reg 0x69
+{0x6B, 0x00 ,0x07}, //Reg 0x6B
+{0x6C, 0x00 ,0xDD}, //Reg 0x6C
+{0x6D, 0x00 ,0xAD}, //Reg 0x6D
+{0x6E, 0x00 ,0xE8}, //Reg 0x6E
+{0x6F, 0x00 ,0x4D}, //Reg 0x6F
+{0x70, 0x00 ,0x00}, //Reg 0x70
+{0x71, 0x00 ,0x80}, //Reg 0x71
+{0x72, 0x00 ,0x00}, //Reg 0x72
+{0x73, 0x00 ,0x00}, //Reg 0x73
+{0x74, 0x00 ,0x01}, //Reg 0x74
+{0x75, 0x00 ,0x10}, //Reg 0x75
+{0x7E, 0x00 ,0x29}, //Reg 0x7E
+{0x8B, 0x00 ,0x10}, //Reg 0x8B
+{0x8D, 0x00 ,0x03}, //Reg 0x8D
+{0xA1, 0x00 ,0xD0}, //Reg 0xA1
+{0xA2, 0x00 ,0x30}, //Reg 0xA2
+{0xA4, 0x00 ,0x0B}, //Reg 0xA4
+{0xA9, 0x00 ,0x02}, //Reg 0xA9
+{0xB0, 0x00 ,0x30}, //Reg 0xB0
+{0xB4, 0x00 ,0x30}, //Reg 0xB4
+{0x90, 0x00 ,0x00}, //Reg 0x90
+{0x91, 0x00 ,0x00}, //Reg 0x91
+{0x92, 0x00 ,0x00}, //Reg 0x92
+{0x93, 0x00 ,0x00}, //Reg 0x93
+{0x94, 0x00 ,0x00}, //Reg 0x94
+{0x95, 0x00 ,0x00}, //Reg 0x95
+{0x96, 0x00 ,0x00}, //Reg 0x96
+{0x97, 0x00 ,0x00}, //Reg 0x97
+{0x98, 0x00 ,0x00}, //Reg 0x98
+{0x99, 0x00 ,0x00}, //Reg 0x99
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_NBAGP_init[34][3]={
+{0xCF, 0xDF, 0x00}, //HT issue
+{0x06, 0xDF, 0x20},
+{0x1E, 0xDF, 0x20},
+{0x50, 0x00, 0x02},
+{0x51, 0x00, 0x00},
+{0x54, 0x00, 0x09},
+{0x55, 0x00, 0x00},
+{0x56, 0x00, 0x80},
+{0x58, 0x00, 0x08},
+{0x60, 0x00, 0xB1},
+{0x61, 0x00, 0x02},
+{0x62, 0x00, 0x60},
+{0x63, 0x00, 0x60},
+{0x64, 0x00, 0xAA},
+{0x65, 0x00, 0x18},
+{0x68, 0x00, 0x23},
+{0x69, 0x00, 0x23},
+{0x6A, 0x00, 0xC8},
+{0x6B, 0x00, 0x08},
+{0x6C, 0x00, 0x00},
+{0x6D, 0x00, 0x00},
+{0x6E, 0x00, 0x08},
+{0x6F, 0x00, 0x00},
+{0xBB, 0x00, 0x00},
+{0xB5, 0x00, 0x30},
+{0xB0, 0x00, 0xDB},
+{0xB6, 0x00, 0x73},
+{0xB7, 0x00, 0x50},
+{0xBA, 0xBF, 0x41},
+{0xB4, 0x3F, 0xC0},
+{0xBF, 0xF9, 0x06},
+{0xBA, 0x00, 0x61},
+{0xBD, 0x7F, 0x80},
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_ACPI_2_init[56][3]={
+{0x00, 0x00, 0xFF}, //Reg 0x00
+{0x01, 0x00, 0xFF}, //Reg 0x01
+{0x02, 0x00, 0x00}, //Reg 0x02
+{0x03, 0x00, 0x00}, //Reg 0x03
+{0x16, 0x00, 0x00}, //Reg 0x16
+{0x20, 0x00, 0xFF}, //Reg 0x20
+{0x21, 0x00, 0xFF}, //Reg 0x21
+{0x22, 0x00, 0x00}, //Reg 0x22
+{0x23, 0x00, 0x00}, //Reg 0x23
+{0x24, 0x00, 0x55}, //Reg 0x24
+{0x25, 0x00, 0x55}, //Reg 0x25
+{0x26, 0x00, 0x55}, //Reg 0x26
+{0x27, 0x00, 0x55}, //Reg 0x27
+{0x2A, 0x00, 0x40}, //Reg 0x2A
+{0x2B, 0x00, 0x10}, //Reg 0x2B
+{0x2E, 0x00, 0xFF}, //Reg 0x2E
+{0x30, 0x00, 0xFF}, //Reg 0x30
+{0x31, 0x00, 0xFF}, //Reg 0x31
+{0x32, 0x00, 0x00}, //Reg 0x32
+{0x33, 0x00, 0x00}, //Reg 0x33
+{0x40, 0x00, 0xFF}, //Reg 0x40
+{0x41, 0x00, 0xFF}, //Reg 0x41
+{0x42, 0x00, 0x00}, //Reg 0x42
+{0x43, 0x00, 0x00}, //Reg 0x43
+{0x4A, 0x00, 0x00}, //Reg 0x4A
+{0x4E, 0x00, 0x0F}, //Reg 0x4E
+{0x5A, 0x00, 0x00}, //Reg 0x5A
+{0x5B, 0x00, 0x00}, //Reg 0x5B
+{0x62, 0x00, 0x00}, //Reg 0x62
+{0x63, 0x00, 0x04}, //Reg 0x63
+{0x68, 0x00, 0xFF}, //Reg 0x68
+{0x76, 0x00, 0xA0}, //Reg 0x76
+{0x77, 0x00, 0x22}, //Reg 0x77
+{0x78, 0xDF, 0x20}, //Reg 0x78
+{0x7A, 0x00, 0x10}, //Reg 0x7A
+{0x7C, 0x00, 0x45}, //Reg 0x7C
+{0x7D, 0x00, 0xB8}, //Reg 0x7D
+{0x7F, 0x00, 0x00}, //Reg 0x7F
+{0x80, 0x00, 0x1C}, //Reg 0x80
+{0x82, 0x00, 0x01}, //Reg 0x82
+{0x84, 0x00, 0x0E}, //Reg 0x84
+{0x85, 0x00, 0x29}, //Reg 0x85
+{0x86, 0x00, 0xCB}, //Reg 0x86
+{0x87, 0x00, 0x55}, //Reg 0x87
+{0x88, 0x00, 0x04}, //Reg 0x88
+{0x96, 0x00, 0x80}, //Reg 0x96
+{0x99, 0x00, 0x80}, //Reg 0x99
+{0x9A, 0x00, 0x15}, //Reg 0x9A
+{0x9D, 0x00, 0x05}, //Reg 0x9D
+{0x9E, 0x00, 0x00}, //Reg 0x9E
+{0x9F, 0x00, 0x04}, //Reg 0x9F
+{0xB0, 0x00, 0x6D}, //Reg 0xB0
+{0xB1, 0x00, 0x8C}, //Reg 0xB1
+{0xB9, 0x00, 0xFF}, //Reg 0xB9
+{0xBA, 0x00, 0x3F}, //Reg 0xBA
+{0x00, 0x00, 0x00} //End of table
+};
+
+static const uint8_t SiS_SiS1183_init[44][3]={
+{0x04, 0x00, 0x05},
+{0x09, 0x00, 0x05},
+{0x2C, 0x00, 0x39},
+{0x2D, 0x00, 0x10},
+{0x2E, 0x00, 0x83},
+{0x2F, 0x00, 0x11},
+{0x90, 0x00, 0x40},
+{0x91, 0x00, 0x00}, // set mode
+{0x50, 0x00, 0xA2},
+{0x52, 0x00, 0xA2},
+{0x55, 0x00, 0x96},
+{0x52, 0x00, 0xA2},
+{0x55, 0xF7, 0x00},
+{0x56, 0x00, 0xC0},
+{0x57, 0x00, 0x14},
+{0x67, 0x00, 0x28},
+{0x81, 0x00, 0xB3},
+{0x82, 0x00, 0x72},
+{0x83, 0x00, 0x40},
+{0x85, 0x00, 0xB3},
+{0x86, 0x00, 0x72},
+{0x87, 0x00, 0x40},
+{0x88, 0x00, 0xDE}, // after set mode
+{0x89, 0x00, 0xB3},
+{0x8A, 0x00, 0x72},
+{0x8B, 0x00, 0x40},
+{0x8C, 0x00, 0xDE},
+{0x8D, 0x00, 0xB3},
+{0x8E, 0x00, 0x92},
+{0x8F, 0x00, 0x40},
+{0x93, 0x00, 0x00},
+{0x94, 0x00, 0x80},
+{0x95, 0x00, 0x08},
+{0x96, 0x00, 0x80},
+{0x97, 0x00, 0x08},
+{0x9C, 0x00, 0x80},
+{0x9D, 0x00, 0x08},
+{0x9E, 0x00, 0x80},
+{0x9F, 0x00, 0x08},
+{0xA0, 0x00, 0x15},
+{0xA1, 0x00, 0x15},
+{0xA2, 0x00, 0x15},
+{0xA3, 0x00, 0x15},
+{0x00, 0x00, 0x00} //End of table
+};
+
+/* In => Share Memory size
+ => 00h : 0MBytes
+ => 02h : 32MBytes
+ => 03h : 64MBytes
+ => 04h : 128MBytes
+ => Others: Reserved
+*/
+static void Init_Share_Memory(uint8_t ShareSize)
+{
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
+ pci_write_config8(dev, 0x4C, (pci_read_config8(dev, 0x4C) & 0x1F) | (ShareSize << 5));
+}
+
+/* In: => Aperture size
+ => 00h : 32MBytes
+ => 01h : 64MBytes
+ => 02h : 128MBytes
+ => 03h : 256MBytes
+ => 04h : 512MBytes
+ => Others: Reserved
+*/
+static void Init_Aper_Size(uint8_t AperSize)
+{
+ device_t dev;
+ uint16_t SiSAperSizeTable[]={0x0F38, 0x0F30, 0x0F20, 0x0F00, 0x0E00};
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_AMD, 0x1103), 0);
+ pci_write_config8(dev, 0x90, AperSize << 1);
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
+ pci_write_config16(dev, 0xB4, SiSAperSizeTable[AperSize]);
+}
+
+static void sis_init_stage1(void)
+{
+ device_t dev;
+ uint8_t temp8;
+ int i;
+ uint8_t GUI_En;
+
+// SiS_Chipset_Initialization
+// ========================== NB =============================
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
+ i=0;
+ while(SiS_NB_init[i][0] != 0)
+ { temp8 = pci_read_config8(dev, SiS_NB_init[i][0]);
+ temp8 &= SiS_NB_init[i][1];
+ temp8 |= SiS_NB_init[i][2];
+ pci_write_config8(dev, SiS_NB_init[i][0], temp8);
+ i++;
+ };
+
+// ========================== LPC =============================
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
+ i=0;
+ while(SiS_LPC_init[i][0] != 0)
+ { temp8 = pci_read_config8(dev, SiS_LPC_init[i][0]);
+ temp8 &= SiS_LPC_init[i][1];
+ temp8 |= SiS_LPC_init[i][2];
+ pci_write_config8(dev, SiS_LPC_init[i][0], temp8);
+ i++;
+ };
+// ========================== ACPI =============================
+ i=0;
+ while(SiS_ACPI_init[i][0] != 0)
+ { temp8 = inb(0x800 + SiS_ACPI_init[i][0]);
+ temp8 &= SiS_ACPI_init[i][1];
+ temp8 |= SiS_ACPI_init[i][2];
+ outb(temp8, 0x800 + SiS_ACPI_init[i][0]);
+ i++;
+ };
+// ========================== NBPCIE =============================
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Disable Internal GUI enable bit
+ temp8 = pci_read_config8(dev, 0x4C);
+ GUI_En = temp8 & 0x10;
+ pci_write_config8(dev, 0x4C, temp8 & (!0x10));
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761_PCIE), 0);
+ i=0;
+ while(SiS_NBPCIE_init[i][0] != 0)
+ { temp8 = pci_read_config8(dev, SiS_NBPCIE_init[i][0]);
+ temp8 &= SiS_NBPCIE_init[i][1];
+ temp8 |= SiS_NBPCIE_init[i][2];
+ pci_write_config8(dev, SiS_NBPCIE_init[i][0], temp8);
+ i++;
+ };
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Restore Internal GUI enable bit
+ temp8 = pci_read_config8(dev, 0x4C);
+ pci_write_config8(dev, 0x4C, temp8 | GUI_En);
+
+ return;
+}
+
+
+
+static void sis_init_stage2(void)
+{
+ device_t dev;
+ msr_t msr;
+ int i;
+ uint8_t temp8;
+ uint16_t temp16;
+
+
+// ========================== NB_AGP =============================
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Enable Internal GUI enable bit
+ pci_write_config8(dev, 0x4C, pci_read_config8(dev, 0x4C) | 0x10);
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_AGP), 0);
+ i=0;
+
+ while(SiS_NBAGP_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_NBAGP_init[i][0]);
+ temp8 &= SiS_NBAGP_init[i][1];
+ temp8 |= SiS_NBAGP_init[i][2];
+ pci_write_config8(dev, SiS_NBAGP_init[i][0], temp8);
+ i++;
+ };
+
+/**
+ * Share Memory size
+ * => 00h : 0MBytes
+ * => 02h : 32MBytes
+ * => 03h : 64MBytes
+ * => 04h : 128MBytes
+ * => Others: Reserved
+ *
+ * Aperture size
+ * => 00h : 32MBytes
+ * => 01h : 64MBytes
+ * => 02h : 128MBytes
+ * => 03h : 256MBytes
+ * => 04h : 512MBytes
+ * => Others: Reserved
+ */
+
+ Init_Share_Memory(0x02); //0x02 : 32M
+ Init_Aper_Size(0x01); //0x1 : 64M
+
+// ========================== NB =============================
+
+ printk(BIOS_DEBUG, "Init NorthBridge sis761 -------->\n");
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
+ msr = rdmsr(0xC001001A);
+ printk(BIOS_DEBUG, "Memory Top Bound %x\n",msr.lo );
+
+ temp16=(pci_read_config8(dev, 0x4C) & 0xE0) >> 5;
+ temp16=0x0001<<(temp16-1);
+ temp16<<=8;
+
+ printk(BIOS_DEBUG, "Integrated VGA Shared memory size=%dM bytes\n", temp16 >> 4);
+ pci_write_config16(dev, 0x8E, (msr.lo >> 16) -temp16*1);
+ pci_write_config8(dev, 0x7F, 0x08); // ACPI Base
+ outb(inb(0x856) | 0x40, 0x856); // Auto-Reset Function
+
+// ========================== ACPI =============================
+ i=0;
+ printk(BIOS_DEBUG, "Init ACPI -------->\n");
+ do
+ { temp8 = inb(0x800 + SiS_ACPI_2_init[i][0]);
+ temp8 &= SiS_ACPI_2_init[i][1];
+ temp8 |= SiS_ACPI_2_init[i][2];
+ outb(temp8, 0x800 + SiS_ACPI_2_init[i][0]);
+ i++;
+ }while(SiS_ACPI_2_init[i][0] != 0);
+
+// ========================== Misc =============================
+ printk(BIOS_DEBUG, "Init Misc -------->\n");
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
+
+ /* R77h Internal PCI Device Enable 1 (Power On Value = 0h)
+ * bit5 : USB Emulation (1=enable)
+ * bit3 : Internal Keyboard Controller Port Access Control enable (1=enable)
+ * bit2 : Reserved
+ * bit1 : Mask USB A20M# Event (1:K8, 0:P4/K7)
+ */
+ pci_write_config8(dev, 0x77, 0x2E);
+
+ /* R7Ch Internal PCI Device Enable 2 (Power On Value = 0h)
+ * bit4 : SATA Controller Enable (0=enable)
+ * bit3 : IDE Controller Enable (0=enable)
+ * bit2 : MAC Controller Enable (0=enable)
+ * bit1 : MODEM Controller Enable (1=disable)
+ * bit0 : AC97 Controller Enable (1=disable)
+ */
+ pci_write_config8(dev, 0x7C, 0x03);
+
+ /* R7Eh Enable Azalia (Power On Value = 08h)
+ * bit3 : Azalia Controller Enable (0=enable)
+ */
+ pci_write_config8(dev, 0x7E, 0x00); // azalia controller enable
+ temp8=inb(0x878)|0x4; //bit2=1 enable Azalia =0 enable AC97
+ outb(temp8, 0x878); // ACPI select AC97 or HDA controller
+ printk(BIOS_DEBUG, "Audio select %x\n",inb(0x878));
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_SATA), 0);
+
+ if (!dev)
+ print_debug("SiS 1183 does not exist !!");
+ // SATA Set Mode
+ pci_write_config8(dev, 0x90, (pci_read_config8(dev, 0x90)&0x3F) | 0x40);
+
+}
+
+
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ uint8_t temp8;
+ printk(BIOS_DEBUG, "enable_smbus -------->\n");
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
+
+ /* set smbus iobase && enable ACPI Space*/
+ pci_write_config16(dev, 0x74, 0x0800); // Set ACPI Base
+ temp8=pci_read_config8(dev, 0x40); // Enable ACPI Space
+ pci_write_config8(dev, 0x40, temp8 | 0x80);
+ temp8=pci_read_config8(dev, 0x76); // Enable SMBUS
+ pci_write_config8(dev, 0x76, temp8 | 0x03);
+
+ printk(BIOS_DEBUG, "enable_smbus <--------\n");
+}
+
+int smbus_read_byte(unsigned device, unsigned address)
+{
+ return do_smbus_read_byte(SMBUS0_IO_BASE, device, address);
+}
+int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
+{
+ return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
+ #define SIS966_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+ #define SIS966_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+static void sis966_enable_rom(void)
+{
+ device_t addr;
+
+ /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
+ addr = pci_locate_device(PCI_ID(0x1039, 0x0966), 0);
+
+ /* Set the 4MB enable bit bit */
+ pci_write_config8(addr, 0x40, pci_read_config8(addr, 0x40) | 0x11);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* TODO: Check whether this actually works (might be copy-paste leftover). */
+
+#include <stdint.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <usbdebug.h>
+#include <device/pci_def.h>
+#include "sis966.h"
+
+#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
+#define SIS966_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
+#else
+#define SIS966_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
+#endif
+
+void set_debug_port(unsigned int port)
+{
+ u32 dword;
+ device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Write the port number to 0x74[15:12]. */
+ dword = pci_read_config32(dev, 0x74);
+ dword &= ~(0xf << 12);
+ dword |= (port << 12);
+ pci_write_config32(dev, 0x74, dword);
+}
+
+void sis966_enable_usbdebug(unsigned int port)
+{
+ device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
+
+ /* Mark the requested physical USB port (1-15) as the Debug Port. */
+ set_debug_port(port);
+
+ /* Set the EHCI BAR address. */
+ pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
+
+ /* Enable access to the EHCI memory space registers. */
+ pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "sis966.h"
+
+uint8_t SiS_SiS5513_init[49][3]={
+{0x04, 0xFF, 0x05},
+{0x0D, 0xFF, 0x80},
+{0x2C, 0xFF, 0x39},
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x13},
+{0x2F, 0xFF, 0x55},
+{0x50, 0xFF, 0xA2},
+{0x51, 0xFF, 0x21},
+{0x53, 0xFF, 0x21},
+{0x54, 0xFF, 0x2A},
+{0x55, 0xFF, 0x96},
+{0x52, 0xFF, 0xA2},
+{0x56, 0xFF, 0x81},
+{0x57, 0xFF, 0xC0},
+{0x60, 0xFF, 0xFB},
+{0x61, 0xFF, 0xAA},
+{0x62, 0xFF, 0xFB},
+{0x63, 0xFF, 0xAA},
+{0x81, 0xFF, 0xB3},
+{0x82, 0xFF, 0x72},
+{0x83, 0xFF, 0x40},
+{0x85, 0xFF, 0xB3},
+{0x86, 0xFF, 0x72},
+{0x87, 0xFF, 0x40},
+{0x94, 0xFF, 0xC0},
+{0x95, 0xFF, 0x08},
+{0x96, 0xFF, 0xC0},
+{0x97, 0xFF, 0x08},
+{0x98, 0xFF, 0xCC},
+{0x99, 0xFF, 0x04},
+{0x9A, 0xFF, 0x0C},
+{0x9B, 0xFF, 0x14},
+{0xA0, 0xFF, 0x11},
+{0x57, 0xFF, 0xD0},
+
+{0xD8, 0xFE, 0x01}, // Com reset
+{0xC8, 0xFE, 0x01},
+{0xC4, 0xFF, 0xFF}, // Clear status
+{0xC5, 0xFF, 0xFF},
+{0xC6, 0xFF, 0xFF},
+{0xC7, 0xFF, 0xFF},
+{0xD4, 0xFF, 0xFF},
+{0xD5, 0xFF, 0xFF},
+{0xD6, 0xFF, 0xFF},
+{0xD7, 0xFF, 0xFF},
+
+
+{0x2C, 0xFF, 0x39}, // set subsystem ID
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x13},
+{0x2F, 0xFF, 0x55},
+
+
+{0x00, 0x00, 0x00} //End of table
+};
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_sis_sis966_config *conf;
+ /* Enable ide devices so the linux ide driver will work */
+ uint32_t dword;
+ uint16_t word;
+ uint8_t byte;
+ conf = dev->chip_info;
+
+
+
+print_debug("IDE_INIT:---------->\n");
+
+
+//-------------- enable IDE (SiS5513) -------------------------
+{
+ uint8_t temp8;
+ int i=0;
+ while(SiS_SiS5513_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_SiS5513_init[i][0]);
+ temp8 &= SiS_SiS5513_init[i][1];
+ temp8 |= SiS_SiS5513_init[i][2];
+ pci_write_config8(dev, SiS_SiS5513_init[i][0], temp8);
+ i++;
+ };
+}
+//-----------------------------------------------------------
+
+ word = pci_read_config16(dev, 0x50);
+ /* Ensure prefetch is disabled */
+ word &= ~((1 << 15) | (1 << 13));
+ if (conf->ide1_enable) {
+ /* Enable secondary ide interface */
+ word |= (1<<0);
+ printk(BIOS_DEBUG, "IDE1 \t");
+ }
+ if (conf->ide0_enable) {
+ /* Enable primary ide interface */
+ word |= (1<<1);
+ printk(BIOS_DEBUG, "IDE0\n");
+ }
+
+ word |= (1<<12);
+ word |= (1<<14);
+
+ pci_write_config16(dev, 0x50, word);
+
+
+ byte = 0x20 ; // Latency: 64-->32
+ pci_write_config8(dev, 0xd, byte);
+
+ dword = pci_read_config32(dev, 0xf8);
+ dword |= 12;
+ pci_write_config32(dev, 0xf8, dword);
+#if CONFIG_PCI_ROM_RUN == 1
+ pci_dev_init(dev);
+#endif
+
+#if DEBUG_IDE
+{
+ int i;
+
+ print_debug("****** IDE PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+#endif
+print_debug("IDE_INIT:<----------\n");
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .scan_bus = 0,
+// .enable = sis966_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver ide_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_IDE,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Linux Networx
+ * Copyright (C) 2003 SuSE Linux AG
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pnp.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <bitops.h>
+#include <arch/io.h>
+#include <arch/ioapic.h>
+#include <cpu/x86/lapic.h>
+#include <stdlib.h>
+#include "sis966.h"
+#include <pc80/keyboard.h>
+
+#define NMI_OFF 0
+
+// 0x7a or e3
+#define PREVIOUS_POWER_STATE 0x7A
+
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+#define SLOW_CPU_OFF 0
+#define SLOW_CPU__ON 1
+
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#undef SLAVE_INIT
+
+static void lpc_common_init(device_t dev)
+{
+ uint8_t byte;
+ uint32_t ioapic_base;
+
+ /* IO APIC initialization */
+ byte = pci_read_config8(dev, 0x74);
+ byte |= (1<<0); // enable APIC
+ pci_write_config8(dev, 0x74, byte);
+ ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
+
+ setup_ioapic(ioapic_base, 0); // Don't rename IO APIC ID
+}
+
+#ifdef SLAVE_INIT
+static void lpc_slave_init(device_t dev)
+{
+ lpc_common_init(dev);
+}
+#endif
+
+static void lpc_usb_legacy_init(device_t dev)
+{
+ uint16_t acpi_base;
+
+ acpi_base = (pci_read_config8(dev,0x75) << 8);
+
+ outb(inb(acpi_base + 0xbb) |0x80, acpi_base + 0xbb);
+ outb(inb(acpi_base + 0xba) |0x80, acpi_base + 0xba);
+}
+
+static void lpc_init(device_t dev)
+{
+ uint8_t byte;
+ uint8_t byte_old;
+ int on;
+ int nmi_option;
+
+ printk(BIOS_DEBUG, "LPC_INIT -------->\n");
+ pc_keyboard_init(0);
+
+ lpc_usb_legacy_init(dev);
+ lpc_common_init(dev);
+
+ /* power after power fail */
+
+
+ on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+ get_option(&on, "power_on_after_fail");
+ byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
+ byte &= ~0x40;
+ if (!on) {
+ byte |= 0x40;
+ }
+ pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
+ printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
+
+ /* Throttle the CPU speed down for testing */
+ on = SLOW_CPU_OFF;
+ get_option(&on, "slow_cpu");
+ if(on) {
+ uint16_t pm10_bar;
+ uint32_t dword;
+ pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
+ outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
+ dword = inl(pm10_bar + 0x10);
+ on = 8-on;
+ printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
+ (on*12)+(on>>1),(on&1)*5);
+ }
+
+ /* Enable Error reporting */
+ /* Set up sync flood detected */
+ byte = pci_read_config8(dev, 0x47);
+ byte |= (1 << 1);
+ pci_write_config8(dev, 0x47, byte);
+
+ /* Set up NMI on errors */
+ byte = inb(0x70); // RTC70
+ byte_old = byte;
+ nmi_option = NMI_OFF;
+ get_option(&nmi_option, "nmi");
+ if (nmi_option) {
+ byte &= ~(1 << 7); /* set NMI */
+ } else {
+ byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
+ }
+ if( byte != byte_old) {
+ outb(byte, 0x70);
+ }
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+
+ printk(BIOS_DEBUG, "LPC_INIT <--------\n");
+}
+
+static void sis966_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP
+
+ /* Add an extra subtractive resource for both memory and I/O. */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->base = 0;
+ res->size = 0x1000;
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->base = 0xff800000;
+ res->size = 0x00800000; /* 8 MB for flash */
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+ IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+/**
+ * Enable resources for children devices.
+ *
+ * @param dev The device whos children's resources are to be enabled.
+ */
+static void sis966_lpc_enable_childrens_resources(device_t dev)
+{
+ struct bus *link;
+ uint32_t reg, reg_var[4];
+ int i;
+ int var_num = 0;
+
+ reg = pci_read_config32(dev, 0xa0);
+
+ for (link = dev->link_list; link; link = link->next) {
+ device_t child;
+ for (child = link->children; child; child = child->sibling) {
+ if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
+ struct resource *res;
+ for(res = child->resource_list; res; res = res->next) {
+ unsigned long base, end; // don't need long long
+ if(!(res->flags & IORESOURCE_IO)) continue;
+ base = res->base;
+ end = resource_end(res);
+ printk(BIOS_DEBUG, "sis966 lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
+ switch(base) {
+ case 0x3f8: // COM1
+ reg |= (1<<0); break;
+ case 0x2f8: // COM2
+ reg |= (1<<1); break;
+ case 0x378: // Parallal 1
+ reg |= (1<<24); break;
+ case 0x3f0: // FD0
+ reg |= (1<<20); break;
+ case 0x220: // Aduio 0
+ reg |= (1<<8); break;
+ case 0x300: // Midi 0
+ reg |= (1<<12); break;
+ }
+ if( (base == 0x290) || (base >= 0x400)) {
+ if(var_num>=4) continue; // only 4 var ; compact them ?
+ reg |= (1<<(28+var_num));
+ reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
+ }
+ }
+ }
+ }
+ }
+ pci_write_config32(dev, 0xa0, reg);
+ for(i=0;i<var_num;i++) {
+ pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
+ }
+
+
+}
+
+static void sis966_lpc_enable_resources(device_t dev)
+{
+ pci_dev_enable_resources(dev);
+ sis966_lpc_enable_childrens_resources(dev);
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = sis966_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = sis966_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+// .enable = sis966_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_LPC,
+};
+
+#ifdef SLAVE_INIT // No device?
+static struct device_operations lpc_slave_ops = {
+ .read_resources = sis966_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = lpc_slave_init,
+// .enable = sis966_enable,
+ .ops_pci = &lops_pci,
+};
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/smbus.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include <delay.h>
+#include "sis966.h"
+
+
+u8 SiS_SiS191_init[6][3]={
+{0x04, 0xFF, 0x07},
+{0x2C, 0xFF, 0x39},
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x91},
+{0x2F, 0xFF, 0x01},
+{0x00, 0x00, 0x00} //End of table
+};
+
+
+#define StatusReg 0x1
+#define SMI_READ 0x0
+#define SMI_REQUEST 0x10
+#define TRUE 1
+#define FALSE 0
+
+u16 MacAddr[3];
+
+
+static void writeApcByte(int addr, u8 value)
+{
+ outb(addr,0x78);
+ outb(value,0x79);
+}
+
+static u8 readApcByte(int addr)
+{
+ u8 value;
+ outb(addr,0x78);
+ value=inb(0x79);
+ return(value);
+}
+
+static void readApcMacAddr(void)
+{
+ u8 i;
+
+// enable APC in south bridge sis966 D2F0
+
+ outl(0x80001048,0xcf8);
+ outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data
+
+ printk(BIOS_DEBUG, "MAC addr in APC = ");
+ for(i = 0x9 ; i <=0xe ; i++)
+ {
+ printk(BIOS_DEBUG, "%2.2x",readApcByte(i));
+ }
+ printk(BIOS_DEBUG, "\n");
+
+ /* Set APC Reload */
+ writeApcByte(0x7,readApcByte(0x7)&0xf7);
+ writeApcByte(0x7,readApcByte(0x7)|0x0a);
+
+ /* disable APC in south bridge */
+ outl(0x80001048,0xcf8);
+ outl(inl(0xcfc)&0xffffffbf,0xcfc);
+}
+
+static void set_apc(struct device *dev)
+{
+ u16 addr;
+ u16 i;
+ u8 bTmp;
+
+ /* enable APC in south bridge sis966 D2F0 */
+ outl(0x80001048,0xcf8);
+ outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data
+
+ for(i = 0 ; i <3; i++)
+ {
+ addr=0x9+2*i;
+ writeApcByte(addr,(u8)(MacAddr[i]&0xFF));
+ writeApcByte(addr+1L,(u8)((MacAddr[i]>>8)&0xFF));
+ // printf("%x - ",readMacAddrByte(0x59+i));
+ }
+
+ /* Set APC Reload */
+ writeApcByte(0x7,readApcByte(0x7)&0xf7);
+ writeApcByte(0x7,readApcByte(0x7)|0x0a);
+
+ /* disable APC in south bridge */
+ outl(0x80001048,0xcf8);
+ outl(inl(0xcfc)&0xffffffbf,0xcfc);
+
+ // CFG reg0x73 bit=1, tell driver MAC Address load to APC
+ bTmp = pci_read_config8(dev, 0x73);
+ bTmp|=0x1;
+ pci_write_config8(dev, 0x73, bTmp);
+}
+
+/**
+ * Read one word out of the serial EEPROM.
+ *
+ * @param dev TODO
+ * @param base TODO
+ * @param Reg EEPROM word to read.
+ * @return Contents of EEPROM word (Reg).
+ */
+#define LoopNum 200
+static unsigned long ReadEEprom( struct device *dev, u32 base, u32 Reg)
+{
+ u32 data;
+ u32 i;
+ u32 ulValue;
+
+
+ ulValue = (0x80 | (0x2 << 8) | (Reg << 10)); //BIT_7
+
+ write32(base+0x3c, ulValue);
+
+ mdelay(10);
+
+ for(i=0 ; i <= LoopNum; i++)
+ {
+ ulValue=read32(base+0x3c);
+
+ if(!(ulValue & 0x0080)) //BIT_7
+ break;
+
+ mdelay(100);
+ }
+
+ mdelay(50);
+
+ if(i==LoopNum) data=0x10000;
+ else{
+ ulValue=read32(base+0x3c);
+ data = ((ulValue & 0xffff0000) >> 16);
+ }
+
+ return data;
+}
+
+static int phy_read(u32 base, unsigned phy_addr, unsigned phy_reg)
+{
+ u32 ulValue;
+ u32 Read_Cmd;
+ u16 usData;
+
+
+
+ Read_Cmd = ((phy_reg << 11) |
+ (phy_addr << 6) |
+ SMI_READ |
+ SMI_REQUEST);
+
+ // SmiMgtInterface Reg is the SMI management interface register(offset 44h) of MAC
+ write32(base+0x44, Read_Cmd);
+
+ // Polling SMI_REQ bit to be deasserted indicated read command completed
+ do
+ {
+ // Wait 20 usec before checking status
+ mdelay(20);
+ ulValue = read32(base+0x44);
+ } while((ulValue & SMI_REQUEST) != 0);
+ //printk(BIOS_DEBUG, "base %x cmd %lx ret val %lx\n", tmp,Read_Cmd,ulValue);
+ usData=(ulValue>>16);
+
+
+
+ return usData;
+
+}
+
+// Detect a valid PHY
+// If there exist a valid PHY then return TRUE, else return FALSE
+static int phy_detect(u32 base,u16 *PhyAddr) //BOOL PHY_Detect()
+{
+ int bFoundPhy = FALSE;
+ u16 usData;
+ int PhyAddress = 0;
+
+
+ // Scan all PHY address(0 ~ 31) to find a valid PHY
+ for(PhyAddress = 0; PhyAddress < 32; PhyAddress++)
+ {
+ usData=phy_read(base,PhyAddress,StatusReg); // Status register is a PHY's register(offset 01h)
+
+ // Found a valid PHY
+
+ if((usData != 0x0) && (usData != 0xffff))
+ {
+ bFoundPhy = TRUE;
+ break;
+ }
+ }
+
+
+ if(!bFoundPhy)
+ {
+ printk(BIOS_DEBUG, "PHY not found !!!! \n");
+ }
+
+ *PhyAddr=PhyAddress;
+
+ return bFoundPhy;
+}
+
+
+static void nic_init(struct device *dev)
+{
+ int val;
+ u16 PhyAddr;
+ u32 base;
+ struct resource *res;
+
+ print_debug("NIC_INIT:---------->\n");
+
+//-------------- enable NIC (SiS19x) -------------------------
+{
+ u8 temp8;
+ int i=0;
+ while(SiS_SiS191_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_SiS191_init[i][0]);
+ temp8 &= SiS_SiS191_init[i][1];
+ temp8 |= SiS_SiS191_init[i][2];
+ pci_write_config8(dev, SiS_SiS191_init[i][0], temp8);
+ i++;
+ };
+}
+//-----------------------------------------------------------
+
+{
+ unsigned long i;
+ unsigned long ulValue;
+
+ res = find_resource(dev, 0x10);
+
+ if(!res)
+ {
+ printk(BIOS_DEBUG, "NIC Cannot find resource..\n");
+ return;
+ }
+ base = res->base;
+ printk(BIOS_DEBUG, "NIC base address %x\n",base);
+
+ if(!(val=phy_detect(base,&PhyAddr)))
+ {
+ printk(BIOS_DEBUG, "PHY detect fail !!!!\n");
+ return;
+ }
+
+ ulValue=read32(base + 0x38L); // check EEPROM existing
+
+ if((ulValue & 0x0002))
+ {
+
+ // read MAC address from EEPROM at first
+
+ // if that is valid we will use that
+
+ printk(BIOS_DEBUG, "EEPROM contents %lx \n",ReadEEprom( dev, base, 0LL));
+ for(i=0;i<3;i++) {
+ //status = smbus_read_byte(dev_eeprom, i);
+ ulValue=ReadEEprom( dev, base, i+3L);
+ if (ulValue ==0x10000) break; // error
+
+ MacAddr[i] =ulValue & 0xFFFF;
+
+ }
+ }else{
+ // read MAC address from firmware
+ printk(BIOS_DEBUG, "EEPROM invalid!!\nReg 0x38h=%.8lx \n",ulValue);
+ MacAddr[0]=read16(0xffffffc0); // mac address store at here
+ MacAddr[1]=read16(0xffffffc2);
+ MacAddr[2]=read16(0xffffffc4);
+ }
+
+ set_apc(dev);
+
+ readApcMacAddr();
+
+#if DEBUG_NIC
+{
+ int i;
+
+ print_debug("****** NIC PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+
+
+#endif
+
+}
+
+print_debug("NIC_INIT:<----------\n");
+return;
+
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .scan_bus = 0,
+// .enable = sis966_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver nic_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_NIC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sis966.h"
+
+static void pcie_init(struct device *dev)
+{
+
+ /* Enable pci error detecting */
+ uint32_t dword;
+
+ /* System error enable */
+ dword = pci_read_config32(dev, 0x04);
+ dword |= (1<<8); /* System error enable */
+ dword |= (1<<30); /* Clear possible errors */
+ pci_write_config32(dev, 0x04, dword);
+
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pcie_init,
+ .scan_bus = pci_scan_bridge,
+// .enable = sis966_enable,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver pciebc_driver __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_PCIE,
+};
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <reset.h>
+
+#define PCI_DEV(BUS, DEV, FN) ( \
+ (((BUS) & 0xFFF) << 20) | \
+ (((DEV) & 0x1F) << 15) | \
+ (((FN) & 0x7) << 12))
+
+typedef unsigned device_t;
+
+static void pci_write_config32(device_t dev, unsigned where, unsigned value)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ outl(value, 0xCFC);
+}
+
+static unsigned pci_read_config32(device_t dev, unsigned where)
+{
+ unsigned addr;
+ addr = (dev>>4) | where;
+ outl(0x80000000 | (addr & ~3), 0xCF8);
+ return inl(0xCFC);
+}
+
+#include "../../../northbridge/amd/amdk8/reset_test.c"
+
+void hard_reset(void)
+{
+ set_bios_reset();
+ /* Try rebooting through port 0xcf9 */
+ /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
+ outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
+ outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
+}
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <delay.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sis966.h"
+#include <arch/io.h>
+
+uint8_t SiS_SiS1183_init[68][3]={
+{0x04, 0x00, 0x05},
+{0x09, 0x00, 0x05},
+{0x2C, 0x00, 0x39},
+{0x2D, 0x00, 0x10},
+{0x2E, 0x00, 0x83},
+{0x2F, 0x00, 0x11},
+{0x90, 0x00, 0x40},
+{0x91, 0x00, 0x00}, // set mode
+{0x50, 0x00, 0xA2},
+{0x52, 0x00, 0xA2},
+{0x55, 0x00, 0x96},
+{0x52, 0x00, 0xA2},
+{0x55, 0xF7, 0x00},
+{0x56, 0x00, 0xC0},
+{0x57, 0x00, 0x14},
+{0x67, 0x00, 0x28},
+{0x81, 0x00, 0xB3},
+{0x82, 0x00, 0x72},
+{0x83, 0x00, 0x40},
+{0x85, 0x00, 0xB3},
+{0x86, 0x00, 0x72},
+{0x87, 0x00, 0x40},
+{0x88, 0x00, 0xDE}, // after set mode
+{0x89, 0x00, 0xB3},
+{0x8A, 0x00, 0x72},
+{0x8B, 0x00, 0x40},
+{0x8C, 0x00, 0xDE},
+{0x8D, 0x00, 0xB3},
+{0x8E, 0x00, 0x92},
+{0x8F, 0x00, 0x40},
+{0x93, 0x00, 0x00},
+{0x94, 0x00, 0x80},
+{0x95, 0x00, 0x08},
+{0x96, 0x00, 0x80},
+{0x97, 0x00, 0x08},
+{0x9C, 0x00, 0x80},
+{0x9D, 0x00, 0x08},
+{0x9E, 0x00, 0x80},
+{0x9F, 0x00, 0x08},
+{0xA0, 0x00, 0x15},
+{0xA1, 0x00, 0x15},
+{0xA2, 0x00, 0x15},
+{0xA3, 0x00, 0x15},
+
+
+{0xD8, 0xFE, 0x01}, // Com reset
+{0xC8, 0xFE, 0x01},
+{0xE8, 0xFE, 0x01},
+{0xF8, 0xFE, 0x01},
+
+{0xD8, 0xFE, 0x00}, // Com reset
+{0xC8, 0xFE, 0x00},
+{0xE8, 0xFE, 0x00},
+{0xF8, 0xFE, 0x00},
+
+
+{0xC4, 0xFF, 0xFF}, // Clear status
+{0xC5, 0xFF, 0xFF},
+{0xC6, 0xFF, 0xFF},
+{0xC7, 0xFF, 0xFF},
+{0xD4, 0xFF, 0xFF},
+{0xD5, 0xFF, 0xFF},
+{0xD6, 0xFF, 0xFF},
+{0xD7, 0xFF, 0xFF},
+{0xE4, 0xFF, 0xFF}, // Clear status
+{0xE5, 0xFF, 0xFF},
+{0xE6, 0xFF, 0xFF},
+{0xE7, 0xFF, 0xFF},
+{0xF4, 0xFF, 0xFF},
+{0xF5, 0xFF, 0xFF},
+{0xF6, 0xFF, 0xFF},
+{0xF7, 0xFF, 0xFF},
+
+{0x00, 0x00, 0x00} //End of table
+};
+
+static void sata_init(struct device *dev)
+{
+ struct southbridge_sis_sis966_config *conf;
+
+
+
+ conf = dev->chip_info;
+ print_debug("SATA_INIT:---------->\n");
+
+//-------------- enable IDE (SiS1183) -------------------------
+{
+ uint8_t temp8;
+ int i=0;
+ while(SiS_SiS1183_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_SiS1183_init[i][0]);
+ temp8 &= SiS_SiS1183_init[i][1];
+ temp8 |= SiS_SiS1183_init[i][2];
+ pci_write_config8(dev, SiS_SiS1183_init[i][0], temp8);
+ i++;
+ };
+}
+//-----------------------------------------------------------
+
+{
+uint32_t i,j;
+uint32_t temp32;
+
+for (i=0;i<10;i++){
+ temp32=0;
+ temp32= pci_read_config32(dev, 0xC0);
+ for ( j=0;j<0xFFFF;j++);
+ printk(BIOS_DEBUG, "status= %x\n",temp32);
+ if (((temp32&0xF) == 0x3) || ((temp32&0xF) == 0x0)) break;
+}
+
+}
+
+#if DEBUG_SATA
+{
+ int i;
+
+ print_debug("****** SATA PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+#endif
+
+ print_debug("SATA_INIT:<----------\n");
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+// .enable = sis966_enable,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver sata0_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_SATA,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "sis966.h"
-
-u8 SiS_SiS7502_init[7][3]={
-{0x04, 0xFF, 0x07},
-{0x2C, 0xFF, 0x39},
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x91},
-{0x2F, 0xFF, 0x01},
-{0x04, 0xFF, 0x06},
-{0x00, 0x00, 0x00} //End of table
-};
-
-static int set_bits(u32 port, u32 mask, u32 val)
-{
- u32 dword;
- int count;
-
- val &= mask;
- dword = read32(port);
- dword &= ~mask;
- dword |= val;
- write32(port, dword);
-
- count = 50;
- do {
- dword = read32(port);
- dword &= mask;
- udelay(100);
- } while ((dword != val) && --count);
-
- if(!count) return -1;
-
- udelay(500);
- return 0;
-
-}
-
-static u32 send_verb(u32 base, u32 verb)
-{
- u32 dword;
-
- dword = read32(base + 0x68);
- dword=dword|(unsigned long)0x0002;
- write32(base + 0x68, dword);
- do {
- dword = read32(base + 0x68);
- } while ((dword & 1)!=0);
- write32(base + 0x60, verb);
- udelay(500);
- dword = read32(base + 0x68);
- dword =(dword |0x1);
- write32(base + 0x68, dword);
- do {
- udelay(100);
- dword = read32(base + 0x68);
- } while ((dword & 3) != 2);
-
- dword = read32(base + 0x64);
- return dword;
-}
-
-
-static int codec_detect(u32 base)
-{
- u32 dword;
- int idx=0;
-
- /* 1 */ // controller reset
- printk(BIOS_DEBUG, "controller reset\n");
-
- set_bits(base + 0x08, 1, 1);
-
- do{
- dword = read32(base + 0x08)&0x1;
- if(idx++>1000) { printk(BIOS_DEBUG, "controller reset fail !!! \n"); break;}
- } while (dword !=1);
-
- dword=send_verb(base,0x000F0000); // get codec VendorId and DeviceId
-
- if(dword==0) {
- printk(BIOS_DEBUG, "No codec!\n");
- return 0;
- }
-
- printk(BIOS_DEBUG, "Codec ID = %x\n", dword);
-
- dword=0x1;
- return dword;
-
-}
-
-
-static u32 verb_data[] = {
-
-//14
- 0x01471c10,
- 0x01471d40,
- 0x01471e01,
- 0x01471f01,
-//15
- 0x01571c12,
- 0x01571d10,
- 0x01571e01,
- 0x01571f01,
-//16
- 0x01671c11,
- 0x01671d60,
- 0x01671e01,
- 0x01671f01,
-//17
- 0x01771c14,
- 0x01771d20,
- 0x01771e01,
- 0x01771f01,
-//18
- 0x01871c40,
- 0x01871d98,
- 0x01871ea1,
- 0x01871f01,
-//19
- 0x01971c50,
- 0x01971d98,
- 0x01971ea1,
- 0x01971f02,
-//1a
- 0x01a71c4f,
- 0x01a71d30,
- 0x01a71e81,
- 0x01a71f01,
-//1b
- 0x01b71c20,
- 0x01b71d40,
- 0x01b71e01,
- 0x01b71f02,
-//1c
- 0x01c71cf0,
- 0x01c71d01,
- 0x01c71e33,
- 0x01c71f59,
-//1d
- 0x01d71c01,
- 0x01d71de6,
- 0x01d71e05,
- 0x01d71f40,
-//1e
- 0x01e71c30,
- 0x01e71d11,
- 0x01e71e44,
- 0x01e71f01,
-//1f
- 0x01f71c60,
- 0x01f71d61,
- 0x01f71ec4,
- 0x01f71f01,
-};
-
-static unsigned find_verb(u32 viddid, u32 **verb)
-{
- if((viddid == 0x10ec0883) || (viddid == 0x10ec0882) || (viddid == 0x10ec0880)) return 0;
- *verb = (u32 *)verb_data;
- return sizeof(verb_data)/sizeof(u32);
-}
-
-
-static void codec_init(u32 base, int addr)
-{
- u32 dword;
- u32 *verb;
- unsigned verb_size;
- int i;
-
- /* 1 */
- do {
- dword = read32(base + 0x68);
- } while (dword & 1);
-
- dword = (addr<<28) | 0x000f0000;
- write32(base + 0x60, dword);
-
- do {
- dword = read32(base + 0x68);
- } while ((dword & 3)!=2);
-
- dword = read32(base + 0x64);
-
- /* 2 */
- printk(BIOS_DEBUG, "codec viddid: %08x\n", dword);
- verb_size = find_verb(dword, &verb);
-
- if(!verb_size) {
- printk(BIOS_DEBUG, "No verb!\n");
- return;
- }
-
- printk(BIOS_DEBUG, "verb_size: %d\n", verb_size);
- /* 3 */
- for(i=0; i<verb_size; i++) {
- send_verb(base,verb[i]);
- }
- printk(BIOS_DEBUG, "verb loaded!\n");
-}
-
-static void codecs_init(u32 base, u32 codec_mask)
-{
- codec_init(base, 0);
- return;
-}
-
-static void aza_init(struct device *dev)
-{
- u32 base;
- struct resource *res;
- u32 codec_mask;
-
- print_debug("AZALIA_INIT:---------->\n");
-
-//-------------- enable AZA (SiS7502) -------------------------
-{
- u8 temp8;
- int i=0;
- while(SiS_SiS7502_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_SiS7502_init[i][0]);
- temp8 &= SiS_SiS7502_init[i][1];
- temp8 |= SiS_SiS7502_init[i][2];
- pci_write_config8(dev, SiS_SiS7502_init[i][0], temp8);
- i++;
- };
-}
-//-----------------------------------------------------------
-
-
- // put audio to D0 state
- pci_write_config8(dev, 0x54,0x00);
-
-#if DEBUG_AZA
-{
- int i;
-
- print_debug("****** Azalia PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-#endif
-
- res = find_resource(dev, 0x10);
- if(!res)
- return;
-
- base = res->base;
- printk(BIOS_DEBUG, "base = 0x%08x\n", base);
-
- codec_mask = codec_detect(base);
-
- if(codec_mask) {
- printk(BIOS_DEBUG, "codec_mask = %02x\n", codec_mask);
- codecs_init(base, codec_mask);
- }
-
- print_debug("AZALIA_INIT:<----------\n");
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations aza_audio_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-// .enable = sis966_enable,
- .init = aza_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver azaaudio_driver __pci_driver = {
- .ops = &aza_audio_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_HD_AUDIO,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <reset.h>
-
-static unsigned get_sbdn(unsigned bus)
-{
- device_t dev;
-
- /* Find the device. */
- dev = pci_locate_device_on_bus(
- PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761),
- bus);
-
- return (dev>>15) & 0x1f;
-}
-
-void hard_reset(void)
-{
- set_bios_reset();
-
- /* full reset */
- outb(0x0a, 0x0cf9);
- outb(0x0e, 0x0cf9);
-}
-
-static void enable_fid_change_on_sb(unsigned sbbusn, unsigned sbdn)
-{
- /* default value for sis966 is good */
- /* set VFSMAF ( VID/FID System Management Action Field) to 2 */
-}
-
-void soft_reset(void)
-{
- set_bios_reset();
-
- /* link reset */
- outb(0x02, 0x0cf9);
- outb(0x06, 0x0cf9);
-
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-void sis966_early_pcie_setup(unsigned busnx, unsigned devnx, unsigned anactrl_io_base, unsigned pci_e_x)
-{
- uint32_t tgio_ctrl;
- uint32_t pll_ctrl;
- uint32_t dword;
- int i;
- device_t dev;
- dev = PCI_DEV(busnx, devnx+1, 1);
- dword = pci_read_config32(dev, 0xe4);
- dword |= 0x3f0; // disable it at first
- pci_write_config32(dev, 0xe4, dword);
-
- for(i=0; i<3; i++) {
- tgio_ctrl = inl(anactrl_io_base + 0xcc);
- tgio_ctrl &= ~(3<<9);
- tgio_ctrl |= (i<<9);
- outl(tgio_ctrl, anactrl_io_base + 0xcc);
- pll_ctrl = inl(anactrl_io_base + 0x30);
- pll_ctrl |= (1<<31);
- outl(pll_ctrl, anactrl_io_base + 0x30);
- do {
- pll_ctrl = inl(anactrl_io_base + 0x30);
- } while (!(pll_ctrl & 1));
- }
- tgio_ctrl = inl(anactrl_io_base + 0xcc);
- tgio_ctrl &= ~((7<<4)|(1<<8));
- tgio_ctrl |= (pci_e_x<<4)|(1<<8);
- outl(tgio_ctrl, anactrl_io_base + 0xcc);
-
-// wait 100us
- udelay(100);
-
- dword = pci_read_config32(dev, 0xe4);
- dword &= ~(0x3f0); // enable
- pci_write_config32(dev, 0xe4, dword);
-
-// need to wait 100ms
- mdelay(100);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-static const unsigned int pcie_ss_tbl[] = {
- 0x0C504103f,
- 0x0C504103f,
- 0x0C504103f,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5042040,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C504b049,
- 0x0C504b049,
- 0x0C504a048,
- 0x0C504a048,
- 0x0C5049047,
- 0x0C5049047,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5048046,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5047045,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5046044,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5045043,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5044042,
- 0x0C5043041,
- 0x0C5043041,
- 0x0C5042040,
- 0x0C5042040,
-};
-static const unsigned int sata_ss_tbl[] = {
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904b049,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c904a048,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9049047,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9048046,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9047045,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9046044,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9045043,
- 0x0c9044042,
- 0x0c9044042,
- 0x0c9044042,
-};
-
-static const unsigned int cpu_ss_tbl[] = {
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5034032,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5035033,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5036034,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5037035,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5038036,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503b039,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C503a038,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
- 0x0C5039037,
-};
-
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "sis966_smbus.h"
-
-#define SMBUS0_IO_BASE 0x8D0
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-int smbus_wait_until_ready(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(smbus_io_base + SMBHSTSTAT);
- val &= 0x1f;
- if (val == 0) {
- return 0;
- }
- outb(val,smbus_io_base + SMBHSTSTAT);
- } while(--loops);
- return -2;
-}
-
-int smbus_wait_until_done(unsigned smbus_io_base)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
-
- val = inb(smbus_io_base + 0x00);
- if ( (val & 0xff) != 0x02) {
- return 0;
- }
- } while(--loops);
- return -3;
-}
-
-int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* byte data recv */
- outb(0x05, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
-
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */
-
- /* read results of transaction */
- byte = inb(smbus_io_base + SMBHSTCMD);
-
- if (global_status_register != 0x80) { // lose check, otherwise it should be 0
- return -1;
- }
- return byte;
-}
-
-int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val)
-{
- unsigned global_status_register;
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* set the command... */
- outb(val, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- /* set up for a byte data write */
- outb(0x04, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
-
- if (global_status_register != 0x80) {
- return -1;
- }
- return 0;
-}
-
-static inline int do_smbus_read_byte(unsigned smbus_io_base, unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- outb(0xff, smbus_io_base + 0x00);
- smbus_delay();
- outb(0x20, smbus_io_base + 0x03);
- smbus_delay();
-
- outb(((device & 0x7f) << 1)|1 , smbus_io_base + 0x04);
- smbus_delay();
- outb(address & 0xff, smbus_io_base + 0x05);
- smbus_delay();
- outb(0x12, smbus_io_base + 0x03);
- smbus_delay();
-
-int i,j;
-for(i=0;i<0x1000;i++)
-{
- if (inb(smbus_io_base + 0x00) != 0x08)
- { smbus_delay();
- for(j=0;j<0xFFFF;j++);
- }
-};
-
- global_status_register = inb(smbus_io_base + 0x00);
- byte = inb(smbus_io_base + 0x08);
-
- if (global_status_register != 0x08) { // lose check, otherwise it should be 0
- print_debug("Fail");print_debug("\r\t");
- return -1;
- }
- print_debug("Success");print_debug("\r\t");
- return byte;
-}
-
-
-static inline int do_smbus_write_byte(unsigned smbus_io_base, unsigned device, unsigned address, unsigned char val)
-{
- unsigned global_status_register;
-
- outb(val, smbus_io_base + SMBHSTDAT0);
- smbus_delay();
-
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 0, smbus_io_base + SMBXMITADD);
- smbus_delay();
-
- outb(address & 0xff, smbus_io_base + SMBHSTCMD);
- smbus_delay();
-
- /* set up for a byte data write */
- outb(0x06, smbus_io_base + SMBHSTPRTCL);
- smbus_delay();
-
- /* poll for transaction completion */
- if (smbus_wait_until_done(smbus_io_base) < 0) {
- return -3;
- }
- global_status_register = inb(smbus_io_base + SMBHSTSTAT) & 0x80; /* lose check */;
-
- if (global_status_register != 0x80) {
- return -1;
- }
- return 0;
-}
-
-
-
-static const uint8_t SiS_LPC_init[34][3]={
-{0x04, 0xF8, 0x07}, //Reg 0x04
-{0x45, 0x00, 0x00}, //Reg 0x45 //Enable Rom Flash
-{0x46, 0x00, 0x3D}, //Reg 0x46
-{0x47, 0x00, 0xDD}, //Reg 0x47
-{0x48, 0x00, 0x12}, //Reg 0x48
-{0x64, 0x00, 0xFF}, //Reg 0x64
-{0x65, 0x00, 0xC1}, //Reg 0x65
-{0x68, 0x00, 0x89}, //Reg 0x68 //SB.ASM, START POST
-{0x69, 0x00, 0x80}, //Reg 0x69
-{0x6B, 0x00, 0x00}, //Reg 0x6B //SBBB.ASM
-{0x6C, 0xFF, 0x97}, //Reg 0x6C //SBBB.ASM
-{0x6E, 0x00, 0x00}, //Reg 0x6E //SBBB.ASM But in Early Post sets 0x04.
-{0x6F, 0xFF, 0x14}, //Reg 0x6F //SBBB.ASM
-{0x77, 0x00, 0x0E}, //Reg 0x77 //SBOEM.ASM, EARLY POST
-{0x78, 0x00, 0x20}, //Reg 0x78
-{0x7B, 0x00, 0x88}, //Reg 0x7B
-{0x7F, 0x00, 0x40}, //Reg 0x7F //SBOEM.ASM, EARLY POST
-{0xC1, 0x00, 0xF0}, //Reg 0xC1
-{0xC2, 0x00, 0x01}, //Reg 0xC2
-{0xC3, 0x00, 0x00}, //Reg 0xC3 //NBAGPBB.ASM
-{0xC9, 0x00, 0x80}, //Reg 0xC9
-{0xCF, 0x00, 0x45}, //Reg 0xCF
-{0xD0, 0x00, 0x02}, //Reg 0xD0
-{0xD4, 0x00, 0x44}, //Reg 0xD4
-{0xD5, 0x00, 0x62}, //Reg 0xD5
-{0xD6, 0x00, 0x32}, //Reg 0xD6
-{0xD8, 0x00, 0x45}, //Reg 0xD8
-{0xDA, 0x00, 0xDA}, //Reg 0xDA
-{0xDB, 0x00, 0x61}, //Reg 0xDB
-{0xDC, 0x00, 0xAA}, //Reg 0xDC
-{0xDD, 0x00, 0xAA}, //Reg 0xDD
-{0xDE, 0x00, 0xAA}, //Reg 0xDE
-{0xDF, 0x00, 0xAA}, //Reg 0xDF
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_NBPCIE_init[43][3]={
-{0x3D, 0x00, 0x00}, //Reg 0x3D
-{0x1C, 0xFE, 0x01}, //Reg 0x1C
-{0x1D, 0xFE, 0x01}, //Reg 0x1D
-{0x24, 0xFE, 0x01}, //Reg 0x24
-{0x26, 0xFE, 0x01}, //Reg 0x26
-{0x40, 0xFF, 0x10}, //Reg 0x40
-{0x43, 0xFF, 0x78}, //Reg 0x43
-{0x44, 0xFF, 0x02}, //Reg 0x44
-{0x45, 0xFF, 0x10}, //Reg 0x45
-{0x48, 0xFF, 0x52}, //Reg 0x48
-{0x49, 0xFF, 0xE3}, //Reg 0x49
-{0x5A, 0x00, 0x00}, //Reg 0x4A
-{0x4B, 0x00, 0x16}, //Reg 0x4B
-{0x4C, 0x00, 0x80}, //Reg 0x4C
-{0x4D, 0x00, 0x02}, //Reg 0x4D
-{0x4E, 0x00, 0x00}, //Reg 0x4E
-{0x5C, 0x00, 0x52}, //Reg 0x5C
-{0x5E, 0x00, 0x10}, //Reg 0x5E
-{0x34, 0x00, 0xD0}, //Reg 0x34
-{0xD0, 0x00, 0x01}, //Reg 0xD0
-{0x4F, 0x00, 0x80}, //Reg 0x4F
-{0xA1, 0x00, 0xF4}, //Reg 0xA1
-{0xA2, 0x7F, 0x00}, //Reg 0xA2
-{0xBD, 0x00, 0xA0}, //Reg 0xBD
-{0xD1, 0xFF, 0x00}, //Reg 0xD1
-{0xD3, 0xFE, 0x01}, //Reg 0xD3
-{0xD4, 0x18, 0x20}, //Reg 0xD4
-{0xD5, 0xF0, 0x00}, //Reg 0xD5
-{0xDD, 0xFF, 0x00}, //Reg 0xDD
-{0xDE, 0xEC, 0x10}, //Reg 0xDE
-{0xDF, 0xFF, 0x00}, //Reg 0xDF
-{0xE0, 0xF7, 0x00}, //Reg 0xE0
-{0xE3, 0xEF, 0x10}, //Reg 0xE3
-{0xE4, 0x7F, 0x80}, //Reg 0xE4
-{0xE5, 0xFF, 0x00}, //Reg 0xE5
-{0xE6, 0x06, 0x00}, //Reg 0xE6
-{0xE7, 0xFF, 0x00}, //Reg 0xE7
-{0xF5, 0x00, 0x00}, //Reg 0xF5
-{0xF6, 0x3F, 0x00}, //Reg 0xF6
-{0xF7, 0xFF, 0x00}, //Reg 0xF7
-{0xFD, 0xFF, 0x00}, //Reg 0xFD
-{0x4F, 0x00, 0x00}, //Reg 0x4F
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_ACPI_init[10][3]={
-{0x1B, 0xBF, 0x40}, //Reg 0x1B
-{0x84, 0x00, 0x0E}, //Reg 0x84
-{0x85, 0x00, 0x29}, //Reg 0x85
-{0x86, 0x00, 0xCB}, //Reg 0x86
-{0x87, 0x00, 0x55}, //Reg 0x87
-{0x6B, 0x00, 0x00}, //Reg 0x6B
-{0x6C, 0x68, 0x97}, //Reg 0x6C
-{0x6E, 0x00, 0x00}, //Reg 0x6E
-{0x6F, 0xFF, 0x14}, //Reg 0x6F
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_SBPCIE_init[13][3]={
-{0x48, 0x00 ,0x07}, //Reg 0x48
-{0x49, 0x00 ,0x06}, //Reg 0x49
-{0x4A, 0x00 ,0x0C}, //Reg 0x4A
-{0x4B, 0x00 ,0x00}, //Reg 0x4B
-{0x4E, 0x00 ,0x20}, //Reg 0x4E
-{0x1C, 0x00 ,0xF1}, //Reg 0x1C
-{0x1D, 0x00 ,0x01}, //Reg 0x1D
-{0x24, 0x00 ,0x01}, //Reg 0x24
-{0x26, 0x00 ,0x01}, //Reg 0x26
-{0xF6, 0x00 ,0x02}, //Reg 0xF6
-{0xF7, 0x00 ,0xC8}, //Reg 0xF7
-{0x5B, 0x00 ,0x40}, //Reg 0x5B
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_NB_init[56][3]={
-{0x04, 0x00 ,0x07}, //Reg 0x04
-{0x05, 0x00 ,0x00}, //Reg 0x05 // alex
-{0x0D, 0x00 ,0x20}, //Reg 0x0D
-{0x2C, 0x00 ,0x39}, //Reg 0x2C
-{0x2D, 0x00 ,0x10}, //Reg 0x2D
-{0x2E, 0x00 ,0x61}, //Reg 0x2E
-{0x2F, 0x00 ,0x07}, //Reg 0x2F
-{0x34, 0x00 ,0xA0}, //Reg 0x34
-{0x40, 0x00 ,0x36}, //Reg 0x40
-{0x42, 0x00 ,0xB9}, //Reg 0x42
-{0x43, 0x00 ,0x8B}, //Reg 0x43
-{0x44, 0x00 ,0x05}, //Reg 0x44
-{0x45, 0x00 ,0xFF}, //Reg 0x45
-{0x46, 0x00 ,0x90}, //Reg 0x46
-{0x47, 0x00 ,0xA0}, //Reg 0x47
-//{0x4C, 0xFF ,0x09}, //Reg 0x4C // SiS307 enable
-{0x4E, 0x00 ,0x00}, //Reg 0x4E
-{0x4F, 0x00 ,0x02}, //Reg 0x4F
-{0x5B, 0x00 ,0x44}, //Reg 0x5B
-{0x5D, 0x00 ,0x00}, //Reg 0x5D
-{0x5E, 0x00 ,0x25}, //Reg 0x5E
-{0x61, 0x00 ,0xB0}, //Reg 0x61
-{0x65, 0x00 ,0xB0}, //Reg 0x65
-{0x68, 0x00 ,0x4C}, //Reg 0x68
-{0x69, 0x00 ,0xD0}, //Reg 0x69
-{0x6B, 0x00 ,0x07}, //Reg 0x6B
-{0x6C, 0x00 ,0xDD}, //Reg 0x6C
-{0x6D, 0x00 ,0xAD}, //Reg 0x6D
-{0x6E, 0x00 ,0xE8}, //Reg 0x6E
-{0x6F, 0x00 ,0x4D}, //Reg 0x6F
-{0x70, 0x00 ,0x00}, //Reg 0x70
-{0x71, 0x00 ,0x80}, //Reg 0x71
-{0x72, 0x00 ,0x00}, //Reg 0x72
-{0x73, 0x00 ,0x00}, //Reg 0x73
-{0x74, 0x00 ,0x01}, //Reg 0x74
-{0x75, 0x00 ,0x10}, //Reg 0x75
-{0x7E, 0x00 ,0x29}, //Reg 0x7E
-{0x8B, 0x00 ,0x10}, //Reg 0x8B
-{0x8D, 0x00 ,0x03}, //Reg 0x8D
-{0xA1, 0x00 ,0xD0}, //Reg 0xA1
-{0xA2, 0x00 ,0x30}, //Reg 0xA2
-{0xA4, 0x00 ,0x0B}, //Reg 0xA4
-{0xA9, 0x00 ,0x02}, //Reg 0xA9
-{0xB0, 0x00 ,0x30}, //Reg 0xB0
-{0xB4, 0x00 ,0x30}, //Reg 0xB4
-{0x90, 0x00 ,0x00}, //Reg 0x90
-{0x91, 0x00 ,0x00}, //Reg 0x91
-{0x92, 0x00 ,0x00}, //Reg 0x92
-{0x93, 0x00 ,0x00}, //Reg 0x93
-{0x94, 0x00 ,0x00}, //Reg 0x94
-{0x95, 0x00 ,0x00}, //Reg 0x95
-{0x96, 0x00 ,0x00}, //Reg 0x96
-{0x97, 0x00 ,0x00}, //Reg 0x97
-{0x98, 0x00 ,0x00}, //Reg 0x98
-{0x99, 0x00 ,0x00}, //Reg 0x99
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_NBAGP_init[34][3]={
-{0xCF, 0xDF, 0x00}, //HT issue
-{0x06, 0xDF, 0x20},
-{0x1E, 0xDF, 0x20},
-{0x50, 0x00, 0x02},
-{0x51, 0x00, 0x00},
-{0x54, 0x00, 0x09},
-{0x55, 0x00, 0x00},
-{0x56, 0x00, 0x80},
-{0x58, 0x00, 0x08},
-{0x60, 0x00, 0xB1},
-{0x61, 0x00, 0x02},
-{0x62, 0x00, 0x60},
-{0x63, 0x00, 0x60},
-{0x64, 0x00, 0xAA},
-{0x65, 0x00, 0x18},
-{0x68, 0x00, 0x23},
-{0x69, 0x00, 0x23},
-{0x6A, 0x00, 0xC8},
-{0x6B, 0x00, 0x08},
-{0x6C, 0x00, 0x00},
-{0x6D, 0x00, 0x00},
-{0x6E, 0x00, 0x08},
-{0x6F, 0x00, 0x00},
-{0xBB, 0x00, 0x00},
-{0xB5, 0x00, 0x30},
-{0xB0, 0x00, 0xDB},
-{0xB6, 0x00, 0x73},
-{0xB7, 0x00, 0x50},
-{0xBA, 0xBF, 0x41},
-{0xB4, 0x3F, 0xC0},
-{0xBF, 0xF9, 0x06},
-{0xBA, 0x00, 0x61},
-{0xBD, 0x7F, 0x80},
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_ACPI_2_init[56][3]={
-{0x00, 0x00, 0xFF}, //Reg 0x00
-{0x01, 0x00, 0xFF}, //Reg 0x01
-{0x02, 0x00, 0x00}, //Reg 0x02
-{0x03, 0x00, 0x00}, //Reg 0x03
-{0x16, 0x00, 0x00}, //Reg 0x16
-{0x20, 0x00, 0xFF}, //Reg 0x20
-{0x21, 0x00, 0xFF}, //Reg 0x21
-{0x22, 0x00, 0x00}, //Reg 0x22
-{0x23, 0x00, 0x00}, //Reg 0x23
-{0x24, 0x00, 0x55}, //Reg 0x24
-{0x25, 0x00, 0x55}, //Reg 0x25
-{0x26, 0x00, 0x55}, //Reg 0x26
-{0x27, 0x00, 0x55}, //Reg 0x27
-{0x2A, 0x00, 0x40}, //Reg 0x2A
-{0x2B, 0x00, 0x10}, //Reg 0x2B
-{0x2E, 0x00, 0xFF}, //Reg 0x2E
-{0x30, 0x00, 0xFF}, //Reg 0x30
-{0x31, 0x00, 0xFF}, //Reg 0x31
-{0x32, 0x00, 0x00}, //Reg 0x32
-{0x33, 0x00, 0x00}, //Reg 0x33
-{0x40, 0x00, 0xFF}, //Reg 0x40
-{0x41, 0x00, 0xFF}, //Reg 0x41
-{0x42, 0x00, 0x00}, //Reg 0x42
-{0x43, 0x00, 0x00}, //Reg 0x43
-{0x4A, 0x00, 0x00}, //Reg 0x4A
-{0x4E, 0x00, 0x0F}, //Reg 0x4E
-{0x5A, 0x00, 0x00}, //Reg 0x5A
-{0x5B, 0x00, 0x00}, //Reg 0x5B
-{0x62, 0x00, 0x00}, //Reg 0x62
-{0x63, 0x00, 0x04}, //Reg 0x63
-{0x68, 0x00, 0xFF}, //Reg 0x68
-{0x76, 0x00, 0xA0}, //Reg 0x76
-{0x77, 0x00, 0x22}, //Reg 0x77
-{0x78, 0xDF, 0x20}, //Reg 0x78
-{0x7A, 0x00, 0x10}, //Reg 0x7A
-{0x7C, 0x00, 0x45}, //Reg 0x7C
-{0x7D, 0x00, 0xB8}, //Reg 0x7D
-{0x7F, 0x00, 0x00}, //Reg 0x7F
-{0x80, 0x00, 0x1C}, //Reg 0x80
-{0x82, 0x00, 0x01}, //Reg 0x82
-{0x84, 0x00, 0x0E}, //Reg 0x84
-{0x85, 0x00, 0x29}, //Reg 0x85
-{0x86, 0x00, 0xCB}, //Reg 0x86
-{0x87, 0x00, 0x55}, //Reg 0x87
-{0x88, 0x00, 0x04}, //Reg 0x88
-{0x96, 0x00, 0x80}, //Reg 0x96
-{0x99, 0x00, 0x80}, //Reg 0x99
-{0x9A, 0x00, 0x15}, //Reg 0x9A
-{0x9D, 0x00, 0x05}, //Reg 0x9D
-{0x9E, 0x00, 0x00}, //Reg 0x9E
-{0x9F, 0x00, 0x04}, //Reg 0x9F
-{0xB0, 0x00, 0x6D}, //Reg 0xB0
-{0xB1, 0x00, 0x8C}, //Reg 0xB1
-{0xB9, 0x00, 0xFF}, //Reg 0xB9
-{0xBA, 0x00, 0x3F}, //Reg 0xBA
-{0x00, 0x00, 0x00} //End of table
-};
-
-static const uint8_t SiS_SiS1183_init[44][3]={
-{0x04, 0x00, 0x05},
-{0x09, 0x00, 0x05},
-{0x2C, 0x00, 0x39},
-{0x2D, 0x00, 0x10},
-{0x2E, 0x00, 0x83},
-{0x2F, 0x00, 0x11},
-{0x90, 0x00, 0x40},
-{0x91, 0x00, 0x00}, // set mode
-{0x50, 0x00, 0xA2},
-{0x52, 0x00, 0xA2},
-{0x55, 0x00, 0x96},
-{0x52, 0x00, 0xA2},
-{0x55, 0xF7, 0x00},
-{0x56, 0x00, 0xC0},
-{0x57, 0x00, 0x14},
-{0x67, 0x00, 0x28},
-{0x81, 0x00, 0xB3},
-{0x82, 0x00, 0x72},
-{0x83, 0x00, 0x40},
-{0x85, 0x00, 0xB3},
-{0x86, 0x00, 0x72},
-{0x87, 0x00, 0x40},
-{0x88, 0x00, 0xDE}, // after set mode
-{0x89, 0x00, 0xB3},
-{0x8A, 0x00, 0x72},
-{0x8B, 0x00, 0x40},
-{0x8C, 0x00, 0xDE},
-{0x8D, 0x00, 0xB3},
-{0x8E, 0x00, 0x92},
-{0x8F, 0x00, 0x40},
-{0x93, 0x00, 0x00},
-{0x94, 0x00, 0x80},
-{0x95, 0x00, 0x08},
-{0x96, 0x00, 0x80},
-{0x97, 0x00, 0x08},
-{0x9C, 0x00, 0x80},
-{0x9D, 0x00, 0x08},
-{0x9E, 0x00, 0x80},
-{0x9F, 0x00, 0x08},
-{0xA0, 0x00, 0x15},
-{0xA1, 0x00, 0x15},
-{0xA2, 0x00, 0x15},
-{0xA3, 0x00, 0x15},
-{0x00, 0x00, 0x00} //End of table
-};
-
-/* In => Share Memory size
- => 00h : 0MBytes
- => 02h : 32MBytes
- => 03h : 64MBytes
- => 04h : 128MBytes
- => Others: Reserved
-*/
-static void Init_Share_Memory(uint8_t ShareSize)
-{
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
- pci_write_config8(dev, 0x4C, (pci_read_config8(dev, 0x4C) & 0x1F) | (ShareSize << 5));
-}
-
-/* In: => Aperture size
- => 00h : 32MBytes
- => 01h : 64MBytes
- => 02h : 128MBytes
- => 03h : 256MBytes
- => 04h : 512MBytes
- => Others: Reserved
-*/
-static void Init_Aper_Size(uint8_t AperSize)
-{
- device_t dev;
- uint16_t SiSAperSizeTable[]={0x0F38, 0x0F30, 0x0F20, 0x0F00, 0x0E00};
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_AMD, 0x1103), 0);
- pci_write_config8(dev, 0x90, AperSize << 1);
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
- pci_write_config16(dev, 0xB4, SiSAperSizeTable[AperSize]);
-}
-
-static void sis_init_stage1(void)
-{
- device_t dev;
- uint8_t temp8;
- int i;
- uint8_t GUI_En;
-
-// SiS_Chipset_Initialization
-// ========================== NB =============================
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
- i=0;
- while(SiS_NB_init[i][0] != 0)
- { temp8 = pci_read_config8(dev, SiS_NB_init[i][0]);
- temp8 &= SiS_NB_init[i][1];
- temp8 |= SiS_NB_init[i][2];
- pci_write_config8(dev, SiS_NB_init[i][0], temp8);
- i++;
- };
-
-// ========================== LPC =============================
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
- i=0;
- while(SiS_LPC_init[i][0] != 0)
- { temp8 = pci_read_config8(dev, SiS_LPC_init[i][0]);
- temp8 &= SiS_LPC_init[i][1];
- temp8 |= SiS_LPC_init[i][2];
- pci_write_config8(dev, SiS_LPC_init[i][0], temp8);
- i++;
- };
-// ========================== ACPI =============================
- i=0;
- while(SiS_ACPI_init[i][0] != 0)
- { temp8 = inb(0x800 + SiS_ACPI_init[i][0]);
- temp8 &= SiS_ACPI_init[i][1];
- temp8 |= SiS_ACPI_init[i][2];
- outb(temp8, 0x800 + SiS_ACPI_init[i][0]);
- i++;
- };
-// ========================== NBPCIE =============================
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Disable Internal GUI enable bit
- temp8 = pci_read_config8(dev, 0x4C);
- GUI_En = temp8 & 0x10;
- pci_write_config8(dev, 0x4C, temp8 & (!0x10));
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761_PCIE), 0);
- i=0;
- while(SiS_NBPCIE_init[i][0] != 0)
- { temp8 = pci_read_config8(dev, SiS_NBPCIE_init[i][0]);
- temp8 &= SiS_NBPCIE_init[i][1];
- temp8 |= SiS_NBPCIE_init[i][2];
- pci_write_config8(dev, SiS_NBPCIE_init[i][0], temp8);
- i++;
- };
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Restore Internal GUI enable bit
- temp8 = pci_read_config8(dev, 0x4C);
- pci_write_config8(dev, 0x4C, temp8 | GUI_En);
-
- return;
-}
-
-
-
-static void sis_init_stage2(void)
-{
- device_t dev;
- msr_t msr;
- int i;
- uint8_t temp8;
- uint16_t temp16;
-
-
-// ========================== NB_AGP =============================
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0); //Enable Internal GUI enable bit
- pci_write_config8(dev, 0x4C, pci_read_config8(dev, 0x4C) | 0x10);
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_AGP), 0);
- i=0;
-
- while(SiS_NBAGP_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_NBAGP_init[i][0]);
- temp8 &= SiS_NBAGP_init[i][1];
- temp8 |= SiS_NBAGP_init[i][2];
- pci_write_config8(dev, SiS_NBAGP_init[i][0], temp8);
- i++;
- };
-
-/**
- * Share Memory size
- * => 00h : 0MBytes
- * => 02h : 32MBytes
- * => 03h : 64MBytes
- * => 04h : 128MBytes
- * => Others: Reserved
- *
- * Aperture size
- * => 00h : 32MBytes
- * => 01h : 64MBytes
- * => 02h : 128MBytes
- * => 03h : 256MBytes
- * => 04h : 512MBytes
- * => Others: Reserved
- */
-
- Init_Share_Memory(0x02); //0x02 : 32M
- Init_Aper_Size(0x01); //0x1 : 64M
-
-// ========================== NB =============================
-
- printk(BIOS_DEBUG, "Init NorthBridge sis761 -------->\n");
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS761), 0);
- msr = rdmsr(0xC001001A);
- printk(BIOS_DEBUG, "Memory Top Bound %x\n",msr.lo );
-
- temp16=(pci_read_config8(dev, 0x4C) & 0xE0) >> 5;
- temp16=0x0001<<(temp16-1);
- temp16<<=8;
-
- printk(BIOS_DEBUG, "Integrated VGA Shared memory size=%dM bytes\n", temp16 >> 4);
- pci_write_config16(dev, 0x8E, (msr.lo >> 16) -temp16*1);
- pci_write_config8(dev, 0x7F, 0x08); // ACPI Base
- outb(inb(0x856) | 0x40, 0x856); // Auto-Reset Function
-
-// ========================== ACPI =============================
- i=0;
- printk(BIOS_DEBUG, "Init ACPI -------->\n");
- do
- { temp8 = inb(0x800 + SiS_ACPI_2_init[i][0]);
- temp8 &= SiS_ACPI_2_init[i][1];
- temp8 |= SiS_ACPI_2_init[i][2];
- outb(temp8, 0x800 + SiS_ACPI_2_init[i][0]);
- i++;
- }while(SiS_ACPI_2_init[i][0] != 0);
-
-// ========================== Misc =============================
- printk(BIOS_DEBUG, "Init Misc -------->\n");
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
-
- /* R77h Internal PCI Device Enable 1 (Power On Value = 0h)
- * bit5 : USB Emulation (1=enable)
- * bit3 : Internal Keyboard Controller Port Access Control enable (1=enable)
- * bit2 : Reserved
- * bit1 : Mask USB A20M# Event (1:K8, 0:P4/K7)
- */
- pci_write_config8(dev, 0x77, 0x2E);
-
- /* R7Ch Internal PCI Device Enable 2 (Power On Value = 0h)
- * bit4 : SATA Controller Enable (0=enable)
- * bit3 : IDE Controller Enable (0=enable)
- * bit2 : MAC Controller Enable (0=enable)
- * bit1 : MODEM Controller Enable (1=disable)
- * bit0 : AC97 Controller Enable (1=disable)
- */
- pci_write_config8(dev, 0x7C, 0x03);
-
- /* R7Eh Enable Azalia (Power On Value = 08h)
- * bit3 : Azalia Controller Enable (0=enable)
- */
- pci_write_config8(dev, 0x7E, 0x00); // azalia controller enable
- temp8=inb(0x878)|0x4; //bit2=1 enable Azalia =0 enable AC97
- outb(temp8, 0x878); // ACPI select AC97 or HDA controller
- printk(BIOS_DEBUG, "Audio select %x\n",inb(0x878));
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_SATA), 0);
-
- if (!dev)
- print_debug("SiS 1183 does not exist !!");
- // SATA Set Mode
- pci_write_config8(dev, 0x90, (pci_read_config8(dev, 0x90)&0x3F) | 0x40);
-
-}
-
-
-
-static void enable_smbus(void)
-{
- device_t dev;
- uint8_t temp8;
- printk(BIOS_DEBUG, "enable_smbus -------->\n");
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_SIS966_LPC), 0);
-
- /* set smbus iobase && enable ACPI Space*/
- pci_write_config16(dev, 0x74, 0x0800); // Set ACPI Base
- temp8=pci_read_config8(dev, 0x40); // Enable ACPI Space
- pci_write_config8(dev, 0x40, temp8 | 0x80);
- temp8=pci_read_config8(dev, 0x76); // Enable SMBUS
- pci_write_config8(dev, 0x76, temp8 | 0x03);
-
- printk(BIOS_DEBUG, "enable_smbus <--------\n");
-}
-
-int smbus_read_byte(unsigned device, unsigned address)
-{
- return do_smbus_read_byte(SMBUS0_IO_BASE, device, address);
-}
-int smbus_write_byte(unsigned device, unsigned address, unsigned char val)
-{
- return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
- #define SIS966_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
- #define SIS966_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-static void sis966_enable_rom(void)
-{
- device_t addr;
-
- /* Enable 4MB rom access at 0xFFC00000 - 0xFFFFFFFF */
- addr = pci_locate_device(PCI_ID(0x1039, 0x0966), 0);
-
- /* Set the 4MB enable bit bit */
- pci_write_config8(addr, 0x40, pci_read_config8(addr, 0x40) | 0x11);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* TODO: Check whether this actually works (might be copy-paste leftover). */
-
-#include <stdint.h>
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <usbdebug.h>
-#include <device/pci_def.h>
-#include "sis966.h"
-
-#if CONFIG_HT_CHAIN_END_UNITID_BASE < CONFIG_HT_CHAIN_UNITID_BASE
-#define SIS966_DEVN_BASE CONFIG_HT_CHAIN_END_UNITID_BASE
-#else
-#define SIS966_DEVN_BASE CONFIG_HT_CHAIN_UNITID_BASE
-#endif
-
-void set_debug_port(unsigned int port)
-{
- u32 dword;
- device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Write the port number to 0x74[15:12]. */
- dword = pci_read_config32(dev, 0x74);
- dword &= ~(0xf << 12);
- dword |= (port << 12);
- pci_write_config32(dev, 0x74, dword);
-}
-
-void sis966_enable_usbdebug(unsigned int port)
-{
- device_t dev = PCI_DEV(0, SIS966_DEVN_BASE + 2, 1); /* USB EHCI */
-
- /* Mark the requested physical USB port (1-15) as the Debug Port. */
- set_debug_port(port);
-
- /* Set the EHCI BAR address. */
- pci_write_config32(dev, EHCI_BAR_INDEX, CONFIG_EHCI_BAR);
-
- /* Enable access to the EHCI memory space registers. */
- pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "sis966.h"
-
-uint8_t SiS_SiS5513_init[49][3]={
-{0x04, 0xFF, 0x05},
-{0x0D, 0xFF, 0x80},
-{0x2C, 0xFF, 0x39},
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x13},
-{0x2F, 0xFF, 0x55},
-{0x50, 0xFF, 0xA2},
-{0x51, 0xFF, 0x21},
-{0x53, 0xFF, 0x21},
-{0x54, 0xFF, 0x2A},
-{0x55, 0xFF, 0x96},
-{0x52, 0xFF, 0xA2},
-{0x56, 0xFF, 0x81},
-{0x57, 0xFF, 0xC0},
-{0x60, 0xFF, 0xFB},
-{0x61, 0xFF, 0xAA},
-{0x62, 0xFF, 0xFB},
-{0x63, 0xFF, 0xAA},
-{0x81, 0xFF, 0xB3},
-{0x82, 0xFF, 0x72},
-{0x83, 0xFF, 0x40},
-{0x85, 0xFF, 0xB3},
-{0x86, 0xFF, 0x72},
-{0x87, 0xFF, 0x40},
-{0x94, 0xFF, 0xC0},
-{0x95, 0xFF, 0x08},
-{0x96, 0xFF, 0xC0},
-{0x97, 0xFF, 0x08},
-{0x98, 0xFF, 0xCC},
-{0x99, 0xFF, 0x04},
-{0x9A, 0xFF, 0x0C},
-{0x9B, 0xFF, 0x14},
-{0xA0, 0xFF, 0x11},
-{0x57, 0xFF, 0xD0},
-
-{0xD8, 0xFE, 0x01}, // Com reset
-{0xC8, 0xFE, 0x01},
-{0xC4, 0xFF, 0xFF}, // Clear status
-{0xC5, 0xFF, 0xFF},
-{0xC6, 0xFF, 0xFF},
-{0xC7, 0xFF, 0xFF},
-{0xD4, 0xFF, 0xFF},
-{0xD5, 0xFF, 0xFF},
-{0xD6, 0xFF, 0xFF},
-{0xD7, 0xFF, 0xFF},
-
-
-{0x2C, 0xFF, 0x39}, // set subsystem ID
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x13},
-{0x2F, 0xFF, 0x55},
-
-
-{0x00, 0x00, 0x00} //End of table
-};
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_sis_sis966_config *conf;
- /* Enable ide devices so the linux ide driver will work */
- uint32_t dword;
- uint16_t word;
- uint8_t byte;
- conf = dev->chip_info;
-
-
-
-print_debug("IDE_INIT:---------->\n");
-
-
-//-------------- enable IDE (SiS5513) -------------------------
-{
- uint8_t temp8;
- int i=0;
- while(SiS_SiS5513_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_SiS5513_init[i][0]);
- temp8 &= SiS_SiS5513_init[i][1];
- temp8 |= SiS_SiS5513_init[i][2];
- pci_write_config8(dev, SiS_SiS5513_init[i][0], temp8);
- i++;
- };
-}
-//-----------------------------------------------------------
-
- word = pci_read_config16(dev, 0x50);
- /* Ensure prefetch is disabled */
- word &= ~((1 << 15) | (1 << 13));
- if (conf->ide1_enable) {
- /* Enable secondary ide interface */
- word |= (1<<0);
- printk(BIOS_DEBUG, "IDE1 \t");
- }
- if (conf->ide0_enable) {
- /* Enable primary ide interface */
- word |= (1<<1);
- printk(BIOS_DEBUG, "IDE0\n");
- }
-
- word |= (1<<12);
- word |= (1<<14);
-
- pci_write_config16(dev, 0x50, word);
-
-
- byte = 0x20 ; // Latency: 64-->32
- pci_write_config8(dev, 0xd, byte);
-
- dword = pci_read_config32(dev, 0xf8);
- dword |= 12;
- pci_write_config32(dev, 0xf8, dword);
-#if CONFIG_PCI_ROM_RUN == 1
- pci_dev_init(dev);
-#endif
-
-#if DEBUG_IDE
-{
- int i;
-
- print_debug("****** IDE PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-#endif
-print_debug("IDE_INIT:<----------\n");
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .scan_bus = 0,
-// .enable = sis966_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver ide_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_IDE,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2003 Linux Networx
- * Copyright (C) 2003 SuSE Linux AG
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pnp.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <pc80/mc146818rtc.h>
-#include <pc80/isa-dma.h>
-#include <bitops.h>
-#include <arch/io.h>
-#include <arch/ioapic.h>
-#include <cpu/x86/lapic.h>
-#include <stdlib.h>
-#include "sis966.h"
-#include <pc80/keyboard.h>
-
-#define NMI_OFF 0
-
-// 0x7a or e3
-#define PREVIOUS_POWER_STATE 0x7A
-
-#define MAINBOARD_POWER_OFF 0
-#define MAINBOARD_POWER_ON 1
-#define SLOW_CPU_OFF 0
-#define SLOW_CPU__ON 1
-
-#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
-#endif
-
-#undef SLAVE_INIT
-
-static void lpc_common_init(device_t dev)
-{
- uint8_t byte;
- uint32_t ioapic_base;
-
- /* IO APIC initialization */
- byte = pci_read_config8(dev, 0x74);
- byte |= (1<<0); // enable APIC
- pci_write_config8(dev, 0x74, byte);
- ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
-
- setup_ioapic(ioapic_base, 0); // Don't rename IO APIC ID
-}
-
-#ifdef SLAVE_INIT
-static void lpc_slave_init(device_t dev)
-{
- lpc_common_init(dev);
-}
-#endif
-
-static void lpc_usb_legacy_init(device_t dev)
-{
- uint16_t acpi_base;
-
- acpi_base = (pci_read_config8(dev,0x75) << 8);
-
- outb(inb(acpi_base + 0xbb) |0x80, acpi_base + 0xbb);
- outb(inb(acpi_base + 0xba) |0x80, acpi_base + 0xba);
-}
-
-static void lpc_init(device_t dev)
-{
- uint8_t byte;
- uint8_t byte_old;
- int on;
- int nmi_option;
-
- printk(BIOS_DEBUG, "LPC_INIT -------->\n");
- pc_keyboard_init(0);
-
- lpc_usb_legacy_init(dev);
- lpc_common_init(dev);
-
- /* power after power fail */
-
-
- on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
- get_option(&on, "power_on_after_fail");
- byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
- byte &= ~0x40;
- if (!on) {
- byte |= 0x40;
- }
- pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
- printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
-
- /* Throttle the CPU speed down for testing */
- on = SLOW_CPU_OFF;
- get_option(&on, "slow_cpu");
- if(on) {
- uint16_t pm10_bar;
- uint32_t dword;
- pm10_bar = (pci_read_config16(dev, 0x60)&0xff00);
- outl(((on<<1)+0x10) ,(pm10_bar + 0x10));
- dword = inl(pm10_bar + 0x10);
- on = 8-on;
- printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
- (on*12)+(on>>1),(on&1)*5);
- }
-
- /* Enable Error reporting */
- /* Set up sync flood detected */
- byte = pci_read_config8(dev, 0x47);
- byte |= (1 << 1);
- pci_write_config8(dev, 0x47, byte);
-
- /* Set up NMI on errors */
- byte = inb(0x70); // RTC70
- byte_old = byte;
- nmi_option = NMI_OFF;
- get_option(&nmi_option, "nmi");
- if (nmi_option) {
- byte &= ~(1 << 7); /* set NMI */
- } else {
- byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
- }
- if( byte != byte_old) {
- outb(byte, 0x70);
- }
-
- /* Initialize the real time clock */
- rtc_init(0);
-
- /* Initialize isa dma */
- isa_dma_init();
-
- printk(BIOS_DEBUG, "LPC_INIT <--------\n");
-}
-
-static void sis966_lpc_read_resources(device_t dev)
-{
- struct resource *res;
-
- /* Get the normal pci resources of this device */
- pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP
-
- /* Add an extra subtractive resource for both memory and I/O. */
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
- res->base = 0;
- res->size = 0x1000;
- res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
- res->base = 0xff800000;
- res->size = 0x00800000; /* 8 MB for flash */
- res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
- IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-/**
- * Enable resources for children devices.
- *
- * @param dev The device whos children's resources are to be enabled.
- */
-static void sis966_lpc_enable_childrens_resources(device_t dev)
-{
- struct bus *link;
- uint32_t reg, reg_var[4];
- int i;
- int var_num = 0;
-
- reg = pci_read_config32(dev, 0xa0);
-
- for (link = dev->link_list; link; link = link->next) {
- device_t child;
- for (child = link->children; child; child = child->sibling) {
- if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
- struct resource *res;
- for(res = child->resource_list; res; res = res->next) {
- unsigned long base, end; // don't need long long
- if(!(res->flags & IORESOURCE_IO)) continue;
- base = res->base;
- end = resource_end(res);
- printk(BIOS_DEBUG, "sis966 lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
- switch(base) {
- case 0x3f8: // COM1
- reg |= (1<<0); break;
- case 0x2f8: // COM2
- reg |= (1<<1); break;
- case 0x378: // Parallal 1
- reg |= (1<<24); break;
- case 0x3f0: // FD0
- reg |= (1<<20); break;
- case 0x220: // Aduio 0
- reg |= (1<<8); break;
- case 0x300: // Midi 0
- reg |= (1<<12); break;
- }
- if( (base == 0x290) || (base >= 0x400)) {
- if(var_num>=4) continue; // only 4 var ; compact them ?
- reg |= (1<<(28+var_num));
- reg_var[var_num++] = (base & 0xffff)|((end & 0xffff)<<16);
- }
- }
- }
- }
- }
- pci_write_config32(dev, 0xa0, reg);
- for(i=0;i<var_num;i++) {
- pci_write_config32(dev, 0xa8 + i*4, reg_var[i]);
- }
-
-
-}
-
-static void sis966_lpc_enable_resources(device_t dev)
-{
- pci_dev_enable_resources(dev);
- sis966_lpc_enable_childrens_resources(dev);
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations lpc_ops = {
- .read_resources = sis966_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = sis966_lpc_enable_resources,
- .init = lpc_init,
- .scan_bus = scan_static_bus,
-// .enable = sis966_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &lpc_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_LPC,
-};
-
-#ifdef SLAVE_INIT // No device?
-static struct device_operations lpc_slave_ops = {
- .read_resources = sis966_lpc_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = lpc_slave_init,
-// .enable = sis966_enable,
- .ops_pci = &lops_pci,
-};
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/smbus.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include <delay.h>
-#include "sis966.h"
-
-
-u8 SiS_SiS191_init[6][3]={
-{0x04, 0xFF, 0x07},
-{0x2C, 0xFF, 0x39},
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x91},
-{0x2F, 0xFF, 0x01},
-{0x00, 0x00, 0x00} //End of table
-};
-
-
-#define StatusReg 0x1
-#define SMI_READ 0x0
-#define SMI_REQUEST 0x10
-#define TRUE 1
-#define FALSE 0
-
-u16 MacAddr[3];
-
-
-static void writeApcByte(int addr, u8 value)
-{
- outb(addr,0x78);
- outb(value,0x79);
-}
-
-static u8 readApcByte(int addr)
-{
- u8 value;
- outb(addr,0x78);
- value=inb(0x79);
- return(value);
-}
-
-static void readApcMacAddr(void)
-{
- u8 i;
-
-// enable APC in south bridge sis966 D2F0
-
- outl(0x80001048,0xcf8);
- outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data
-
- printk(BIOS_DEBUG, "MAC addr in APC = ");
- for(i = 0x9 ; i <=0xe ; i++)
- {
- printk(BIOS_DEBUG, "%2.2x",readApcByte(i));
- }
- printk(BIOS_DEBUG, "\n");
-
- /* Set APC Reload */
- writeApcByte(0x7,readApcByte(0x7)&0xf7);
- writeApcByte(0x7,readApcByte(0x7)|0x0a);
-
- /* disable APC in south bridge */
- outl(0x80001048,0xcf8);
- outl(inl(0xcfc)&0xffffffbf,0xcfc);
-}
-
-static void set_apc(struct device *dev)
-{
- u16 addr;
- u16 i;
- u8 bTmp;
-
- /* enable APC in south bridge sis966 D2F0 */
- outl(0x80001048,0xcf8);
- outl((inl(0xcfc) & 0xfffffffd),0xcfc ); // enable IO78/79h for APC Index/Data
-
- for(i = 0 ; i <3; i++)
- {
- addr=0x9+2*i;
- writeApcByte(addr,(u8)(MacAddr[i]&0xFF));
- writeApcByte(addr+1L,(u8)((MacAddr[i]>>8)&0xFF));
- // printf("%x - ",readMacAddrByte(0x59+i));
- }
-
- /* Set APC Reload */
- writeApcByte(0x7,readApcByte(0x7)&0xf7);
- writeApcByte(0x7,readApcByte(0x7)|0x0a);
-
- /* disable APC in south bridge */
- outl(0x80001048,0xcf8);
- outl(inl(0xcfc)&0xffffffbf,0xcfc);
-
- // CFG reg0x73 bit=1, tell driver MAC Address load to APC
- bTmp = pci_read_config8(dev, 0x73);
- bTmp|=0x1;
- pci_write_config8(dev, 0x73, bTmp);
-}
-
-/**
- * Read one word out of the serial EEPROM.
- *
- * @param dev TODO
- * @param base TODO
- * @param Reg EEPROM word to read.
- * @return Contents of EEPROM word (Reg).
- */
-#define LoopNum 200
-static unsigned long ReadEEprom( struct device *dev, u32 base, u32 Reg)
-{
- u32 data;
- u32 i;
- u32 ulValue;
-
-
- ulValue = (0x80 | (0x2 << 8) | (Reg << 10)); //BIT_7
-
- write32(base+0x3c, ulValue);
-
- mdelay(10);
-
- for(i=0 ; i <= LoopNum; i++)
- {
- ulValue=read32(base+0x3c);
-
- if(!(ulValue & 0x0080)) //BIT_7
- break;
-
- mdelay(100);
- }
-
- mdelay(50);
-
- if(i==LoopNum) data=0x10000;
- else{
- ulValue=read32(base+0x3c);
- data = ((ulValue & 0xffff0000) >> 16);
- }
-
- return data;
-}
-
-static int phy_read(u32 base, unsigned phy_addr, unsigned phy_reg)
-{
- u32 ulValue;
- u32 Read_Cmd;
- u16 usData;
-
-
-
- Read_Cmd = ((phy_reg << 11) |
- (phy_addr << 6) |
- SMI_READ |
- SMI_REQUEST);
-
- // SmiMgtInterface Reg is the SMI management interface register(offset 44h) of MAC
- write32(base+0x44, Read_Cmd);
-
- // Polling SMI_REQ bit to be deasserted indicated read command completed
- do
- {
- // Wait 20 usec before checking status
- mdelay(20);
- ulValue = read32(base+0x44);
- } while((ulValue & SMI_REQUEST) != 0);
- //printk(BIOS_DEBUG, "base %x cmd %lx ret val %lx\n", tmp,Read_Cmd,ulValue);
- usData=(ulValue>>16);
-
-
-
- return usData;
-
-}
-
-// Detect a valid PHY
-// If there exist a valid PHY then return TRUE, else return FALSE
-static int phy_detect(u32 base,u16 *PhyAddr) //BOOL PHY_Detect()
-{
- int bFoundPhy = FALSE;
- u16 usData;
- int PhyAddress = 0;
-
-
- // Scan all PHY address(0 ~ 31) to find a valid PHY
- for(PhyAddress = 0; PhyAddress < 32; PhyAddress++)
- {
- usData=phy_read(base,PhyAddress,StatusReg); // Status register is a PHY's register(offset 01h)
-
- // Found a valid PHY
-
- if((usData != 0x0) && (usData != 0xffff))
- {
- bFoundPhy = TRUE;
- break;
- }
- }
-
-
- if(!bFoundPhy)
- {
- printk(BIOS_DEBUG, "PHY not found !!!! \n");
- }
-
- *PhyAddr=PhyAddress;
-
- return bFoundPhy;
-}
-
-
-static void nic_init(struct device *dev)
-{
- int val;
- u16 PhyAddr;
- u32 base;
- struct resource *res;
-
- print_debug("NIC_INIT:---------->\n");
-
-//-------------- enable NIC (SiS19x) -------------------------
-{
- u8 temp8;
- int i=0;
- while(SiS_SiS191_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_SiS191_init[i][0]);
- temp8 &= SiS_SiS191_init[i][1];
- temp8 |= SiS_SiS191_init[i][2];
- pci_write_config8(dev, SiS_SiS191_init[i][0], temp8);
- i++;
- };
-}
-//-----------------------------------------------------------
-
-{
- unsigned long i;
- unsigned long ulValue;
-
- res = find_resource(dev, 0x10);
-
- if(!res)
- {
- printk(BIOS_DEBUG, "NIC Cannot find resource..\n");
- return;
- }
- base = res->base;
- printk(BIOS_DEBUG, "NIC base address %x\n",base);
-
- if(!(val=phy_detect(base,&PhyAddr)))
- {
- printk(BIOS_DEBUG, "PHY detect fail !!!!\n");
- return;
- }
-
- ulValue=read32(base + 0x38L); // check EEPROM existing
-
- if((ulValue & 0x0002))
- {
-
- // read MAC address from EEPROM at first
-
- // if that is valid we will use that
-
- printk(BIOS_DEBUG, "EEPROM contents %lx \n",ReadEEprom( dev, base, 0LL));
- for(i=0;i<3;i++) {
- //status = smbus_read_byte(dev_eeprom, i);
- ulValue=ReadEEprom( dev, base, i+3L);
- if (ulValue ==0x10000) break; // error
-
- MacAddr[i] =ulValue & 0xFFFF;
-
- }
- }else{
- // read MAC address from firmware
- printk(BIOS_DEBUG, "EEPROM invalid!!\nReg 0x38h=%.8lx \n",ulValue);
- MacAddr[0]=read16(0xffffffc0); // mac address store at here
- MacAddr[1]=read16(0xffffffc2);
- MacAddr[2]=read16(0xffffffc4);
- }
-
- set_apc(dev);
-
- readApcMacAddr();
-
-#if DEBUG_NIC
-{
- int i;
-
- print_debug("****** NIC PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-
-
-#endif
-
-}
-
-print_debug("NIC_INIT:<----------\n");
-return;
-
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .scan_bus = 0,
-// .enable = sis966_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver nic_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_NIC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sis966.h"
-
-static void pcie_init(struct device *dev)
-{
-
- /* Enable pci error detecting */
- uint32_t dword;
-
- /* System error enable */
- dword = pci_read_config32(dev, 0x04);
- dword |= (1<<8); /* System error enable */
- dword |= (1<<30); /* Clear possible errors */
- pci_write_config32(dev, 0x04, dword);
-
-}
-
-static struct pci_operations lops_pci = {
- .set_subsystem = 0,
-};
-
-static struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .init = pcie_init,
- .scan_bus = pci_scan_bridge,
-// .enable = sis966_enable,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver pciebc_driver __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_PCIE,
-};
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <reset.h>
-
-#define PCI_DEV(BUS, DEV, FN) ( \
- (((BUS) & 0xFFF) << 20) | \
- (((DEV) & 0x1F) << 15) | \
- (((FN) & 0x7) << 12))
-
-typedef unsigned device_t;
-
-static void pci_write_config32(device_t dev, unsigned where, unsigned value)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- outl(value, 0xCFC);
-}
-
-static unsigned pci_read_config32(device_t dev, unsigned where)
-{
- unsigned addr;
- addr = (dev>>4) | where;
- outl(0x80000000 | (addr & ~3), 0xCF8);
- return inl(0xCFC);
-}
-
-#include "../../../northbridge/amd/amdk8/reset_test.c"
-
-void hard_reset(void)
-{
- set_bios_reset();
- /* Try rebooting through port 0xcf9 */
- /* Actually it is not a real hard_reset --- it only reset coherent link table, but not reset link freq and width */
- outb((0 <<3)|(0<<2)|(1<<1), 0xcf9);
- outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
-}
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <delay.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sis966.h"
-#include <arch/io.h>
-
-uint8_t SiS_SiS1183_init[68][3]={
-{0x04, 0x00, 0x05},
-{0x09, 0x00, 0x05},
-{0x2C, 0x00, 0x39},
-{0x2D, 0x00, 0x10},
-{0x2E, 0x00, 0x83},
-{0x2F, 0x00, 0x11},
-{0x90, 0x00, 0x40},
-{0x91, 0x00, 0x00}, // set mode
-{0x50, 0x00, 0xA2},
-{0x52, 0x00, 0xA2},
-{0x55, 0x00, 0x96},
-{0x52, 0x00, 0xA2},
-{0x55, 0xF7, 0x00},
-{0x56, 0x00, 0xC0},
-{0x57, 0x00, 0x14},
-{0x67, 0x00, 0x28},
-{0x81, 0x00, 0xB3},
-{0x82, 0x00, 0x72},
-{0x83, 0x00, 0x40},
-{0x85, 0x00, 0xB3},
-{0x86, 0x00, 0x72},
-{0x87, 0x00, 0x40},
-{0x88, 0x00, 0xDE}, // after set mode
-{0x89, 0x00, 0xB3},
-{0x8A, 0x00, 0x72},
-{0x8B, 0x00, 0x40},
-{0x8C, 0x00, 0xDE},
-{0x8D, 0x00, 0xB3},
-{0x8E, 0x00, 0x92},
-{0x8F, 0x00, 0x40},
-{0x93, 0x00, 0x00},
-{0x94, 0x00, 0x80},
-{0x95, 0x00, 0x08},
-{0x96, 0x00, 0x80},
-{0x97, 0x00, 0x08},
-{0x9C, 0x00, 0x80},
-{0x9D, 0x00, 0x08},
-{0x9E, 0x00, 0x80},
-{0x9F, 0x00, 0x08},
-{0xA0, 0x00, 0x15},
-{0xA1, 0x00, 0x15},
-{0xA2, 0x00, 0x15},
-{0xA3, 0x00, 0x15},
-
-
-{0xD8, 0xFE, 0x01}, // Com reset
-{0xC8, 0xFE, 0x01},
-{0xE8, 0xFE, 0x01},
-{0xF8, 0xFE, 0x01},
-
-{0xD8, 0xFE, 0x00}, // Com reset
-{0xC8, 0xFE, 0x00},
-{0xE8, 0xFE, 0x00},
-{0xF8, 0xFE, 0x00},
-
-
-{0xC4, 0xFF, 0xFF}, // Clear status
-{0xC5, 0xFF, 0xFF},
-{0xC6, 0xFF, 0xFF},
-{0xC7, 0xFF, 0xFF},
-{0xD4, 0xFF, 0xFF},
-{0xD5, 0xFF, 0xFF},
-{0xD6, 0xFF, 0xFF},
-{0xD7, 0xFF, 0xFF},
-{0xE4, 0xFF, 0xFF}, // Clear status
-{0xE5, 0xFF, 0xFF},
-{0xE6, 0xFF, 0xFF},
-{0xE7, 0xFF, 0xFF},
-{0xF4, 0xFF, 0xFF},
-{0xF5, 0xFF, 0xFF},
-{0xF6, 0xFF, 0xFF},
-{0xF7, 0xFF, 0xFF},
-
-{0x00, 0x00, 0x00} //End of table
-};
-
-static void sata_init(struct device *dev)
-{
- struct southbridge_sis_sis966_config *conf;
-
-
-
- conf = dev->chip_info;
- print_debug("SATA_INIT:---------->\n");
-
-//-------------- enable IDE (SiS1183) -------------------------
-{
- uint8_t temp8;
- int i=0;
- while(SiS_SiS1183_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_SiS1183_init[i][0]);
- temp8 &= SiS_SiS1183_init[i][1];
- temp8 |= SiS_SiS1183_init[i][2];
- pci_write_config8(dev, SiS_SiS1183_init[i][0], temp8);
- i++;
- };
-}
-//-----------------------------------------------------------
-
-{
-uint32_t i,j;
-uint32_t temp32;
-
-for (i=0;i<10;i++){
- temp32=0;
- temp32= pci_read_config32(dev, 0xC0);
- for ( j=0;j<0xFFFF;j++);
- printk(BIOS_DEBUG, "status= %x\n",temp32);
- if (((temp32&0xF) == 0x3) || ((temp32&0xF) == 0x0)) break;
-}
-
-}
-
-#if DEBUG_SATA
-{
- int i;
-
- print_debug("****** SATA PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-#endif
-
- print_debug("SATA_INIT:<----------\n");
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations sata_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
-// .enable = sis966_enable,
- .init = sata_init,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver sata0_driver __pci_driver = {
- .ops = &sata_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_SATA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/smbus_def.h>
-
-#define SMBHSTSTAT 0x1
-#define SMBHSTPRTCL 0x0
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x2
-#define SMBHSTDAT0 0x4
-#define SMBHSTDAT1 0x5
-
-/* Between 1-10 seconds, We should never timeout normally
- * Longer than this is just painful when a timeout condition occurs.
- */
-#define SMBUS_TIMEOUT (100*1000*10)
-
-int smbus_wait_until_ready(unsigned smbus_io_base);
-int smbus_wait_until_done(unsigned smbus_io_base);
-int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device);
-int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val);
-int smbus_read_byte(unsigned device, unsigned address);
-int smbus_write_byte(unsigned device, unsigned address, unsigned char val);
-
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include "sis966.h"
-
-uint8_t SiS_SiS7001_init[16][3]={
-{0x04, 0x00, 0x07},
-{0x0C, 0x00, 0x08},
-{0x0D, 0x00, 0x20},
-
-{0x2C, 0xFF, 0x39},
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x01},
-{0x2F, 0xFF, 0x70},
-
-{0x44, 0x00, 0x54},
-{0x45, 0x00, 0xAD},
-{0x46, 0x00, 0x01},
-{0x47, 0x00, 0x00},
-
-{0x48, 0x00, 0x73},
-{0x49, 0x00, 0x02},
-{0x4A, 0x00, 0x00},
-{0x4B, 0x00, 0x00},
-
-{0x00, 0x00, 0x00} //End of table
-};
-
-static void usb_init(struct device *dev)
-{
- print_debug("USB 1.1 INIT:---------->\n");
-
-//-------------- enable USB1.1 (SiS7001) -------------------------
-{
- uint8_t temp8;
- int i=0;
-
- while(SiS_SiS7001_init[i][0] != 0)
- { temp8 = pci_read_config8(dev, SiS_SiS7001_init[i][0]);
- temp8 &= SiS_SiS7001_init[i][1];
- temp8 |= SiS_SiS7001_init[i][2];
- pci_write_config8(dev, SiS_SiS7001_init[i][0], temp8);
- i++;
- };
-}
-//-----------------------------------------------------------
-
-#if DEBUG_USB
-{
- int i;
-
- print_debug("****** USB 1.1 PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-#endif
- print_debug("USB 1.1 INIT:<----------\n");
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
-// .enable = sis966_enable,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_USB,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Tyan Computer
- * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
- * Copyright (C) 2006,2007 AMD
- * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
- * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
- * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <device/pci_ops.h>
-#include <arch/io.h>
-#include "sis966.h"
-#include <usbdebug.h>
-
-extern struct ehci_debug_info dbg_info;
-
-u8 SiS_SiS7002_init[22][3]={
-{0x04, 0x00, 0x06},
-{0x0D, 0x00, 0x00},
-
-{0x2C, 0xFF, 0x39},
-{0x2D, 0xFF, 0x10},
-{0x2E, 0xFF, 0x02},
-{0x2F, 0xFF, 0x70},
-
-{0x74, 0x00, 0x00},
-{0x75, 0x00, 0x00},
-{0x76, 0x00, 0x00},
-{0x77, 0x00, 0x00},
-
-{0x7A, 0x00, 0x00},
-{0x7B, 0x00, 0x00},
-
-{0x40, 0x00, 0x20},
-{0x41, 0x00, 0x00},
-{0x42, 0x00, 0x00},
-{0x43, 0x00, 0x08},
-
-{0x44, 0x00, 0x04},
-
-{0x48, 0x00, 0x10},
-{0x49, 0x00, 0x80},
-{0x4A, 0x00, 0x07},
-{0x4B, 0x00, 0x00},
-
-{0x00, 0x00, 0x00} //End of table
-};
-
-static void usb2_init(struct device *dev)
-{
- u32 base;
- struct resource *res;
-
- print_debug("USB 2.0 INIT:---------->\n");
-
-//-------------- enable USB2.0 (SiS7002) -------------------------
-{
- u8 temp8;
- int i=0;
-
- while(SiS_SiS7002_init[i][0] != 0)
- {
- temp8 = pci_read_config8(dev, SiS_SiS7002_init[i][0]);
- temp8 &= SiS_SiS7002_init[i][1];
- temp8 |= SiS_SiS7002_init[i][2];
- pci_write_config8(dev, SiS_SiS7002_init[i][0], temp8);
- i++;
- };
-}
-
- res = find_resource(dev, 0x10);
- if(!res)
- return;
-
- base = res->base;
- printk(BIOS_DEBUG, "base = 0x%08x\n", base);
- write32(base+0x20, 0x2);
-//-----------------------------------------------------------
-
-#if DEBUG_USB2
-{
- int i;
-
- print_debug("****** USB 2.0 PCI config ******");
- print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
-
- for(i=0;i<0xff;i+=4){
- if((i%16)==0){
- print_debug("\n");
- print_debug_hex8(i);
- print_debug(": ");
- }
- print_debug_hex32(pci_read_config32(dev,i));
- print_debug(" ");
- }
- print_debug("\n");
-}
-#endif
- print_debug("USB 2.0 INIT:<----------\n");
-}
-
-static void usb2_set_resources(struct device *dev)
-{
-#if CONFIG_USBDEBUG
- struct resource *res;
- unsigned base;
- unsigned old_debug;
-
- old_debug = get_ehci_debug();
- set_ehci_debug(0);
-#endif
- pci_dev_set_resources(dev);
-
-#if CONFIG_USBDEBUG
- res = find_resource(dev, 0x10);
- set_ehci_debug(old_debug);
- if (!res) return;
- base = res->base;
- set_ehci_base(base);
- report_resource_stored(dev, res, "");
-#endif
-
-}
-
-static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
-{
- pci_write_config32(dev, 0x40,
- ((device & 0xffff) << 16) | (vendor & 0xffff));
-}
-static struct pci_operations lops_pci = {
- .set_subsystem = lpci_set_subsystem,
-};
-
-static struct device_operations usb2_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = usb2_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb2_init,
-// .enable = sis966_enable,
- .scan_bus = 0,
- .ops_pci = &lops_pci,
-};
-
-static const struct pci_driver usb2_driver __pci_driver = {
- .ops = &usb2_ops,
- .vendor = PCI_VENDOR_ID_SIS,
- .device = PCI_DEVICE_ID_SIS_SIS966_USB2,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x1
+#define SMBHSTPRTCL 0x0
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x2
+#define SMBHSTDAT0 0x4
+#define SMBHSTDAT1 0x5
+
+/* Between 1-10 seconds, We should never timeout normally
+ * Longer than this is just painful when a timeout condition occurs.
+ */
+#define SMBUS_TIMEOUT (100*1000*10)
+
+int smbus_wait_until_ready(unsigned smbus_io_base);
+int smbus_wait_until_done(unsigned smbus_io_base);
+int do_smbus_recv_byte(unsigned smbus_io_base, unsigned device);
+int do_smbus_send_byte(unsigned smbus_io_base, unsigned device, unsigned char val);
+int smbus_read_byte(unsigned device, unsigned address);
+int smbus_write_byte(unsigned device, unsigned address, unsigned char val);
+
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "sis966.h"
+
+uint8_t SiS_SiS7001_init[16][3]={
+{0x04, 0x00, 0x07},
+{0x0C, 0x00, 0x08},
+{0x0D, 0x00, 0x20},
+
+{0x2C, 0xFF, 0x39},
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x01},
+{0x2F, 0xFF, 0x70},
+
+{0x44, 0x00, 0x54},
+{0x45, 0x00, 0xAD},
+{0x46, 0x00, 0x01},
+{0x47, 0x00, 0x00},
+
+{0x48, 0x00, 0x73},
+{0x49, 0x00, 0x02},
+{0x4A, 0x00, 0x00},
+{0x4B, 0x00, 0x00},
+
+{0x00, 0x00, 0x00} //End of table
+};
+
+static void usb_init(struct device *dev)
+{
+ print_debug("USB 1.1 INIT:---------->\n");
+
+//-------------- enable USB1.1 (SiS7001) -------------------------
+{
+ uint8_t temp8;
+ int i=0;
+
+ while(SiS_SiS7001_init[i][0] != 0)
+ { temp8 = pci_read_config8(dev, SiS_SiS7001_init[i][0]);
+ temp8 &= SiS_SiS7001_init[i][1];
+ temp8 |= SiS_SiS7001_init[i][2];
+ pci_write_config8(dev, SiS_SiS7001_init[i][0], temp8);
+ i++;
+ };
+}
+//-----------------------------------------------------------
+
+#if DEBUG_USB
+{
+ int i;
+
+ print_debug("****** USB 1.1 PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+#endif
+ print_debug("USB 1.1 INIT:<----------\n");
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+// .enable = sis966_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_USB,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Tyan Computer
+ * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
+ * Copyright (C) 2006,2007 AMD
+ * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
+ * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS)
+ * Written by Morgan Tsai <my_tsai@sis.com> for SiS.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <arch/io.h>
+#include "sis966.h"
+#include <usbdebug.h>
+
+extern struct ehci_debug_info dbg_info;
+
+u8 SiS_SiS7002_init[22][3]={
+{0x04, 0x00, 0x06},
+{0x0D, 0x00, 0x00},
+
+{0x2C, 0xFF, 0x39},
+{0x2D, 0xFF, 0x10},
+{0x2E, 0xFF, 0x02},
+{0x2F, 0xFF, 0x70},
+
+{0x74, 0x00, 0x00},
+{0x75, 0x00, 0x00},
+{0x76, 0x00, 0x00},
+{0x77, 0x00, 0x00},
+
+{0x7A, 0x00, 0x00},
+{0x7B, 0x00, 0x00},
+
+{0x40, 0x00, 0x20},
+{0x41, 0x00, 0x00},
+{0x42, 0x00, 0x00},
+{0x43, 0x00, 0x08},
+
+{0x44, 0x00, 0x04},
+
+{0x48, 0x00, 0x10},
+{0x49, 0x00, 0x80},
+{0x4A, 0x00, 0x07},
+{0x4B, 0x00, 0x00},
+
+{0x00, 0x00, 0x00} //End of table
+};
+
+static void usb2_init(struct device *dev)
+{
+ u32 base;
+ struct resource *res;
+
+ print_debug("USB 2.0 INIT:---------->\n");
+
+//-------------- enable USB2.0 (SiS7002) -------------------------
+{
+ u8 temp8;
+ int i=0;
+
+ while(SiS_SiS7002_init[i][0] != 0)
+ {
+ temp8 = pci_read_config8(dev, SiS_SiS7002_init[i][0]);
+ temp8 &= SiS_SiS7002_init[i][1];
+ temp8 |= SiS_SiS7002_init[i][2];
+ pci_write_config8(dev, SiS_SiS7002_init[i][0], temp8);
+ i++;
+ };
+}
+
+ res = find_resource(dev, 0x10);
+ if(!res)
+ return;
+
+ base = res->base;
+ printk(BIOS_DEBUG, "base = 0x%08x\n", base);
+ write32(base+0x20, 0x2);
+//-----------------------------------------------------------
+
+#if DEBUG_USB2
+{
+ int i;
+
+ print_debug("****** USB 2.0 PCI config ******");
+ print_debug("\n 03020100 07060504 0B0A0908 0F0E0D0C");
+
+ for(i=0;i<0xff;i+=4){
+ if((i%16)==0){
+ print_debug("\n");
+ print_debug_hex8(i);
+ print_debug(": ");
+ }
+ print_debug_hex32(pci_read_config32(dev,i));
+ print_debug(" ");
+ }
+ print_debug("\n");
+}
+#endif
+ print_debug("USB 2.0 INIT:<----------\n");
+}
+
+static void usb2_set_resources(struct device *dev)
+{
+#if CONFIG_USBDEBUG
+ struct resource *res;
+ unsigned base;
+ unsigned old_debug;
+
+ old_debug = get_ehci_debug();
+ set_ehci_debug(0);
+#endif
+ pci_dev_set_resources(dev);
+
+#if CONFIG_USBDEBUG
+ res = find_resource(dev, 0x10);
+ set_ehci_debug(old_debug);
+ if (!res) return;
+ base = res->base;
+ set_ehci_base(base);
+ report_resource_stored(dev, res, "");
+#endif
+
+}
+
+static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, 0x40,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+static struct pci_operations lops_pci = {
+ .set_subsystem = lpci_set_subsystem,
+};
+
+static struct device_operations usb2_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = usb2_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb2_init,
+// .enable = sis966_enable,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static const struct pci_driver usb2_driver __pci_driver = {
+ .ops = &usb2_ops,
+ .vendor = PCI_VENDOR_ID_SIS,
+ .device = PCI_DEVICE_ID_SIS_SIS966_USB2,
+};
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
-driver-y += pci7420_cardbus.c
-driver-y += pci7420_firewire.c
+driver-y += cardbus.c
+driver-y += firewire.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <device/cardbus.h>
+#include "pci7420.h"
+#include "chip.h"
+
+#ifdef ODD_IRQ_FIXUP
+static int cardbus_count = 0;
+#endif
+
+static void pci7420_cardbus_init(device_t dev)
+{
+ u8 reg8;
+ u16 reg16;
+ u32 reg32;
+
+ struct southbridge_ti_pci7420_config *config = dev->chip_info;
+ int smartcard_enabled = 0;
+
+ printk(BIOS_DEBUG, "TI PCI7420/7620 init\n");
+
+ if (!config) {
+ printk(BIOS_DEBUG, "PCI7420: No configuration found.\n");
+ } else {
+ smartcard_enabled = config->smartcard_enabled;
+ }
+
+ reg32 = pci_read_config32(dev, SYSCTL);
+ reg32 |= RIMUX;
+ pci_write_config32(dev, SYSCTL, reg32);
+
+ /* Enable SPKROUT */
+ reg8 = pci_read_config8(dev, CARDCTL);
+ reg8 |= SPKROUTEN;
+ pci_write_config8(dev, CARDCTL, reg8);
+
+ /* Power switch select and FM disable */
+ reg16 = pci_read_config16(dev, GENCTL);
+ reg16 |= P12V_SW_SEL; // 12V capable power switch
+ if (smartcard_enabled == 0)
+ reg16 |= DISABLE_FM;
+ pci_write_config16(dev, GENCTL, reg16);
+
+ /* Multifunction routing status */
+ pci_write_config32(dev, MFUNC, 0x018a1b22);
+
+#ifdef ODD_IRQ_FIXUP
+ /* This is a workaround for buggy kernels. This should
+ * probably be read from the device tree, but as long
+ * as only one mainboard is using this bridge it does
+ * not matter.
+ *
+ * Basically what we do here is assign INTA to the first
+ * cardbus controller, and INTB to the second one. We know
+ * there are only two of them.
+ */
+ pci_write_config8(dev, PCI_INTERRUPT_PIN, cardbus_count);
+ cardbus_count++;
+#endif
+}
+
+static void pci7420_cardbus_read_resources(device_t dev)
+{
+ cardbus_read_resources(dev);
+}
+
+static void pci7420_cardbus_set_resources(device_t dev)
+{
+ printk(BIOS_DEBUG, "%s In set resources \n",dev_path(dev));
+
+ pci_dev_set_resources(dev);
+
+ printk(BIOS_DEBUG, "%s done set resources \n",dev_path(dev));
+}
+
+static struct device_operations ti_pci7420_ops = {
+ .read_resources = pci7420_cardbus_read_resources,
+ .set_resources = pci7420_cardbus_set_resources,
+ .enable_resources = cardbus_enable_resources,
+ .init = pci7420_cardbus_init,
+ .scan_bus = pci_scan_bridge,
+};
+
+static const struct pci_driver ti_pci7420_driver __pci_driver = {
+ .ops = &ti_pci7420_ops,
+ .vendor = 0x104c,
+ .device = 0xac8e,
+};
+
+static const struct pci_driver ti_pci7620_driver __pci_driver = {
+ .ops = &ti_pci7420_ops,
+ .vendor = 0x104c,
+ .device = 0xac8d,
+};
+
+static void ti_pci7420_enable_dev(device_t dev)
+{
+ /* Nothing here yet */
+}
+
+struct chip_operations southbridge_ti_pci7420_ops = {
+ CHIP_NAME("Texas Instruments PCI7420/7620 Cardbus Controller")
+ .enable_dev = ti_pci7420_enable_dev,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <device/cardbus.h>
+#include "pci7420.h"
+#include "chip.h"
+
+static void pci7420_firewire_init(device_t dev)
+{
+ printk(BIOS_DEBUG, "TI PCI7420/7620 FireWire init\n");
+
+#ifdef ODD_IRQ_FIXUP
+ /* This is a workaround for buggy kernels. This should
+ * probably be read from the device tree, but as long
+ * as only one mainboard is using this bridge it does
+ * not matter
+ */
+ pci_write_config8(dev, PCI_INTERRUPT_PIN, INTC);
+#endif
+}
+
+static struct device_operations ti_pci7420_firewire_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = pci7420_firewire_init,
+};
+
+static const struct pci_driver ti_pci7420_driver __pci_driver = {
+ .ops = &ti_pci7420_firewire_ops,
+ .vendor = 0x104c,
+ .device = 0x802e,
+};
+
+static void ti_pci7420_firewire_enable_dev(device_t dev)
+{
+ /* Nothing here yet */
+}
+
+struct chip_operations southbridge_ti_pci7420_firewire_ops = {
+ CHIP_NAME("Texas Instruments PCI7420/7620 FireWire (IEEE 1394)")
+ .enable_dev = ti_pci7420_firewire_enable_dev,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <device/cardbus.h>
-#include "pci7420.h"
-#include "chip.h"
-
-#ifdef ODD_IRQ_FIXUP
-static int cardbus_count = 0;
-#endif
-
-static void pci7420_cardbus_init(device_t dev)
-{
- u8 reg8;
- u16 reg16;
- u32 reg32;
-
- struct southbridge_ti_pci7420_config *config = dev->chip_info;
- int smartcard_enabled = 0;
-
- printk(BIOS_DEBUG, "TI PCI7420/7620 init\n");
-
- if (!config) {
- printk(BIOS_DEBUG, "PCI7420: No configuration found.\n");
- } else {
- smartcard_enabled = config->smartcard_enabled;
- }
-
- reg32 = pci_read_config32(dev, SYSCTL);
- reg32 |= RIMUX;
- pci_write_config32(dev, SYSCTL, reg32);
-
- /* Enable SPKROUT */
- reg8 = pci_read_config8(dev, CARDCTL);
- reg8 |= SPKROUTEN;
- pci_write_config8(dev, CARDCTL, reg8);
-
- /* Power switch select and FM disable */
- reg16 = pci_read_config16(dev, GENCTL);
- reg16 |= P12V_SW_SEL; // 12V capable power switch
- if (smartcard_enabled == 0)
- reg16 |= DISABLE_FM;
- pci_write_config16(dev, GENCTL, reg16);
-
- /* Multifunction routing status */
- pci_write_config32(dev, MFUNC, 0x018a1b22);
-
-#ifdef ODD_IRQ_FIXUP
- /* This is a workaround for buggy kernels. This should
- * probably be read from the device tree, but as long
- * as only one mainboard is using this bridge it does
- * not matter.
- *
- * Basically what we do here is assign INTA to the first
- * cardbus controller, and INTB to the second one. We know
- * there are only two of them.
- */
- pci_write_config8(dev, PCI_INTERRUPT_PIN, cardbus_count);
- cardbus_count++;
-#endif
-}
-
-static void pci7420_cardbus_read_resources(device_t dev)
-{
- cardbus_read_resources(dev);
-}
-
-static void pci7420_cardbus_set_resources(device_t dev)
-{
- printk(BIOS_DEBUG, "%s In set resources \n",dev_path(dev));
-
- pci_dev_set_resources(dev);
-
- printk(BIOS_DEBUG, "%s done set resources \n",dev_path(dev));
-}
-
-static struct device_operations ti_pci7420_ops = {
- .read_resources = pci7420_cardbus_read_resources,
- .set_resources = pci7420_cardbus_set_resources,
- .enable_resources = cardbus_enable_resources,
- .init = pci7420_cardbus_init,
- .scan_bus = pci_scan_bridge,
-};
-
-static const struct pci_driver ti_pci7420_driver __pci_driver = {
- .ops = &ti_pci7420_ops,
- .vendor = 0x104c,
- .device = 0xac8e,
-};
-
-static const struct pci_driver ti_pci7620_driver __pci_driver = {
- .ops = &ti_pci7420_ops,
- .vendor = 0x104c,
- .device = 0xac8d,
-};
-
-static void ti_pci7420_enable_dev(device_t dev)
-{
- /* Nothing here yet */
-}
-
-struct chip_operations southbridge_ti_pci7420_ops = {
- CHIP_NAME("Texas Instruments PCI7420/7620 Cardbus Controller")
- .enable_dev = ti_pci7420_enable_dev,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <device/cardbus.h>
-#include "pci7420.h"
-#include "chip.h"
-
-static void pci7420_firewire_init(device_t dev)
-{
- printk(BIOS_DEBUG, "TI PCI7420/7620 FireWire init\n");
-
-#ifdef ODD_IRQ_FIXUP
- /* This is a workaround for buggy kernels. This should
- * probably be read from the device tree, but as long
- * as only one mainboard is using this bridge it does
- * not matter
- */
- pci_write_config8(dev, PCI_INTERRUPT_PIN, INTC);
-#endif
-}
-
-static struct device_operations ti_pci7420_firewire_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = pci7420_firewire_init,
-};
-
-static const struct pci_driver ti_pci7420_driver __pci_driver = {
- .ops = &ti_pci7420_firewire_ops,
- .vendor = 0x104c,
- .device = 0x802e,
-};
-
-static void ti_pci7420_firewire_enable_dev(device_t dev)
-{
- /* Nothing here yet */
-}
-
-struct chip_operations southbridge_ti_pci7420_firewire_ops = {
- CHIP_NAME("Texas Instruments PCI7420/7620 FireWire (IEEE 1394)")
- .enable_dev = ti_pci7420_firewire_enable_dev,
-};
-driver-y += k8t890_ctrl.c
-driver-y += k8t890_dram.c
-driver-y += k8t890_bridge.c
-driver-y += k8t890_host.c
-driver-y += k8t890_host_ctrl.c
-driver-y += k8t890_pcie.c
-driver-y += k8t890_traf_ctrl.c
-driver-y += k8t890_error.c
-driver-y += k8m890_chrome.c
+driver-y += ctrl.c
+driver-y += dram.c
+driver-y += bridge.c
+driver-y += host.c
+driver-y += host_ctrl.c
+driver-y += pcie.c
+driver-y += traf_ctrl.c
+driver-y += error.c
+driver-y += chrome.c
chipset_bootblock_inc += $(src)/southbridge/via/k8t890/romstrap.inc
chipset_bootblock_lds += $(src)/southbridge/via/k8t890/romstrap.lds
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "k8t890.h"
+
+static void bridge_enable(struct device *dev)
+{
+ u8 tmp;
+ print_debug("B188 device dump\n");
+ /* VIA recommends this, sorry no known info. */
+
+ writeback(dev, 0x40, 0x91);
+ writeback(dev, 0x41, 0x40);
+ writeback(dev, 0x43, 0x44);
+ writeback(dev, 0x44, 0x31); /* K8M890 should have 0x35 datasheet
+ * says it is reserved
+ */
+ writeback(dev, 0x45, 0x3a);
+ writeback(dev, 0x46, 0x88); /* PCI ID lo */
+ writeback(dev, 0x47, 0xb1); /* PCI ID hi */
+
+ /* Bridge control, K8M890 bit 3 should be set to enable VGA on AGP
+ * (Forward VGA compatible memory and I/O cycles )
+ */
+
+ writeback(dev, 0x3e, 0x16);
+ dump_south(dev);
+
+ /* disable I/O and memory decode, or it freezes PCI bus during BAR sizing */
+ tmp = pci_read_config8(dev, PCI_COMMAND);
+ tmp &= ~0x3;
+ pci_write_config8(dev, PCI_COMMAND, tmp);
+
+}
+
+static const struct device_operations bridge_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .enable = bridge_enable,
+ .scan_bus = pci_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &bridge_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_BR,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 Luc Verhaegen <libv@skynet.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <string.h> /* for memset */
+#include "k8t890.h"
+
+#if CONFIG_VGA
+#include <pc80/vga_io.h>
+#include <pc80/vga.h>
+#include <arch/io.h>
+
+/*
+ *
+ */
+static void
+chrome_vga_init(struct device *dev)
+{
+ vga_sr_write(0x10, 0x01); /* unlock extended regs */
+
+ vga_sr_mask(0x1A, 0x02, 0x02); /* enable mmio */
+
+ vga_sr_mask(0x1A, 0x40, 0x40); /* Software Reset */
+
+ vga_cr_mask(0x6A, 0x00, 0xC8); /* Disable CRTC2 & Simultaneous */
+
+ /* Make sure that non of the primary VGA overflow registers are set */
+ vga_cr_write(0x33, 0x00);
+ vga_cr_write(0x35, 0x00);
+ vga_cr_mask(0x11, 0x00, 0x30);
+
+ vga_sr_mask(0x16, 0x00, 0x40); /* Wire CRT to CRTC1 */
+ vga_cr_mask(0x36, 0x00, 0x30); /* Power on CRT */
+
+ /* Disable Extended Display Mode */
+ vga_sr_mask(0x15, 0x00, 0x02);
+
+ /* Disable Wrap-around */
+ vga_sr_mask(0x15, 0x00, 0x20);
+
+ /* Disable Extended Mode memory access */
+ vga_sr_mask(0x1A, 0x00, 0x08);
+
+ /* Make sure that we only touch CRTC1s DAC */
+ vga_sr_mask(0x1A, 0x00, 0x01);
+
+ /* Set up power to the clocks/crtcs */
+ vga_sr_mask(0x19, 0x7F, 0x7F); /* enable clock gating for all. */
+ vga_sr_mask(0x1B, 0xC0, 0xC0); /* secondary clock according to pm */
+ vga_sr_mask(0x1B, 0x20, 0x30); /* primary clock is always on */
+
+ /* set everything according to PM/Engine idle state except pci dma */
+ vga_sr_write(0x2D, 0xFF); /* Power management control 1 */
+ vga_sr_write(0x2E, 0xFB); /* Power management control 2 */
+ vga_sr_write(0x3F, 0xFF); /* Power management control 3 */
+
+ /* now set up the engine clock. */
+ vga_sr_write(0x47, 0xB8);
+ vga_sr_write(0x48, 0x08);
+ vga_sr_write(0x49, 0x03);
+
+ /* trigger engine clock setting */
+ vga_sr_mask(0x40, 0x01, 0x01);
+ vga_sr_mask(0x40, 0, 0x01);
+
+ vga_cr_mask(0x30, 0x04, 0x04); /* Enable PowerNow in primary path */
+ vga_cr_mask(0x36, 0x01, 0x01); /* Enable PCI Power Management */
+
+ /* Power now indicators... */
+ vga_cr_write(0x41, 0xB9);
+ vga_cr_write(0x42, 0xB4);
+ /* could these be the CRTC2 power now indicators? */
+ vga_cr_write(0x9D, 0x80); /* Power Now Ending position enable */
+ vga_cr_write(0x9E, 0xB4); /* Power Now Control 3 */
+
+ /* primary fifo setting */
+ vga_sr_mask(0x16, 0x28, 0xBF); /* pthreshold: 160 */
+ vga_sr_write(0x17, 0x60); /* max depth: 194 */
+ vga_sr_mask(0x18, 0x0E, 0xBF); /* high priority threshold: 56 */
+ vga_sr_write(0x1C, 0x54); /* Fetch count */
+
+ vga_sr_write(0x20, 0x40); /* display queue typical arbiter control 0 */
+ vga_sr_write(0x21, 0x40); /* display queue typical arbiter control 1 */
+ vga_sr_mask(0x22, 0x14, 0x1F); /* display queue expire number */
+
+ /* Typical Arbiter Control */
+ vga_sr_mask(0x41, 0x40, 0xF0); /* Request threshold */
+ vga_sr_mask(0x42, 0x20, 0x20); /* Support Fetch Cycle with Length 2 */
+
+ vga_sr_write(0x50, 0x1F); /* AGP Control Register */
+ vga_sr_write(0x51, 0xF5); /* AGP FIFO Control 1 */
+
+ vga_cr_mask(0x33, 0x08, 0x08); /* Enable Prefetch Mode */
+}
+
+#endif /* CONFIG_VGA */
+
+/*
+ *
+ */
+static void
+chrome_init(struct device *dev)
+{
+ uint32_t fb_size, fb_address;
+
+ fb_size = k8m890_host_fb_size_get();
+ if (!fb_size) {
+ printk(BIOS_WARNING, "Chrome: Device has not been initialised in the"
+ " ramcontroller!\n");
+ return;
+ }
+
+ fb_address = pci_read_config32(dev, 0x10);
+ fb_address &= ~0x0F;
+ if (!fb_address) {
+ printk(BIOS_WARNING, "Chrome: No FB BAR assigned!\n");
+ return;
+ }
+
+ printk(BIOS_INFO, "Chrome: Using %dMB Framebuffer at 0x%08X.\n",
+ fb_size, fb_address);
+
+ //k8m890_host_fb_direct_set(fb_address);
+
+#if CONFIG_VGA
+ /* Now set up the VGA console */
+ vga_io_init(); /* Enable full IO access */
+
+ chrome_vga_init(dev);
+
+ vga_textmode_init();
+
+ printk(BIOS_INFO, "Chrome VGA Textmode initialized.\n");
+
+ /* if we don't have console, at least print something... */
+ vga_line_write(0, "Chrome VGA Textmode initialized.");
+#endif /* CONFIG_VGA */
+}
+
+static struct device_operations
+chrome_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = chrome_init,
+ .scan_bus = 0,
+ .enable = 0,
+};
+
+static const struct pci_driver unichrome_driver __pci_driver = {
+ .ops = &chrome_ops,
+ .vendor = 0x1106,
+ .device = 0x3230,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+
+/* We support here K8M890/K8T890 and VT8237R PCI1/Vlink which setup is not in separate
+ * PCI device 0:11.7, but it is mapped to PCI 0:0.7 (0x70-0x7c for PCI1)
+ */
+
+static void vt8237r_cfg(struct device *dev, struct device *devsb)
+{
+ u8 regm, regm3;
+
+ device_t devfun3;
+
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
+
+ if (!devfun3)
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
+
+ if (!devfun3)
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
+
+ pci_write_config8(dev, 0x70, 0xc2);
+
+ /* PCI Control */
+ pci_write_config8(dev, 0x72, 0xee);
+ pci_write_config8(dev, 0x73, 0x01);
+ pci_write_config8(dev, 0x74, 0x24);
+ pci_write_config8(dev, 0x75, 0x0f);
+ pci_write_config8(dev, 0x76, 0x50);
+ pci_write_config8(dev, 0x77, 0x08);
+ pci_write_config8(dev, 0x78, 0x01);
+ /* APIC on HT */
+ pci_write_config8(dev, 0x7c, 0x7f);
+ pci_write_config8(dev, 0x7f, 0x02);
+
+ /* WARNING: Need to copy some registers from NB (D0F3) to SB (D0F7). */
+
+ regm = pci_read_config8(devfun3, 0x88); /* Shadow mem CTRL */
+ pci_write_config8(dev, 0x57, regm);
+
+ regm = pci_read_config8(devfun3, 0x80); /* Shadow page C */
+ pci_write_config8(dev, 0x61, regm);
+
+ regm = pci_read_config8(devfun3, 0x81); /* Shadow page D */
+ pci_write_config8(dev, 0x62, regm);
+
+ regm = pci_read_config8(devfun3, 0x86); /* SMM and APIC decoding */
+ pci_write_config8(dev, 0xe6, regm);
+
+ regm3 = pci_read_config8(devfun3, 0x82);/* Shadow page E */
+
+ /*
+ * All access bits for 0xE0000-0xEFFFF encode as just 2 bits!
+ * So the NB reg is quite inconsistent, we expect there only 0xff or 0x00,
+ * and write them to 0x63 7-6 but! VIA 8237A has the mirror at 0x64!
+ */
+ if (regm3 == 0xff)
+ regm3 = 0xc0;
+ else
+ regm3 = 0x0;
+
+ /* Shadow page F + memhole copy */
+ regm = pci_read_config8(devfun3, 0x83);
+ pci_write_config8(dev, 0x63, regm3 | (regm & 0x3F));
+}
+
+
+
+/**
+ * Setup the V-Link for VT8237R, 8X mode.
+ *
+ * For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
+ *
+ * REG DEF AW VIA-8X VIA-4X
+ * -----------------------------
+ * NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
+ * NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
+ * NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
+ * NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
+ * SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
+ * SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
+ * SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
+ * SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
+ * V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
+ * V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
+ */
+
+static void vt8237r_vlink_init(struct device *dev)
+{
+ u8 reg;
+
+ /*
+ * This init code is valid only for the VT8237R! For different
+ * sounthbridges (e.g. VT8237A, VT8237S, VT8237 (without plus R)
+ * and VT8251) a different init code is required.
+ */
+
+ pci_write_config8(dev, 0xb5, 0x88);
+ pci_write_config8(dev, 0xb6, 0x88);
+ pci_write_config8(dev, 0xb7, 0x61);
+
+ reg = pci_read_config8(dev, 0xb4);
+ reg |= 0x11;
+ pci_write_config8(dev, 0xb4, reg);
+
+ pci_write_config8(dev, 0xb9, 0x98);
+ pci_write_config8(dev, 0xba, 0x77);
+ pci_write_config8(dev, 0xbb, 0x11);
+
+ reg = pci_read_config8(dev, 0xb8);
+ reg |= 0x1;
+ pci_write_config8(dev, 0xb8, reg);
+
+ pci_write_config8(dev, 0xb0, 0x06);
+ pci_write_config8(dev, 0xb1, 0x01);
+
+ /* Program V-link 8X 16bit full duplex, parity enabled. */
+ pci_write_config8(dev, 0x48, 0xa3);
+}
+
+static void ctrl_init(struct device *dev) {
+
+ /* TODO: Fix some ordering issue fo V-link set Rx77[6] and PCI1_Rx4F[0]
+ should to 1 */
+
+ /* C2P Read ACK Return Priority */
+ /* PCI CFG Address bits[27:24] are used as extended register address
+ bit[11:8] */
+
+ pci_write_config8(dev, 0x47, 0x30);
+
+ /* VT8237R specific configuration other SB are done in their own directories */
+
+ device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
+ if (devsb) {
+ vt8237r_vlink_init(dev);
+ vt8237r_cfg(dev, devsb);
+ }
+
+}
+
+static const struct device_operations ctrl_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ctrl_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &ctrl_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_7,
+};
+
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
+ .ops = &ctrl_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CF_7,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &ctrl_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_7,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <cpu/x86/msr.h>
+#include <cpu/amd/mtrr.h>
+#include <pc80/mc146818rtc.h>
+#include <bitops.h>
+#include "k8t890.h"
+
+static void dram_enable(struct device *dev)
+{
+ msr_t msr;
+ u16 reg;
+
+ /*
+ * Enable Lowest Interrupt arbitration for APIC, enable NB APIC
+ * decoding, MSI support, no SMRAM, compatible SMM.
+ */
+ pci_write_config8(dev, 0x86, 0x39);
+
+ /*
+ * We want to use the 0xC0000-0xEFFFF as RAM mark area as RW, even if
+ * memory is doing K8 the DMA from SB will fail if we have it wrong,
+ * AND even we have it here, we must later copy it to SB to make it work :/
+ */
+
+ /* For CC000-CFFFF, bits 7:6 (10 = REn, 01 = WEn) bits 1:0 for
+ * C0000-C3FFF etc.
+ */
+ pci_write_config8(dev, 0x80, 0xff);
+ /* For page D0000-DFFFF */
+ pci_write_config8(dev, 0x81, 0xff);
+ /* For page E0000-EFFFF */
+ pci_write_config8(dev, 0x82, 0xff);
+ pci_write_config8(dev, 0x83, 0x30);
+
+ msr = rdmsr(TOP_MEM);
+ reg = pci_read_config16(dev, 0x84);
+ reg &= 0xf;
+ pci_write_config16(dev, 0x84, (msr.lo >> 16) | reg);
+
+ reg = pci_read_config16(dev, 0x88);
+ reg &= 0xf800;
+
+ /* The Address Next to the Last Valid DRAM Address */
+ pci_write_config16(dev, 0x88, (msr.lo >> 24) | reg);
+
+}
+
+#if CONFIG_GFXUMA
+extern uint64_t uma_memory_base, uma_memory_size;
+#endif
+
+static void dram_enable_k8m890(struct device *dev)
+{
+#if CONFIG_GFXUMA
+ msr_t msr;
+ int ret;
+ unsigned int fbbits;
+
+ /* use CMOS */
+ if (CONFIG_VIDEO_MB == -1) {
+ ret = get_option(&fbbits, "videoram_size");
+ if (ret) {
+ printk(BIOS_WARNING, "Failed to get videoram size (error %d), using default.\n", ret);
+ fbbits = 5;
+ }
+
+ if ((fbbits < 1) || (fbbits > 7)) {
+ printk(BIOS_WARNING, "Invalid videoram size (%d), using default.\n",
+ 4 << fbbits);
+ fbbits = 5;
+ }
+ uma_memory_size = 4 << (fbbits + 20);
+ } else {
+ uma_memory_size = (CONFIG_VIDEO_MB << 20);
+ }
+
+ msr = rdmsr(TOP_MEM);
+ uma_memory_base = msr.lo - uma_memory_size;
+ printk(BIOS_INFO, "K8M890: UMA base is %llx size is %u (MB)\n", uma_memory_base,
+ (u32) (uma_memory_size / 1024 / 1024));
+ /* enable VGA, so the bridges gets VGA_EN and resources are set */
+ pci_write_config8(dev, 0xa1, 0x80);
+#endif
+ dram_enable(dev);
+}
+
+int
+k8m890_host_fb_size_get(void)
+{
+ struct device *dev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
+ unsigned char tmp;
+
+ tmp = pci_read_config8(dev, 0xA1);
+ tmp >>= 4;
+ if (tmp & 0x08)
+ return 4 << (tmp & 7);
+ else
+ return 0;
+}
+
+static void dram_init_fb(struct device *dev)
+{
+#if CONFIG_GFXUMA
+ /* Important bits:
+ * Enable the internal GFX bit 7 of reg 0xa1 plus in same reg:
+ * bits 6:4 X fbuffer size will be 2^(X+2) or 100 = 64MB, 101 = 128MB
+ * bits 3:0 BASE [31:28]
+ * reg 0xa0 bits 7:1 BASE [27:21] bit0 enable CPU access
+ */
+ unsigned int fbbits = 0;
+ u8 tmp;
+
+ fbbits = ((log2(uma_memory_size >> 20) - 2) << 4);
+ printk(BIOS_INFO, "K8M890: Using a %dMB framebuffer.\n", (unsigned int) (uma_memory_size >> 20));
+
+ /* Step 1: enable UMA but no FB */
+ pci_write_config8(dev, 0xa1, 0x80);
+
+ /* Step 2: enough is just the FB size, the CPU accessible address is not needed */
+ tmp = fbbits | 0x80;
+ pci_write_config8(dev, 0xa1, tmp);
+
+ /* TODO K8 needs some UMA fine tuning too maybe call some generic routine here? */
+#endif
+}
+
+static const struct device_operations dram_ops_t = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = dram_enable,
+ .ops_pci = 0,
+};
+
+static const struct device_operations dram_ops_m = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = dram_enable_k8m890,
+ .init = dram_init_fb,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &dram_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_3,
+};
+
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
+ .ops = &dram_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CF_3,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &dram_ops_m,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_3,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Seems the link and width of HT link needs to be setup too, you need to
+ * generate PCI reset or LDTSTOP to apply.
+ */
+
+#include <stdlib.h>
+#include <cbmem.h>
+#include <arch/io.h>
+#include "k8t890.h"
+
+/* The 256 bytes of NVRAM for S3 storage, 256B aligned */
+#define K8T890_NVRAM_IO_BASE 0xf00
+#define K8T890_MULTIPLE_FN_EN 0x4f
+
+/* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */
+static u8 ldtreg[3] = {0x86, 0xa6, 0xc6};
+
+/* This functions sets KT890 link frequency and width to same values as
+ * it has been setup on K8 side, by AMD NB init.
+ */
+
+u8 k8t890_early_setup_ht(void)
+{
+ u8 awidth, afreq, cldtfreq, reg;
+ u8 cldtwidth_in, cldtwidth_out, vldtwidth_in, vldtwidth_out, ldtnr, width;
+ u16 vldtcaps;
+
+ /* hack, enable NVRAM in chipset */
+ pci_write_config8(PCI_DEV(0, 0x0, 0), K8T890_MULTIPLE_FN_EN, 0x01);
+
+ /*
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
+ */
+
+ pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+ reg = pci_read_config8(PCI_DEV(0, 0x0, 2), 0xa1);
+ reg |= 0x1;
+ pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa1, reg);
+
+ /* check if connected non coherent, initcomplete (find the SB on K8 side) */
+ ldtnr = 0;
+ if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0x98)) {
+ ldtnr = 0;
+ } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xb8)) {
+ ldtnr = 1;
+ } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xd8)) {
+ ldtnr = 2;
+ }
+
+ print_debug("K8T890 found at LDT ");
+ print_debug_hex8(ldtnr);
+
+ /* get the maximum widths for both sides */
+ cldtwidth_in = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) & 0x7;
+ cldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) >> 4) & 0x7;
+ vldtwidth_in = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) & 0x7;
+ vldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) >> 4) & 0x7;
+
+ width = MIN(MIN(MIN(cldtwidth_out, cldtwidth_in), vldtwidth_out), vldtwidth_in);
+ print_debug(" Agreed on width: ");
+ print_debug_hex8(width);
+
+ awidth = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x67);
+
+ /* Update the desired HT LNK to match AMD NB max from VIA NB is 0x1 */
+ width = (width == 0x01) ? 0x11 : 0x00;
+
+ pci_write_config8(PCI_DEV(0, 0x0, 0), 0x67, width);
+
+ /* Get programmed HT freq at base 0x89 */
+ cldtfreq = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr] + 3) & 0xf;
+ print_debug(" CPU programmed to HT freq: ");
+ print_debug_hex8(cldtfreq);
+
+ print_debug(" VIA HT caps: ");
+ vldtcaps = pci_read_config16(PCI_DEV(0, 0, 0), 0x6e);
+ print_debug_hex16(vldtcaps);
+
+ if (!(vldtcaps & (1 << cldtfreq ))) {
+ die("Chipset does not support desired HT frequency\n");
+ }
+
+ afreq = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x6d);
+ pci_write_config8(PCI_DEV(0, 0x0, 0), 0x6d, cldtfreq);
+ print_debug("\n");
+
+ /* no reset needed */
+ if ((width == awidth) && (afreq == cldtfreq)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static inline int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
+{
+
+ printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
+ switch (size) {
+ case 1:
+ outb((dword & 0xff), K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=1;
+ break;
+ case 2:
+ outw((dword & 0xffff), K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=2;
+ break;
+ default:
+ outl(dword, K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=4;
+ break;
+ }
+ return nvram_pos;
+}
+
+static inline int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
+{
+ switch (size) {
+ case 1:
+ *old_dword &= ~0xff;
+ *old_dword |= inb(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=1;
+ break;
+ case 2:
+ *old_dword &= ~0xffff;
+ *old_dword |= inw(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=2;
+ break;
+ default:
+ *old_dword = inl(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=4;
+ break;
+ }
+ printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size);
+ return nvram_pos;
+}
+
+/* this should be a function
+struct cbmem_entry *get_cbmem_toc(void) {
+*/
+
+#define get_cbmem_toc() ((struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC))
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+
+static void error_enable(struct device *dev)
+{
+ /*
+ * bit0 - Enable V-link parity error reporting in 0x50 bit0 (RWC)
+ * bit6 - Parity Error/SERR# Report Through V-Link to SB
+ * bit7 - Parity Error/SERR# Report Through NMI
+ */
+ pci_write_config8(dev, 0x58, 0x81);
+
+ /* TODO: enable AGP errors reporting on K8M890 */
+}
+
+static const struct device_operations error_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = error_enable,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &error_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_1,
+};
+
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
+ .ops = &error_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CF_1,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &error_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_1,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "k8t890.h"
+
+static void host_enable(struct device *dev)
+{
+ /* Multiple function control */
+ pci_write_config8(dev, K8T890_MULTIPLE_FN_EN, 0x01);
+
+}
+
+
+static void host_init(struct device *dev)
+{
+ u8 reg;
+
+ /* AGP Capability Header Control */
+ reg = pci_read_config8(dev, 0x4d);
+ reg |= 0x20; /* GART access enabled by either D0F0 Rx90[8] or D1F0 Rx90[8] */
+ pci_write_config8(dev, 0x4d, reg);
+
+ /* GD Output Stagger Delay */
+ reg = pci_read_config8(dev, 0x42);
+ reg |= 0x10; /* AD[31:16] with 1ns */
+ pci_write_config8(dev, 0x42, reg);
+
+ /* AGP Control */
+ reg = pci_read_config8(dev, 0xbc);
+ reg |= 0x20; /* AGP Read Snoop DRAM Post-Write Buffer */
+ pci_write_config8(dev, 0xbc, reg);
+
+}
+
+static const struct device_operations host_ops_t = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = host_enable,
+ .ops_pci = 0,
+};
+
+static const struct device_operations host_ops_m = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = host_enable,
+ .init = host_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &host_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_0,
+};
+
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
+ .ops = &host_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CF_0,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &host_ops_m,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_0,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include <cbmem.h>
+#include <arch/io.h>
+#include "k8t890.h"
+
+/* this may be later merged */
+
+/* This fine tunes the HT link settings, which were loaded by ROM strap. */
+static void host_ctrl_enable_k8t890(struct device *dev)
+{
+ dump_south(dev);
+
+ /*
+ * Bit 4 is reserved but set by AW. Set PCI to HT outstanding
+ * requests to 3.
+ */
+ pci_write_config8(dev, 0xa0, 0x13);
+
+ /*
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
+ * Some bits are set and reserved.
+ */
+ pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+
+ /* enable NB NVRAM and enable non-posted PCI writes. */
+ pci_write_config8(dev, 0xa1, 0x8f);
+ /* Arbitration control, some bits are reserved. */
+ pci_write_config8(dev, 0xa5, 0x3c);
+
+ /* Arbitration control 2 */
+ pci_write_config8(dev, 0xa6, 0x80);
+
+ /* this will be possibly removed, when I figure out
+ * if the ROM SIP is good, second reason is that the
+ * unknown bits are AGP related, which are dummy on K8T890
+ */
+
+ writeback(dev, 0xa0, 0x13); /* Bit4 is reserved! */
+ writeback(dev, 0xa1, 0x8e); /* Some bits are reserved. */
+ writeback(dev, 0xa2, 0x0e); /* I/O NVRAM base 0xe00-0xeff disabled. */
+ writeback(dev, 0xa3, 0x31);
+ writeback(dev, 0xa4, 0x30);
+
+ writeback(dev, 0xa5, 0x3c); /* Some bits reserved. */
+ writeback(dev, 0xa6, 0x80); /* Some bits reserved. */
+ writeback(dev, 0xa7, 0x86); /* Some bits reserved. */
+ writeback(dev, 0xa8, 0x7f); /* Some bits reserved. */
+ writeback(dev, 0xa9, 0xcf); /* Some bits reserved. */
+ writeback(dev, 0xaa, 0x44);
+ writeback(dev, 0xab, 0x22);
+ writeback(dev, 0xac, 0x35); /* Maybe bit0 is read-only? */
+
+ writeback(dev, 0xae, 0x22);
+ writeback(dev, 0xaf, 0x40);
+ /* b0 is missing. */
+ writeback(dev, 0xb1, 0x13);
+ writeback(dev, 0xb4, 0x02); /* Some bits are reserved. */
+ writeback(dev, 0xc0, 0x20);
+ writeback(dev, 0xc1, 0xaa);
+ writeback(dev, 0xc2, 0xaa);
+ writeback(dev, 0xc3, 0x02);
+ writeback(dev, 0xc4, 0x50);
+ writeback(dev, 0xc5, 0x50);
+
+ dump_south(dev);
+}
+
+/* This fine tunes the HT link settings, which were loaded by ROM strap. */
+static void host_ctrl_enable_k8m890(struct device *dev) {
+
+ /*
+ * Set PCI to HT outstanding requests to 03.
+ * Bit 4 32 AGP ADS Read Outstanding Request Number
+ */
+ pci_write_config8(dev, 0xa0, 0x13);
+
+ /*
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
+ */
+
+ pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+
+ /* Enable NVRAM and enable non-posted PCI writes. */
+ pci_write_config8(dev, 0xa1, 0x8f);
+
+ /* Arbitration control */
+ pci_write_config8(dev, 0xa5, 0x3c);
+
+ /* Arbitration control 2, Enable C2NOW delay to PSTATECTL */
+ pci_write_config8(dev, 0xa6, 0x83);
+
+}
+#if 0
+struct cbmem_entry *get_cbmem_toc(void) {
+ return (struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
+}
+#endif
+void set_cbmem_toc(struct cbmem_entry *toc) {
+ outl((u32) toc, K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
+}
+
+static const struct device_operations host_ctrl_ops_t = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = host_ctrl_enable_k8t890,
+ .ops_pci = 0,
+};
+
+static const struct device_operations host_ctrl_ops_m = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = host_ctrl_enable_k8m890,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &host_ctrl_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_2,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &host_ctrl_ops_m,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_2,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007-2009 Luc Verhaegen <libv@skynet.be>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <string.h> /* for memset */
-#include "k8t890.h"
-
-#if CONFIG_VGA
-#include <pc80/vga_io.h>
-#include <pc80/vga.h>
-#include <arch/io.h>
-
-/*
- *
- */
-static void
-chrome_vga_init(struct device *dev)
-{
- vga_sr_write(0x10, 0x01); /* unlock extended regs */
-
- vga_sr_mask(0x1A, 0x02, 0x02); /* enable mmio */
-
- vga_sr_mask(0x1A, 0x40, 0x40); /* Software Reset */
-
- vga_cr_mask(0x6A, 0x00, 0xC8); /* Disable CRTC2 & Simultaneous */
-
- /* Make sure that non of the primary VGA overflow registers are set */
- vga_cr_write(0x33, 0x00);
- vga_cr_write(0x35, 0x00);
- vga_cr_mask(0x11, 0x00, 0x30);
-
- vga_sr_mask(0x16, 0x00, 0x40); /* Wire CRT to CRTC1 */
- vga_cr_mask(0x36, 0x00, 0x30); /* Power on CRT */
-
- /* Disable Extended Display Mode */
- vga_sr_mask(0x15, 0x00, 0x02);
-
- /* Disable Wrap-around */
- vga_sr_mask(0x15, 0x00, 0x20);
-
- /* Disable Extended Mode memory access */
- vga_sr_mask(0x1A, 0x00, 0x08);
-
- /* Make sure that we only touch CRTC1s DAC */
- vga_sr_mask(0x1A, 0x00, 0x01);
-
- /* Set up power to the clocks/crtcs */
- vga_sr_mask(0x19, 0x7F, 0x7F); /* enable clock gating for all. */
- vga_sr_mask(0x1B, 0xC0, 0xC0); /* secondary clock according to pm */
- vga_sr_mask(0x1B, 0x20, 0x30); /* primary clock is always on */
-
- /* set everything according to PM/Engine idle state except pci dma */
- vga_sr_write(0x2D, 0xFF); /* Power management control 1 */
- vga_sr_write(0x2E, 0xFB); /* Power management control 2 */
- vga_sr_write(0x3F, 0xFF); /* Power management control 3 */
-
- /* now set up the engine clock. */
- vga_sr_write(0x47, 0xB8);
- vga_sr_write(0x48, 0x08);
- vga_sr_write(0x49, 0x03);
-
- /* trigger engine clock setting */
- vga_sr_mask(0x40, 0x01, 0x01);
- vga_sr_mask(0x40, 0, 0x01);
-
- vga_cr_mask(0x30, 0x04, 0x04); /* Enable PowerNow in primary path */
- vga_cr_mask(0x36, 0x01, 0x01); /* Enable PCI Power Management */
-
- /* Power now indicators... */
- vga_cr_write(0x41, 0xB9);
- vga_cr_write(0x42, 0xB4);
- /* could these be the CRTC2 power now indicators? */
- vga_cr_write(0x9D, 0x80); /* Power Now Ending position enable */
- vga_cr_write(0x9E, 0xB4); /* Power Now Control 3 */
-
- /* primary fifo setting */
- vga_sr_mask(0x16, 0x28, 0xBF); /* pthreshold: 160 */
- vga_sr_write(0x17, 0x60); /* max depth: 194 */
- vga_sr_mask(0x18, 0x0E, 0xBF); /* high priority threshold: 56 */
- vga_sr_write(0x1C, 0x54); /* Fetch count */
-
- vga_sr_write(0x20, 0x40); /* display queue typical arbiter control 0 */
- vga_sr_write(0x21, 0x40); /* display queue typical arbiter control 1 */
- vga_sr_mask(0x22, 0x14, 0x1F); /* display queue expire number */
-
- /* Typical Arbiter Control */
- vga_sr_mask(0x41, 0x40, 0xF0); /* Request threshold */
- vga_sr_mask(0x42, 0x20, 0x20); /* Support Fetch Cycle with Length 2 */
-
- vga_sr_write(0x50, 0x1F); /* AGP Control Register */
- vga_sr_write(0x51, 0xF5); /* AGP FIFO Control 1 */
-
- vga_cr_mask(0x33, 0x08, 0x08); /* Enable Prefetch Mode */
-}
-
-#endif /* CONFIG_VGA */
-
-/*
- *
- */
-static void
-chrome_init(struct device *dev)
-{
- uint32_t fb_size, fb_address;
-
- fb_size = k8m890_host_fb_size_get();
- if (!fb_size) {
- printk(BIOS_WARNING, "Chrome: Device has not been initialised in the"
- " ramcontroller!\n");
- return;
- }
-
- fb_address = pci_read_config32(dev, 0x10);
- fb_address &= ~0x0F;
- if (!fb_address) {
- printk(BIOS_WARNING, "Chrome: No FB BAR assigned!\n");
- return;
- }
-
- printk(BIOS_INFO, "Chrome: Using %dMB Framebuffer at 0x%08X.\n",
- fb_size, fb_address);
-
- //k8m890_host_fb_direct_set(fb_address);
-
-#if CONFIG_VGA
- /* Now set up the VGA console */
- vga_io_init(); /* Enable full IO access */
-
- chrome_vga_init(dev);
-
- vga_textmode_init();
-
- printk(BIOS_INFO, "Chrome VGA Textmode initialized.\n");
-
- /* if we don't have console, at least print something... */
- vga_line_write(0, "Chrome VGA Textmode initialized.");
-#endif /* CONFIG_VGA */
-}
-
-static struct device_operations
-chrome_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = chrome_init,
- .scan_bus = 0,
- .enable = 0,
-};
-
-static const struct pci_driver unichrome_driver __pci_driver = {
- .ops = &chrome_ops,
- .vendor = 0x1106,
- .device = 0x3230,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "k8t890.h"
-
-static void bridge_enable(struct device *dev)
-{
- u8 tmp;
- print_debug("B188 device dump\n");
- /* VIA recommends this, sorry no known info. */
-
- writeback(dev, 0x40, 0x91);
- writeback(dev, 0x41, 0x40);
- writeback(dev, 0x43, 0x44);
- writeback(dev, 0x44, 0x31); /* K8M890 should have 0x35 datasheet
- * says it is reserved
- */
- writeback(dev, 0x45, 0x3a);
- writeback(dev, 0x46, 0x88); /* PCI ID lo */
- writeback(dev, 0x47, 0xb1); /* PCI ID hi */
-
- /* Bridge control, K8M890 bit 3 should be set to enable VGA on AGP
- * (Forward VGA compatible memory and I/O cycles )
- */
-
- writeback(dev, 0x3e, 0x16);
- dump_south(dev);
-
- /* disable I/O and memory decode, or it freezes PCI bus during BAR sizing */
- tmp = pci_read_config8(dev, PCI_COMMAND);
- tmp &= ~0x3;
- pci_write_config8(dev, PCI_COMMAND, tmp);
-
-}
-
-static const struct device_operations bridge_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .enable = bridge_enable,
- .scan_bus = pci_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &bridge_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_BR,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-
-/* We support here K8M890/K8T890 and VT8237R PCI1/Vlink which setup is not in separate
- * PCI device 0:11.7, but it is mapped to PCI 0:0.7 (0x70-0x7c for PCI1)
- */
-
-static void vt8237r_cfg(struct device *dev, struct device *devsb)
-{
- u8 regm, regm3;
-
- device_t devfun3;
-
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
-
- if (!devfun3)
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
-
- if (!devfun3)
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
-
- pci_write_config8(dev, 0x70, 0xc2);
-
- /* PCI Control */
- pci_write_config8(dev, 0x72, 0xee);
- pci_write_config8(dev, 0x73, 0x01);
- pci_write_config8(dev, 0x74, 0x24);
- pci_write_config8(dev, 0x75, 0x0f);
- pci_write_config8(dev, 0x76, 0x50);
- pci_write_config8(dev, 0x77, 0x08);
- pci_write_config8(dev, 0x78, 0x01);
- /* APIC on HT */
- pci_write_config8(dev, 0x7c, 0x7f);
- pci_write_config8(dev, 0x7f, 0x02);
-
- /* WARNING: Need to copy some registers from NB (D0F3) to SB (D0F7). */
-
- regm = pci_read_config8(devfun3, 0x88); /* Shadow mem CTRL */
- pci_write_config8(dev, 0x57, regm);
-
- regm = pci_read_config8(devfun3, 0x80); /* Shadow page C */
- pci_write_config8(dev, 0x61, regm);
-
- regm = pci_read_config8(devfun3, 0x81); /* Shadow page D */
- pci_write_config8(dev, 0x62, regm);
-
- regm = pci_read_config8(devfun3, 0x86); /* SMM and APIC decoding */
- pci_write_config8(dev, 0xe6, regm);
-
- regm3 = pci_read_config8(devfun3, 0x82);/* Shadow page E */
-
- /*
- * All access bits for 0xE0000-0xEFFFF encode as just 2 bits!
- * So the NB reg is quite inconsistent, we expect there only 0xff or 0x00,
- * and write them to 0x63 7-6 but! VIA 8237A has the mirror at 0x64!
- */
- if (regm3 == 0xff)
- regm3 = 0xc0;
- else
- regm3 = 0x0;
-
- /* Shadow page F + memhole copy */
- regm = pci_read_config8(devfun3, 0x83);
- pci_write_config8(dev, 0x63, regm3 | (regm & 0x3F));
-}
-
-
-
-/**
- * Setup the V-Link for VT8237R, 8X mode.
- *
- * For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
- *
- * REG DEF AW VIA-8X VIA-4X
- * -----------------------------
- * NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
- * NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
- * NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
- * NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
- * SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
- * SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
- * SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
- * SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
- * V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
- * V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
- */
-
-static void vt8237r_vlink_init(struct device *dev)
-{
- u8 reg;
-
- /*
- * This init code is valid only for the VT8237R! For different
- * sounthbridges (e.g. VT8237A, VT8237S, VT8237 (without plus R)
- * and VT8251) a different init code is required.
- */
-
- pci_write_config8(dev, 0xb5, 0x88);
- pci_write_config8(dev, 0xb6, 0x88);
- pci_write_config8(dev, 0xb7, 0x61);
-
- reg = pci_read_config8(dev, 0xb4);
- reg |= 0x11;
- pci_write_config8(dev, 0xb4, reg);
-
- pci_write_config8(dev, 0xb9, 0x98);
- pci_write_config8(dev, 0xba, 0x77);
- pci_write_config8(dev, 0xbb, 0x11);
-
- reg = pci_read_config8(dev, 0xb8);
- reg |= 0x1;
- pci_write_config8(dev, 0xb8, reg);
-
- pci_write_config8(dev, 0xb0, 0x06);
- pci_write_config8(dev, 0xb1, 0x01);
-
- /* Program V-link 8X 16bit full duplex, parity enabled. */
- pci_write_config8(dev, 0x48, 0xa3);
-}
-
-static void ctrl_init(struct device *dev) {
-
- /* TODO: Fix some ordering issue fo V-link set Rx77[6] and PCI1_Rx4F[0]
- should to 1 */
-
- /* C2P Read ACK Return Priority */
- /* PCI CFG Address bits[27:24] are used as extended register address
- bit[11:8] */
-
- pci_write_config8(dev, 0x47, 0x30);
-
- /* VT8237R specific configuration other SB are done in their own directories */
-
- device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
- if (devsb) {
- vt8237r_vlink_init(dev);
- vt8237r_cfg(dev, devsb);
- }
-
-}
-
-static const struct device_operations ctrl_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ctrl_init,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_7,
-};
-
-static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops = &ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_7,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_7,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <cpu/x86/msr.h>
-#include <cpu/amd/mtrr.h>
-#include <pc80/mc146818rtc.h>
-#include <bitops.h>
-#include "k8t890.h"
-
-static void dram_enable(struct device *dev)
-{
- msr_t msr;
- u16 reg;
-
- /*
- * Enable Lowest Interrupt arbitration for APIC, enable NB APIC
- * decoding, MSI support, no SMRAM, compatible SMM.
- */
- pci_write_config8(dev, 0x86, 0x39);
-
- /*
- * We want to use the 0xC0000-0xEFFFF as RAM mark area as RW, even if
- * memory is doing K8 the DMA from SB will fail if we have it wrong,
- * AND even we have it here, we must later copy it to SB to make it work :/
- */
-
- /* For CC000-CFFFF, bits 7:6 (10 = REn, 01 = WEn) bits 1:0 for
- * C0000-C3FFF etc.
- */
- pci_write_config8(dev, 0x80, 0xff);
- /* For page D0000-DFFFF */
- pci_write_config8(dev, 0x81, 0xff);
- /* For page E0000-EFFFF */
- pci_write_config8(dev, 0x82, 0xff);
- pci_write_config8(dev, 0x83, 0x30);
-
- msr = rdmsr(TOP_MEM);
- reg = pci_read_config16(dev, 0x84);
- reg &= 0xf;
- pci_write_config16(dev, 0x84, (msr.lo >> 16) | reg);
-
- reg = pci_read_config16(dev, 0x88);
- reg &= 0xf800;
-
- /* The Address Next to the Last Valid DRAM Address */
- pci_write_config16(dev, 0x88, (msr.lo >> 24) | reg);
-
-}
-
-#if CONFIG_GFXUMA
-extern uint64_t uma_memory_base, uma_memory_size;
-#endif
-
-static void dram_enable_k8m890(struct device *dev)
-{
-#if CONFIG_GFXUMA
- msr_t msr;
- int ret;
- unsigned int fbbits;
-
- /* use CMOS */
- if (CONFIG_VIDEO_MB == -1) {
- ret = get_option(&fbbits, "videoram_size");
- if (ret) {
- printk(BIOS_WARNING, "Failed to get videoram size (error %d), using default.\n", ret);
- fbbits = 5;
- }
-
- if ((fbbits < 1) || (fbbits > 7)) {
- printk(BIOS_WARNING, "Invalid videoram size (%d), using default.\n",
- 4 << fbbits);
- fbbits = 5;
- }
- uma_memory_size = 4 << (fbbits + 20);
- } else {
- uma_memory_size = (CONFIG_VIDEO_MB << 20);
- }
-
- msr = rdmsr(TOP_MEM);
- uma_memory_base = msr.lo - uma_memory_size;
- printk(BIOS_INFO, "K8M890: UMA base is %llx size is %u (MB)\n", uma_memory_base,
- (u32) (uma_memory_size / 1024 / 1024));
- /* enable VGA, so the bridges gets VGA_EN and resources are set */
- pci_write_config8(dev, 0xa1, 0x80);
-#endif
- dram_enable(dev);
-}
-
-int
-k8m890_host_fb_size_get(void)
-{
- struct device *dev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
- unsigned char tmp;
-
- tmp = pci_read_config8(dev, 0xA1);
- tmp >>= 4;
- if (tmp & 0x08)
- return 4 << (tmp & 7);
- else
- return 0;
-}
-
-static void dram_init_fb(struct device *dev)
-{
-#if CONFIG_GFXUMA
- /* Important bits:
- * Enable the internal GFX bit 7 of reg 0xa1 plus in same reg:
- * bits 6:4 X fbuffer size will be 2^(X+2) or 100 = 64MB, 101 = 128MB
- * bits 3:0 BASE [31:28]
- * reg 0xa0 bits 7:1 BASE [27:21] bit0 enable CPU access
- */
- unsigned int fbbits = 0;
- u8 tmp;
-
- fbbits = ((log2(uma_memory_size >> 20) - 2) << 4);
- printk(BIOS_INFO, "K8M890: Using a %dMB framebuffer.\n", (unsigned int) (uma_memory_size >> 20));
-
- /* Step 1: enable UMA but no FB */
- pci_write_config8(dev, 0xa1, 0x80);
-
- /* Step 2: enough is just the FB size, the CPU accessible address is not needed */
- tmp = fbbits | 0x80;
- pci_write_config8(dev, 0xa1, tmp);
-
- /* TODO K8 needs some UMA fine tuning too maybe call some generic routine here? */
-#endif
-}
-
-static const struct device_operations dram_ops_t = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = dram_enable,
- .ops_pci = 0,
-};
-
-static const struct device_operations dram_ops_m = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = dram_enable_k8m890,
- .init = dram_init_fb,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &dram_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_3,
-};
-
-static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops = &dram_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_3,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &dram_ops_m,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_3,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/*
- * Seems the link and width of HT link needs to be setup too, you need to
- * generate PCI reset or LDTSTOP to apply.
- */
-
-#include <stdlib.h>
-#include <cbmem.h>
-#include <arch/io.h>
-#include "k8t890.h"
-
-/* The 256 bytes of NVRAM for S3 storage, 256B aligned */
-#define K8T890_NVRAM_IO_BASE 0xf00
-#define K8T890_MULTIPLE_FN_EN 0x4f
-
-/* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */
-static u8 ldtreg[3] = {0x86, 0xa6, 0xc6};
-
-/* This functions sets KT890 link frequency and width to same values as
- * it has been setup on K8 side, by AMD NB init.
- */
-
-u8 k8t890_early_setup_ht(void)
-{
- u8 awidth, afreq, cldtfreq, reg;
- u8 cldtwidth_in, cldtwidth_out, vldtwidth_in, vldtwidth_out, ldtnr, width;
- u16 vldtcaps;
-
- /* hack, enable NVRAM in chipset */
- pci_write_config8(PCI_DEV(0, 0x0, 0), K8T890_MULTIPLE_FN_EN, 0x01);
-
- /*
- * NVRAM I/O base at K8T890_NVRAM_IO_BASE
- */
-
- pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
- reg = pci_read_config8(PCI_DEV(0, 0x0, 2), 0xa1);
- reg |= 0x1;
- pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa1, reg);
-
- /* check if connected non coherent, initcomplete (find the SB on K8 side) */
- ldtnr = 0;
- if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0x98)) {
- ldtnr = 0;
- } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xb8)) {
- ldtnr = 1;
- } else if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0xd8)) {
- ldtnr = 2;
- }
-
- print_debug("K8T890 found at LDT ");
- print_debug_hex8(ldtnr);
-
- /* get the maximum widths for both sides */
- cldtwidth_in = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) & 0x7;
- cldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr]) >> 4) & 0x7;
- vldtwidth_in = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) & 0x7;
- vldtwidth_out = (pci_read_config8(PCI_DEV(0, 0x0, 0), 0x66) >> 4) & 0x7;
-
- width = MIN(MIN(MIN(cldtwidth_out, cldtwidth_in), vldtwidth_out), vldtwidth_in);
- print_debug(" Agreed on width: ");
- print_debug_hex8(width);
-
- awidth = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x67);
-
- /* Update the desired HT LNK to match AMD NB max from VIA NB is 0x1 */
- width = (width == 0x01) ? 0x11 : 0x00;
-
- pci_write_config8(PCI_DEV(0, 0x0, 0), 0x67, width);
-
- /* Get programmed HT freq at base 0x89 */
- cldtfreq = pci_read_config8(PCI_DEV(0, 0x18, 0), ldtreg[ldtnr] + 3) & 0xf;
- print_debug(" CPU programmed to HT freq: ");
- print_debug_hex8(cldtfreq);
-
- print_debug(" VIA HT caps: ");
- vldtcaps = pci_read_config16(PCI_DEV(0, 0, 0), 0x6e);
- print_debug_hex16(vldtcaps);
-
- if (!(vldtcaps & (1 << cldtfreq ))) {
- die("Chipset does not support desired HT frequency\n");
- }
-
- afreq = pci_read_config8(PCI_DEV(0, 0x0, 0), 0x6d);
- pci_write_config8(PCI_DEV(0, 0x0, 0), 0x6d, cldtfreq);
- print_debug("\n");
-
- /* no reset needed */
- if ((width == awidth) && (afreq == cldtfreq)) {
- return 0;
- }
-
- return 1;
-}
-
-static inline int s3_save_nvram_early(u32 dword, int size, int nvram_pos)
-{
-
- printk(BIOS_DEBUG, "Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
- switch (size) {
- case 1:
- outb((dword & 0xff), K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=1;
- break;
- case 2:
- outw((dword & 0xffff), K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=2;
- break;
- default:
- outl(dword, K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=4;
- break;
- }
- return nvram_pos;
-}
-
-static inline int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos)
-{
- switch (size) {
- case 1:
- *old_dword &= ~0xff;
- *old_dword |= inb(K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=1;
- break;
- case 2:
- *old_dword &= ~0xffff;
- *old_dword |= inw(K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=2;
- break;
- default:
- *old_dword = inl(K8T890_NVRAM_IO_BASE+nvram_pos);
- nvram_pos +=4;
- break;
- }
- printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size);
- return nvram_pos;
-}
-
-/* this should be a function
-struct cbmem_entry *get_cbmem_toc(void) {
-*/
-
-#define get_cbmem_toc() ((struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC))
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-
-static void error_enable(struct device *dev)
-{
- /*
- * bit0 - Enable V-link parity error reporting in 0x50 bit0 (RWC)
- * bit6 - Parity Error/SERR# Report Through V-Link to SB
- * bit7 - Parity Error/SERR# Report Through NMI
- */
- pci_write_config8(dev, 0x58, 0x81);
-
- /* TODO: enable AGP errors reporting on K8M890 */
-}
-
-static const struct device_operations error_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = error_enable,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &error_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_1,
-};
-
-static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops = &error_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_1,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &error_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_1,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "k8t890.h"
-
-static void host_enable(struct device *dev)
-{
- /* Multiple function control */
- pci_write_config8(dev, K8T890_MULTIPLE_FN_EN, 0x01);
-
-}
-
-
-static void host_init(struct device *dev)
-{
- u8 reg;
-
- /* AGP Capability Header Control */
- reg = pci_read_config8(dev, 0x4d);
- reg |= 0x20; /* GART access enabled by either D0F0 Rx90[8] or D1F0 Rx90[8] */
- pci_write_config8(dev, 0x4d, reg);
-
- /* GD Output Stagger Delay */
- reg = pci_read_config8(dev, 0x42);
- reg |= 0x10; /* AD[31:16] with 1ns */
- pci_write_config8(dev, 0x42, reg);
-
- /* AGP Control */
- reg = pci_read_config8(dev, 0xbc);
- reg |= 0x20; /* AGP Read Snoop DRAM Post-Write Buffer */
- pci_write_config8(dev, 0xbc, reg);
-
-}
-
-static const struct device_operations host_ops_t = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = host_enable,
- .ops_pci = 0,
-};
-
-static const struct device_operations host_ops_m = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = host_enable,
- .init = host_init,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &host_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_0,
-};
-
-static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops = &host_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_0,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &host_ops_m,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_0,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include <cbmem.h>
-#include <arch/io.h>
-#include "k8t890.h"
-
-/* this may be later merged */
-
-/* This fine tunes the HT link settings, which were loaded by ROM strap. */
-static void host_ctrl_enable_k8t890(struct device *dev)
-{
- dump_south(dev);
-
- /*
- * Bit 4 is reserved but set by AW. Set PCI to HT outstanding
- * requests to 3.
- */
- pci_write_config8(dev, 0xa0, 0x13);
-
- /*
- * NVRAM I/O base at K8T890_NVRAM_IO_BASE
- * Some bits are set and reserved.
- */
- pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
-
- /* enable NB NVRAM and enable non-posted PCI writes. */
- pci_write_config8(dev, 0xa1, 0x8f);
- /* Arbitration control, some bits are reserved. */
- pci_write_config8(dev, 0xa5, 0x3c);
-
- /* Arbitration control 2 */
- pci_write_config8(dev, 0xa6, 0x80);
-
- /* this will be possibly removed, when I figure out
- * if the ROM SIP is good, second reason is that the
- * unknown bits are AGP related, which are dummy on K8T890
- */
-
- writeback(dev, 0xa0, 0x13); /* Bit4 is reserved! */
- writeback(dev, 0xa1, 0x8e); /* Some bits are reserved. */
- writeback(dev, 0xa2, 0x0e); /* I/O NVRAM base 0xe00-0xeff disabled. */
- writeback(dev, 0xa3, 0x31);
- writeback(dev, 0xa4, 0x30);
-
- writeback(dev, 0xa5, 0x3c); /* Some bits reserved. */
- writeback(dev, 0xa6, 0x80); /* Some bits reserved. */
- writeback(dev, 0xa7, 0x86); /* Some bits reserved. */
- writeback(dev, 0xa8, 0x7f); /* Some bits reserved. */
- writeback(dev, 0xa9, 0xcf); /* Some bits reserved. */
- writeback(dev, 0xaa, 0x44);
- writeback(dev, 0xab, 0x22);
- writeback(dev, 0xac, 0x35); /* Maybe bit0 is read-only? */
-
- writeback(dev, 0xae, 0x22);
- writeback(dev, 0xaf, 0x40);
- /* b0 is missing. */
- writeback(dev, 0xb1, 0x13);
- writeback(dev, 0xb4, 0x02); /* Some bits are reserved. */
- writeback(dev, 0xc0, 0x20);
- writeback(dev, 0xc1, 0xaa);
- writeback(dev, 0xc2, 0xaa);
- writeback(dev, 0xc3, 0x02);
- writeback(dev, 0xc4, 0x50);
- writeback(dev, 0xc5, 0x50);
-
- dump_south(dev);
-}
-
-/* This fine tunes the HT link settings, which were loaded by ROM strap. */
-static void host_ctrl_enable_k8m890(struct device *dev) {
-
- /*
- * Set PCI to HT outstanding requests to 03.
- * Bit 4 32 AGP ADS Read Outstanding Request Number
- */
- pci_write_config8(dev, 0xa0, 0x13);
-
- /*
- * NVRAM I/O base at K8T890_NVRAM_IO_BASE
- */
-
- pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
-
- /* Enable NVRAM and enable non-posted PCI writes. */
- pci_write_config8(dev, 0xa1, 0x8f);
-
- /* Arbitration control */
- pci_write_config8(dev, 0xa5, 0x3c);
-
- /* Arbitration control 2, Enable C2NOW delay to PSTATECTL */
- pci_write_config8(dev, 0xa6, 0x83);
-
-}
-#if 0
-struct cbmem_entry *get_cbmem_toc(void) {
- return (struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
-}
-#endif
-void set_cbmem_toc(struct cbmem_entry *toc) {
- outl((u32) toc, K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC);
-}
-
-static const struct device_operations host_ctrl_ops_t = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = host_ctrl_enable_k8t890,
- .ops_pci = 0,
-};
-
-static const struct device_operations host_ctrl_ops_m = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = host_ctrl_enable_k8m890,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &host_ctrl_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_2,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &host_ctrl_ops_m,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_2,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pciexp.h>
-#include <device/pci_ids.h>
-#include <delay.h>
-#include "k8t890.h"
-
-/*
- * Note:
- * The pcie bridges are similar to the VX800 ones documented at
- * http://linux.via.com.tw/
- */
-
-static void pcie_common_init(struct device *dev)
-{
- u8 reg;
- int i, up;
-
- /* Disable downstream read cycle retry,
- * otherwise the bus scan will hang if no device is plugged in. */
- reg = pci_read_config8(dev, 0xa3);
- pci_write_config8(dev, 0xa3, reg & ~0x01);
-
- /* Use PHY negotiation for lane config */
- reg = pci_read_config8(dev, 0xc1);
- pci_write_config8(dev, 0xc1, reg & ~0x1f);
-
- /* Award has 0xb, VIA recommends 0xd, default 0x8.
- * bit4: receive polarity change control
- * bits3:2: squelch window select 64~175mv
- * bit1: Number of non-idle bits detected before exiting idle state
- * 0: 10 bits, 1: 2 bits
- * bit0: Number of idle bits detected before entering idle state
- * 0: 10 bits, 1: 2 bits
- */
- pci_write_config8(dev, 0xe1, 0xb);
-
- /* Set replay timer limit. */
- pci_write_config8(dev, 0xb1, 0xf0);
-
- /* Enable link. */
- reg = pci_read_config8(dev, 0x50);
- pci_write_config8(dev, 0x50, reg & ~0x10);
-
- /* Wait up to 100ms for link to come up */
- up = 0;
- for (i=0; i<1000; i++) {
- if (pci_read_config16(dev, 0x52) & (1<<13)) {
- up = 1;
- break;
- }
- udelay(100);
- }
-
- printk(BIOS_SPEW, "%s PCIe link ", dev_path(dev));
- if (up)
- printk(BIOS_SPEW, "up after %d us\n", i*100);
- else
- printk(BIOS_SPEW, "timeout\n");
-
- dump_south(dev);
-}
-
-static void peg_init(struct device *dev)
-{
- u8 reg;
-
- printk(BIOS_DEBUG, "Configuring PCIe PEG\n");
- dump_south(dev);
-
- /* Disable link. */
- reg = pci_read_config8(dev, 0x50);
- pci_write_config8(dev, 0x50, reg | 0x10);
-
- /*
- * pci_write_config8(dev, 0xe2, 0x0);
- * pci_write_config8(dev, 0xe3, 0x92);
- */
-
- /* Bit0 = 1 SDP (Start DLLP) always at Lane0. */
- reg = pci_read_config8(dev, 0xb8);
- pci_write_config8(dev, 0xb8, reg | 0x1);
-
- /*
- * Downstream wait and Upstream Checking Malformed TLP through
- * "Byte Enable Rule" And "Over 4K Boundary Rule".
- */
- reg = pci_read_config8(dev, 0xa4);
- pci_write_config8(dev, 0xa4, reg | 0x30);
-
- pcie_common_init(dev);
-}
-
-static void pcie_init(struct device *dev)
-{
- u8 reg;
-
- printk(BIOS_DEBUG, "Configuring PCIe PEXs\n");
- dump_south(dev);
-
- /* Disable link. */
- reg = pci_read_config8(dev, 0x50);
- pci_write_config8(dev, 0x50, reg | 0x10);
-
- pcie_common_init(dev);
-}
-
-static const struct device_operations peg_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .enable = peg_init,
- .scan_bus = pciexp_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = 0,
-};
-
-static const struct device_operations pcie_ops = {
- .read_resources = pci_bus_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_bus_enable_resources,
- .enable = pcie_init,
- .scan_bus = pciexp_scan_bridge,
- .reset_bus = pci_bus_reset,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &peg_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_PEG,
-};
-
-static const struct pci_driver pcie_drvd3f0 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX0,
-};
-
-static const struct pci_driver pcie_drvd3f1 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX1,
-};
-
-static const struct pci_driver pcie_drvd3f2 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX2,
-};
-
-static const struct pci_driver pcie_drvd3f3 __pci_driver = {
- .ops = &pcie_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX3,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "k8t890.h"
-
-extern unsigned long log2(unsigned long x);
-
-static void mmconfig_set_resources(device_t dev)
-{
- struct resource *resource;
- u8 reg;
-
- resource = find_resource(dev, K8T890_MMCONFIG_MBAR);
- if (resource) {
- report_resource_stored(dev, resource, "<mmconfig>");
-
- /* Remember this resource has been stored. */
- resource->flags |= IORESOURCE_STORED;
- pci_write_config8(dev, K8T890_MMCONFIG_MBAR,
- (resource->base >> 28));
- reg = pci_read_config8(dev, 0x60);
- reg |= 0x3;
- /* Enable MMCONFIG decoding. */
- pci_write_config8(dev, 0x60, reg);
- }
- pci_dev_set_resources(dev);
-}
-
-static void apic_mmconfig_read_resources(device_t dev)
-{
- struct resource *res;
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 0x40);
- /* NB APIC fixed to this address. */
- res->base = K8T890_APIC_BASE;
- res->size = 256;
- res->limit = res->base + res->size - 1;
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- /* Add an MMCONFIG resource. */
- res = new_resource(dev, K8T890_MMCONFIG_MBAR);
- res->size = 256 * 1024 * 1024;
- res->align = log2(res->size);
- res->gran = log2(res->size);
- res->limit = 0xffffffff; /* 4G */
- res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE;
-}
-
-static void traf_ctrl_enable_generic(struct device *dev)
-{
- volatile u32 *apic;
- u32 data;
-
- /* no device2 redirect, enable just one device behind
- * bridge device 2 and device 3).
- */
- pci_write_config8(dev, 0x60, 0x08);
-
- /* Will enable MMCONFIG later. */
- pci_write_config8(dev, 0x64, 0x23);
- /* No extended RCRB Base Address. */
- pci_write_config8(dev, 0x62, 0x00);
-
- /* Offset80 ->95 bit 4 in 1 in Award. */
-
- /* Enable APIC, to K8T890_APIC_BASE. */
- pci_write_config8(dev, 0x41, 0x00);
- pci_write_config8(dev, 0x40, 0x8c);
- /* BT_INTR enable, APIC Nonshare Mode Enable. */
- pci_write_config8(dev, 0x42, 0x5);
-
- apic = (u32 *)K8T890_APIC_BASE;
-
- /* Set APIC to FSB transported messages. */
- apic[0] = 3;
- data = apic[4];
- apic[4] = (data & 0xFFFFFE) | 1;
-
- /* Set APIC ID. */
- apic[0] = 0;
- data = apic[4];
- apic[4] = (data & 0xF0FFFF) | (K8T890_APIC_ID << 24);
-}
-
-static void traf_ctrl_enable_k8m890(struct device *dev)
-{
- traf_ctrl_enable_generic(dev);
-}
-
-static void traf_ctrl_enable_k8t890(struct device *dev)
-{
- u8 reg;
-
- traf_ctrl_enable_generic(dev);
-
- /* Enable D3F1-D3F3 */
- reg = pci_read_config8(dev, 0x60);
- pci_write_config8(dev, 0x60, 0x80 | reg);
-}
-
-static const struct device_operations traf_ctrl_ops_m = {
- .read_resources = apic_mmconfig_read_resources,
- .set_resources = mmconfig_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = traf_ctrl_enable_k8m890,
- .ops_pci = 0,
-};
-
-static const struct device_operations traf_ctrl_ops_t = {
- .read_resources = apic_mmconfig_read_resources,
- .set_resources = mmconfig_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .enable = traf_ctrl_enable_k8t890,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &traf_ctrl_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CE_5,
-};
-
-static const struct pci_driver northbridge_driver_tcf __pci_driver = {
- .ops = &traf_ctrl_ops_t,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8T890CF_5,
-};
-
-static const struct pci_driver northbridge_driver_m __pci_driver = {
- .ops = &traf_ctrl_ops_m,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_K8M890CE_5,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pciexp.h>
+#include <device/pci_ids.h>
+#include <delay.h>
+#include "k8t890.h"
+
+/*
+ * Note:
+ * The pcie bridges are similar to the VX800 ones documented at
+ * http://linux.via.com.tw/
+ */
+
+static void pcie_common_init(struct device *dev)
+{
+ u8 reg;
+ int i, up;
+
+ /* Disable downstream read cycle retry,
+ * otherwise the bus scan will hang if no device is plugged in. */
+ reg = pci_read_config8(dev, 0xa3);
+ pci_write_config8(dev, 0xa3, reg & ~0x01);
+
+ /* Use PHY negotiation for lane config */
+ reg = pci_read_config8(dev, 0xc1);
+ pci_write_config8(dev, 0xc1, reg & ~0x1f);
+
+ /* Award has 0xb, VIA recommends 0xd, default 0x8.
+ * bit4: receive polarity change control
+ * bits3:2: squelch window select 64~175mv
+ * bit1: Number of non-idle bits detected before exiting idle state
+ * 0: 10 bits, 1: 2 bits
+ * bit0: Number of idle bits detected before entering idle state
+ * 0: 10 bits, 1: 2 bits
+ */
+ pci_write_config8(dev, 0xe1, 0xb);
+
+ /* Set replay timer limit. */
+ pci_write_config8(dev, 0xb1, 0xf0);
+
+ /* Enable link. */
+ reg = pci_read_config8(dev, 0x50);
+ pci_write_config8(dev, 0x50, reg & ~0x10);
+
+ /* Wait up to 100ms for link to come up */
+ up = 0;
+ for (i=0; i<1000; i++) {
+ if (pci_read_config16(dev, 0x52) & (1<<13)) {
+ up = 1;
+ break;
+ }
+ udelay(100);
+ }
+
+ printk(BIOS_SPEW, "%s PCIe link ", dev_path(dev));
+ if (up)
+ printk(BIOS_SPEW, "up after %d us\n", i*100);
+ else
+ printk(BIOS_SPEW, "timeout\n");
+
+ dump_south(dev);
+}
+
+static void peg_init(struct device *dev)
+{
+ u8 reg;
+
+ printk(BIOS_DEBUG, "Configuring PCIe PEG\n");
+ dump_south(dev);
+
+ /* Disable link. */
+ reg = pci_read_config8(dev, 0x50);
+ pci_write_config8(dev, 0x50, reg | 0x10);
+
+ /*
+ * pci_write_config8(dev, 0xe2, 0x0);
+ * pci_write_config8(dev, 0xe3, 0x92);
+ */
+
+ /* Bit0 = 1 SDP (Start DLLP) always at Lane0. */
+ reg = pci_read_config8(dev, 0xb8);
+ pci_write_config8(dev, 0xb8, reg | 0x1);
+
+ /*
+ * Downstream wait and Upstream Checking Malformed TLP through
+ * "Byte Enable Rule" And "Over 4K Boundary Rule".
+ */
+ reg = pci_read_config8(dev, 0xa4);
+ pci_write_config8(dev, 0xa4, reg | 0x30);
+
+ pcie_common_init(dev);
+}
+
+static void pcie_init(struct device *dev)
+{
+ u8 reg;
+
+ printk(BIOS_DEBUG, "Configuring PCIe PEXs\n");
+ dump_south(dev);
+
+ /* Disable link. */
+ reg = pci_read_config8(dev, 0x50);
+ pci_write_config8(dev, 0x50, reg | 0x10);
+
+ pcie_common_init(dev);
+}
+
+static const struct device_operations peg_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .enable = peg_init,
+ .scan_bus = pciexp_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = 0,
+};
+
+static const struct device_operations pcie_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .enable = pcie_init,
+ .scan_bus = pciexp_scan_bridge,
+ .reset_bus = pci_bus_reset,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &peg_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_PEG,
+};
+
+static const struct pci_driver pcie_drvd3f0 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX0,
+};
+
+static const struct pci_driver pcie_drvd3f1 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX1,
+};
+
+static const struct pci_driver pcie_drvd3f2 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX2,
+};
+
+static const struct pci_driver pcie_drvd3f3 __pci_driver = {
+ .ops = &pcie_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_PEX3,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "k8t890.h"
+
+extern unsigned long log2(unsigned long x);
+
+static void mmconfig_set_resources(device_t dev)
+{
+ struct resource *resource;
+ u8 reg;
+
+ resource = find_resource(dev, K8T890_MMCONFIG_MBAR);
+ if (resource) {
+ report_resource_stored(dev, resource, "<mmconfig>");
+
+ /* Remember this resource has been stored. */
+ resource->flags |= IORESOURCE_STORED;
+ pci_write_config8(dev, K8T890_MMCONFIG_MBAR,
+ (resource->base >> 28));
+ reg = pci_read_config8(dev, 0x60);
+ reg |= 0x3;
+ /* Enable MMCONFIG decoding. */
+ pci_write_config8(dev, 0x60, reg);
+ }
+ pci_dev_set_resources(dev);
+}
+
+static void apic_mmconfig_read_resources(device_t dev)
+{
+ struct resource *res;
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 0x40);
+ /* NB APIC fixed to this address. */
+ res->base = K8T890_APIC_BASE;
+ res->size = 256;
+ res->limit = res->base + res->size - 1;
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Add an MMCONFIG resource. */
+ res = new_resource(dev, K8T890_MMCONFIG_MBAR);
+ res->size = 256 * 1024 * 1024;
+ res->align = log2(res->size);
+ res->gran = log2(res->size);
+ res->limit = 0xffffffff; /* 4G */
+ res->flags = IORESOURCE_MEM | IORESOURCE_RESERVE;
+}
+
+static void traf_ctrl_enable_generic(struct device *dev)
+{
+ volatile u32 *apic;
+ u32 data;
+
+ /* no device2 redirect, enable just one device behind
+ * bridge device 2 and device 3).
+ */
+ pci_write_config8(dev, 0x60, 0x08);
+
+ /* Will enable MMCONFIG later. */
+ pci_write_config8(dev, 0x64, 0x23);
+ /* No extended RCRB Base Address. */
+ pci_write_config8(dev, 0x62, 0x00);
+
+ /* Offset80 ->95 bit 4 in 1 in Award. */
+
+ /* Enable APIC, to K8T890_APIC_BASE. */
+ pci_write_config8(dev, 0x41, 0x00);
+ pci_write_config8(dev, 0x40, 0x8c);
+ /* BT_INTR enable, APIC Nonshare Mode Enable. */
+ pci_write_config8(dev, 0x42, 0x5);
+
+ apic = (u32 *)K8T890_APIC_BASE;
+
+ /* Set APIC to FSB transported messages. */
+ apic[0] = 3;
+ data = apic[4];
+ apic[4] = (data & 0xFFFFFE) | 1;
+
+ /* Set APIC ID. */
+ apic[0] = 0;
+ data = apic[4];
+ apic[4] = (data & 0xF0FFFF) | (K8T890_APIC_ID << 24);
+}
+
+static void traf_ctrl_enable_k8m890(struct device *dev)
+{
+ traf_ctrl_enable_generic(dev);
+}
+
+static void traf_ctrl_enable_k8t890(struct device *dev)
+{
+ u8 reg;
+
+ traf_ctrl_enable_generic(dev);
+
+ /* Enable D3F1-D3F3 */
+ reg = pci_read_config8(dev, 0x60);
+ pci_write_config8(dev, 0x60, 0x80 | reg);
+}
+
+static const struct device_operations traf_ctrl_ops_m = {
+ .read_resources = apic_mmconfig_read_resources,
+ .set_resources = mmconfig_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = traf_ctrl_enable_k8m890,
+ .ops_pci = 0,
+};
+
+static const struct device_operations traf_ctrl_ops_t = {
+ .read_resources = apic_mmconfig_read_resources,
+ .set_resources = mmconfig_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .enable = traf_ctrl_enable_k8t890,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &traf_ctrl_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CE_5,
+};
+
+static const struct pci_driver northbridge_driver_tcf __pci_driver = {
+ .ops = &traf_ctrl_ops_t,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8T890CF_5,
+};
+
+static const struct pci_driver northbridge_driver_m __pci_driver = {
+ .ops = &traf_ctrl_ops_m,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_K8M890CE_5,
+};
##
driver-y += vt8231.c
-driver-y += vt8231_lpc.c
-driver-y += vt8231_acpi.c
-driver-y += vt8231_ide.c
-driver-y += vt8231_nic.c
-#driver-y += vt8231_usb.c
+driver-y += lpc.c
+driver-y += acpi.c
+driver-y += ide.c
+driver-y += nic.c
+#driver-y += usb.c
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+
+static void acpi_init(struct device *dev)
+{
+ printk(BIOS_DEBUG, "Configuring VIA ACPI\n");
+
+ // Set ACPI base address to IO 0x4000
+ pci_write_config32(dev, 0x48, 0x4001);
+
+ // Enable ACPI access (and setup like award)
+ pci_write_config8(dev, 0x41, 0x84);
+
+ // Set hardware monitor base address to IO 0x6000
+ pci_write_config32(dev, 0x70, 0x6001);
+
+ // Enable hardware monitor (and setup like award)
+ pci_write_config8(dev, 0x74, 0x01);
+
+ // set IO base address to 0x5000
+ pci_write_config32(dev, 0x90, 0x5001);
+
+ // Enable SMBus
+ pci_write_config8(dev, 0xd2, 0x01);
+}
+
+static struct device_operations acpi_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = acpi_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &acpi_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8231_4,
+};
--- /dev/null
+/*
+ * Enable the serial evices on the VIA
+ */
+
+
+/* The base address is 0x15c, 0x2e, depending on config bytes */
+
+#define SIO_BASE 0x3f0
+#define SIO_DATA SIO_BASE+1
+
+static void vt8231_writesuper(uint8_t reg, uint8_t val)
+{
+ outb(reg, SIO_BASE);
+ outb(val, SIO_DATA);
+}
+
+static void vt8231_writesiobyte(uint16_t reg, uint8_t val)
+{
+ outb(val, reg);
+}
+
+static void vt8231_writesioword(uint16_t reg, uint16_t val)
+{
+ outw(val, reg);
+}
+
+
+/* regs we use: 85, and the southbridge devfn is defined by the
+ mainboard
+ */
+
+static void enable_vt8231_serial(void)
+{
+ uint8_t c;
+ device_t dev;
+ outb(6, 0x80);
+ dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ outb(7, 0x80);
+ die("Serial controller not found\n");
+ }
+
+ /* first, you have to enable the superio and superio config.
+ put a 6 reg 80
+ */
+ c = pci_read_config8(dev, 0x50);
+ c |= 6;
+ pci_write_config8(dev, 0x50, c);
+ outb(2, 0x80);
+ // now go ahead and set up com1.
+ // set address
+ vt8231_writesuper(0xf4, 0xfe);
+ // enable serial out
+ vt8231_writesuper(0xf2, 7);
+ // That's it for the sio stuff.
+ // movl $SUPERIOCONFIG, %eax
+ // movb $9, %dl
+ // PCI_WRITE_CONFIG_BYTE
+ // set up reg to set baud rate.
+ vt8231_writesiobyte(0x3fb, 0x80);
+ // Set 115 kb
+ vt8231_writesioword(0x3f8, 1);
+ // Set 9.6 kb
+ // WRITESIOWORD(0x3f8, 12)
+ // now set no parity, one stop, 8 bits
+ vt8231_writesiobyte(0x3fb, 3);
+ // now turn on RTS, DRT
+ vt8231_writesiobyte(0x3fc, 3);
+ // Enable interrupts
+ vt8231_writesiobyte(0x3f9, 0xf);
+ // should be done. Dump a char for fun.
+ vt8231_writesiobyte(0x3f8, 48);
+}
--- /dev/null
+#define SMBUS_IO_BASE 0x5000
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBSLVCTL 0x8
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+/* Define register settings */
+#define HOST_RESET 0xff
+#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
+
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ unsigned char c;
+ /* Power management controller */
+ dev = pci_locate_device(PCI_ID(0x1106, 0x8235), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ }
+ // set IO base address to SMBUS_IO_BASE
+ pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
+
+ // Enable SMBus
+ c = pci_read_config8(dev, 0xd2);
+ c |= 5;
+ pci_write_config8(dev, 0xd2, c);
+
+ /* make it work for I/O ...
+ */
+ dev = pci_locate_device(PCI_ID(0x1106, 0x8231), 0);
+ c = pci_read_config8(dev, 4);
+ c |= 1;
+ pci_write_config8(dev, 4, c);
+ print_debug_hex8(c);
+ print_debug(" is the comm register\n");
+
+ print_debug("SMBus controller enabled\n");
+}
+
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_active(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1)) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : -4;
+}
+
+static int smbus_wait_until_ready(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1) == 0) {
+ break;
+ }
+ if (loops == (SMBUS_TIMEOUT / 2)) {
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+ }
+ } while (--loops);
+ return loops ? 0 : -2;
+}
+
+static int smbus_wait_until_done(void)
+{
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ unsigned char val;
+ smbus_delay();
+
+ val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if ((val & 1) == 0) {
+ break;
+ }
+ } while (--loops);
+ return loops ? 0 : -3;
+}
+
+#if 0
+void smbus_reset(void)
+{
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+
+ smbus_wait_until_ready();
+ print_debug("After reset status ");
+ print_debug_hex8(inb(SMBUS_IO_BASE + SMBHSTSTAT));
+ print_debug("\n");
+}
+#endif
+
+#if CONFIG_DEBUG_SMBUS
+static void smbus_print_error(unsigned char host_status_register)
+{
+
+ print_err("smbus_error: ");
+ print_err_hex8(host_status_register);
+ print_err("\n");
+ if (host_status_register & (1 << 4)) {
+ print_err("Interrup/SMI# was Failed Bus Transaction\n");
+ }
+ if (host_status_register & (1 << 3)) {
+ print_err("Bus Error\n");
+ }
+ if (host_status_register & (1 << 2)) {
+ print_err("Device Error\n");
+ }
+ if (host_status_register & (1 << 1)) {
+ print_err("Interrupt/SMI# was Successful Completion\n");
+ }
+ if (host_status_register & (1 << 0)) {
+ print_err("Host Busy\n");
+ }
+}
+#endif
+
+/*
+ * Copied from intel/i82801dbm early smbus code - suggested by rgm.
+ * Modifications/check against i2c-viapro driver code from linux-2.4.22
+ * and VT8231 Reference Docs - mw.
+ */
+static int smbus_read_byte(unsigned device, unsigned address)
+{
+ unsigned char global_status_register;
+ unsigned char byte;
+
+ if (smbus_wait_until_ready() < 0) {
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+ if (smbus_wait_until_ready() < 0) {
+ return -2;
+ }
+ }
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte... */
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start a byte read, with interrupts disabled */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+ /* poll for it to start */
+ if (smbus_wait_until_active() < 0) {
+ return -4;
+ }
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done() < 0) {
+ return -3;
+ }
+
+ /* Ignore the Host Busy & Command Complete ? */
+ global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~((1 << 1) | (1 << 0));
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+
+ if (global_status_register != 0) {
+ return -1;
+ }
+ return byte;
+}
+
+#if 0
+/* SMBus routines borrowed from VIA's Trident Driver */
+/* this works, so I am not going to touch it for now -- rgm */
+static unsigned char smbus_read_byte(unsigned char devAdr, unsigned char bIndex)
+{
+ unsigned int i;
+ unsigned char bData;
+ unsigned char sts = 0;
+
+ /* clear host status */
+ outb(0xff, SMBUS_IO_BASE);
+
+ /* check SMBUS ready */
+ for (i = 0; i < SMBUS_TIMEOUT; i++)
+ if ((inb(SMBUS_IO_BASE) & 0x01) == 0)
+ break;
+
+ /* set host command */
+ outb(bIndex, SMBUS_IO_BASE + 3);
+
+ /* set slave address */
+ outb(devAdr | 0x01, SMBUS_IO_BASE + 4);
+
+ /* start */
+ outb(0x48, SMBUS_IO_BASE + 2);
+
+ /* SMBUS Wait Ready */
+ for (i = 0; i < SMBUS_TIMEOUT; i++)
+ if (((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0)
+ break;
+ if ((sts & ~3) != 0) {
+ smbus_print_error(sts);
+ return 0;
+ }
+ bData = inb(SMBUS_IO_BASE + 5);
+
+ return bData;
+
+}
+#endif
+/* for reference, here is the fancier version which we will use at some
+ * point
+ */
+# if 0
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+ unsigned char host_status_register;
+ unsigned char byte;
+
+ reset();
+
+ smbus_wait_until_ready();
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte... */
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+
+ host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ host_status_register &= ~(1 << 6);
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+ smbus_print_error(byte);
+
+ *result = byte;
+ return host_status_register != 0x02;
+}
+
+
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+
+static void vt8231_enable_rom(void)
+{
+ device_t dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8231), 0);
+
+ /*
+ * ROM decode control register (0x43):
+ *
+ * Bit Decode range
+ * -----------------
+ * 7 0xFFFE0000-0xFFFEFFFF
+ * 6 0xFFF80000-0xFFFDFFFF
+ * 5 0xFFF00000-0xFFF7FFFF
+ * 4 0x000E0000-0x000EFFFF
+ * 3 0x000D8000-0x000DFFFF
+ * 2 0x000D0000-0x000D7FFF
+ * 1 0x000C8000-0x000CFFFF
+ * 0 0x000C0000-0x000C7FFF
+ */
+ pci_write_config8(dev, 0x43, (1 << 7) | (1 << 6) | (1 << 5));
+}
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include "chip.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_via_vt8231_config *conf = (struct southbridge_via_vt8231_config *)dev->chip_info;
+ unsigned char enables;
+
+ if (!conf->enable_native_ide) {
+ // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
+ // interrupts. Using PCI ints confuses linux for some reason.
+ /* Setting reg 0x42 here does not work. It is set in mainboard/romstage.c
+ * It probably can only be changed while the IDE is disabled
+ * or it is possibly a timing issue. Ben Hewson 29 Apr 2007.
+ */
+
+ /*
+ printk(BIOS_INFO, "%s: enabling compatibility IDE addresses\n", __func__);
+ enables = pci_read_config8(dev, 0x42);
+ printk(BIOS_DEBUG, "enables in reg 0x42 0x%x\n", enables);
+ enables &= ~0xc0; // compatability mode
+ pci_write_config8(dev, 0x42, enables);
+ enables = pci_read_config8(dev, 0x42);
+ printk(BIOS_DEBUG, "enables in reg 0x42 read back as 0x%x\n", enables);
+ */
+ }
+
+ enables = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "enables in reg 0x40 0x%x\n", enables);
+ enables |= 3;
+ pci_write_config8(dev, 0x40, enables);
+ enables = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "enables in reg 0x40 read back as 0x%x\n", enables);
+
+ // Enable prefetch buffers
+ enables = pci_read_config8(dev, 0x41);
+ enables |= 0xf0;
+ pci_write_config8(dev, 0x41, enables);
+
+ // Lower thresholds (cause award does it)
+ enables = pci_read_config8(dev, 0x43);
+ enables &= ~0x0f;
+ enables |= 0x05;
+ pci_write_config8(dev, 0x43, enables);
+
+ // PIO read prefetch counter (cause award does it)
+ pci_write_config8(dev, 0x44, 0x18);
+
+ // Use memory read multiple
+ pci_write_config8(dev, 0x45, 0x1c);
+
+ // address decoding.
+ // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
+ // kevinh@ispiri.com - the standard linux drivers seem ass slow when
+ // used in native mode - I've changed back to classic
+ enables = pci_read_config8(dev, 0x9);
+ printk(BIOS_DEBUG, "enables in reg 0x9 0x%x\n", enables);
+ // by the book, set the low-order nibble to 0xa.
+ if (conf->enable_native_ide) {
+ enables &= ~0xf;
+ // cf/cg silicon needs an 'f' here.
+ enables |= 0xf;
+ } else {
+ enables &= ~0x5;
+ }
+
+ pci_write_config8(dev, 0x9, enables);
+ enables = pci_read_config8(dev, 0x9);
+ printk(BIOS_DEBUG, "enables in reg 0x9 read back as 0x%x\n", enables);
+
+ // standard bios sets master bit.
+ enables = pci_read_config8(dev, 0x4);
+ printk(BIOS_DEBUG, "command in reg 0x4 0x%x\n", enables);
+ enables |= 7;
+
+ // No need for stepping - kevinh@ispiri.com
+ enables &= ~0x80;
+
+ pci_write_config8(dev, 0x4, enables);
+ enables = pci_read_config8(dev, 0x4);
+ printk(BIOS_DEBUG, "command in reg 0x4 reads back as 0x%x\n", enables);
+
+ if (!conf->enable_native_ide) {
+ // Use compatability mode - per award bios
+ pci_write_config32(dev, 0x10, 0x0);
+ pci_write_config32(dev, 0x14, 0x0);
+ pci_write_config32(dev, 0x18, 0x0);
+ pci_write_config32(dev, 0x1c, 0x0);
+
+ // Force interrupts to use compat mode - just like Award bios
+ pci_write_config8(dev, 0x3d, 00);
+ pci_write_config8(dev, 0x3c, 0xff);
+ }
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_82C586_1,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/ioapic.h>
+#include "chip.h"
+
+/* PIRQ init
+ */
+static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 };
+static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 };
+static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
+
+/*
+ Our IDSEL mappings are as follows
+ PCI slot is AD31 (device 15) (00:14.0)
+ Southbridge is AD28 (device 12) (00:11.0)
+*/
+static void pci_routing_fixup(struct device *dev)
+{
+
+ printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
+ if (dev) {
+ /* initialize PCI interupts - these assignments depend
+ on the PCB routing of PINTA-D
+
+ PINTA = IRQ11
+ PINTB = IRQ5
+ PINTC = IRQ10
+ PINTD = IRQ12
+ */
+ pci_write_config8(dev, 0x55, 0xb0);
+ pci_write_config8(dev, 0x56, 0xa5);
+ pci_write_config8(dev, 0x57, 0xc0);
+ }
+
+ // Standard southbridge components
+ printk(BIOS_INFO, "setting southbridge\n");
+ pci_assign_irqs(0, 0x11, southbridgeIrqs);
+
+ // Ethernet built into southbridge
+ printk(BIOS_INFO, "setting ethernet\n");
+ pci_assign_irqs(0, 0x12, enetIrqs);
+
+ // PCI slot
+ printk(BIOS_INFO, "setting pci slot\n");
+ pci_assign_irqs(0, 0x14, slotIrqs);
+ printk(BIOS_INFO, "%s: DONE\n", __func__);
+}
+
+static void vt8231_init(struct device *dev)
+{
+ unsigned char enables;
+
+ printk(BIOS_DEBUG, "vt8231 init\n");
+
+ // enable the internal I/O decode
+ enables = pci_read_config8(dev, 0x6C);
+ enables |= 0x80;
+ pci_write_config8(dev, 0x6C, enables);
+
+ // Set bit 6 of 0x40, because Award does it (IO recovery time)
+ // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
+ // interrupts can be properly marked as level triggered.
+ enables = pci_read_config8(dev, 0x40);
+ pci_write_config8(dev, 0x40, enables);
+
+ // Set 0x42 to 0xf0 to match Award bios
+ enables = pci_read_config8(dev, 0x42);
+ enables |= 0xf0;
+ pci_write_config8(dev, 0x42, enables);
+
+ // Set bit 3 of 0x4a, to match award (dummy pci request)
+ enables = pci_read_config8(dev, 0x4a);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4a, enables);
+
+ // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
+ enables = pci_read_config8(dev, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4f, enables);
+
+ // Set 0x58 to 0x03 to match Award
+ pci_write_config8(dev, 0x58, 0x03);
+
+ // enable the ethernet/RTC
+ if (dev) {
+ enables = pci_read_config8(dev, 0x51);
+ enables |= 0x18;
+ pci_write_config8(dev, 0x51, enables);
+ }
+
+ // enable IDE, since Linux won't do it.
+ // First do some more things to devfn (17,0)
+ // note: this should already be cleared, according to the book.
+ enables = pci_read_config8(dev, 0x50);
+ printk(BIOS_DEBUG, "IDE enable in reg. 50 is 0x%x\n", enables);
+ enables &= ~8; // need manifest constant here!
+ printk(BIOS_DEBUG, "set IDE reg. 50 to 0x%x\n", enables);
+ pci_write_config8(dev, 0x50, enables);
+
+ // set default interrupt values (IDE)
+ enables = pci_read_config8(dev, 0x4c);
+ printk(BIOS_DEBUG, "IRQs in reg. 4c are 0x%x\n", enables & 0xf);
+ // clear out whatever was there.
+ enables &= ~0xf;
+ enables |= 4;
+ printk(BIOS_DEBUG, "setting reg. 4c to 0x%x\n", enables);
+ pci_write_config8(dev, 0x4c, enables);
+
+ // set up the serial port interrupts.
+ // com2 to 3, com1 to 4
+ pci_write_config8(dev, 0x46, 0x04);
+ pci_write_config8(dev, 0x47, 0x03);
+ pci_write_config8(dev, 0x6e, 0x98);
+
+ /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
+ pci_write_config8(dev, 0x40, 0x54);
+ //ethernet_fixup();
+
+ // Start the rtc
+ rtc_init(0);
+}
+
+static void vt8231_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 1);
+ res->base = 0x0UL;
+ res->size = 0x1000UL;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void southbridge_init(struct device *dev)
+{
+ vt8231_init(dev);
+ pci_routing_fixup(dev);
+}
+
+static struct device_operations vt8231_lpc_ops = {
+ .read_resources = vt8231_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = &southbridge_init,
+ .scan_bus = scan_static_bus,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &vt8231_lpc_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8231,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+
+/*
+ * Enable the ethernet device and turn off stepping (because it is integrated
+ * inside the southbridge)
+ */
+static void nic_init(struct device *dev)
+{
+ uint8_t byte;
+
+ printk(BIOS_DEBUG, "Configuring VIA LAN\n");
+
+ /* We don't need stepping - though the device supports it */
+ byte = pci_read_config8(dev, PCI_COMMAND);
+ byte &= ~PCI_COMMAND_WAIT;
+ pci_write_config8(dev, PCI_COMMAND, byte);
+}
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8233_7,
+};
--- /dev/null
+
+static void usb_on(int enable)
+{
+ unsigned char regval;
+
+ /* Base 8231 controller */
+ device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
+ /* USB controller 1 */
+ device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
+ /* USB controller 2 */
+ device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
+
+ /* enable USB1 */
+ if(dev2) {
+ if (enable) {
+ pci_write_config8(dev2, 0x3c, 0x05);
+ pci_write_config8(dev2, 0x04, 0x07);
+ } else {
+ pci_write_config8(dev2, 0x3c, 0x00);
+ pci_write_config8(dev2, 0x04, 0x00);
+ }
+ }
+
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ if (enable)
+ regval &= ~(0x10);
+ else
+ regval |= 0x10;
+ pci_write_config8(dev0, 0x50, regval);
+ }
+
+ /* enable USB2 */
+ if(dev3) {
+ if (enable) {
+ pci_write_config8(dev3, 0x3c, 0x05);
+ pci_write_config8(dev3, 0x04, 0x07);
+ } else {
+ pci_write_config8(dev3, 0x3c, 0x00);
+ pci_write_config8(dev3, 0x04, 0x00);
+ }
+ }
+
+ if(dev0) {
+ regval = pci_read_config8(dev0, 0x50);
+ if (enable)
+ regval &= ~(0x20);
+ else
+ regval |= 0x20;
+ pci_write_config8(dev0, 0x50, regval);
+ }
+}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-static void acpi_init(struct device *dev)
-{
- printk(BIOS_DEBUG, "Configuring VIA ACPI\n");
-
- // Set ACPI base address to IO 0x4000
- pci_write_config32(dev, 0x48, 0x4001);
-
- // Enable ACPI access (and setup like award)
- pci_write_config8(dev, 0x41, 0x84);
-
- // Set hardware monitor base address to IO 0x6000
- pci_write_config32(dev, 0x70, 0x6001);
-
- // Enable hardware monitor (and setup like award)
- pci_write_config8(dev, 0x74, 0x01);
-
- // set IO base address to 0x5000
- pci_write_config32(dev, 0x90, 0x5001);
-
- // Enable SMBus
- pci_write_config8(dev, 0xd2, 0x01);
-}
-
-static struct device_operations acpi_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = acpi_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &acpi_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8231_4,
-};
+++ /dev/null
-/*
- * Enable the serial evices on the VIA
- */
-
-
-/* The base address is 0x15c, 0x2e, depending on config bytes */
-
-#define SIO_BASE 0x3f0
-#define SIO_DATA SIO_BASE+1
-
-static void vt8231_writesuper(uint8_t reg, uint8_t val)
-{
- outb(reg, SIO_BASE);
- outb(val, SIO_DATA);
-}
-
-static void vt8231_writesiobyte(uint16_t reg, uint8_t val)
-{
- outb(val, reg);
-}
-
-static void vt8231_writesioword(uint16_t reg, uint16_t val)
-{
- outw(val, reg);
-}
-
-
-/* regs we use: 85, and the southbridge devfn is defined by the
- mainboard
- */
-
-static void enable_vt8231_serial(void)
-{
- uint8_t c;
- device_t dev;
- outb(6, 0x80);
- dev = pci_locate_device(PCI_ID(0x1106,0x8231), 0);
-
- if (dev == PCI_DEV_INVALID) {
- outb(7, 0x80);
- die("Serial controller not found\n");
- }
-
- /* first, you have to enable the superio and superio config.
- put a 6 reg 80
- */
- c = pci_read_config8(dev, 0x50);
- c |= 6;
- pci_write_config8(dev, 0x50, c);
- outb(2, 0x80);
- // now go ahead and set up com1.
- // set address
- vt8231_writesuper(0xf4, 0xfe);
- // enable serial out
- vt8231_writesuper(0xf2, 7);
- // That's it for the sio stuff.
- // movl $SUPERIOCONFIG, %eax
- // movb $9, %dl
- // PCI_WRITE_CONFIG_BYTE
- // set up reg to set baud rate.
- vt8231_writesiobyte(0x3fb, 0x80);
- // Set 115 kb
- vt8231_writesioword(0x3f8, 1);
- // Set 9.6 kb
- // WRITESIOWORD(0x3f8, 12)
- // now set no parity, one stop, 8 bits
- vt8231_writesiobyte(0x3fb, 3);
- // now turn on RTS, DRT
- vt8231_writesiobyte(0x3fc, 3);
- // Enable interrupts
- vt8231_writesiobyte(0x3f9, 0xf);
- // should be done. Dump a char for fun.
- vt8231_writesiobyte(0x3f8, 48);
-}
+++ /dev/null
-#define SMBUS_IO_BASE 0x5000
-
-#define SMBHSTSTAT 0x0
-#define SMBSLVSTAT 0x1
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBSLVCTL 0x8
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-
-/* Define register settings */
-#define HOST_RESET 0xff
-#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
-
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-static void enable_smbus(void)
-{
- device_t dev;
- unsigned char c;
- /* Power management controller */
- dev = pci_locate_device(PCI_ID(0x1106, 0x8235), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- }
- // set IO base address to SMBUS_IO_BASE
- pci_write_config32(dev, 0x90, SMBUS_IO_BASE | 1);
-
- // Enable SMBus
- c = pci_read_config8(dev, 0xd2);
- c |= 5;
- pci_write_config8(dev, 0xd2, c);
-
- /* make it work for I/O ...
- */
- dev = pci_locate_device(PCI_ID(0x1106, 0x8231), 0);
- c = pci_read_config8(dev, 4);
- c |= 1;
- pci_write_config8(dev, 4, c);
- print_debug_hex8(c);
- print_debug(" is the comm register\n");
-
- print_debug("SMBus controller enabled\n");
-}
-
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_active(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1)) {
- break;
- }
- } while (--loops);
- return loops ? 0 : -4;
-}
-
-static int smbus_wait_until_ready(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1) == 0) {
- break;
- }
- if (loops == (SMBUS_TIMEOUT / 2)) {
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- }
- } while (--loops);
- return loops ? 0 : -2;
-}
-
-static int smbus_wait_until_done(void)
-{
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- unsigned char val;
- smbus_delay();
-
- val = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if ((val & 1) == 0) {
- break;
- }
- } while (--loops);
- return loops ? 0 : -3;
-}
-
-#if 0
-void smbus_reset(void)
-{
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
-
- smbus_wait_until_ready();
- print_debug("After reset status ");
- print_debug_hex8(inb(SMBUS_IO_BASE + SMBHSTSTAT));
- print_debug("\n");
-}
-#endif
-
-#if CONFIG_DEBUG_SMBUS
-static void smbus_print_error(unsigned char host_status_register)
-{
-
- print_err("smbus_error: ");
- print_err_hex8(host_status_register);
- print_err("\n");
- if (host_status_register & (1 << 4)) {
- print_err("Interrup/SMI# was Failed Bus Transaction\n");
- }
- if (host_status_register & (1 << 3)) {
- print_err("Bus Error\n");
- }
- if (host_status_register & (1 << 2)) {
- print_err("Device Error\n");
- }
- if (host_status_register & (1 << 1)) {
- print_err("Interrupt/SMI# was Successful Completion\n");
- }
- if (host_status_register & (1 << 0)) {
- print_err("Host Busy\n");
- }
-}
-#endif
-
-/*
- * Copied from intel/i82801dbm early smbus code - suggested by rgm.
- * Modifications/check against i2c-viapro driver code from linux-2.4.22
- * and VT8231 Reference Docs - mw.
- */
-static int smbus_read_byte(unsigned device, unsigned address)
-{
- unsigned char global_status_register;
- unsigned char byte;
-
- if (smbus_wait_until_ready() < 0) {
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- if (smbus_wait_until_ready() < 0) {
- return -2;
- }
- }
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xfe, SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xe3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte... */
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start a byte read, with interrupts disabled */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
- /* poll for it to start */
- if (smbus_wait_until_active() < 0) {
- return -4;
- }
-
- /* poll for transaction completion */
- if (smbus_wait_until_done() < 0) {
- return -3;
- }
-
- /* Ignore the Host Busy & Command Complete ? */
- global_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT) & ~((1 << 1) | (1 << 0));
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
-
- if (global_status_register != 0) {
- return -1;
- }
- return byte;
-}
-
-#if 0
-/* SMBus routines borrowed from VIA's Trident Driver */
-/* this works, so I am not going to touch it for now -- rgm */
-static unsigned char smbus_read_byte(unsigned char devAdr, unsigned char bIndex)
-{
- unsigned int i;
- unsigned char bData;
- unsigned char sts = 0;
-
- /* clear host status */
- outb(0xff, SMBUS_IO_BASE);
-
- /* check SMBUS ready */
- for (i = 0; i < SMBUS_TIMEOUT; i++)
- if ((inb(SMBUS_IO_BASE) & 0x01) == 0)
- break;
-
- /* set host command */
- outb(bIndex, SMBUS_IO_BASE + 3);
-
- /* set slave address */
- outb(devAdr | 0x01, SMBUS_IO_BASE + 4);
-
- /* start */
- outb(0x48, SMBUS_IO_BASE + 2);
-
- /* SMBUS Wait Ready */
- for (i = 0; i < SMBUS_TIMEOUT; i++)
- if (((sts = inb(SMBUS_IO_BASE)) & 0x01) == 0)
- break;
- if ((sts & ~3) != 0) {
- smbus_print_error(sts);
- return 0;
- }
- bData = inb(SMBUS_IO_BASE + 5);
-
- return bData;
-
-}
-#endif
-/* for reference, here is the fancier version which we will use at some
- * point
- */
-# if 0
-int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
-{
- unsigned char host_status_register;
- unsigned char byte;
-
- reset();
-
- smbus_wait_until_ready();
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte... */
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
-
- host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- host_status_register &= ~(1 << 6);
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
- smbus_print_error(byte);
-
- *result = byte;
- return host_status_register != 0x02;
-}
-
-
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2010 Uwe Hermann <uwe@hermann-uwe.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/io.h>
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-
-static void vt8231_enable_rom(void)
-{
- device_t dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8231), 0);
-
- /*
- * ROM decode control register (0x43):
- *
- * Bit Decode range
- * -----------------
- * 7 0xFFFE0000-0xFFFEFFFF
- * 6 0xFFF80000-0xFFFDFFFF
- * 5 0xFFF00000-0xFFF7FFFF
- * 4 0x000E0000-0x000EFFFF
- * 3 0x000D8000-0x000DFFFF
- * 2 0x000D0000-0x000D7FFF
- * 1 0x000C8000-0x000CFFFF
- * 0 0x000C0000-0x000C7FFF
- */
- pci_write_config8(dev, 0x43, (1 << 7) | (1 << 6) | (1 << 5));
-}
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include "chip.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_via_vt8231_config *conf = (struct southbridge_via_vt8231_config *)dev->chip_info;
- unsigned char enables;
-
- if (!conf->enable_native_ide) {
- // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
- // interrupts. Using PCI ints confuses linux for some reason.
- /* Setting reg 0x42 here does not work. It is set in mainboard/romstage.c
- * It probably can only be changed while the IDE is disabled
- * or it is possibly a timing issue. Ben Hewson 29 Apr 2007.
- */
-
- /*
- printk(BIOS_INFO, "%s: enabling compatibility IDE addresses\n", __func__);
- enables = pci_read_config8(dev, 0x42);
- printk(BIOS_DEBUG, "enables in reg 0x42 0x%x\n", enables);
- enables &= ~0xc0; // compatability mode
- pci_write_config8(dev, 0x42, enables);
- enables = pci_read_config8(dev, 0x42);
- printk(BIOS_DEBUG, "enables in reg 0x42 read back as 0x%x\n", enables);
- */
- }
-
- enables = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "enables in reg 0x40 0x%x\n", enables);
- enables |= 3;
- pci_write_config8(dev, 0x40, enables);
- enables = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "enables in reg 0x40 read back as 0x%x\n", enables);
-
- // Enable prefetch buffers
- enables = pci_read_config8(dev, 0x41);
- enables |= 0xf0;
- pci_write_config8(dev, 0x41, enables);
-
- // Lower thresholds (cause award does it)
- enables = pci_read_config8(dev, 0x43);
- enables &= ~0x0f;
- enables |= 0x05;
- pci_write_config8(dev, 0x43, enables);
-
- // PIO read prefetch counter (cause award does it)
- pci_write_config8(dev, 0x44, 0x18);
-
- // Use memory read multiple
- pci_write_config8(dev, 0x45, 0x1c);
-
- // address decoding.
- // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
- // kevinh@ispiri.com - the standard linux drivers seem ass slow when
- // used in native mode - I've changed back to classic
- enables = pci_read_config8(dev, 0x9);
- printk(BIOS_DEBUG, "enables in reg 0x9 0x%x\n", enables);
- // by the book, set the low-order nibble to 0xa.
- if (conf->enable_native_ide) {
- enables &= ~0xf;
- // cf/cg silicon needs an 'f' here.
- enables |= 0xf;
- } else {
- enables &= ~0x5;
- }
-
- pci_write_config8(dev, 0x9, enables);
- enables = pci_read_config8(dev, 0x9);
- printk(BIOS_DEBUG, "enables in reg 0x9 read back as 0x%x\n", enables);
-
- // standard bios sets master bit.
- enables = pci_read_config8(dev, 0x4);
- printk(BIOS_DEBUG, "command in reg 0x4 0x%x\n", enables);
- enables |= 7;
-
- // No need for stepping - kevinh@ispiri.com
- enables &= ~0x80;
-
- pci_write_config8(dev, 0x4, enables);
- enables = pci_read_config8(dev, 0x4);
- printk(BIOS_DEBUG, "command in reg 0x4 reads back as 0x%x\n", enables);
-
- if (!conf->enable_native_ide) {
- // Use compatability mode - per award bios
- pci_write_config32(dev, 0x10, 0x0);
- pci_write_config32(dev, 0x14, 0x0);
- pci_write_config32(dev, 0x18, 0x0);
- pci_write_config32(dev, 0x1c, 0x0);
-
- // Force interrupts to use compat mode - just like Award bios
- pci_write_config8(dev, 0x3d, 00);
- pci_write_config8(dev, 0x3c, 0xff);
- }
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_82C586_1,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <arch/ioapic.h>
-#include "chip.h"
-
-/* PIRQ init
- */
-static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 };
-static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 };
-
-/*
- Our IDSEL mappings are as follows
- PCI slot is AD31 (device 15) (00:14.0)
- Southbridge is AD28 (device 12) (00:11.0)
-*/
-static void pci_routing_fixup(struct device *dev)
-{
-
- printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
- if (dev) {
- /* initialize PCI interupts - these assignments depend
- on the PCB routing of PINTA-D
-
- PINTA = IRQ11
- PINTB = IRQ5
- PINTC = IRQ10
- PINTD = IRQ12
- */
- pci_write_config8(dev, 0x55, 0xb0);
- pci_write_config8(dev, 0x56, 0xa5);
- pci_write_config8(dev, 0x57, 0xc0);
- }
-
- // Standard southbridge components
- printk(BIOS_INFO, "setting southbridge\n");
- pci_assign_irqs(0, 0x11, southbridgeIrqs);
-
- // Ethernet built into southbridge
- printk(BIOS_INFO, "setting ethernet\n");
- pci_assign_irqs(0, 0x12, enetIrqs);
-
- // PCI slot
- printk(BIOS_INFO, "setting pci slot\n");
- pci_assign_irqs(0, 0x14, slotIrqs);
- printk(BIOS_INFO, "%s: DONE\n", __func__);
-}
-
-static void vt8231_init(struct device *dev)
-{
- unsigned char enables;
-
- printk(BIOS_DEBUG, "vt8231 init\n");
-
- // enable the internal I/O decode
- enables = pci_read_config8(dev, 0x6C);
- enables |= 0x80;
- pci_write_config8(dev, 0x6C, enables);
-
- // Set bit 6 of 0x40, because Award does it (IO recovery time)
- // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
- // interrupts can be properly marked as level triggered.
- enables = pci_read_config8(dev, 0x40);
- pci_write_config8(dev, 0x40, enables);
-
- // Set 0x42 to 0xf0 to match Award bios
- enables = pci_read_config8(dev, 0x42);
- enables |= 0xf0;
- pci_write_config8(dev, 0x42, enables);
-
- // Set bit 3 of 0x4a, to match award (dummy pci request)
- enables = pci_read_config8(dev, 0x4a);
- enables |= 0x08;
- pci_write_config8(dev, 0x4a, enables);
-
- // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
- enables = pci_read_config8(dev, 0x4f);
- enables |= 0x08;
- pci_write_config8(dev, 0x4f, enables);
-
- // Set 0x58 to 0x03 to match Award
- pci_write_config8(dev, 0x58, 0x03);
-
- // enable the ethernet/RTC
- if (dev) {
- enables = pci_read_config8(dev, 0x51);
- enables |= 0x18;
- pci_write_config8(dev, 0x51, enables);
- }
-
- // enable IDE, since Linux won't do it.
- // First do some more things to devfn (17,0)
- // note: this should already be cleared, according to the book.
- enables = pci_read_config8(dev, 0x50);
- printk(BIOS_DEBUG, "IDE enable in reg. 50 is 0x%x\n", enables);
- enables &= ~8; // need manifest constant here!
- printk(BIOS_DEBUG, "set IDE reg. 50 to 0x%x\n", enables);
- pci_write_config8(dev, 0x50, enables);
-
- // set default interrupt values (IDE)
- enables = pci_read_config8(dev, 0x4c);
- printk(BIOS_DEBUG, "IRQs in reg. 4c are 0x%x\n", enables & 0xf);
- // clear out whatever was there.
- enables &= ~0xf;
- enables |= 4;
- printk(BIOS_DEBUG, "setting reg. 4c to 0x%x\n", enables);
- pci_write_config8(dev, 0x4c, enables);
-
- // set up the serial port interrupts.
- // com2 to 3, com1 to 4
- pci_write_config8(dev, 0x46, 0x04);
- pci_write_config8(dev, 0x47, 0x03);
- pci_write_config8(dev, 0x6e, 0x98);
-
- /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
- pci_write_config8(dev, 0x40, 0x54);
- //ethernet_fixup();
-
- // Start the rtc
- rtc_init(0);
-}
-
-static void vt8231_read_resources(device_t dev)
-{
- struct resource *res;
-
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 1);
- res->base = 0x0UL;
- res->size = 0x1000UL;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void southbridge_init(struct device *dev)
-{
- vt8231_init(dev);
- pci_routing_fixup(dev);
-}
-
-static struct device_operations vt8231_lpc_ops = {
- .read_resources = vt8231_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = &southbridge_init,
- .scan_bus = scan_static_bus,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &vt8231_lpc_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8231,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-/*
- * Enable the ethernet device and turn off stepping (because it is integrated
- * inside the southbridge)
- */
-static void nic_init(struct device *dev)
-{
- uint8_t byte;
-
- printk(BIOS_DEBUG, "Configuring VIA LAN\n");
-
- /* We don't need stepping - though the device supports it */
- byte = pci_read_config8(dev, PCI_COMMAND);
- byte &= ~PCI_COMMAND_WAIT;
- pci_write_config8(dev, PCI_COMMAND, byte);
-}
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8233_7,
-};
+++ /dev/null
-
-static void usb_on(int enable)
-{
- unsigned char regval;
-
- /* Base 8231 controller */
- device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, 0);
- /* USB controller 1 */
- device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
- /* USB controller 2 */
- device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2);
-
- /* enable USB1 */
- if(dev2) {
- if (enable) {
- pci_write_config8(dev2, 0x3c, 0x05);
- pci_write_config8(dev2, 0x04, 0x07);
- } else {
- pci_write_config8(dev2, 0x3c, 0x00);
- pci_write_config8(dev2, 0x04, 0x00);
- }
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x10);
- else
- regval |= 0x10;
- pci_write_config8(dev0, 0x50, regval);
- }
-
- /* enable USB2 */
- if(dev3) {
- if (enable) {
- pci_write_config8(dev3, 0x3c, 0x05);
- pci_write_config8(dev3, 0x04, 0x07);
- } else {
- pci_write_config8(dev3, 0x3c, 0x00);
- pci_write_config8(dev3, 0x04, 0x00);
- }
- }
-
- if(dev0) {
- regval = pci_read_config8(dev0, 0x50);
- if (enable)
- regval &= ~(0x20);
- else
- regval |= 0x20;
- pci_write_config8(dev0, 0x50, regval);
- }
-}
##
driver-y += vt8235.c
-driver-y += vt8235_ide.c
-driver-y += vt8235_lpc.c
-driver-y += vt8235_nic.c
-driver-y += vt8235_usb.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += nic.c
+driver-y += usb.c
--- /dev/null
+/*
+ * Enable the serial evices on the VIA
+ */
+
+
+/* The base address is 0x15c, 0x2e, depending on config bytes */
+
+#define SIO_BASE 0x3f0
+#define SIO_DATA SIO_BASE+1
+
+static void vt8235_writepnpaddr(uint8_t val)
+{
+ outb(val, 0x2e);
+ outb(val, 0xeb);
+}
+
+static void vt8235_writepnpdata(uint8_t val)
+{
+ outb(val, 0x2f);
+ outb(val, 0xeb);
+}
+
+
+static void vt8235_writesiobyte(uint16_t reg, uint8_t val)
+{
+ outb(val, reg);
+}
+
+static void vt8235_writesioword(uint16_t reg, uint16_t val)
+{
+ outw(val, reg);
+}
+
+
+/* regs we use: 85, and the southbridge devfn is defined by the
+ mainboard
+ */
+
+static void enable_vt8235_serial(void)
+{
+ // turn on pnp
+ vt8235_writepnpaddr(0x87);
+ vt8235_writepnpaddr(0x87);
+ // now go ahead and set up com1.
+ // set address
+ vt8235_writepnpaddr(0x7);
+ vt8235_writepnpdata(0x2);
+ // enable serial out
+ vt8235_writepnpaddr(0x30);
+ vt8235_writepnpdata(0x1);
+ // serial port 1 base address (FEh)
+ vt8235_writepnpaddr(0x60);
+ vt8235_writepnpdata(0xfe);
+ // serial port 1 IRQ (04h)
+ vt8235_writepnpaddr(0x70);
+ vt8235_writepnpdata(0x4);
+ // serial port 1 control
+ vt8235_writepnpaddr(0xf0);
+ vt8235_writepnpdata(0x2);
+ // turn of pnp
+ vt8235_writepnpaddr(0xaa);
+
+ // set up reg to set baud rate.
+ vt8235_writesiobyte(0x3fb, 0x80);
+ // Set 115 kb
+ vt8235_writesioword(0x3f8, 1);
+ // Set 9.6 kb
+ // WRITESIOWORD(0x3f8, 12)
+ // now set no parity, one stop, 8 bits
+ vt8235_writesiobyte(0x3fb, 3);
+ // now turn on RTS, DRT
+ vt8235_writesiobyte(0x3fc, 3);
+ // Enable interrupts
+ vt8235_writesiobyte(0x3f9, 0xf);
+ // should be done. Dump a char for fun.
+ vt8235_writesiobyte(0x3f8, 48);
+}
--- /dev/null
+#define SMBUS_IO_BASE 0xf00
+
+#define SMBHSTSTAT 0x0
+#define SMBSLVSTAT 0x1
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBSLVCTL 0x8
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+
+/* Define register settings */
+#define HOST_RESET 0xff
+#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
+
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+#define I2C_TRANS_CMD 0x40
+#define CLOCK_SLAVE_ADDRESS 0x69
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ unsigned char c;
+ int i;
+
+ /* Power management controller */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8235), 0);
+
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBUS controller not found\n");
+ }
+
+ // set IO base address to SMBUS_IO_BASE
+ pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1);
+
+ // Enable SMBus
+ pci_write_config8(dev, 0xd2, (0x4 << 1) | 1);
+
+ /* make it work for I/O ...
+ */
+ pci_write_config16(dev, 4, 1);
+
+ /* FIX for half baud rate problem */
+ /* let clocks and the like settle */
+ /* as yet arbitrary count - 1000 is too little 5000 works */
+ for(i = 0 ; i < 5000 ; i++)
+ outb(0x80,0x80);
+
+ /*
+ * The VT1211 serial port needs 48 mhz clock, on power up it is getting
+ * only 24 mhz, there is some mysterious device on the smbus that can
+ * fix this...this code below does it.
+ * */
+ outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
+ outb(0x7f, SMBUS_IO_BASE+SMBHSTDAT0);
+ outb(0x83, SMBUS_IO_BASE+SMBHSTCMD);
+ outb(CLOCK_SLAVE_ADDRESS<<1 , SMBUS_IO_BASE+SMBXMITADD);
+ outb(8 | I2C_TRANS_CMD, SMBUS_IO_BASE+SMBHSTCTL);
+
+ for (;;) {
+ c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
+ if ((c & 1) == 0)
+ break;
+ }
+}
+
+
+static inline void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(void)
+{
+ unsigned char c;
+ unsigned long loops;
+ loops = SMBUS_TIMEOUT;
+ do {
+ smbus_delay();
+ c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ while((c & 1) == 1) {
+ print_debug("c is ");
+ print_debug_hex8(c);
+ print_debug("\n");
+ c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ /* nop */
+ }
+
+ } while(--loops);
+ return loops?0:-1;
+}
+
+void smbus_reset(void)
+{
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+ outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
+
+ smbus_wait_until_ready();
+ print_debug("After reset status ");
+ print_debug_hex8( inb(SMBUS_IO_BASE + SMBHSTSTAT));
+ print_debug("\n");
+}
+
+
+
+static int smbus_wait_until_done(void)
+{
+ unsigned long loops;
+ unsigned char byte;
+ loops = SMBUS_TIMEOUT;
+ do {
+ smbus_delay();
+
+ byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+ if (byte & 1)
+ break;
+
+ } while(--loops);
+ return loops?0:-1;
+}
+
+static void smbus_print_error(unsigned char host_status_register)
+{
+
+ print_err("smbus_error: ");
+ print_err_hex8(host_status_register);
+ print_err("\n");
+ if (host_status_register & (1 << 4)) {
+ print_err("Interrup/SMI# was Failed Bus Transaction\n");
+ }
+ if (host_status_register & (1 << 3)) {
+ print_err("Bus Error\n");
+ }
+ if (host_status_register & (1 << 2)) {
+ print_err("Device Error\n");
+ }
+ if (host_status_register & (1 << 1)) {
+ print_err("Interrupt/SMI# was Successful Completion\n");
+ }
+ if (host_status_register & (1 << 0)) {
+ print_err("Host Busy\n");
+ }
+}
+
+
+/* SMBus routines borrowed from VIA's Trident Driver */
+/* this works, so I am not going to touch it for now -- rgm */
+static unsigned char smbus_read_byte(unsigned char devAdr,
+ unsigned char bIndex)
+{
+ unsigned short i;
+ unsigned char bData;
+ unsigned char sts = 0;
+
+ /* clear host status */
+ outb(0xff, SMBUS_IO_BASE);
+
+ /* check SMBUS ready */
+ for ( i = 0; i < 0xFFFF; i++ )
+ if ( (inb(SMBUS_IO_BASE) & 0x01) == 0 )
+ break;
+
+ /* set host command */
+ outb(bIndex, SMBUS_IO_BASE+3);
+
+ /* set slave address */
+ outb((devAdr << 1) | 0x01, SMBUS_IO_BASE+4);
+
+ /* start */
+ outb(0x48, SMBUS_IO_BASE+2);
+
+ /* SMBUS Wait Ready */
+ for ( i = 0; i < 0xFFFF; i++ )
+ if ( ((sts = (inb(SMBUS_IO_BASE) & 0x1f)) & 0x01) == 0 )
+ break;
+
+ if ((sts & ~3) != 0) {
+ smbus_print_error(sts);
+ return 0;
+ }
+ bData=inb(SMBUS_IO_BASE+5);
+
+ return bData;
+
+}
+
+/* for reference, here is the fancier version which we will use at some
+ * point
+ */
+# if 0
+int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
+{
+ unsigned char host_status_register;
+ unsigned char byte;
+
+ reset();
+
+ smbus_wait_until_ready();
+
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
+ SMBUS_IO_BASE + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ smbus_wait_until_done();
+
+ host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ host_status_register &= ~(1 << 6);
+
+ /* read results of transaction */
+ byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
+ smbus_print_error(byte);
+
+ *result = byte;
+ return host_status_register != 0x02;
+}
+
+
+#endif
+
--- /dev/null
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "chip.h"
+
+static void ide_init(struct device *dev)
+{
+ struct southbridge_via_vt8235_config *conf = dev->chip_info;
+ unsigned char enables;
+
+ printk(BIOS_INFO, "Enabling VIA IDE.\n");
+
+ /*if (!conf->enable_native_ide) { */
+ /*
+ * Run the IDE controller in 'compatiblity mode - i.e. don't
+ * use PCI interrupts. Using PCI ints confuses linux for some
+ * reason.
+ */
+ printk(BIOS_INFO, "%s: enabling compatibility IDE addresses\n",
+ __func__);
+ enables = pci_read_config8(dev, 0x42);
+ printk(BIOS_DEBUG, "enables in reg 0x42 0x%x\n", enables);
+ enables &= ~0xc0; // compatability mode
+ pci_write_config8(dev, 0x42, enables);
+ enables = pci_read_config8(dev, 0x42);
+ printk(BIOS_DEBUG, "enables in reg 0x42 read back as 0x%x\n",
+ enables);
+ /* } */
+
+ enables = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "enables in reg 0x40 0x%x\n", enables);
+ enables |= 3;
+ pci_write_config8(dev, 0x40, enables);
+ enables = pci_read_config8(dev, 0x40);
+ printk(BIOS_DEBUG, "enables in reg 0x40 read back as 0x%x\n", enables);
+
+ // Enable prefetch buffers
+ enables = pci_read_config8(dev, 0x41);
+ enables |= 0xf0;
+ pci_write_config8(dev, 0x41, enables);
+
+ // Lower thresholds (cause award does it)
+ enables = pci_read_config8(dev, 0x43);
+ enables &= ~0x0f;
+ enables |= 0x05;
+ pci_write_config8(dev, 0x43, enables);
+
+ // PIO read prefetch counter (cause award does it)
+ pci_write_config8(dev, 0x44, 0x18);
+
+ // Use memory read multiple
+ pci_write_config8(dev, 0x45, 0x1c);
+
+ // address decoding.
+ // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
+ // kevinh@ispiri.com - the standard linux drivers seem ass slow when
+ // used in native mode - I've changed back to classic
+ enables = pci_read_config8(dev, 0x9);
+ printk(BIOS_DEBUG, "enables in reg 0x9 0x%x\n", enables);
+ // by the book, set the low-order nibble to 0xa.
+ if (conf->enable_native_ide) {
+ enables &= ~0xf;
+ // cf/cg silicon needs an 'f' here.
+ enables |= 0xf;
+ } else {
+ enables &= ~0x5;
+ }
+
+ pci_write_config8(dev, 0x9, enables);
+ enables = pci_read_config8(dev, 0x9);
+ printk(BIOS_DEBUG, "enables in reg 0x9 read back as 0x%x\n", enables);
+
+ // standard bios sets master bit.
+ enables = pci_read_config8(dev, 0x4);
+ printk(BIOS_DEBUG, "command in reg 0x4 0x%x\n", enables);
+ enables |= 7;
+
+ // No need for stepping - kevinh@ispiri.com
+ enables &= ~0x80;
+
+ pci_write_config8(dev, 0x4, enables);
+ enables = pci_read_config8(dev, 0x4);
+ printk(BIOS_DEBUG, "command in reg 0x4 reads back as 0x%x\n", enables);
+
+ if (!conf->enable_native_ide) {
+ // Use compatability mode - per award bios
+ pci_write_config32(dev, 0x10, 0x0);
+ pci_write_config32(dev, 0x14, 0x0);
+ pci_write_config32(dev, 0x18, 0x0);
+ pci_write_config32(dev, 0x1c, 0x0);
+
+ // Force interrupts to use compat mode - just like Award bios
+ pci_write_config8(dev, 0x3d, 0x0);
+ pci_write_config8(dev, 0x3c, 0xff);
+ }
+}
+
+static struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_82C586_1,
+};
--- /dev/null
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/ioapic.h>
+#include "chip.h"
+
+/* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
+ This is how the Award bios sets it up too.
+ epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
+ make sure that ACPI dsdt is changed to suit.
+
+ IRQ 0 = timer
+ IRQ 1 = keyboard
+ IRQ 2 = cascade
+ IRQ 3 = COM 2
+ IRQ 4 = COM 1
+ IRQ 5 = available for PCI interrupts
+ IRQ 6 = floppy or availbale for PCI if floppy controller disabled
+ IRQ 7 = LPT or available if LPT port disabled
+ IRQ 8 = rtc
+ IRQ 9 = available for PCI interrupts
+ IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
+ IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
+ IRQ 12 = PS2 mouse (hardwired to 12)
+ IRQ 13 = legacy FPU interrupt
+ IRQ 14 = IDE controller 1
+ IRQ 15 = IDE controller 2
+
+*/
+static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
+
+static const unsigned char usbPins[4] = { 'A','B','C','D'};
+static const unsigned char enetPins[4] = { 'A','B','C','D'};
+static const unsigned char slotPins[4] = { 'B','C','D','A'};
+static const unsigned char firewirePins[4] = { 'B','C','D','A'};
+static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
+static const unsigned char vgaPins[4] = { 'A','B','C','D'};
+static const unsigned char cbPins[4] = { 'A','B','C','D'};
+static const unsigned char riserPins[4] = { 'A','B','C','D'};
+
+
+static unsigned char *pin_to_irq(const unsigned char *pin)
+{
+ static unsigned char Irqs[4];
+ int i;
+ for (i = 0 ; i < 4 ; i++)
+ Irqs[i] = pciIrqs[ pin[i] - 'A' ];
+
+ return Irqs;
+}
+
+static void pci_routing_fixup(struct device *dev)
+{
+ printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
+
+ /* set up PCI IRQ routing */
+ pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+ pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+ pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
+
+ // firewire built into southbridge
+ printk(BIOS_INFO, "setting firewire\n");
+ pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
+
+ // Standard usb components
+ printk(BIOS_INFO, "setting usb\n");
+ pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
+
+ // VT8235 + sound hardware
+ printk(BIOS_INFO, "setting vt8235\n");
+ pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
+
+ // Ethernet built into southbridge
+ printk(BIOS_INFO, "setting ethernet\n");
+ pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
+
+ // VGA
+ printk(BIOS_INFO, "setting vga\n");
+ pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
+
+ // PCI slot
+ printk(BIOS_INFO, "setting pci slot\n");
+ pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
+
+ // Cardbus slot
+ printk(BIOS_INFO, "setting cardbus slot\n");
+ pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
+
+ // Via 2 slot riser card 2nd slot
+ printk(BIOS_INFO, "setting riser slot\n");
+ pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
+
+ printk(BIOS_SPEW, "%s: DONE\n", __func__);
+}
+
+/*
+ * Set up the power management capabilities directly into ACPI mode. This
+ * avoids having to handle any System Management Interrupts (SMI's) which I
+ * can't figure out how to do !!!!
+ */
+
+static void setup_pm(device_t dev)
+{
+ // Set gen config 0
+ pci_write_config8(dev, 0x80, 0x20);
+
+ // Set ACPI base address to IO 0x400
+ pci_write_config16(dev, 0x88, 0x0401);
+
+ // set ACPI irq to 5
+ pci_write_config8(dev, 0x82, 0x45);
+
+ // primary interupt channel
+ pci_write_config16(dev, 0x84, 0x30f2);
+
+ // throttle / stop clock control
+ pci_write_config8(dev, 0x8d, 0x18);
+
+ pci_write_config8(dev, 0x93, 0x88);
+ pci_write_config8(dev, 0x94, 0xb0);
+ pci_write_config8(dev, 0x95, 0xc0);
+ pci_write_config8(dev, 0x98, 0);
+ pci_write_config8(dev, 0x99, 0xea);
+ pci_write_config8(dev, 0xe4, 0x14);
+ pci_write_config8(dev, 0xe5, 0x08);
+
+
+ // Enable ACPI access (and setup like award)
+ pci_write_config8(dev, 0x81, 0x84);
+
+ outw(0xffff, 0x400);
+ outw(0xffff, 0x420);
+ outw(0xffff, 0x428);
+ outl(0xffffffff, 0x430);
+
+ outw(0x0, 0x424);
+ outw(0x0, 0x42a);
+ outw(0x1, 0x42c);
+ outl(0x0, 0x434);
+ outl(0x01, 0x438);
+ outb(0x0, 0x442);
+ outl(0xffff7fff, 0x448);
+ outw(0x001, 0x404);
+}
+
+static void vt8235_init(struct device *dev)
+{
+ unsigned char enables;
+
+ printk(BIOS_DEBUG, "vt8235 init\n");
+
+ // enable the internal I/O decode
+ enables = pci_read_config8(dev, 0x6C);
+ enables |= 0x80;
+ pci_write_config8(dev, 0x6C, enables);
+
+ // Map 4MB of FLASH into the address space
+ pci_write_config8(dev, 0x41, 0x7f);
+
+ // Set bit 6 of 0x40, because Award does it (IO recovery time)
+ // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
+ // interrupts can be properly marked as level triggered.
+ enables = pci_read_config8(dev, 0x40);
+ enables |= 0x45;
+ pci_write_config8(dev, 0x40, enables);
+
+ // Set 0x42 to 0xf0 to match Award bios
+ enables = pci_read_config8(dev, 0x42);
+ enables |= 0xf0;
+ pci_write_config8(dev, 0x42, enables);
+
+ /* Set 0x58 to 0x03 to match Award */
+ pci_write_config8(dev, 0x58, 0x03);
+
+ /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
+ enables = pci_read_config8(dev, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4f, enables);
+
+ // Set bit 3 of 0x4a, to match award (dummy pci request)
+ enables = pci_read_config8(dev, 0x4a);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4a, enables);
+
+ // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
+ enables = pci_read_config8(dev, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4f, enables);
+
+ // Set 0x58 to 0x03 to match Award
+ pci_write_config8(dev, 0x58, 0x03);
+
+
+ /* enable serial irq */
+ pci_write_config8(dev, 0x52, 0x9);
+
+ /* dma */
+ pci_write_config8(dev, 0x53, 0x00);
+
+ // Power management setup
+ setup_pm(dev);
+
+ /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
+ pci_write_config8(dev, 0x40, 0x54);
+
+ // Start the rtc
+ rtc_init(0);
+}
+
+/* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
+ device has a resource to set - so set a dummy one */
+static void vt8235_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ pci_dev_read_resources(dev);
+
+ res = new_resource(dev, 1);
+ res->base = 0x0UL;
+ res->size = 0x1000UL;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+ res = new_resource(dev, 3); /* IOAPIC */
+ res->base = IO_APIC_ADDR;
+ res->size = 0x00001000;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void vt8235_set_resources(device_t dev)
+{
+ //struct resource *resource;
+ //resource = find_resource(dev,1);
+ //resource->flags |= IORESOURCE_STORED;
+ pci_dev_set_resources(dev);
+}
+
+static void southbridge_init(struct device *dev)
+{
+ vt8235_init(dev);
+ pci_routing_fixup(dev);
+}
+
+static struct device_operations vt8235_lpc_ops = {
+ .read_resources = vt8235_read_resources,
+ .set_resources = vt8235_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = southbridge_init,
+ .scan_bus = scan_static_bus,
+};
+
+static const struct pci_driver lpc_driver __pci_driver = {
+ .ops = &vt8235_lpc_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8235,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+
+/*
+ * Enable the ethernet device and turn off stepping (because it is integrated
+ * inside the southbridge)
+ */
+static void nic_init(struct device *dev)
+{
+ uint8_t byte;
+
+ printk(BIOS_DEBUG, "Configuring VIA Rhine LAN\n");
+
+ /* We don't need stepping - though the device supports it */
+ byte = pci_read_config8(dev, PCI_COMMAND);
+ byte &= ~PCI_COMMAND_WAIT;
+ pci_write_config8(dev, PCI_COMMAND, byte);
+}
+
+static struct device_operations nic_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = nic_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &nic_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8233_7,
+};
--- /dev/null
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+
+/* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated
+ properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */
+
+static void usb_init(struct device *dev)
+{
+ printk(BIOS_DEBUG, "Configuring VIA USB 1.1\n");
+
+ /* pci_write_config8(dev, 0x04, 0x07); */
+
+ /*
+ * To disable; though do we need to do this?
+ pci_write_config8(dev1, 0x3c, 0x00);
+ pci_write_config8(dev1, 0x04, 0x00);
+
+ Also, on the root dev, for enable:
+ regval = pci_read_config8(dev0, 0x50);
+ regval &= ~(0x36);
+ pci_write_config8(dev0, 0x50, regval);
+
+ (regval |= 0x36; for disable)
+ */
+}
+
+static struct device_operations usb_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &usb_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_82C586_2,
+};
+
+++ /dev/null
-/*
- * Enable the serial evices on the VIA
- */
-
-
-/* The base address is 0x15c, 0x2e, depending on config bytes */
-
-#define SIO_BASE 0x3f0
-#define SIO_DATA SIO_BASE+1
-
-static void vt8235_writepnpaddr(uint8_t val)
-{
- outb(val, 0x2e);
- outb(val, 0xeb);
-}
-
-static void vt8235_writepnpdata(uint8_t val)
-{
- outb(val, 0x2f);
- outb(val, 0xeb);
-}
-
-
-static void vt8235_writesiobyte(uint16_t reg, uint8_t val)
-{
- outb(val, reg);
-}
-
-static void vt8235_writesioword(uint16_t reg, uint16_t val)
-{
- outw(val, reg);
-}
-
-
-/* regs we use: 85, and the southbridge devfn is defined by the
- mainboard
- */
-
-static void enable_vt8235_serial(void)
-{
- // turn on pnp
- vt8235_writepnpaddr(0x87);
- vt8235_writepnpaddr(0x87);
- // now go ahead and set up com1.
- // set address
- vt8235_writepnpaddr(0x7);
- vt8235_writepnpdata(0x2);
- // enable serial out
- vt8235_writepnpaddr(0x30);
- vt8235_writepnpdata(0x1);
- // serial port 1 base address (FEh)
- vt8235_writepnpaddr(0x60);
- vt8235_writepnpdata(0xfe);
- // serial port 1 IRQ (04h)
- vt8235_writepnpaddr(0x70);
- vt8235_writepnpdata(0x4);
- // serial port 1 control
- vt8235_writepnpaddr(0xf0);
- vt8235_writepnpdata(0x2);
- // turn of pnp
- vt8235_writepnpaddr(0xaa);
-
- // set up reg to set baud rate.
- vt8235_writesiobyte(0x3fb, 0x80);
- // Set 115 kb
- vt8235_writesioword(0x3f8, 1);
- // Set 9.6 kb
- // WRITESIOWORD(0x3f8, 12)
- // now set no parity, one stop, 8 bits
- vt8235_writesiobyte(0x3fb, 3);
- // now turn on RTS, DRT
- vt8235_writesiobyte(0x3fc, 3);
- // Enable interrupts
- vt8235_writesiobyte(0x3f9, 0xf);
- // should be done. Dump a char for fun.
- vt8235_writesiobyte(0x3f8, 48);
-}
+++ /dev/null
-#define SMBUS_IO_BASE 0xf00
-
-#define SMBHSTSTAT 0x0
-#define SMBSLVSTAT 0x1
-#define SMBHSTCTL 0x2
-#define SMBHSTCMD 0x3
-#define SMBXMITADD 0x4
-#define SMBHSTDAT0 0x5
-#define SMBHSTDAT1 0x6
-#define SMBBLKDAT 0x7
-#define SMBSLVCTL 0x8
-#define SMBTRNSADD 0x9
-#define SMBSLVDATA 0xa
-#define SMLINK_PIN_CTL 0xe
-#define SMBUS_PIN_CTL 0xf
-
-/* Define register settings */
-#define HOST_RESET 0xff
-#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
-
-
-#define SMBUS_TIMEOUT (100*1000*10)
-
-#define I2C_TRANS_CMD 0x40
-#define CLOCK_SLAVE_ADDRESS 0x69
-
-static void enable_smbus(void)
-{
- device_t dev;
- unsigned char c;
- int i;
-
- /* Power management controller */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8235), 0);
-
- if (dev == PCI_DEV_INVALID) {
- die("SMBUS controller not found\n");
- }
-
- // set IO base address to SMBUS_IO_BASE
- pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1);
-
- // Enable SMBus
- pci_write_config8(dev, 0xd2, (0x4 << 1) | 1);
-
- /* make it work for I/O ...
- */
- pci_write_config16(dev, 4, 1);
-
- /* FIX for half baud rate problem */
- /* let clocks and the like settle */
- /* as yet arbitrary count - 1000 is too little 5000 works */
- for(i = 0 ; i < 5000 ; i++)
- outb(0x80,0x80);
-
- /*
- * The VT1211 serial port needs 48 mhz clock, on power up it is getting
- * only 24 mhz, there is some mysterious device on the smbus that can
- * fix this...this code below does it.
- * */
- outb(0xff, SMBUS_IO_BASE+SMBHSTSTAT);
- outb(0x7f, SMBUS_IO_BASE+SMBHSTDAT0);
- outb(0x83, SMBUS_IO_BASE+SMBHSTCMD);
- outb(CLOCK_SLAVE_ADDRESS<<1 , SMBUS_IO_BASE+SMBXMITADD);
- outb(8 | I2C_TRANS_CMD, SMBUS_IO_BASE+SMBHSTCTL);
-
- for (;;) {
- c = inb(SMBUS_IO_BASE+SMBHSTSTAT);
- if ((c & 1) == 0)
- break;
- }
-}
-
-
-static inline void smbus_delay(void)
-{
- outb(0x80, 0x80);
-}
-
-static int smbus_wait_until_ready(void)
-{
- unsigned char c;
- unsigned long loops;
- loops = SMBUS_TIMEOUT;
- do {
- smbus_delay();
- c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- while((c & 1) == 1) {
- print_debug("c is ");
- print_debug_hex8(c);
- print_debug("\n");
- c = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- /* nop */
- }
-
- } while(--loops);
- return loops?0:-1;
-}
-
-void smbus_reset(void)
-{
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
- outb(HOST_RESET, SMBUS_IO_BASE + SMBHSTSTAT);
-
- smbus_wait_until_ready();
- print_debug("After reset status ");
- print_debug_hex8( inb(SMBUS_IO_BASE + SMBHSTSTAT));
- print_debug("\n");
-}
-
-
-
-static int smbus_wait_until_done(void)
-{
- unsigned long loops;
- unsigned char byte;
- loops = SMBUS_TIMEOUT;
- do {
- smbus_delay();
-
- byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
- if (byte & 1)
- break;
-
- } while(--loops);
- return loops?0:-1;
-}
-
-static void smbus_print_error(unsigned char host_status_register)
-{
-
- print_err("smbus_error: ");
- print_err_hex8(host_status_register);
- print_err("\n");
- if (host_status_register & (1 << 4)) {
- print_err("Interrup/SMI# was Failed Bus Transaction\n");
- }
- if (host_status_register & (1 << 3)) {
- print_err("Bus Error\n");
- }
- if (host_status_register & (1 << 2)) {
- print_err("Device Error\n");
- }
- if (host_status_register & (1 << 1)) {
- print_err("Interrupt/SMI# was Successful Completion\n");
- }
- if (host_status_register & (1 << 0)) {
- print_err("Host Busy\n");
- }
-}
-
-
-/* SMBus routines borrowed from VIA's Trident Driver */
-/* this works, so I am not going to touch it for now -- rgm */
-static unsigned char smbus_read_byte(unsigned char devAdr,
- unsigned char bIndex)
-{
- unsigned short i;
- unsigned char bData;
- unsigned char sts = 0;
-
- /* clear host status */
- outb(0xff, SMBUS_IO_BASE);
-
- /* check SMBUS ready */
- for ( i = 0; i < 0xFFFF; i++ )
- if ( (inb(SMBUS_IO_BASE) & 0x01) == 0 )
- break;
-
- /* set host command */
- outb(bIndex, SMBUS_IO_BASE+3);
-
- /* set slave address */
- outb((devAdr << 1) | 0x01, SMBUS_IO_BASE+4);
-
- /* start */
- outb(0x48, SMBUS_IO_BASE+2);
-
- /* SMBUS Wait Ready */
- for ( i = 0; i < 0xFFFF; i++ )
- if ( ((sts = (inb(SMBUS_IO_BASE) & 0x1f)) & 0x01) == 0 )
- break;
-
- if ((sts & ~3) != 0) {
- smbus_print_error(sts);
- return 0;
- }
- bData=inb(SMBUS_IO_BASE+5);
-
- return bData;
-
-}
-
-/* for reference, here is the fancier version which we will use at some
- * point
- */
-# if 0
-int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
-{
- unsigned char host_status_register;
- unsigned char byte;
-
- reset();
-
- smbus_wait_until_ready();
-
- /* setup transaction */
- /* disable interrupts */
- outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
- /* set the device I'm talking too */
- outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
- /* set the command/address... */
- outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
- /* set up for a byte data read */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* clear any lingering errors, so the transaction will run */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* clear the data byte...*/
- outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
-
- /* start the command */
- outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40),
- SMBUS_IO_BASE + SMBHSTCTL);
-
- /* poll for transaction completion */
- smbus_wait_until_done();
-
- host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
-
- /* Ignore the In Use Status... */
- host_status_register &= ~(1 << 6);
-
- /* read results of transaction */
- byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
- smbus_print_error(byte);
-
- *result = byte;
- return host_status_register != 0x02;
-}
-
-
-#endif
-
+++ /dev/null
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "chip.h"
-
-static void ide_init(struct device *dev)
-{
- struct southbridge_via_vt8235_config *conf = dev->chip_info;
- unsigned char enables;
-
- printk(BIOS_INFO, "Enabling VIA IDE.\n");
-
- /*if (!conf->enable_native_ide) { */
- /*
- * Run the IDE controller in 'compatiblity mode - i.e. don't
- * use PCI interrupts. Using PCI ints confuses linux for some
- * reason.
- */
- printk(BIOS_INFO, "%s: enabling compatibility IDE addresses\n",
- __func__);
- enables = pci_read_config8(dev, 0x42);
- printk(BIOS_DEBUG, "enables in reg 0x42 0x%x\n", enables);
- enables &= ~0xc0; // compatability mode
- pci_write_config8(dev, 0x42, enables);
- enables = pci_read_config8(dev, 0x42);
- printk(BIOS_DEBUG, "enables in reg 0x42 read back as 0x%x\n",
- enables);
- /* } */
-
- enables = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "enables in reg 0x40 0x%x\n", enables);
- enables |= 3;
- pci_write_config8(dev, 0x40, enables);
- enables = pci_read_config8(dev, 0x40);
- printk(BIOS_DEBUG, "enables in reg 0x40 read back as 0x%x\n", enables);
-
- // Enable prefetch buffers
- enables = pci_read_config8(dev, 0x41);
- enables |= 0xf0;
- pci_write_config8(dev, 0x41, enables);
-
- // Lower thresholds (cause award does it)
- enables = pci_read_config8(dev, 0x43);
- enables &= ~0x0f;
- enables |= 0x05;
- pci_write_config8(dev, 0x43, enables);
-
- // PIO read prefetch counter (cause award does it)
- pci_write_config8(dev, 0x44, 0x18);
-
- // Use memory read multiple
- pci_write_config8(dev, 0x45, 0x1c);
-
- // address decoding.
- // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
- // kevinh@ispiri.com - the standard linux drivers seem ass slow when
- // used in native mode - I've changed back to classic
- enables = pci_read_config8(dev, 0x9);
- printk(BIOS_DEBUG, "enables in reg 0x9 0x%x\n", enables);
- // by the book, set the low-order nibble to 0xa.
- if (conf->enable_native_ide) {
- enables &= ~0xf;
- // cf/cg silicon needs an 'f' here.
- enables |= 0xf;
- } else {
- enables &= ~0x5;
- }
-
- pci_write_config8(dev, 0x9, enables);
- enables = pci_read_config8(dev, 0x9);
- printk(BIOS_DEBUG, "enables in reg 0x9 read back as 0x%x\n", enables);
-
- // standard bios sets master bit.
- enables = pci_read_config8(dev, 0x4);
- printk(BIOS_DEBUG, "command in reg 0x4 0x%x\n", enables);
- enables |= 7;
-
- // No need for stepping - kevinh@ispiri.com
- enables &= ~0x80;
-
- pci_write_config8(dev, 0x4, enables);
- enables = pci_read_config8(dev, 0x4);
- printk(BIOS_DEBUG, "command in reg 0x4 reads back as 0x%x\n", enables);
-
- if (!conf->enable_native_ide) {
- // Use compatability mode - per award bios
- pci_write_config32(dev, 0x10, 0x0);
- pci_write_config32(dev, 0x14, 0x0);
- pci_write_config32(dev, 0x18, 0x0);
- pci_write_config32(dev, 0x1c, 0x0);
-
- // Force interrupts to use compat mode - just like Award bios
- pci_write_config8(dev, 0x3d, 0x0);
- pci_write_config8(dev, 0x3c, 0xff);
- }
-}
-
-static struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_82C586_1,
-};
+++ /dev/null
-#include <arch/io.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <arch/ioapic.h>
-#include "chip.h"
-
-/* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
- This is how the Award bios sets it up too.
- epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
- make sure that ACPI dsdt is changed to suit.
-
- IRQ 0 = timer
- IRQ 1 = keyboard
- IRQ 2 = cascade
- IRQ 3 = COM 2
- IRQ 4 = COM 1
- IRQ 5 = available for PCI interrupts
- IRQ 6 = floppy or availbale for PCI if floppy controller disabled
- IRQ 7 = LPT or available if LPT port disabled
- IRQ 8 = rtc
- IRQ 9 = available for PCI interrupts
- IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
- IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
- IRQ 12 = PS2 mouse (hardwired to 12)
- IRQ 13 = legacy FPU interrupt
- IRQ 14 = IDE controller 1
- IRQ 15 = IDE controller 2
-
-*/
-static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
-
-static const unsigned char usbPins[4] = { 'A','B','C','D'};
-static const unsigned char enetPins[4] = { 'A','B','C','D'};
-static const unsigned char slotPins[4] = { 'B','C','D','A'};
-static const unsigned char firewirePins[4] = { 'B','C','D','A'};
-static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
-static const unsigned char vgaPins[4] = { 'A','B','C','D'};
-static const unsigned char cbPins[4] = { 'A','B','C','D'};
-static const unsigned char riserPins[4] = { 'A','B','C','D'};
-
-
-static unsigned char *pin_to_irq(const unsigned char *pin)
-{
- static unsigned char Irqs[4];
- int i;
- for (i = 0 ; i < 4 ; i++)
- Irqs[i] = pciIrqs[ pin[i] - 'A' ];
-
- return Irqs;
-}
-
-static void pci_routing_fixup(struct device *dev)
-{
- printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
-
- /* set up PCI IRQ routing */
- pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
- pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
- pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
-
-
- // firewire built into southbridge
- printk(BIOS_INFO, "setting firewire\n");
- pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
-
- // Standard usb components
- printk(BIOS_INFO, "setting usb\n");
- pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
-
- // VT8235 + sound hardware
- printk(BIOS_INFO, "setting vt8235\n");
- pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
-
- // Ethernet built into southbridge
- printk(BIOS_INFO, "setting ethernet\n");
- pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
-
- // VGA
- printk(BIOS_INFO, "setting vga\n");
- pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
-
- // PCI slot
- printk(BIOS_INFO, "setting pci slot\n");
- pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
-
- // Cardbus slot
- printk(BIOS_INFO, "setting cardbus slot\n");
- pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
-
- // Via 2 slot riser card 2nd slot
- printk(BIOS_INFO, "setting riser slot\n");
- pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
-
- printk(BIOS_SPEW, "%s: DONE\n", __func__);
-}
-
-/*
- * Set up the power management capabilities directly into ACPI mode. This
- * avoids having to handle any System Management Interrupts (SMI's) which I
- * can't figure out how to do !!!!
- */
-
-static void setup_pm(device_t dev)
-{
- // Set gen config 0
- pci_write_config8(dev, 0x80, 0x20);
-
- // Set ACPI base address to IO 0x400
- pci_write_config16(dev, 0x88, 0x0401);
-
- // set ACPI irq to 5
- pci_write_config8(dev, 0x82, 0x45);
-
- // primary interupt channel
- pci_write_config16(dev, 0x84, 0x30f2);
-
- // throttle / stop clock control
- pci_write_config8(dev, 0x8d, 0x18);
-
- pci_write_config8(dev, 0x93, 0x88);
- pci_write_config8(dev, 0x94, 0xb0);
- pci_write_config8(dev, 0x95, 0xc0);
- pci_write_config8(dev, 0x98, 0);
- pci_write_config8(dev, 0x99, 0xea);
- pci_write_config8(dev, 0xe4, 0x14);
- pci_write_config8(dev, 0xe5, 0x08);
-
-
- // Enable ACPI access (and setup like award)
- pci_write_config8(dev, 0x81, 0x84);
-
- outw(0xffff, 0x400);
- outw(0xffff, 0x420);
- outw(0xffff, 0x428);
- outl(0xffffffff, 0x430);
-
- outw(0x0, 0x424);
- outw(0x0, 0x42a);
- outw(0x1, 0x42c);
- outl(0x0, 0x434);
- outl(0x01, 0x438);
- outb(0x0, 0x442);
- outl(0xffff7fff, 0x448);
- outw(0x001, 0x404);
-}
-
-static void vt8235_init(struct device *dev)
-{
- unsigned char enables;
-
- printk(BIOS_DEBUG, "vt8235 init\n");
-
- // enable the internal I/O decode
- enables = pci_read_config8(dev, 0x6C);
- enables |= 0x80;
- pci_write_config8(dev, 0x6C, enables);
-
- // Map 4MB of FLASH into the address space
- pci_write_config8(dev, 0x41, 0x7f);
-
- // Set bit 6 of 0x40, because Award does it (IO recovery time)
- // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
- // interrupts can be properly marked as level triggered.
- enables = pci_read_config8(dev, 0x40);
- enables |= 0x45;
- pci_write_config8(dev, 0x40, enables);
-
- // Set 0x42 to 0xf0 to match Award bios
- enables = pci_read_config8(dev, 0x42);
- enables |= 0xf0;
- pci_write_config8(dev, 0x42, enables);
-
- /* Set 0x58 to 0x03 to match Award */
- pci_write_config8(dev, 0x58, 0x03);
-
- /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
- enables = pci_read_config8(dev, 0x4f);
- enables |= 0x08;
- pci_write_config8(dev, 0x4f, enables);
-
- // Set bit 3 of 0x4a, to match award (dummy pci request)
- enables = pci_read_config8(dev, 0x4a);
- enables |= 0x08;
- pci_write_config8(dev, 0x4a, enables);
-
- // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
- enables = pci_read_config8(dev, 0x4f);
- enables |= 0x08;
- pci_write_config8(dev, 0x4f, enables);
-
- // Set 0x58 to 0x03 to match Award
- pci_write_config8(dev, 0x58, 0x03);
-
-
- /* enable serial irq */
- pci_write_config8(dev, 0x52, 0x9);
-
- /* dma */
- pci_write_config8(dev, 0x53, 0x00);
-
- // Power management setup
- setup_pm(dev);
-
- /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
- pci_write_config8(dev, 0x40, 0x54);
-
- // Start the rtc
- rtc_init(0);
-}
-
-/* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
- device has a resource to set - so set a dummy one */
-static void vt8235_read_resources(device_t dev)
-{
- struct resource *res;
-
- pci_dev_read_resources(dev);
-
- res = new_resource(dev, 1);
- res->base = 0x0UL;
- res->size = 0x1000UL;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-
- res = new_resource(dev, 3); /* IOAPIC */
- res->base = IO_APIC_ADDR;
- res->size = 0x00001000;
- res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void vt8235_set_resources(device_t dev)
-{
- //struct resource *resource;
- //resource = find_resource(dev,1);
- //resource->flags |= IORESOURCE_STORED;
- pci_dev_set_resources(dev);
-}
-
-static void southbridge_init(struct device *dev)
-{
- vt8235_init(dev);
- pci_routing_fixup(dev);
-}
-
-static struct device_operations vt8235_lpc_ops = {
- .read_resources = vt8235_read_resources,
- .set_resources = vt8235_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = southbridge_init,
- .scan_bus = scan_static_bus,
-};
-
-static const struct pci_driver lpc_driver __pci_driver = {
- .ops = &vt8235_lpc_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8235,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-/*
- * Enable the ethernet device and turn off stepping (because it is integrated
- * inside the southbridge)
- */
-static void nic_init(struct device *dev)
-{
- uint8_t byte;
-
- printk(BIOS_DEBUG, "Configuring VIA Rhine LAN\n");
-
- /* We don't need stepping - though the device supports it */
- byte = pci_read_config8(dev, PCI_COMMAND);
- byte &= ~PCI_COMMAND_WAIT;
- pci_write_config8(dev, PCI_COMMAND, byte);
-}
-
-static struct device_operations nic_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = nic_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &nic_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8233_7,
-};
+++ /dev/null
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-
-/* really nothing to do here, both usb 1.1 & 2.0 are normal PCI devices and so get resources allocated
- properly. They are part of the southbridge and are enabled in the chip enable function for the southbridge */
-
-static void usb_init(struct device *dev)
-{
- printk(BIOS_DEBUG, "Configuring VIA USB 1.1\n");
-
- /* pci_write_config8(dev, 0x04, 0x07); */
-
- /*
- * To disable; though do we need to do this?
- pci_write_config8(dev1, 0x3c, 0x00);
- pci_write_config8(dev1, 0x04, 0x00);
-
- Also, on the root dev, for enable:
- regval = pci_read_config8(dev0, 0x50);
- regval &= ~(0x36);
- pci_write_config8(dev0, 0x50, regval);
-
- (regval |= 0x36; for disable)
- */
-}
-
-static struct device_operations usb_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &usb_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_82C586_2,
-};
-
##
driver-y += vt8237r.c
-driver-y += vt8237_ctrl.c
-driver-y += vt8237r_ide.c
-driver-y += vt8237r_lpc.c
-driver-y += vt8237r_sata.c
-driver-y += vt8237r_usb.c
-driver-$(CONFIG_PIRQ_ROUTE) += vt8237r_pirq.c
-ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += vt8237_fadt.c
+driver-y += ctrl.c
+driver-y += ide.c
+driver-y += lpc.c
+driver-y += sata.c
+driver-y += usb.c
+driver-$(CONFIG_PIRQ_ROUTE) += pirq.c
+ramstage-$(CONFIG_GENERATE_ACPI_TABLES) += fadt.c
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "vt8237r.h"
+
+/* We support here K8M890/K8T890 and VT8237/S/A PCI1/Vlink */
+
+static void vt8237_cfg(struct device *dev)
+{
+ u8 regm, regm3;
+ device_t devfun3;
+
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
+ if (!devfun3)
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
+ if (!devfun3)
+ devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
+ if (!devfun3)
+ die("Unknown NB");
+
+ /* CPU to PCI Flow Control 1 & 2, just fill in recommended. */
+ pci_write_config8(dev, 0x70, 0xc2);
+ pci_write_config8(dev, 0x71, 0xc8);
+
+ /* PCI Control */
+ pci_write_config8(dev, 0x72, 0xee);
+ pci_write_config8(dev, 0x73, 0x01);
+ pci_write_config8(dev, 0x74, 0x3c);
+ pci_write_config8(dev, 0x75, 0x0f);
+ pci_write_config8(dev, 0x76, 0x50);
+ pci_write_config8(dev, 0x77, 0x48);
+ pci_write_config8(dev, 0x78, 0x01);
+ /* APIC on HT */
+ /* Maybe Enable LDT APIC Mode bit3 set to 1 */
+ pci_write_config8(dev, 0x7c, 0x77);
+
+ /* WARNING: Need to copy some registers from NB (D0F3) to SB (D11F7). */
+
+ regm = pci_read_config8(devfun3, 0x88); /* Shadow mem CTRL */
+ pci_write_config8(dev, 0x57, regm);
+
+ regm = pci_read_config8(devfun3, 0x80); /* Shadow page C */
+ pci_write_config8(dev, 0x61, regm);
+
+ regm = pci_read_config8(devfun3, 0x81); /* Shadow page D */
+ pci_write_config8(dev, 0x62, regm);
+
+ /* Shadow page F + memhole copy */
+ regm = pci_read_config8(devfun3, 0x83);
+ pci_write_config8(dev, 0x63, regm);
+
+ // FIXME is this really supposed to be regm3?
+ regm3 = pci_read_config8(devfun3, 0x82);/* Shadow page E */
+ pci_write_config8(dev, 0x64, regm);
+
+ regm = pci_read_config8(devfun3, 0x86); /* SMM and APIC decoding */
+ pci_write_config8(dev, 0xe6, regm);
+}
+
+/**
+ * Example of setup: Setup the V-Link for VT8237R, 8X mode.
+ *
+ * For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
+ *
+ * REG DEF AW VIA-8X VIA-4X
+ * -----------------------------
+ * NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
+ * NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
+ * NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
+ * NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
+ * SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
+ * SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
+ * SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
+ * SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
+ * V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
+ * V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
+ */
+
+/* we setup 533MB/s mode full duplex */
+
+static void vt8237s_vlink_init(struct device *dev)
+{
+ u8 reg;
+ device_t devfun7;
+
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
+ if (!devfun7)
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
+ if (!devfun7)
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
+ /* No pairing NB was found. */
+ if (!devfun7)
+ return;
+
+ /*
+ * This init code is valid only for the VT8237S! For different
+ * sounthbridges (e.g. VT8237A, VT8237S, VT8237R (without plus R)
+ * and VT8251) a different init code is required.
+ */
+
+ /* disable auto disconnect */
+ reg = pci_read_config8(devfun7, 0x42);
+ reg &= ~0x4;
+ pci_write_config8(devfun7, 0x42, reg);
+
+ /* NB part setup */
+ pci_write_config8(devfun7, 0xb5, 0x66);
+ pci_write_config8(devfun7, 0xb6, 0x66);
+ pci_write_config8(devfun7, 0xb7, 0x64);
+
+ reg = pci_read_config8(devfun7, 0xb4);
+ reg |= 0x1;
+ reg &= ~0x10;
+ pci_write_config8(devfun7, 0xb4, reg);
+
+ pci_write_config8(devfun7, 0xb0, 0x6);
+ pci_write_config8(devfun7, 0xb1, 0x1);
+
+ /* SB part setup */
+ pci_write_config8(dev, 0xb7, 0x60);
+ pci_write_config8(dev, 0xb9, 0x88);
+ pci_write_config8(dev, 0xba, 0x88);
+ pci_write_config8(dev, 0xbb, 0x89);
+
+ reg = pci_read_config8(dev, 0xbd);
+ reg |= 0x3;
+ reg &= ~0x4;
+ pci_write_config8(dev, 0xbd, reg);
+
+ reg = pci_read_config8(dev, 0xbc);
+ reg &= ~0x7;
+ pci_write_config8(dev, 0xbc, reg);
+
+ /* Program V-link 8X 8bit full duplex, parity enabled. */
+ pci_write_config8(dev, 0x48, 0x23 | 0x80);
+
+ /* enable auto disconnect, for STPGNT and HALT */
+ reg = pci_read_config8(devfun7, 0x42);
+ reg |= 0x7;
+ pci_write_config8(devfun7, 0x42, reg);
+
+}
+
+static void vt8237a_vlink_init(struct device *dev)
+{
+ u8 reg;
+ device_t devfun7;
+
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
+ if (!devfun7)
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
+ if (!devfun7)
+ devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
+ /* No pairing NB was found. */
+ if (!devfun7)
+ return;
+
+ /*
+ * This init code is valid only for the VT8237A! For different
+ * sounthbridges (e.g. VT8237S, VT8237R and VT8251) a different
+ * init code is required.
+ *
+ * FIXME: This is based on vt8237r_vlink_init() in
+ * k8t890/k8t890_ctrl.c and modified to fit what the AMI
+ * BIOS on my M2V wrote to these registers (by looking
+ * at lspci -nxxx output).
+ * Works for me.
+ */
+
+ /* disable auto disconnect */
+ reg = pci_read_config8(devfun7, 0x42);
+ reg &= ~0x4;
+ pci_write_config8(devfun7, 0x42, reg);
+
+ /* NB part setup */
+ pci_write_config8(devfun7, 0xb5, 0x88);
+ pci_write_config8(devfun7, 0xb6, 0x88);
+ pci_write_config8(devfun7, 0xb7, 0x61);
+
+ reg = pci_read_config8(devfun7, 0xb4);
+ reg |= 0x11;
+ pci_write_config8(devfun7, 0xb4, reg);
+
+ pci_write_config8(devfun7, 0xb0, 0x6);
+ pci_write_config8(devfun7, 0xb1, 0x1);
+
+ /* SB part setup */
+ pci_write_config8(dev, 0xb7, 0x50);
+ pci_write_config8(dev, 0xb9, 0x88);
+ pci_write_config8(dev, 0xba, 0x8a);
+ pci_write_config8(dev, 0xbb, 0x88);
+
+ reg = pci_read_config8(dev, 0xbd);
+ reg |= 0x3;
+ reg &= ~0x4;
+ pci_write_config8(dev, 0xbd, reg);
+
+ reg = pci_read_config8(dev, 0xbc);
+ reg &= ~0x7;
+ pci_write_config8(dev, 0xbc, reg);
+
+ pci_write_config8(dev, 0x48, 0x23);
+
+ /* enable auto disconnect, for STPGNT and HALT */
+ reg = pci_read_config8(devfun7, 0x42);
+ reg |= 0x7;
+ pci_write_config8(devfun7, 0x42, reg);
+}
+
+static void ctrl_enable(struct device *dev)
+{
+ /* Enable the 0:13 and 0:13.1. */
+ /* FIXME */
+ pci_write_config8(dev, 0x4f, 0x43);
+}
+
+static void ctrl_init(struct device *dev)
+{
+ /*
+ * TODO: Fix some ordering issue for V-link set Rx77[6] and
+ * PCI1_Rx4F[0] should to 1.
+ * FIXME DO you need?
+ */
+
+ /*
+ * VT8237R specific configuration. Other SB are done in their own
+ * directories. TODO: Add A version.
+ */
+ device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
+ if (devsb) {
+ vt8237s_vlink_init(dev);
+ }
+
+ devsb = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237A_LPC, 0);
+ if (devsb) {
+ vt8237a_vlink_init(dev);
+ }
+
+ /* Configure PCI1 and copy mirror registers from D0F3. */
+ vt8237_cfg(dev);
+ dump_south(dev);
+}
+
+static const struct device_operations ctrl_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ctrl_init,
+ .enable = ctrl_enable,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_t __pci_driver = {
+ .ops = &ctrl_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237_VLINK,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/pci_ids.h>
+#include <spd.h>
+#include <stdlib.h>
+#include "vt8237r.h"
+
+/**
+ * Print an error, should it occur. If no error, just exit.
+ *
+ * @param host_status The data returned on the host status register after
+ * a transaction is processed.
+ * @param loops The number of times a transaction was attempted.
+ */
+static void smbus_print_error(u8 host_status, int loops)
+{
+ /* Check if there actually was an error. */
+ if ((host_status == 0x00 || host_status == 0x40 ||
+ host_status == 0x42) && (loops < SMBUS_TIMEOUT))
+ return;
+
+ if (loops >= SMBUS_TIMEOUT)
+ print_err("SMBus timeout\n");
+ if (host_status & (1 << 4))
+ print_err("Interrupt/SMI# was Failed Bus Transaction\n");
+ if (host_status & (1 << 3))
+ print_err("Bus error\n");
+ if (host_status & (1 << 2))
+ print_err("Device error\n");
+ if (host_status & (1 << 1))
+ print_debug("Interrupt/SMI# completed successfully\n");
+ if (host_status & (1 << 0))
+ print_err("Host busy\n");
+}
+
+/**
+ * Wait for the SMBus to become ready to process the next transaction.
+ */
+static void smbus_wait_until_ready(void)
+{
+ int loops;
+
+ PRINT_DEBUG("Waiting until SMBus ready\n");
+
+ /* Loop up to SMBUS_TIMEOUT times, waiting for bit 0 of the
+ * SMBus Host Status register to go to 0, indicating the operation
+ * was completed successfully. I don't remember why I did it this way,
+ * but I think it was because ROMCC was running low on registers */
+ loops = 0;
+ while ((inb(SMBHSTSTAT) & 1) == 1 && loops < SMBUS_TIMEOUT)
+ ++loops;
+
+ smbus_print_error(inb(SMBHSTSTAT), loops);
+}
+
+/**
+ * Reset and take ownership of the SMBus.
+ */
+static void smbus_reset(void)
+{
+ outb(HOST_RESET, SMBHSTSTAT);
+
+ /* Datasheet says we have to read it to take ownership of SMBus. */
+ inb(SMBHSTSTAT);
+
+ PRINT_DEBUG("After reset status: ");
+ PRINT_DEBUG_HEX16(inb(SMBHSTSTAT));
+ PRINT_DEBUG("\n");
+}
+
+/**
+ * Read a byte from the SMBus.
+ *
+ * @param dimm The address location of the DIMM on the SMBus.
+ * @param offset The offset the data is located at.
+ */
+u8 smbus_read_byte(u8 dimm, u8 offset)
+{
+ u8 val;
+
+ PRINT_DEBUG("DIMM ");
+ PRINT_DEBUG_HEX16(dimm);
+ PRINT_DEBUG(" OFFSET ");
+ PRINT_DEBUG_HEX16(offset);
+ PRINT_DEBUG("\n");
+
+ smbus_reset();
+
+ /* Clear host data port. */
+ outb(0x00, SMBHSTDAT0);
+ SMBUS_DELAY();
+ smbus_wait_until_ready();
+
+ /* Actual addr to reg format. */
+ dimm = (dimm << 1);
+ dimm |= 1;
+ outb(dimm, SMBXMITADD);
+ outb(offset, SMBHSTCMD);
+
+ /* Start transaction, byte data read. */
+ outb(0x48, SMBHSTCTL);
+ SMBUS_DELAY();
+ smbus_wait_until_ready();
+
+ val = inb(SMBHSTDAT0);
+ PRINT_DEBUG("Read: ");
+ PRINT_DEBUG_HEX16(val);
+ PRINT_DEBUG("\n");
+
+ /* Probably don't have to do this, but it can't hurt. */
+ smbus_reset();
+
+ return val;
+}
+
+#define PSONREADY_TIMEOUT 0x7fffffff
+
+static device_t get_vt8237_lpc(void)
+{
+ device_t dev;
+
+ /* Power management controller */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237R_LPC), 0);
+ if (dev != PCI_DEV_INVALID)
+ return dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC), 0);
+ if (dev != PCI_DEV_INVALID)
+ return dev;
+
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237A_LPC), 0);
+ return dev;
+}
+
+/**
+ * Enable the SMBus on VT8237R-based systems.
+ */
+void enable_smbus(void)
+{
+ device_t dev;
+ int loops;
+
+ /* Power management controller */
+ dev = get_vt8237_lpc();
+ if (dev == PCI_DEV_INVALID)
+ die("Power management controller not found\n");
+
+ /* Make sure the RTC power well is up before touching smbus. */
+ loops = 0;
+ while (!(pci_read_config8(dev, VT8237R_PSON) & (1<<6))
+ && loops < PSONREADY_TIMEOUT)
+ ++loops;
+
+ /*
+ * 7 = SMBus Clock from RTC 32.768KHz
+ * 5 = Internal PLL reset from susp
+ */
+ pci_write_config8(dev, VT8237R_POWER_WELL, 0xa0);
+
+ /* Enable SMBus. */
+ pci_write_config16(dev, VT8237R_SMBUS_IO_BASE_REG,
+ VT8237R_SMBUS_IO_BASE | 0x1);
+
+ /* SMBus Host Configuration, enable. */
+ pci_write_config8(dev, VT8237R_SMBUS_HOST_CONF, 0x01);
+
+ /* Make it work for I/O. */
+ pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+
+ smbus_reset();
+
+ /* Reset the internal pointer. */
+ inb(SMBHSTCTL);
+}
+
+/**
+ * A fixup for some systems that need time for the SMBus to "warm up". This is
+ * needed on some VT823x based systems, where the SMBus spurts out bad data for
+ * a short time after power on. This has been seen on the VIA Epia series and
+ * Jetway J7F2-series. It reads the ID byte from SMBus, looking for
+ * known-good data from a slot/address. Exits on either good data or a timeout.
+ *
+ * TODO: This should probably go into some global file, but one would need to
+ * be created just for it. If some other chip needs/wants it, we can
+ * worry about it then.
+ *
+ * @param ctrl The memory controller and SMBus addresses.
+ */
+void smbus_fixup(const struct mem_controller *ctrl)
+{
+ int i, ram_slots, current_slot = 0;
+ u8 result = 0;
+
+ ram_slots = ARRAY_SIZE(ctrl->channel0);
+ if (!ram_slots) {
+ print_err("smbus_fixup() thinks there are no RAM slots!\n");
+ return;
+ }
+
+ PRINT_DEBUG("Waiting for SMBus to warm up");
+
+ /*
+ * Bad SPD data should be either 0 or 0xff, but YMMV. So we look for
+ * the ID bytes of SDRAM, DDR, DDR2, and DDR3 (and anything in between).
+ * VT8237R has only been seen on DDR and DDR2 based systems, so far.
+ */
+ for (i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) ||
+ (result > SPD_MEMORY_TYPE_SDRAM_DDR3))); i++) {
+
+ if (current_slot > ram_slots)
+ current_slot = 0;
+
+ result = smbus_read_byte(ctrl->channel0[current_slot],
+ SPD_MEMORY_TYPE);
+ current_slot++;
+ PRINT_DEBUG(".");
+ }
+
+ if (i >= SMBUS_TIMEOUT)
+ print_err("SMBus timed out while warming up\n");
+ else
+ PRINT_DEBUG("Done\n");
+}
+
+/* FIXME: Better separate the NB and SB, will be done once it works. */
+
+void vt8237_sb_enable_fid_vid(void)
+{
+ device_t dev, devctl;
+ u16 devid;
+
+ /* Power management controller */
+ dev = get_vt8237_lpc();
+ if (dev == PCI_DEV_INVALID)
+ return;
+
+ devid = pci_read_config16(dev, PCI_DEVICE_ID);
+
+ /* generic setup */
+
+ /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
+ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
+
+ /* Enable ACPI accessm RTC signal gated with PSON. */
+ pci_write_config8(dev, 0x81, 0x84);
+
+ /* chipset-specific parts */
+
+ /* VLINK: FIXME: can we drop the devid check and just look for the VLINK device? */
+ if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC ||
+ devid == PCI_DEVICE_ID_VIA_VT8237A_LPC) {
+ devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
+
+ if (devctl != PCI_DEV_INVALID) {
+ /* So the chip knows we are on AMD. */
+ pci_write_config8(devctl, 0x7c, 0x7f);
+ }
+ }
+
+ if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) {
+ /*
+ * Allow SLP# signal to assert LDTSTOP_L.
+ * Will work for C3 and for FID/VID change.
+ */
+
+ outb(0xff, VT8237R_ACPI_IO_BASE + 0x50);
+
+ /* Reduce further the STPCLK/LDTSTP signal to 5us. */
+ pci_write_config8(dev, 0xec, 0x4);
+
+ return;
+ }
+
+ /* VT8237R and VT8237A */
+
+ /*
+ * Allow SLP# signal to assert LDTSTOP_L.
+ * Will work for C3 and for FID/VID change.
+ */
+ outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
+}
+
+void enable_rom_decode(void)
+{
+ device_t dev;
+
+ /* Power management controller */
+ dev = get_vt8237_lpc();
+ if (dev == PCI_DEV_INVALID)
+ return;
+
+ /* ROM decode last 1MB FFC00000 - FFFFFFFF. */
+ pci_write_config8(dev, 0x41, 0x7f);
+}
+
+#if CONFIG_HAVE_ACPI_RESUME == 1
+static int acpi_is_wakeup_early(void) {
+ device_t dev;
+ u16 tmp;
+
+ print_debug("IN TEST WAKEUP\n");
+
+ /* Power management controller */
+ dev = get_vt8237_lpc();
+ if (dev == PCI_DEV_INVALID)
+ die("Power management controller not found\n");
+
+ /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
+ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
+
+ /* Enable ACPI accessm RTC signal gated with PSON. */
+ pci_write_config8(dev, 0x81, 0x84);
+
+ tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
+
+ print_debug_hex8(tmp);
+ return ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
+}
+#endif
+
+#if defined(__GNUC__)
+void vt8237_early_spi_init(void)
+{
+ device_t dev;
+ volatile u16 *spireg;
+ u32 tmp;
+
+ /* Bus Control and Power Management */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC), 0);
+
+ if (dev == PCI_DEV_INVALID)
+ die("SB not found\n");
+
+ /* Put SPI base 20 d0 fe. */
+ tmp = pci_read_config32(dev, 0xbc);
+ pci_write_config32(dev, 0xbc,
+ (VT8237S_SPI_MEM_BASE >> 8) | (tmp & 0xFF000000));
+
+ /* Set SPI clock to 33MHz. */
+ spireg = (u16 *) (VT8237S_SPI_MEM_BASE + 0x6c);
+ (*spireg) &= 0xff00;
+}
+#endif
+
+/* This #if is special. ROMCC chokes on the (rom == NULL) comparison.
+ * Since the whole function is only called for one target and that target
+ * is compiled with GCC, hide the function from ROMCC and be happy.
+ */
+#if defined(__GNUC__)
+/*
+ * Offset 0x58:
+ * 31:20 reserved
+ * 19:16 4 bit position in shadow EEPROM
+ * 15:0 data to write
+ *
+ * Offset 0x5c:
+ * 31:28 reserved
+ * 27 ERDBG - enable read from 0x5c
+ * 26 reserved
+ * 25 SEELD
+ * 24 SEEPR - write 1 when done updating, wait until SEELD is
+ * set to 1, sticky
+ * cleared by reset, if it is 1 writing is disabled
+ * 19:16 4 bit position in shadow EEPROM
+ * 15:0 data from shadow EEPROM
+ *
+ * After PCIRESET SEELD and SEEPR must be 1 and 1.
+ */
+
+/* 1 = needs PCI reset, 0 don't reset, network initialized. */
+
+/* FIXME: Maybe close the debug register after use? */
+
+#define LAN_TIMEOUT 0x7FFFFFFF
+
+int vt8237_early_network_init(struct vt8237_network_rom *rom)
+{
+ struct vt8237_network_rom n;
+ int i, loops;
+ device_t dev;
+ u32 tmp;
+ u8 status;
+ u16 *rom_write;
+ unsigned int checksum;
+
+ /* Network adapter */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_8233_7), 0);
+ if (dev == PCI_DEV_INVALID) {
+ print_err("Network is disabled, please enable\n");
+ return 0;
+ }
+
+ tmp = pci_read_config32(dev, 0x5c);
+ tmp |= 0x08000000; /* Enable ERDBG. */
+ pci_write_config32(dev, 0x5c, tmp);
+
+ status = ((pci_read_config32(dev, 0x5c) >> 24) & 0x3);
+
+ /* Network controller OK, EEPROM loaded. */
+ if (status == 3)
+ return 0;
+
+ if (rom == NULL) {
+ print_err("No config data specified, using default MAC!\n");
+ n.mac_address[0] = 0x0;
+ n.mac_address[1] = 0x0;
+ n.mac_address[2] = 0xde;
+ n.mac_address[3] = 0xad;
+ n.mac_address[4] = 0xbe;
+ n.mac_address[5] = 0xef;
+ n.phy_addr = 0x1;
+ n.res1 = 0x0;
+ n.sub_sid = 0x102;
+ n.sub_vid = 0x1106;
+ n.pid = 0x3065;
+ n.vid = 0x1106;
+ n.pmcc = 0x1f;
+ n.data_sel = 0x10;
+ n.pmu_data_reg = 0x0;
+ n.aux_curr = 0x0;
+ n.reserved = 0x0;
+ n.min_gnt = 0x3;
+ n.max_lat = 0x8;
+ n.bcr0 = 0x9;
+ n.bcr1 = 0xe;
+ n.cfg_a = 0x3;
+ n.cfg_b = 0x0;
+ n.cfg_c = 0x40;
+ n.cfg_d = 0x82;
+ n.checksum = 0x0;
+ rom = &n;
+ }
+
+ rom_write = (u16 *) rom;
+ checksum = 0;
+ /* Write all data except checksum and second to last byte. */
+ tmp &= 0xff000000; /* Leave reserved bits in. */
+ for (i = 0; i < 15; i++) {
+ pci_write_config32(dev, 0x58, tmp | (i << 16) | rom_write[i]);
+ /* Lame code FIXME */
+ checksum += rom_write[i] & 0xff;
+ /* checksum %= 256; */
+ checksum += (rom_write[i] >> 8) & 0xff;
+ /* checksum %= 256; */
+ }
+
+ checksum += (rom_write[15] & 0xff);
+ checksum = ~(checksum & 0xff);
+ tmp |= (((checksum & 0xff) << 8) | rom_write[15]);
+
+ /* Write last byte and checksum. */
+ pci_write_config32(dev, 0x58, (15 << 16) | tmp);
+
+ tmp = pci_read_config32(dev, 0x5c);
+ pci_write_config32(dev, 0x5c, tmp | 0x01000000); /* Toggle SEEPR. */
+
+ /* Yes, this is a mess, but it's the easiest way to do it. */
+ /* XXX not so messy, but an explanation of the hack would have been better */
+ loops = 0;
+ while ((((pci_read_config32(dev, 0x5c) >> 25) & 1) == 0)
+ && (loops < LAN_TIMEOUT)) {
+ ++loops;
+ }
+
+ if (loops >= LAN_TIMEOUT) {
+ print_err("Timeout - LAN controller didn't accept config\n");
+ return 0;
+ }
+
+ /* We are done, config will be used after PCIRST#. */
+ return 1;
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
+ * Copyright (C) 2007, 2009 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+#include <arch/acpi.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237r.h"
+
+/**
+ * Create the Fixed ACPI Description Tables (FADT) for any board with this SB.
+ */
+void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
+{
+ acpi_header_t *header = &(fadt->header);
+ device_t dev;
+ int is_vt8237s = 0;
+
+ /* Power management controller */
+ dev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
+
+ if (dev)
+ is_vt8237s = 1;
+
+ memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+ memcpy(header->signature, "FACP", 4);
+ header->length = 244;
+ header->revision = 4;
+ memcpy(header->oem_id, "COREBO", 6);
+ memcpy(header->oem_table_id, "COREBOOT", 8);
+ memcpy(header->asl_compiler_id, "CORE", 4);
+ header->asl_compiler_revision = 42;
+
+ fadt->firmware_ctrl = (u32)facs;
+ fadt->dsdt = (u32)dsdt;
+ fadt->preferred_pm_profile = 0;
+ fadt->sci_int = 9;
+ fadt->smi_cmd = 0;
+ fadt->acpi_enable = 0;
+ fadt->acpi_disable = 0;
+ fadt->s4bios_req = 0x0;
+ fadt->pstate_cnt = 0x0;
+
+ fadt->pm1a_evt_blk = VT8237R_ACPI_IO_BASE;
+ fadt->pm1b_evt_blk = 0x0;
+ fadt->pm1a_cnt_blk = VT8237R_ACPI_IO_BASE + 0x4;
+ fadt->pm1b_cnt_blk = 0x0;
+ /* once we support C2/C3 this could be set to 0x22 and chipset needs to be adjusted too */
+ fadt->pm2_cnt_blk = 0x0;
+ fadt->pm_tmr_blk = VT8237R_ACPI_IO_BASE + 0x8;
+ fadt->gpe0_blk = VT8237R_ACPI_IO_BASE + 0x20;
+ if (is_vt8237s) {
+ fadt->gpe1_blk = VT8237R_ACPI_IO_BASE + 0x60;
+ fadt->gpe1_base = 0x10;
+ fadt->gpe1_blk_len = 4;
+ } else {
+ fadt->gpe1_blk = 0x0;
+ fadt->gpe1_base = 0;
+ fadt->gpe1_blk_len = 0;
+ }
+
+ fadt->pm1_evt_len = 4;
+ fadt->pm1_cnt_len = 2;
+ fadt->pm2_cnt_len = 0;
+ fadt->pm_tmr_len = 4;
+ fadt->gpe0_blk_len = 4;
+
+ fadt->cst_cnt = 0;
+ fadt->p_lvl2_lat = 90;
+ fadt->p_lvl3_lat = 900;
+ fadt->flush_size = 0;
+ fadt->flush_stride = 0;
+ fadt->duty_offset = 0;
+ fadt->duty_width = 1; //??
+ fadt->day_alrm = 0x7d;
+ fadt->mon_alrm = 0x7e;
+ fadt->century = 0x32;
+ /* We have legacy devices, 8042, VGA is ok to probe, MSI are not supported */
+ fadt->iapc_boot_arch = 0xb;
+ /* check me */
+ fadt->flags = 0xa5;
+
+ fadt->reset_reg.space_id = 0;
+ fadt->reset_reg.bit_width = 0;
+ fadt->reset_reg.bit_offset = 0;
+ fadt->reset_reg.resv = 0;
+ fadt->reset_reg.addrl = 0x0;
+ fadt->reset_reg.addrh = 0x0;
+
+ fadt->reset_value = 0;
+ fadt->x_firmware_ctl_l = (u32)facs;
+ fadt->x_firmware_ctl_h = 0;
+ fadt->x_dsdt_l = (u32)dsdt;
+ fadt->x_dsdt_h = 0;
+
+ fadt->x_pm1a_evt_blk.space_id = 1;
+ fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1a_evt_blk.bit_offset = 0;
+ fadt->x_pm1a_evt_blk.resv = 0;
+ fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
+ fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_evt_blk.space_id = 1;
+ fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
+ fadt->x_pm1b_evt_blk.bit_offset = 0;
+ fadt->x_pm1b_evt_blk.resv = 0;
+ fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
+ fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+ fadt->x_pm1a_cnt_blk.space_id = 1;
+ fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1a_cnt_blk.bit_offset = 0;
+ fadt->x_pm1a_cnt_blk.resv = 0;
+ fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
+ fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm1b_cnt_blk.space_id = 1;
+ fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
+ fadt->x_pm1b_cnt_blk.bit_offset = 0;
+ fadt->x_pm1b_cnt_blk.resv = 0;
+ fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
+ fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm2_cnt_blk.space_id = 1;
+ fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
+ fadt->x_pm2_cnt_blk.bit_offset = 0;
+ fadt->x_pm2_cnt_blk.resv = 0;
+ fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
+ fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+ fadt->x_pm_tmr_blk.space_id = 1;
+ fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
+ fadt->x_pm_tmr_blk.bit_offset = 0;
+ fadt->x_pm_tmr_blk.resv = 0;
+ fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
+ fadt->x_pm_tmr_blk.addrh = 0x0;
+
+ fadt->x_gpe0_blk.space_id = 1;
+ fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
+ fadt->x_gpe0_blk.bit_offset = 0;
+ fadt->x_gpe0_blk.resv = 0;
+ fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
+ fadt->x_gpe0_blk.addrh = 0x0;
+
+ fadt->x_gpe1_blk.space_id = 1;
+ fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
+ fadt->x_gpe1_blk.bit_offset = 0;
+ fadt->x_gpe1_blk.resv = 0;
+ fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
+ fadt->x_gpe1_blk.addrh = 0x0;
+
+ header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
+}
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Based on other VIA SB code. */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <console/console.h>
+#include "vt8237r.h"
+#include "chip.h"
+
+/**
+ * Cable type detect function, weak so it can be overloaded in mainboard.c
+ */
+u32 __attribute__((weak)) vt8237_ide_80pin_detect(struct device *dev)
+{
+ struct southbridge_via_vt8237r_config *sb =
+ (struct southbridge_via_vt8237r_config *)dev->chip_info;
+ u32 res;
+ res = sb->ide0_80pin_cable ? VT8237R_IDE0_80PIN_CABLE : 0;
+ res |= sb->ide1_80pin_cable ? VT8237R_IDE1_80PIN_CABLE : 0;
+ return res;
+}
+
+/**
+ * No native mode. Interrupts from unconnected HDDs might occur if
+ * IRQ14/15 is used for PCI. Therefore no native mode support.
+ */
+static void ide_init(struct device *dev)
+{
+ struct southbridge_via_vt8237r_config *sb =
+ (struct southbridge_via_vt8237r_config *)dev->chip_info;
+
+ u8 enables;
+ u32 cablesel;
+
+ printk(BIOS_INFO, "%s IDE interface %s\n", "Primary",
+ sb->ide0_enable ? "enabled" : "disabled");
+ printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary",
+ sb->ide1_enable ? "enabled" : "disabled");
+ enables = pci_read_config8(dev, IDE_CS) & ~0x3;
+ enables |= (sb->ide0_enable << 1) | sb->ide1_enable;
+ pci_write_config8(dev, IDE_CS, enables);
+ enables = pci_read_config8(dev, IDE_CS);
+ printk(BIOS_DEBUG, "Enables in reg 0x40 read back as 0x%x\n", enables);
+
+ /* Enable only compatibility mode. */
+ enables = pci_read_config8(dev, 0x09);
+ enables &= 0xFA;
+ pci_write_config8(dev, 0x09, enables);
+
+ enables = pci_read_config8(dev, IDE_CONF_II);
+ enables &= ~0xc0;
+ pci_write_config8(dev, IDE_CONF_II, enables);
+ enables = pci_read_config8(dev, IDE_CONF_II);
+ printk(BIOS_DEBUG, "Enables in reg 0x42 read back as 0x%x\n", enables);
+
+ /* Enable prefetch buffers. */
+ enables = pci_read_config8(dev, IDE_CONF_I);
+ enables |= 0xf0;
+ pci_write_config8(dev, IDE_CONF_I, enables);
+
+ /* Flush FIFOs at half. */
+ enables = pci_read_config8(dev, IDE_CONF_FIFO);
+ enables &= 0xf0;
+ enables |= (1 << 2) | (1 << 0);
+ pci_write_config8(dev, IDE_CONF_FIFO, enables);
+
+ /* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */
+ enables = pci_read_config8(dev, IDE_MISC_I);
+ enables &= 0xe2;
+ enables |= (1 << 4) | (1 << 3);
+ pci_write_config8(dev, IDE_MISC_I, enables);
+
+ /* Use memory read multiple, Memory-Write-and-Invalidate. */
+ enables = pci_read_config8(dev, IDE_MISC_II);
+ enables &= 0xEF;
+ enables |= (1 << 2) | (1 << 3);
+ pci_write_config8(dev, IDE_MISC_II, enables);
+
+ /* Force interrupts to use compat mode. */
+ pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
+ pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
+
+ /* Cable guy... */
+ cablesel = pci_read_config32(dev, IDE_UDMA);
+ cablesel &= ~VT8237R_IDE_CABLESEL_MASK;
+ cablesel |= vt8237_ide_80pin_detect(dev);
+ pci_write_config32(dev, IDE_UDMA, cablesel);
+
+#if CONFIG_EPIA_VT8237R_INIT
+ device_t lpc_dev;
+
+ /* Set PATA Output Drive Strength */
+ lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
+ if (lpc_dev)
+ pci_write_config8(lpc_dev, 0x7C, 0x20);
+#endif
+}
+
+static const struct device_operations ide_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ide_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver __pci_driver = {
+ .ops = &ide_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_82C586_1,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Inspiration from other VIA SB code. */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/mc146818rtc.h>
+#include <arch/ioapic.h>
+#include <cpu/x86/lapic.h>
+#include <pc80/keyboard.h>
+#include <pc80/i8259.h>
+#include <stdlib.h>
+#include "vt8237r.h"
+#include "chip.h"
+
+static void southbridge_init_common(struct device *dev);
+
+#if CONFIG_EPIA_VT8237R_INIT
+ /* Interrupts for INT# A B C D */
+static const unsigned char pciIrqs[4] = { 10, 11, 12, 0};
+
+ /* Interrupt Assignments for Pins 1 2 3 4 */
+static const unsigned char sataPins[4] = { 'A','B','C','D'};
+static const unsigned char vgaPins[4] = { 'A','B','C','D'};
+static const unsigned char usbPins[4] = { 'A','B','C','D'};
+static const unsigned char enetPins[4] = { 'A','B','C','D'};
+static const unsigned char vt8237Pins[4] = { 'A','B','C','D'};
+static const unsigned char slotPins[4] = { 'C','D','A','B'};
+static const unsigned char riserPins[4] = { 'D','C','B','A'};
+
+static unsigned char *pin_to_irq(const unsigned char *pin)
+{
+ static unsigned char Irqs[4];
+ int i;
+ for (i = 0 ; i < 4 ; i++)
+ Irqs[i] = pciIrqs[ pin[i] - 'A' ];
+
+ return Irqs;
+}
+#endif
+
+/** Set up PCI IRQ routing, route everything through APIC. */
+static void pci_routing_fixup(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ device_t pdev;
+#endif
+
+ /* PCI PNP Interrupt Routing INTE/F - disable */
+ pci_write_config8(dev, 0x44, 0x00);
+
+ /* PCI PNP Interrupt Routing INTG/H - disable */
+ pci_write_config8(dev, 0x45, 0x00);
+
+ /* Gate Interrupts until RAM Writes are flushed */
+ pci_write_config8(dev, 0x49, 0x20);
+
+#if CONFIG_EPIA_VT8237R_INIT
+
+ /* Share INTE-INTH with INTA-INTD as per stock BIOS. */
+ pci_write_config8(dev, 0x46, 0x00);
+
+ /* setup PCI IRQ routing (For PCI Slot)*/
+ pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
+ pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
+ pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
+
+ /* PCI Routing Fixup */
+
+ //Setup MiniPCI Slot
+ pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
+
+ // Via 2 slot riser card 2nd slot
+ pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
+
+ //Setup USB
+ pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
+
+ //Setup VT8237R Sound
+ pci_assign_irqs(0, 0x11, pin_to_irq(vt8237Pins));
+
+ //Setup Ethernet
+ pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
+
+ //Setup VGA
+ pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
+
+ /* APIC Routing Fixup */
+
+ // Setup SATA
+ pdev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT6420_SATA, 0);
+ pci_write_config8(pdev, PCI_INTERRUPT_PIN, 0x02);
+ pci_assign_irqs(0, 0x0f, pin_to_irq(sataPins));
+
+
+ // Setup PATA Override
+ pdev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C586_1, 0);
+ pci_write_config8(pdev, PCI_INTERRUPT_PIN, 0x01);
+ pci_write_config8(pdev, PCI_INTERRUPT_LINE, 0xFF);
+
+#else
+ /* Route INTE-INTH through registers above, no map to INTA-INTD. */
+ pci_write_config8(dev, 0x46, 0x10);
+
+ /* PCI Interrupt Polarity */
+ pci_write_config8(dev, 0x54, 0x00);
+
+ /* PCI INTA# Routing */
+ pci_write_config8(dev, 0x55, 0x00);
+
+ /* PCI INTB#/C# Routing */
+ pci_write_config8(dev, 0x56, 0x00);
+
+ /* PCI INTD# Routing */
+ pci_write_config8(dev, 0x57, 0x00);
+#endif
+}
+
+
+
+/**
+ * Set up the power management capabilities directly into ACPI mode.
+ * This avoids having to handle any System Management Interrupts (SMIs).
+ */
+
+extern u8 acpi_slp_type;
+
+
+static void setup_pm(device_t dev)
+{
+ u16 tmp;
+ /* Debounce LID and PWRBTN# Inputs for 16ms. */
+ pci_write_config8(dev, 0x80, 0x20);
+
+ /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
+ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
+
+ /* Set ACPI to 9, must set IRQ 9 override to level! Set PSON gating. */
+ pci_write_config8(dev, 0x82, 0x40 | VT8237R_ACPI_IRQ);
+
+#if CONFIG_EPIA_VT8237R_INIT
+ /* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
+ pci_write_config16(dev, 0x84, 0x3052);
+#else
+ /* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
+ pci_write_config16(dev, 0x84, 0x30b2);
+
+#endif
+ /* SMI output level to low, 7.5us throttle clock */
+ pci_write_config8(dev, 0x8d, 0x18);
+
+ /* GP Timer Control 1s */
+ pci_write_config8(dev, 0x93, 0x88);
+
+ /*
+ * 7 = SMBus clock from RTC 32.768KHz
+ * 5 = Internal PLL reset from susp disabled
+ * 2 = GPO2 is SUSA#
+ */
+ pci_write_config8(dev, 0x94, 0xa0);
+
+ /*
+ * 7 = stp to sust delay 1msec
+ * 6 = SUSST# Deasserted Before PWRGD for STD
+ * 5 = Keyboard/Mouse Swap
+ * 4 = PWRGOOD reset on VT8237A/S
+ * 3 = GPO26/GPO27 is GPO
+ * 2 = Disable Alert on Lan
+ * 1 = SUSCLK/GPO4
+ * 0 = USB Wakeup
+ */
+
+#if CONFIG_EPIA_VT8237R_INIT
+ pci_write_config8(dev, 0x95, 0xc2);
+#else
+ pci_write_config8(dev, 0x95, 0xcc);
+#endif
+
+ /* Disable GP3 timer. */
+ pci_write_config8(dev, 0x98, 0);
+
+ /* Enable ACPI accessm RTC signal gated with PSON. */
+ pci_write_config8(dev, 0x81, 0x84);
+
+ /* Clear status events. */
+ outw(0xffff, VT8237R_ACPI_IO_BASE + 0x00);
+ outw(0xffff, VT8237R_ACPI_IO_BASE + 0x20);
+ outw(0xffff, VT8237R_ACPI_IO_BASE + 0x28);
+ outl(0xffffffff, VT8237R_ACPI_IO_BASE + 0x30);
+
+ /* Disable SCI on GPIO. */
+ outw(0x0, VT8237R_ACPI_IO_BASE + 0x22);
+
+ /* Disable SMI on GPIO. */
+ outw(0x0, VT8237R_ACPI_IO_BASE + 0x24);
+
+ /* Disable all global enable SMIs. */
+ outw(0x0, VT8237R_ACPI_IO_BASE + 0x2a);
+
+ /* All SMI off, both IDE buses ON, PSON rising edge. */
+ outw(0x0, VT8237R_ACPI_IO_BASE + 0x2c);
+
+ /* Primary activity SMI disable. */
+ outl(0x0, VT8237R_ACPI_IO_BASE + 0x34);
+
+ /* GP timer reload on none. */
+ outl(0x0, VT8237R_ACPI_IO_BASE + 0x38);
+
+ /* Disable extended IO traps. */
+ outb(0x0, VT8237R_ACPI_IO_BASE + 0x42);
+
+ /* SCI is generated for RTC/pwrBtn/slpBtn. */
+ tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
+#if CONFIG_HAVE_ACPI_RESUME == 1
+ acpi_slp_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
+ printk(BIOS_DEBUG, "SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
+#endif
+ /* clear sleep */
+ tmp &= ~(7 << 10);
+ tmp |= 1;
+ outw(tmp, VT8237R_ACPI_IO_BASE + 0x04);
+}
+
+static void vt8237r_init(struct device *dev)
+{
+ u8 enables;
+
+#if CONFIG_EPIA_VT8237R_INIT
+ printk(BIOS_SPEW, "Entering vt8237r_init, for EPIA.\n");
+ /*
+ * TODO: Looks like stock BIOS can do this but causes a hang
+ * Enable SATA LED, disable special CPU Frequency Change -
+ * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
+ * Setup to match EPIA default
+ * PCS0# on Pin U1
+ */
+ enables = pci_read_config8(dev, 0xe5);
+ enables |= 0x23;
+ pci_write_config8(dev, 0xe5, enables);
+
+ /*
+ * Enable Flash Write Access.
+ * Note EPIA-N Does not use REQ5 or PCISTP#(Hang)
+ */
+ enables = pci_read_config8(dev, 0xe4);
+ enables |= 0x2B;
+ pci_write_config8(dev, 0xe4, enables);
+
+ /* Enables Extra RTC Ports */
+ enables = pci_read_config8(dev, 0x4E);
+ enables |= 0x80;
+ pci_write_config8(dev, 0x4E, enables);
+
+#else
+ printk(BIOS_SPEW, "Entering vt8237r_init.\n");
+ /*
+ * Enable SATA LED, disable special CPU Frequency Change -
+ * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
+ */
+ pci_write_config8(dev, 0xe5, 0x09);
+
+ /* REQ5 as PCI request input - should be together with INTE-INTH. */
+ pci_write_config8(dev, 0xe4, 0x4);
+#endif
+
+ /* Set bit 3 of 0x4f (use INIT# as CPU reset). */
+ enables = pci_read_config8(dev, 0x4f);
+ enables |= 0x08;
+ pci_write_config8(dev, 0x4f, enables);
+
+#if CONFIG_EPIA_VT8237R_INIT
+ /*
+ * Set Read Pass Write Control Enable
+ */
+ pci_write_config8(dev, 0x48, 0x0c);
+#else
+ /*
+ * Set Read Pass Write Control Enable
+ * (force A2 from APIC FSB to low).
+ */
+ pci_write_config8(dev, 0x48, 0x8c);
+#endif
+
+ southbridge_init_common(dev);
+
+#if !CONFIG_EPIA_VT8237R_INIT
+ /* FIXME: Intel needs more bit set for C2/C3. */
+
+ /*
+ * Allow SLP# signal to assert LDTSTOP_L.
+ * Will work for C3 and for FID/VID change.
+ */
+ outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
+#endif
+
+ printk(BIOS_SPEW, "Leaving %s.\n", __func__);
+}
+
+static void vt8237a_init(struct device *dev)
+{
+ /*
+ * FIXME: This is based on vt8237s_init() and the values the AMI
+ * BIOS on my M2V wrote to these registers (by loking
+ * at lspci -nxxx output).
+ * Works for me.
+ */
+ u32 tmp;
+
+ /* Set bit 3 of 0x4f (use INIT# as CPU reset). */
+ tmp = pci_read_config8(dev, 0x4f);
+ tmp |= 0x08;
+ pci_write_config8(dev, 0x4f, tmp);
+
+ /*
+ * bit2: REQ5 as PCI request input - should be together with INTE-INTH.
+ * bit5: usb power control lines as gpio
+ */
+ pci_write_config8(dev, 0xe4, 0x24);
+ /*
+ * Enable APIC wakeup from INTH
+ * Enable SATA LED, disable special CPU Frequency Change -
+ * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
+ */
+ pci_write_config8(dev, 0xe5, 0x69);
+
+ /* Reduce further the STPCLK/LDTSTP signal to 5us. */
+ pci_write_config8(dev, 0xec, 0x4);
+
+ /* Host Bus Power Management Control, maybe not needed */
+ pci_write_config8(dev, 0x8c, 0x5);
+
+ /* Enable HPET at VT8237R_HPET_ADDR. */
+ pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
+
+ southbridge_init_common(dev);
+
+ /* Share INTE-INTH with INTA-INTD for simplicity */
+ pci_write_config8(dev, 0x46, 0x00);
+
+ /* FIXME: Intel needs more bit set for C2/C3. */
+
+ /*
+ * Allow SLP# signal to assert LDTSTOP_L.
+ * Will work for C3 and for FID/VID change.
+ */
+ outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
+
+ dump_south(dev);
+}
+
+static void vt8237s_init(struct device *dev)
+{
+ u32 tmp;
+
+ /* Put SPI base VT8237S_SPI_MEM_BASE. */
+ tmp = pci_read_config32(dev, 0xbc);
+ pci_write_config32(dev, 0xbc,
+ (VT8237S_SPI_MEM_BASE >> 8) | (tmp & 0xFF000000));
+
+ /*
+ * REQ5 as PCI request input - should be together with INTE-INTH.
+ */
+ pci_write_config8(dev, 0xe4, 0x04);
+
+ /* Reduce further the STPCLK/LDTSTP signal to 5us. */
+ pci_write_config8(dev, 0xec, 0x4);
+
+ /* Host Bus Power Management Control, maybe not needed */
+ pci_write_config8(dev, 0x8c, 0x5);
+
+ /* Enable HPET at VT8237R_HPET_ADDR., does not work correctly on R. */
+ pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
+
+ southbridge_init_common(dev);
+
+ /* FIXME: Intel needs more bit set for C2/C3. */
+
+ /*
+ * Allow SLP# signal to assert LDTSTOP_L.
+ * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2.
+ */
+ outb(0xff, VT8237R_ACPI_IO_BASE + 0x50);
+
+ dump_south(dev);
+}
+
+static void vt8237_common_init(struct device *dev)
+{
+ u8 enables, byte;
+
+ /* Enable addr/data stepping. */
+ byte = pci_read_config8(dev, PCI_COMMAND);
+ byte |= PCI_COMMAND_WAIT;
+ pci_write_config8(dev, PCI_COMMAND, byte);
+
+/* EPIA-N(L) Uses CN400 for BIOS Access */
+#if !CONFIG_EPIA_VT8237R_INIT
+ /* Enable the internal I/O decode. */
+ enables = pci_read_config8(dev, 0x6C);
+ enables |= 0x80;
+ pci_write_config8(dev, 0x6C, enables);
+
+ /*
+ * ROM decode
+ * bit range
+ * 7 000E0000h-000EFFFFh
+ * 6 FFF00000h-FFF7FFFFh
+ * 5 FFE80000h-FFEFFFFFh
+ * 4 FFE00000h-FFE7FFFFh
+ * 3 FFD80000h-FFDFFFFFh
+ * 2 FFD00000h-FFD7FFFFh
+ * 1 FFC80000h-FFCFFFFFh
+ * 0 FFC00000h-FFC7FFFFh
+ * So 0x7f here sets ROM decode to FFC00000-FFFFFFFF or 4Mbyte.
+ */
+ pci_write_config8(dev, 0x41, 0x7f);
+#endif
+
+ /*
+ * Set bit 6 of 0x40 (I/O recovery time).
+ * IMPORTANT FIX - EISA = ECLR reg at 0x4d0! Decoding must be on so
+ * that PCI interrupts can be properly marked as level triggered.
+ */
+ enables = pci_read_config8(dev, 0x40);
+ enables |= 0x44;
+ pci_write_config8(dev, 0x40, enables);
+
+ /* Line buffer control */
+ enables = pci_read_config8(dev, 0x42);
+ enables |= 0xf8;
+ pci_write_config8(dev, 0x42, enables);
+
+ /* Delay transaction control */
+ pci_write_config8(dev, 0x43, 0xb);
+
+#if CONFIG_EPIA_VT8237R_INIT
+ /* I/O recovery time, default IDE routing */
+ pci_write_config8(dev, 0x4c, 0x04);
+
+ /* ROM memory cycles go to LPC. */
+ pci_write_config8(dev, 0x59, 0x80);
+
+ /*
+ * Bit | Meaning
+ * -------------
+ * 3 | Bypass APIC De-Assert Message (1=Enable)
+ * 1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI"
+ * | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch
+ * 0 | Dynamic Clock Gating Main Switch (1=Enable)
+ */
+ pci_write_config8(dev, 0x5b, 0x9);
+
+ /* Set 0x58 to 0x42 APIC On and RTC Write Protect.*/
+ pci_write_config8(dev, 0x58, 0x42);
+
+ /* Enable serial IRQ, 6PCI clocks. */
+ pci_write_config8(dev, 0x52, 0x9);
+#else
+ /* I/O recovery time, default IDE routing */
+ pci_write_config8(dev, 0x4c, 0x44);
+
+ /* ROM memory cycles go to LPC. */
+ pci_write_config8(dev, 0x59, 0x80);
+
+ /*
+ * Bit | Meaning
+ * -------------
+ * 3 | Bypass APIC De-Assert Message (1=Enable)
+ * 1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI"
+ * | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch
+ * 0 | Dynamic Clock Gating Main Switch (1=Enable)
+ */
+ pci_write_config8(dev, 0x5b, 0xb);
+
+ /* Set 0x58 to 0x43 APIC and RTC. */
+ pci_write_config8(dev, 0x58, 0x43);
+
+ /* Enable serial IRQ, 6PCI clocks. */
+ pci_write_config8(dev, 0x52, 0x9);
+
+#endif
+
+ /* Power management setup */
+ setup_pm(dev);
+
+ /* Start the RTC. */
+ rtc_init(0);
+}
+
+static void vt8237r_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ pci_dev_read_resources(dev);
+
+ /* Fixed ACPI Base IO Base*/
+ res = new_resource(dev, 0x88);
+ res->base = VT8237R_ACPI_IO_BASE;
+ res->size = 128;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Fixed EISA ECLR I/O Regs */
+ res = new_resource(dev, 3);
+ res->base = 0x4d0;
+ res->size = 2;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Fixed System Management Bus I/O Resource */
+ res = new_resource(dev, 0xD0);
+ res->base = VT8237R_SMBUS_IO_BASE;
+ res->size = 16;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Fixed APIC resource */
+ res = new_resource(dev, 0x44);
+ res->base = IO_APIC_ADDR;
+ res->size = 256;
+ res->limit = 0xffffffffUL;
+ res->align = 8;
+ res->gran = 8;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ /* Fixed flashrom resource */
+ res = new_resource(dev, 4);
+ res->base = 0xff000000UL;
+ res->size = 0x01000000UL; /* 16MB */
+ res->limit = 0xffffffffUL;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
+ IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+
+ res = new_resource(dev, 1);
+ res->base = 0x0UL;
+ res->size = 0x1000UL;
+ res->limit = 0xffffUL;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+}
+
+static void init_keyboard(struct device *dev)
+{
+ u8 regval = pci_read_config8(dev, 0x51);
+ if (regval & 0x1)
+ pc_keyboard_init(0);
+}
+
+static void southbridge_init_common(struct device *dev)
+{
+ vt8237_common_init(dev);
+ pci_routing_fixup(dev);
+ setup_ioapic(IO_APIC_ADDR, VT8237R_APIC_ID);
+ setup_i8259();
+ init_keyboard(dev);
+}
+
+static const struct device_operations vt8237r_lpc_ops_s = {
+ .read_resources = vt8237r_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = vt8237s_init,
+ .scan_bus = scan_static_bus,
+};
+
+static const struct device_operations vt8237r_lpc_ops_r = {
+ .read_resources = vt8237r_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = vt8237r_init,
+ .scan_bus = scan_static_bus,
+};
+
+static const struct device_operations vt8237r_lpc_ops_a = {
+ .read_resources = vt8237r_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = vt8237a_init,
+ .scan_bus = scan_static_bus,
+};
+
+static const struct pci_driver lpc_driver_r __pci_driver = {
+ .ops = &vt8237r_lpc_ops_r,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237R_LPC,
+};
+
+static const struct pci_driver lpc_driver_a __pci_driver = {
+ .ops = &vt8237r_lpc_ops_a,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237A_LPC,
+};
+
+static const struct pci_driver lpc_driver_s __pci_driver = {
+ .ops = &vt8237r_lpc_ops_s,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237S_LPC,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237r.h"
+
+
+static void vt8237_eth_read_resources(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+
+ /* Fix the I/O Resources of the USB2.0 Interface */
+ res = new_resource(dev, PCI_BASE_ADDRESS_0);
+ res->base = 0xF6001000ULL;
+ res->size = 256;
+ res->align = 12;
+ res->gran = 8;
+ res->limit = res->base + res->size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+
+static const struct device_operations vt8237_eth_ops = {
+ .read_resources = vt8237_eth_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver vt8237r_driver_eth __pci_driver = {
+ .ops = &vt8237_eth_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8233_7,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
+ * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot@tdiedrich.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <arch/pirq_routing.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <pc80/i8259.h>
+
+#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
+void pirq_assign_irqs(const unsigned char route[4])
+{
+ device_t pdev;
+
+ pdev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
+ if (!pdev)
+ pdev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
+ if (!pdev)
+ pdev = dev_find_device(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237A_LPC, 0);
+ if (!pdev)
+ return;
+
+ pci_write_config8(pdev, 0x55, route[0] << 4);
+ pci_write_config8(pdev, 0x56, (route[2] << 4) | route[1]);
+ pci_write_config8(pdev, 0x57, route[3] << 4);
+
+ /* Enable INT[E-H] mapped to INT[A-D] for simplicity */
+ pci_write_config8(pdev, 0x46, 0x00);
+}
+#endif
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#define SATA_MISC_CTRL 0x45
+
+static void sata_i_init(struct device *dev)
+{
+ u8 reg;
+
+ printk(BIOS_DEBUG, "Configuring VIA SATA controller\n");
+
+ /* Class IDE Disk */
+ reg = pci_read_config8(dev, SATA_MISC_CTRL);
+ reg &= 0x7f; /* Sub Class Write Protect off */
+ pci_write_config8(dev, SATA_MISC_CTRL, reg);
+
+ /* Change the device class to SATA from RAID. */
+ pci_write_config8(dev, PCI_CLASS_DEVICE, 0x1);
+ reg |= 0x80; /* Sub Class Write Protect on */
+ pci_write_config8(dev, SATA_MISC_CTRL, reg);
+
+ return;
+}
+
+static void sata_ii_init(struct device *dev)
+{
+ u8 reg;
+
+ sata_i_init(dev);
+
+ /*
+ * Analog black magic, you may or may not need to adjust 0x60-0x6f,
+ * depends on PCB.
+ */
+
+ /*
+ * Analog PHY - gen1
+ * CDR bandwidth [6:5] = 3
+ * Squelch Window Select [4:3] = 1
+ * CDR Charge Pump [2:0] = 1
+ */
+
+ pci_write_config8(dev, 0x64, 0x49);
+
+ /* Adjust driver current source value to 9. */
+ reg = pci_read_config8(dev, 0x65);
+ reg &= 0xf0;
+ reg |= 0x9;
+ pci_write_config8(dev, 0x65, reg);
+
+ /* Set all manual termination 50ohm bits [2:0] and enable [4]. */
+ reg = pci_read_config8(dev, 0x6a);
+ reg |= 0xf;
+ pci_write_config8(dev, 0x6a, reg);
+
+ /*
+ * Analog PHY - gen2
+ * CDR bandwidth [5:4] = 2
+ * Pre / De-emphasis Level [7:6] controls bits [3:2], rest in 0x6e
+ * CDR Charge Pump [2:0] = 1
+ */
+
+ reg = pci_read_config8(dev, 0x6f);
+ reg &= 0x08;
+ reg |= 0x61;
+ pci_write_config8(dev, 0x6f, reg);
+
+ /* Check if staggered spinup is supported. */
+ reg = pci_read_config8(dev, 0x83);
+ if ((reg & 0x8) == 0) {
+ /* Start OOB sequence on both drives. */
+ reg |= 0x30;
+ pci_write_config8(dev, 0x83, reg);
+ }
+}
+
+static const struct device_operations sata_i_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_i_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct device_operations sata_ii_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_ii_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver northbridge_driver_ii __pci_driver = {
+ .ops = &sata_ii_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237_SATA,
+};
+
+static const struct pci_driver northbridge_driver_i_a __pci_driver = {
+ .ops = &sata_i_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237A_SATA,
+};
+
+static const struct pci_driver northbridge_driver_i __pci_driver = {
+ .ops = &sata_i_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT6420_SATA,
+};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * 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/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237r.h"
+
+#if CONFIG_EPIA_VT8237R_INIT
+u32 usb_io_addr[4] = {0xcc00, 0xd000, 0xd400, 0xd800};
+#endif
+
+static void usb_i_init(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ u8 reg8;
+
+ printk(BIOS_DEBUG, "Entering %s\n", __func__);
+
+ reg8 = pci_read_config8(dev, 0x04);
+
+ printk(BIOS_SPEW, "%s Read %02X from PCI Command Reg\n", dev_path(dev), reg8);
+
+ reg8 = reg8 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config8(dev, 0x04, reg8);
+
+ printk(BIOS_SPEW, "%s Wrote %02X to PCI Command Reg\n", dev_path(dev), reg8);
+
+ /* Set Cache Line Size and Latency Timer */
+ pci_write_config8(dev, 0x0c, 0x08);
+ pci_write_config8(dev, 0x0d, 0x20);
+
+ /* Enable Sub Device ID Back Door and set Generic */
+ reg8 = pci_read_config8(dev, 0x42);
+ reg8 |= 0x10;
+ pci_write_config8(dev, 0x42, reg8);
+ pci_write_config16(dev, 0x2e, 0xAA07);
+ reg8 &= ~0x10;
+ pci_write_config8(dev, 0x42, reg8);
+
+
+ pci_write_config8(dev, 0x41, 0x12);
+
+ pci_write_config8(dev, 0x49, 0x0B);
+
+ /* Clear PCI Status */
+ pci_write_config16(dev, 0x06, 0x7A10);
+#endif
+ return;
+}
+
+static void vt8237_usb_i_read_resources(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+ u8 function = (u8) dev->path.pci.devfn & 0x7;
+
+ printk(BIOS_SPEW, "VT8237R Fixing USB 1.1 fn %d I/O resource = 0x%04X\n", function, usb_io_addr[function]);
+
+ /* Fix the I/O Resources of the USB1.1 Interfaces */
+ /* Auto PCI probe seems to size the resources */
+ /* Incorrectly */
+ res = new_resource(dev, PCI_BASE_ADDRESS_4);
+ res->base = usb_io_addr[function];
+ res->size = 256;
+ res->limit = 0xffffUL;
+ res->align = 10;
+ res->gran = 8;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+static void usb_ii_init(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ u8 reg8;
+
+ printk(BIOS_DEBUG, "Entering %s\n", __func__);
+
+ /* Set memory Write and Invalidate */
+ reg8 = pci_read_config8(dev, 0x04);
+ reg8 |= 0x10;
+ pci_write_config8(dev, 0x04, reg8);
+
+ /* Set Cache line Size and Latency Timer */
+ pci_write_config8(dev, 0x0c, 0x08);
+ pci_write_config8(dev, 0x0d, 0x20);
+
+ /* Clear PCI Status */
+ pci_write_config16(dev, 0x06, 0x7A10);
+#endif
+
+}
+
+static void vt8237_usb_ii_read_resources(struct device *dev)
+{
+#if CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+
+ /* Fix the I/O Resources of the USB2.0 Interface */
+ res = new_resource(dev, PCI_BASE_ADDRESS_0);
+ res->base = 0xF6000000ULL;
+ res->size = 256;
+ res->align = 12;
+ res->gran = 8;
+ res->limit = res->base + res->size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+static const struct device_operations usb_i_ops = {
+ .read_resources = vt8237_usb_i_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_i_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct device_operations usb_ii_ops = {
+ .read_resources = vt8237_usb_ii_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_ii_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver vt8237r_driver_usbii __pci_driver = {
+ .ops = &usb_ii_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237R_EHCI,
+};
+
+static const struct pci_driver vt8237r_driver_usbi __pci_driver = {
+ .ops = &usb_i_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237R_UHCI,
+};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2008 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ops.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "vt8237r.h"
-
-/* We support here K8M890/K8T890 and VT8237/S/A PCI1/Vlink */
-
-static void vt8237_cfg(struct device *dev)
-{
- u8 regm, regm3;
- device_t devfun3;
-
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CE_3, 0);
- if (!devfun3)
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8M890CE_3, 0);
- if (!devfun3)
- devfun3 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CF_3, 0);
- if (!devfun3)
- die("Unknown NB");
-
- /* CPU to PCI Flow Control 1 & 2, just fill in recommended. */
- pci_write_config8(dev, 0x70, 0xc2);
- pci_write_config8(dev, 0x71, 0xc8);
-
- /* PCI Control */
- pci_write_config8(dev, 0x72, 0xee);
- pci_write_config8(dev, 0x73, 0x01);
- pci_write_config8(dev, 0x74, 0x3c);
- pci_write_config8(dev, 0x75, 0x0f);
- pci_write_config8(dev, 0x76, 0x50);
- pci_write_config8(dev, 0x77, 0x48);
- pci_write_config8(dev, 0x78, 0x01);
- /* APIC on HT */
- /* Maybe Enable LDT APIC Mode bit3 set to 1 */
- pci_write_config8(dev, 0x7c, 0x77);
-
- /* WARNING: Need to copy some registers from NB (D0F3) to SB (D11F7). */
-
- regm = pci_read_config8(devfun3, 0x88); /* Shadow mem CTRL */
- pci_write_config8(dev, 0x57, regm);
-
- regm = pci_read_config8(devfun3, 0x80); /* Shadow page C */
- pci_write_config8(dev, 0x61, regm);
-
- regm = pci_read_config8(devfun3, 0x81); /* Shadow page D */
- pci_write_config8(dev, 0x62, regm);
-
- /* Shadow page F + memhole copy */
- regm = pci_read_config8(devfun3, 0x83);
- pci_write_config8(dev, 0x63, regm);
-
- // FIXME is this really supposed to be regm3?
- regm3 = pci_read_config8(devfun3, 0x82);/* Shadow page E */
- pci_write_config8(dev, 0x64, regm);
-
- regm = pci_read_config8(devfun3, 0x86); /* SMM and APIC decoding */
- pci_write_config8(dev, 0xe6, regm);
-}
-
-/**
- * Example of setup: Setup the V-Link for VT8237R, 8X mode.
- *
- * For K8T890CF VIA recommends what is in VIA column, AW is award 8X:
- *
- * REG DEF AW VIA-8X VIA-4X
- * -----------------------------
- * NB V-Link Manual Driving Control strobe 0xb5 0x46 0x46 0x88 0x88
- * NB V-Link Manual Driving Control - Data 0xb6 0x46 0x46 0x88 0x88
- * NB V-Link Receiving Strobe Delay 0xb7 0x02 0x02 0x61 0x01
- * NB V-Link Compensation Control bit4,0 (b5,b6) 0xb4 0x10 0x10 0x11 0x11
- * SB V-Link Strobe Drive Control 0xb9 0x00 0xa5 0x98 0x98
- * SB V-Link Data drive Control???? 0xba 0x00 0xbb 0x77 0x77
- * SB V-Link Receive Strobe Delay???? 0xbb 0x04 0x11 0x11 0x11
- * SB V-Link Compensation Control bit0 (use b9) 0xb8 0x00 0x01 0x01 0x01
- * V-Link CKG Control 0xb0 0x05 0x05 0x06 0x03
- * V-Link CKG Control 0xb1 0x05 0x05 0x01 0x03
- */
-
-/* we setup 533MB/s mode full duplex */
-
-static void vt8237s_vlink_init(struct device *dev)
-{
- u8 reg;
- device_t devfun7;
-
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
- if (!devfun7)
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
- if (!devfun7)
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
- /* No pairing NB was found. */
- if (!devfun7)
- return;
-
- /*
- * This init code is valid only for the VT8237S! For different
- * sounthbridges (e.g. VT8237A, VT8237S, VT8237R (without plus R)
- * and VT8251) a different init code is required.
- */
-
- /* disable auto disconnect */
- reg = pci_read_config8(devfun7, 0x42);
- reg &= ~0x4;
- pci_write_config8(devfun7, 0x42, reg);
-
- /* NB part setup */
- pci_write_config8(devfun7, 0xb5, 0x66);
- pci_write_config8(devfun7, 0xb6, 0x66);
- pci_write_config8(devfun7, 0xb7, 0x64);
-
- reg = pci_read_config8(devfun7, 0xb4);
- reg |= 0x1;
- reg &= ~0x10;
- pci_write_config8(devfun7, 0xb4, reg);
-
- pci_write_config8(devfun7, 0xb0, 0x6);
- pci_write_config8(devfun7, 0xb1, 0x1);
-
- /* SB part setup */
- pci_write_config8(dev, 0xb7, 0x60);
- pci_write_config8(dev, 0xb9, 0x88);
- pci_write_config8(dev, 0xba, 0x88);
- pci_write_config8(dev, 0xbb, 0x89);
-
- reg = pci_read_config8(dev, 0xbd);
- reg |= 0x3;
- reg &= ~0x4;
- pci_write_config8(dev, 0xbd, reg);
-
- reg = pci_read_config8(dev, 0xbc);
- reg &= ~0x7;
- pci_write_config8(dev, 0xbc, reg);
-
- /* Program V-link 8X 8bit full duplex, parity enabled. */
- pci_write_config8(dev, 0x48, 0x23 | 0x80);
-
- /* enable auto disconnect, for STPGNT and HALT */
- reg = pci_read_config8(devfun7, 0x42);
- reg |= 0x7;
- pci_write_config8(devfun7, 0x42, reg);
-
-}
-
-static void vt8237a_vlink_init(struct device *dev)
-{
- u8 reg;
- device_t devfun7;
-
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CE_7, 0);
- if (!devfun7)
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8M890CE_7, 0);
- if (!devfun7)
- devfun7 = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_K8T890CF_7, 0);
- /* No pairing NB was found. */
- if (!devfun7)
- return;
-
- /*
- * This init code is valid only for the VT8237A! For different
- * sounthbridges (e.g. VT8237S, VT8237R and VT8251) a different
- * init code is required.
- *
- * FIXME: This is based on vt8237r_vlink_init() in
- * k8t890/k8t890_ctrl.c and modified to fit what the AMI
- * BIOS on my M2V wrote to these registers (by looking
- * at lspci -nxxx output).
- * Works for me.
- */
-
- /* disable auto disconnect */
- reg = pci_read_config8(devfun7, 0x42);
- reg &= ~0x4;
- pci_write_config8(devfun7, 0x42, reg);
-
- /* NB part setup */
- pci_write_config8(devfun7, 0xb5, 0x88);
- pci_write_config8(devfun7, 0xb6, 0x88);
- pci_write_config8(devfun7, 0xb7, 0x61);
-
- reg = pci_read_config8(devfun7, 0xb4);
- reg |= 0x11;
- pci_write_config8(devfun7, 0xb4, reg);
-
- pci_write_config8(devfun7, 0xb0, 0x6);
- pci_write_config8(devfun7, 0xb1, 0x1);
-
- /* SB part setup */
- pci_write_config8(dev, 0xb7, 0x50);
- pci_write_config8(dev, 0xb9, 0x88);
- pci_write_config8(dev, 0xba, 0x8a);
- pci_write_config8(dev, 0xbb, 0x88);
-
- reg = pci_read_config8(dev, 0xbd);
- reg |= 0x3;
- reg &= ~0x4;
- pci_write_config8(dev, 0xbd, reg);
-
- reg = pci_read_config8(dev, 0xbc);
- reg &= ~0x7;
- pci_write_config8(dev, 0xbc, reg);
-
- pci_write_config8(dev, 0x48, 0x23);
-
- /* enable auto disconnect, for STPGNT and HALT */
- reg = pci_read_config8(devfun7, 0x42);
- reg |= 0x7;
- pci_write_config8(devfun7, 0x42, reg);
-}
-
-static void ctrl_enable(struct device *dev)
-{
- /* Enable the 0:13 and 0:13.1. */
- /* FIXME */
- pci_write_config8(dev, 0x4f, 0x43);
-}
-
-static void ctrl_init(struct device *dev)
-{
- /*
- * TODO: Fix some ordering issue for V-link set Rx77[6] and
- * PCI1_Rx4F[0] should to 1.
- * FIXME DO you need?
- */
-
- /*
- * VT8237R specific configuration. Other SB are done in their own
- * directories. TODO: Add A version.
- */
- device_t devsb = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
- if (devsb) {
- vt8237s_vlink_init(dev);
- }
-
- devsb = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237A_LPC, 0);
- if (devsb) {
- vt8237a_vlink_init(dev);
- }
-
- /* Configure PCI1 and copy mirror registers from D0F3. */
- vt8237_cfg(dev);
- dump_south(dev);
-}
-
-static const struct device_operations ctrl_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ctrl_init,
- .enable = ctrl_enable,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_t __pci_driver = {
- .ops = &ctrl_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237_VLINK,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2004 Nick Barker <nick.barker9@btinternet.com>
- * Copyright (C) 2007, 2009 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-#include <arch/acpi.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "vt8237r.h"
-
-/**
- * Create the Fixed ACPI Description Tables (FADT) for any board with this SB.
- */
-void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt)
-{
- acpi_header_t *header = &(fadt->header);
- device_t dev;
- int is_vt8237s = 0;
-
- /* Power management controller */
- dev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
-
- if (dev)
- is_vt8237s = 1;
-
- memset((void *) fadt, 0, sizeof(acpi_fadt_t));
- memcpy(header->signature, "FACP", 4);
- header->length = 244;
- header->revision = 4;
- memcpy(header->oem_id, "COREBO", 6);
- memcpy(header->oem_table_id, "COREBOOT", 8);
- memcpy(header->asl_compiler_id, "CORE", 4);
- header->asl_compiler_revision = 42;
-
- fadt->firmware_ctrl = (u32)facs;
- fadt->dsdt = (u32)dsdt;
- fadt->preferred_pm_profile = 0;
- fadt->sci_int = 9;
- fadt->smi_cmd = 0;
- fadt->acpi_enable = 0;
- fadt->acpi_disable = 0;
- fadt->s4bios_req = 0x0;
- fadt->pstate_cnt = 0x0;
-
- fadt->pm1a_evt_blk = VT8237R_ACPI_IO_BASE;
- fadt->pm1b_evt_blk = 0x0;
- fadt->pm1a_cnt_blk = VT8237R_ACPI_IO_BASE + 0x4;
- fadt->pm1b_cnt_blk = 0x0;
- /* once we support C2/C3 this could be set to 0x22 and chipset needs to be adjusted too */
- fadt->pm2_cnt_blk = 0x0;
- fadt->pm_tmr_blk = VT8237R_ACPI_IO_BASE + 0x8;
- fadt->gpe0_blk = VT8237R_ACPI_IO_BASE + 0x20;
- if (is_vt8237s) {
- fadt->gpe1_blk = VT8237R_ACPI_IO_BASE + 0x60;
- fadt->gpe1_base = 0x10;
- fadt->gpe1_blk_len = 4;
- } else {
- fadt->gpe1_blk = 0x0;
- fadt->gpe1_base = 0;
- fadt->gpe1_blk_len = 0;
- }
-
- fadt->pm1_evt_len = 4;
- fadt->pm1_cnt_len = 2;
- fadt->pm2_cnt_len = 0;
- fadt->pm_tmr_len = 4;
- fadt->gpe0_blk_len = 4;
-
- fadt->cst_cnt = 0;
- fadt->p_lvl2_lat = 90;
- fadt->p_lvl3_lat = 900;
- fadt->flush_size = 0;
- fadt->flush_stride = 0;
- fadt->duty_offset = 0;
- fadt->duty_width = 1; //??
- fadt->day_alrm = 0x7d;
- fadt->mon_alrm = 0x7e;
- fadt->century = 0x32;
- /* We have legacy devices, 8042, VGA is ok to probe, MSI are not supported */
- fadt->iapc_boot_arch = 0xb;
- /* check me */
- fadt->flags = 0xa5;
-
- fadt->reset_reg.space_id = 0;
- fadt->reset_reg.bit_width = 0;
- fadt->reset_reg.bit_offset = 0;
- fadt->reset_reg.resv = 0;
- fadt->reset_reg.addrl = 0x0;
- fadt->reset_reg.addrh = 0x0;
-
- fadt->reset_value = 0;
- fadt->x_firmware_ctl_l = (u32)facs;
- fadt->x_firmware_ctl_h = 0;
- fadt->x_dsdt_l = (u32)dsdt;
- fadt->x_dsdt_h = 0;
-
- fadt->x_pm1a_evt_blk.space_id = 1;
- fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1a_evt_blk.bit_offset = 0;
- fadt->x_pm1a_evt_blk.resv = 0;
- fadt->x_pm1a_evt_blk.addrl = fadt->pm1a_evt_blk;
- fadt->x_pm1a_evt_blk.addrh = 0x0;
-
- fadt->x_pm1b_evt_blk.space_id = 1;
- fadt->x_pm1b_evt_blk.bit_width = fadt->pm1_evt_len * 8;
- fadt->x_pm1b_evt_blk.bit_offset = 0;
- fadt->x_pm1b_evt_blk.resv = 0;
- fadt->x_pm1b_evt_blk.addrl = fadt->pm1b_evt_blk;
- fadt->x_pm1b_evt_blk.addrh = 0x0;
-
- fadt->x_pm1a_cnt_blk.space_id = 1;
- fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1a_cnt_blk.bit_offset = 0;
- fadt->x_pm1a_cnt_blk.resv = 0;
- fadt->x_pm1a_cnt_blk.addrl = fadt->pm1a_cnt_blk;
- fadt->x_pm1a_cnt_blk.addrh = 0x0;
-
- fadt->x_pm1b_cnt_blk.space_id = 1;
- fadt->x_pm1b_cnt_blk.bit_width = fadt->pm1_cnt_len * 8;
- fadt->x_pm1b_cnt_blk.bit_offset = 0;
- fadt->x_pm1b_cnt_blk.resv = 0;
- fadt->x_pm1b_cnt_blk.addrl = fadt->pm1b_cnt_blk;
- fadt->x_pm1b_cnt_blk.addrh = 0x0;
-
- fadt->x_pm2_cnt_blk.space_id = 1;
- fadt->x_pm2_cnt_blk.bit_width = fadt->pm2_cnt_len * 8;
- fadt->x_pm2_cnt_blk.bit_offset = 0;
- fadt->x_pm2_cnt_blk.resv = 0;
- fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
- fadt->x_pm2_cnt_blk.addrh = 0x0;
-
- fadt->x_pm_tmr_blk.space_id = 1;
- fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
- fadt->x_pm_tmr_blk.bit_offset = 0;
- fadt->x_pm_tmr_blk.resv = 0;
- fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
- fadt->x_pm_tmr_blk.addrh = 0x0;
-
- fadt->x_gpe0_blk.space_id = 1;
- fadt->x_gpe0_blk.bit_width = fadt->gpe0_blk_len * 8;
- fadt->x_gpe0_blk.bit_offset = 0;
- fadt->x_gpe0_blk.resv = 0;
- fadt->x_gpe0_blk.addrl = fadt->gpe0_blk;
- fadt->x_gpe0_blk.addrh = 0x0;
-
- fadt->x_gpe1_blk.space_id = 1;
- fadt->x_gpe1_blk.bit_width = fadt->gpe1_blk_len * 8;;
- fadt->x_gpe1_blk.bit_offset = 0;
- fadt->x_gpe1_blk.resv = 0;
- fadt->x_gpe1_blk.addrl = fadt->gpe1_blk;
- fadt->x_gpe1_blk.addrh = 0x0;
-
- header->checksum = acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
-}
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Corey Osgood <corey.osgood@gmail.com>
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <device/pci_ids.h>
-#include <spd.h>
-#include <stdlib.h>
-#include "vt8237r.h"
-
-/**
- * Print an error, should it occur. If no error, just exit.
- *
- * @param host_status The data returned on the host status register after
- * a transaction is processed.
- * @param loops The number of times a transaction was attempted.
- */
-static void smbus_print_error(u8 host_status, int loops)
-{
- /* Check if there actually was an error. */
- if ((host_status == 0x00 || host_status == 0x40 ||
- host_status == 0x42) && (loops < SMBUS_TIMEOUT))
- return;
-
- if (loops >= SMBUS_TIMEOUT)
- print_err("SMBus timeout\n");
- if (host_status & (1 << 4))
- print_err("Interrupt/SMI# was Failed Bus Transaction\n");
- if (host_status & (1 << 3))
- print_err("Bus error\n");
- if (host_status & (1 << 2))
- print_err("Device error\n");
- if (host_status & (1 << 1))
- print_debug("Interrupt/SMI# completed successfully\n");
- if (host_status & (1 << 0))
- print_err("Host busy\n");
-}
-
-/**
- * Wait for the SMBus to become ready to process the next transaction.
- */
-static void smbus_wait_until_ready(void)
-{
- int loops;
-
- PRINT_DEBUG("Waiting until SMBus ready\n");
-
- /* Loop up to SMBUS_TIMEOUT times, waiting for bit 0 of the
- * SMBus Host Status register to go to 0, indicating the operation
- * was completed successfully. I don't remember why I did it this way,
- * but I think it was because ROMCC was running low on registers */
- loops = 0;
- while ((inb(SMBHSTSTAT) & 1) == 1 && loops < SMBUS_TIMEOUT)
- ++loops;
-
- smbus_print_error(inb(SMBHSTSTAT), loops);
-}
-
-/**
- * Reset and take ownership of the SMBus.
- */
-static void smbus_reset(void)
-{
- outb(HOST_RESET, SMBHSTSTAT);
-
- /* Datasheet says we have to read it to take ownership of SMBus. */
- inb(SMBHSTSTAT);
-
- PRINT_DEBUG("After reset status: ");
- PRINT_DEBUG_HEX16(inb(SMBHSTSTAT));
- PRINT_DEBUG("\n");
-}
-
-/**
- * Read a byte from the SMBus.
- *
- * @param dimm The address location of the DIMM on the SMBus.
- * @param offset The offset the data is located at.
- */
-u8 smbus_read_byte(u8 dimm, u8 offset)
-{
- u8 val;
-
- PRINT_DEBUG("DIMM ");
- PRINT_DEBUG_HEX16(dimm);
- PRINT_DEBUG(" OFFSET ");
- PRINT_DEBUG_HEX16(offset);
- PRINT_DEBUG("\n");
-
- smbus_reset();
-
- /* Clear host data port. */
- outb(0x00, SMBHSTDAT0);
- SMBUS_DELAY();
- smbus_wait_until_ready();
-
- /* Actual addr to reg format. */
- dimm = (dimm << 1);
- dimm |= 1;
- outb(dimm, SMBXMITADD);
- outb(offset, SMBHSTCMD);
-
- /* Start transaction, byte data read. */
- outb(0x48, SMBHSTCTL);
- SMBUS_DELAY();
- smbus_wait_until_ready();
-
- val = inb(SMBHSTDAT0);
- PRINT_DEBUG("Read: ");
- PRINT_DEBUG_HEX16(val);
- PRINT_DEBUG("\n");
-
- /* Probably don't have to do this, but it can't hurt. */
- smbus_reset();
-
- return val;
-}
-
-#define PSONREADY_TIMEOUT 0x7fffffff
-
-static device_t get_vt8237_lpc(void)
-{
- device_t dev;
-
- /* Power management controller */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237R_LPC), 0);
- if (dev != PCI_DEV_INVALID)
- return dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237S_LPC), 0);
- if (dev != PCI_DEV_INVALID)
- return dev;
-
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237A_LPC), 0);
- return dev;
-}
-
-/**
- * Enable the SMBus on VT8237R-based systems.
- */
-void enable_smbus(void)
-{
- device_t dev;
- int loops;
-
- /* Power management controller */
- dev = get_vt8237_lpc();
- if (dev == PCI_DEV_INVALID)
- die("Power management controller not found\n");
-
- /* Make sure the RTC power well is up before touching smbus. */
- loops = 0;
- while (!(pci_read_config8(dev, VT8237R_PSON) & (1<<6))
- && loops < PSONREADY_TIMEOUT)
- ++loops;
-
- /*
- * 7 = SMBus Clock from RTC 32.768KHz
- * 5 = Internal PLL reset from susp
- */
- pci_write_config8(dev, VT8237R_POWER_WELL, 0xa0);
-
- /* Enable SMBus. */
- pci_write_config16(dev, VT8237R_SMBUS_IO_BASE_REG,
- VT8237R_SMBUS_IO_BASE | 0x1);
-
- /* SMBus Host Configuration, enable. */
- pci_write_config8(dev, VT8237R_SMBUS_HOST_CONF, 0x01);
-
- /* Make it work for I/O. */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- smbus_reset();
-
- /* Reset the internal pointer. */
- inb(SMBHSTCTL);
-}
-
-/**
- * A fixup for some systems that need time for the SMBus to "warm up". This is
- * needed on some VT823x based systems, where the SMBus spurts out bad data for
- * a short time after power on. This has been seen on the VIA Epia series and
- * Jetway J7F2-series. It reads the ID byte from SMBus, looking for
- * known-good data from a slot/address. Exits on either good data or a timeout.
- *
- * TODO: This should probably go into some global file, but one would need to
- * be created just for it. If some other chip needs/wants it, we can
- * worry about it then.
- *
- * @param ctrl The memory controller and SMBus addresses.
- */
-void smbus_fixup(const struct mem_controller *ctrl)
-{
- int i, ram_slots, current_slot = 0;
- u8 result = 0;
-
- ram_slots = ARRAY_SIZE(ctrl->channel0);
- if (!ram_slots) {
- print_err("smbus_fixup() thinks there are no RAM slots!\n");
- return;
- }
-
- PRINT_DEBUG("Waiting for SMBus to warm up");
-
- /*
- * Bad SPD data should be either 0 or 0xff, but YMMV. So we look for
- * the ID bytes of SDRAM, DDR, DDR2, and DDR3 (and anything in between).
- * VT8237R has only been seen on DDR and DDR2 based systems, so far.
- */
- for (i = 0; (i < SMBUS_TIMEOUT && ((result < SPD_MEMORY_TYPE_SDRAM) ||
- (result > SPD_MEMORY_TYPE_SDRAM_DDR3))); i++) {
-
- if (current_slot > ram_slots)
- current_slot = 0;
-
- result = smbus_read_byte(ctrl->channel0[current_slot],
- SPD_MEMORY_TYPE);
- current_slot++;
- PRINT_DEBUG(".");
- }
-
- if (i >= SMBUS_TIMEOUT)
- print_err("SMBus timed out while warming up\n");
- else
- PRINT_DEBUG("Done\n");
-}
-
-/* FIXME: Better separate the NB and SB, will be done once it works. */
-
-void vt8237_sb_enable_fid_vid(void)
-{
- device_t dev, devctl;
- u16 devid;
-
- /* Power management controller */
- dev = get_vt8237_lpc();
- if (dev == PCI_DEV_INVALID)
- return;
-
- devid = pci_read_config16(dev, PCI_DEVICE_ID);
-
- /* generic setup */
-
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
- pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
-
- /* Enable ACPI accessm RTC signal gated with PSON. */
- pci_write_config8(dev, 0x81, 0x84);
-
- /* chipset-specific parts */
-
- /* VLINK: FIXME: can we drop the devid check and just look for the VLINK device? */
- if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC ||
- devid == PCI_DEVICE_ID_VIA_VT8237A_LPC) {
- devctl = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237_VLINK), 0);
-
- if (devctl != PCI_DEV_INVALID) {
- /* So the chip knows we are on AMD. */
- pci_write_config8(devctl, 0x7c, 0x7f);
- }
- }
-
- if (devid == PCI_DEVICE_ID_VIA_VT8237S_LPC) {
- /*
- * Allow SLP# signal to assert LDTSTOP_L.
- * Will work for C3 and for FID/VID change.
- */
-
- outb(0xff, VT8237R_ACPI_IO_BASE + 0x50);
-
- /* Reduce further the STPCLK/LDTSTP signal to 5us. */
- pci_write_config8(dev, 0xec, 0x4);
-
- return;
- }
-
- /* VT8237R and VT8237A */
-
- /*
- * Allow SLP# signal to assert LDTSTOP_L.
- * Will work for C3 and for FID/VID change.
- */
- outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
-}
-
-void enable_rom_decode(void)
-{
- device_t dev;
-
- /* Power management controller */
- dev = get_vt8237_lpc();
- if (dev == PCI_DEV_INVALID)
- return;
-
- /* ROM decode last 1MB FFC00000 - FFFFFFFF. */
- pci_write_config8(dev, 0x41, 0x7f);
-}
-
-#if CONFIG_HAVE_ACPI_RESUME == 1
-static int acpi_is_wakeup_early(void) {
- device_t dev;
- u16 tmp;
-
- print_debug("IN TEST WAKEUP\n");
-
- /* Power management controller */
- dev = get_vt8237_lpc();
- if (dev == PCI_DEV_INVALID)
- die("Power management controller not found\n");
-
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
- pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
-
- /* Enable ACPI accessm RTC signal gated with PSON. */
- pci_write_config8(dev, 0x81, 0x84);
-
- tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
-
- print_debug_hex8(tmp);
- return ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
-}
-#endif
-
-#if defined(__GNUC__)
-void vt8237_early_spi_init(void)
-{
- device_t dev;
- volatile u16 *spireg;
- u32 tmp;
-
- /* Bus Control and Power Management */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237S_LPC), 0);
-
- if (dev == PCI_DEV_INVALID)
- die("SB not found\n");
-
- /* Put SPI base 20 d0 fe. */
- tmp = pci_read_config32(dev, 0xbc);
- pci_write_config32(dev, 0xbc,
- (VT8237S_SPI_MEM_BASE >> 8) | (tmp & 0xFF000000));
-
- /* Set SPI clock to 33MHz. */
- spireg = (u16 *) (VT8237S_SPI_MEM_BASE + 0x6c);
- (*spireg) &= 0xff00;
-}
-#endif
-
-/* This #if is special. ROMCC chokes on the (rom == NULL) comparison.
- * Since the whole function is only called for one target and that target
- * is compiled with GCC, hide the function from ROMCC and be happy.
- */
-#if defined(__GNUC__)
-/*
- * Offset 0x58:
- * 31:20 reserved
- * 19:16 4 bit position in shadow EEPROM
- * 15:0 data to write
- *
- * Offset 0x5c:
- * 31:28 reserved
- * 27 ERDBG - enable read from 0x5c
- * 26 reserved
- * 25 SEELD
- * 24 SEEPR - write 1 when done updating, wait until SEELD is
- * set to 1, sticky
- * cleared by reset, if it is 1 writing is disabled
- * 19:16 4 bit position in shadow EEPROM
- * 15:0 data from shadow EEPROM
- *
- * After PCIRESET SEELD and SEEPR must be 1 and 1.
- */
-
-/* 1 = needs PCI reset, 0 don't reset, network initialized. */
-
-/* FIXME: Maybe close the debug register after use? */
-
-#define LAN_TIMEOUT 0x7FFFFFFF
-
-int vt8237_early_network_init(struct vt8237_network_rom *rom)
-{
- struct vt8237_network_rom n;
- int i, loops;
- device_t dev;
- u32 tmp;
- u8 status;
- u16 *rom_write;
- unsigned int checksum;
-
- /* Network adapter */
- dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_8233_7), 0);
- if (dev == PCI_DEV_INVALID) {
- print_err("Network is disabled, please enable\n");
- return 0;
- }
-
- tmp = pci_read_config32(dev, 0x5c);
- tmp |= 0x08000000; /* Enable ERDBG. */
- pci_write_config32(dev, 0x5c, tmp);
-
- status = ((pci_read_config32(dev, 0x5c) >> 24) & 0x3);
-
- /* Network controller OK, EEPROM loaded. */
- if (status == 3)
- return 0;
-
- if (rom == NULL) {
- print_err("No config data specified, using default MAC!\n");
- n.mac_address[0] = 0x0;
- n.mac_address[1] = 0x0;
- n.mac_address[2] = 0xde;
- n.mac_address[3] = 0xad;
- n.mac_address[4] = 0xbe;
- n.mac_address[5] = 0xef;
- n.phy_addr = 0x1;
- n.res1 = 0x0;
- n.sub_sid = 0x102;
- n.sub_vid = 0x1106;
- n.pid = 0x3065;
- n.vid = 0x1106;
- n.pmcc = 0x1f;
- n.data_sel = 0x10;
- n.pmu_data_reg = 0x0;
- n.aux_curr = 0x0;
- n.reserved = 0x0;
- n.min_gnt = 0x3;
- n.max_lat = 0x8;
- n.bcr0 = 0x9;
- n.bcr1 = 0xe;
- n.cfg_a = 0x3;
- n.cfg_b = 0x0;
- n.cfg_c = 0x40;
- n.cfg_d = 0x82;
- n.checksum = 0x0;
- rom = &n;
- }
-
- rom_write = (u16 *) rom;
- checksum = 0;
- /* Write all data except checksum and second to last byte. */
- tmp &= 0xff000000; /* Leave reserved bits in. */
- for (i = 0; i < 15; i++) {
- pci_write_config32(dev, 0x58, tmp | (i << 16) | rom_write[i]);
- /* Lame code FIXME */
- checksum += rom_write[i] & 0xff;
- /* checksum %= 256; */
- checksum += (rom_write[i] >> 8) & 0xff;
- /* checksum %= 256; */
- }
-
- checksum += (rom_write[15] & 0xff);
- checksum = ~(checksum & 0xff);
- tmp |= (((checksum & 0xff) << 8) | rom_write[15]);
-
- /* Write last byte and checksum. */
- pci_write_config32(dev, 0x58, (15 << 16) | tmp);
-
- tmp = pci_read_config32(dev, 0x5c);
- pci_write_config32(dev, 0x5c, tmp | 0x01000000); /* Toggle SEEPR. */
-
- /* Yes, this is a mess, but it's the easiest way to do it. */
- /* XXX not so messy, but an explanation of the hack would have been better */
- loops = 0;
- while ((((pci_read_config32(dev, 0x5c) >> 25) & 1) == 0)
- && (loops < LAN_TIMEOUT)) {
- ++loops;
- }
-
- if (loops >= LAN_TIMEOUT) {
- print_err("Timeout - LAN controller didn't accept config\n");
- return 0;
- }
-
- /* We are done, config will be used after PCIRST#. */
- return 1;
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Based on other VIA SB code. */
-
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <console/console.h>
-#include "vt8237r.h"
-#include "chip.h"
-
-/**
- * Cable type detect function, weak so it can be overloaded in mainboard.c
- */
-u32 __attribute__((weak)) vt8237_ide_80pin_detect(struct device *dev)
-{
- struct southbridge_via_vt8237r_config *sb =
- (struct southbridge_via_vt8237r_config *)dev->chip_info;
- u32 res;
- res = sb->ide0_80pin_cable ? VT8237R_IDE0_80PIN_CABLE : 0;
- res |= sb->ide1_80pin_cable ? VT8237R_IDE1_80PIN_CABLE : 0;
- return res;
-}
-
-/**
- * No native mode. Interrupts from unconnected HDDs might occur if
- * IRQ14/15 is used for PCI. Therefore no native mode support.
- */
-static void ide_init(struct device *dev)
-{
- struct southbridge_via_vt8237r_config *sb =
- (struct southbridge_via_vt8237r_config *)dev->chip_info;
-
- u8 enables;
- u32 cablesel;
-
- printk(BIOS_INFO, "%s IDE interface %s\n", "Primary",
- sb->ide0_enable ? "enabled" : "disabled");
- printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary",
- sb->ide1_enable ? "enabled" : "disabled");
- enables = pci_read_config8(dev, IDE_CS) & ~0x3;
- enables |= (sb->ide0_enable << 1) | sb->ide1_enable;
- pci_write_config8(dev, IDE_CS, enables);
- enables = pci_read_config8(dev, IDE_CS);
- printk(BIOS_DEBUG, "Enables in reg 0x40 read back as 0x%x\n", enables);
-
- /* Enable only compatibility mode. */
- enables = pci_read_config8(dev, 0x09);
- enables &= 0xFA;
- pci_write_config8(dev, 0x09, enables);
-
- enables = pci_read_config8(dev, IDE_CONF_II);
- enables &= ~0xc0;
- pci_write_config8(dev, IDE_CONF_II, enables);
- enables = pci_read_config8(dev, IDE_CONF_II);
- printk(BIOS_DEBUG, "Enables in reg 0x42 read back as 0x%x\n", enables);
-
- /* Enable prefetch buffers. */
- enables = pci_read_config8(dev, IDE_CONF_I);
- enables |= 0xf0;
- pci_write_config8(dev, IDE_CONF_I, enables);
-
- /* Flush FIFOs at half. */
- enables = pci_read_config8(dev, IDE_CONF_FIFO);
- enables &= 0xf0;
- enables |= (1 << 2) | (1 << 0);
- pci_write_config8(dev, IDE_CONF_FIFO, enables);
-
- /* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */
- enables = pci_read_config8(dev, IDE_MISC_I);
- enables &= 0xe2;
- enables |= (1 << 4) | (1 << 3);
- pci_write_config8(dev, IDE_MISC_I, enables);
-
- /* Use memory read multiple, Memory-Write-and-Invalidate. */
- enables = pci_read_config8(dev, IDE_MISC_II);
- enables &= 0xEF;
- enables |= (1 << 2) | (1 << 3);
- pci_write_config8(dev, IDE_MISC_II, enables);
-
- /* Force interrupts to use compat mode. */
- pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
- pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
-
- /* Cable guy... */
- cablesel = pci_read_config32(dev, IDE_UDMA);
- cablesel &= ~VT8237R_IDE_CABLESEL_MASK;
- cablesel |= vt8237_ide_80pin_detect(dev);
- pci_write_config32(dev, IDE_UDMA, cablesel);
-
-#if CONFIG_EPIA_VT8237R_INIT
- device_t lpc_dev;
-
- /* Set PATA Output Drive Strength */
- lpc_dev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
- if (lpc_dev)
- pci_write_config8(lpc_dev, 0x7C, 0x20);
-#endif
-}
-
-static const struct device_operations ide_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = ide_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver __pci_driver = {
- .ops = &ide_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_82C586_1,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
- * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* Inspiration from other VIA SB code. */
-
-#include <arch/io.h>
-#include <console/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/mc146818rtc.h>
-#include <arch/ioapic.h>
-#include <cpu/x86/lapic.h>
-#include <pc80/keyboard.h>
-#include <pc80/i8259.h>
-#include <stdlib.h>
-#include "vt8237r.h"
-#include "chip.h"
-
-static void southbridge_init_common(struct device *dev);
-
-#if CONFIG_EPIA_VT8237R_INIT
- /* Interrupts for INT# A B C D */
-static const unsigned char pciIrqs[4] = { 10, 11, 12, 0};
-
- /* Interrupt Assignments for Pins 1 2 3 4 */
-static const unsigned char sataPins[4] = { 'A','B','C','D'};
-static const unsigned char vgaPins[4] = { 'A','B','C','D'};
-static const unsigned char usbPins[4] = { 'A','B','C','D'};
-static const unsigned char enetPins[4] = { 'A','B','C','D'};
-static const unsigned char vt8237Pins[4] = { 'A','B','C','D'};
-static const unsigned char slotPins[4] = { 'C','D','A','B'};
-static const unsigned char riserPins[4] = { 'D','C','B','A'};
-
-static unsigned char *pin_to_irq(const unsigned char *pin)
-{
- static unsigned char Irqs[4];
- int i;
- for (i = 0 ; i < 4 ; i++)
- Irqs[i] = pciIrqs[ pin[i] - 'A' ];
-
- return Irqs;
-}
-#endif
-
-/** Set up PCI IRQ routing, route everything through APIC. */
-static void pci_routing_fixup(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- device_t pdev;
-#endif
-
- /* PCI PNP Interrupt Routing INTE/F - disable */
- pci_write_config8(dev, 0x44, 0x00);
-
- /* PCI PNP Interrupt Routing INTG/H - disable */
- pci_write_config8(dev, 0x45, 0x00);
-
- /* Gate Interrupts until RAM Writes are flushed */
- pci_write_config8(dev, 0x49, 0x20);
-
-#if CONFIG_EPIA_VT8237R_INIT
-
- /* Share INTE-INTH with INTA-INTD as per stock BIOS. */
- pci_write_config8(dev, 0x46, 0x00);
-
- /* setup PCI IRQ routing (For PCI Slot)*/
- pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
- pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
- pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
-
- /* PCI Routing Fixup */
-
- //Setup MiniPCI Slot
- pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
-
- // Via 2 slot riser card 2nd slot
- pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
-
- //Setup USB
- pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
-
- //Setup VT8237R Sound
- pci_assign_irqs(0, 0x11, pin_to_irq(vt8237Pins));
-
- //Setup Ethernet
- pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
-
- //Setup VGA
- pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
-
- /* APIC Routing Fixup */
-
- // Setup SATA
- pdev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT6420_SATA, 0);
- pci_write_config8(pdev, PCI_INTERRUPT_PIN, 0x02);
- pci_assign_irqs(0, 0x0f, pin_to_irq(sataPins));
-
-
- // Setup PATA Override
- pdev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_82C586_1, 0);
- pci_write_config8(pdev, PCI_INTERRUPT_PIN, 0x01);
- pci_write_config8(pdev, PCI_INTERRUPT_LINE, 0xFF);
-
-#else
- /* Route INTE-INTH through registers above, no map to INTA-INTD. */
- pci_write_config8(dev, 0x46, 0x10);
-
- /* PCI Interrupt Polarity */
- pci_write_config8(dev, 0x54, 0x00);
-
- /* PCI INTA# Routing */
- pci_write_config8(dev, 0x55, 0x00);
-
- /* PCI INTB#/C# Routing */
- pci_write_config8(dev, 0x56, 0x00);
-
- /* PCI INTD# Routing */
- pci_write_config8(dev, 0x57, 0x00);
-#endif
-}
-
-
-
-/**
- * Set up the power management capabilities directly into ACPI mode.
- * This avoids having to handle any System Management Interrupts (SMIs).
- */
-
-extern u8 acpi_slp_type;
-
-
-static void setup_pm(device_t dev)
-{
- u16 tmp;
- /* Debounce LID and PWRBTN# Inputs for 16ms. */
- pci_write_config8(dev, 0x80, 0x20);
-
- /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
- pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
-
- /* Set ACPI to 9, must set IRQ 9 override to level! Set PSON gating. */
- pci_write_config8(dev, 0x82, 0x40 | VT8237R_ACPI_IRQ);
-
-#if CONFIG_EPIA_VT8237R_INIT
- /* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
- pci_write_config16(dev, 0x84, 0x3052);
-#else
- /* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
- pci_write_config16(dev, 0x84, 0x30b2);
-
-#endif
- /* SMI output level to low, 7.5us throttle clock */
- pci_write_config8(dev, 0x8d, 0x18);
-
- /* GP Timer Control 1s */
- pci_write_config8(dev, 0x93, 0x88);
-
- /*
- * 7 = SMBus clock from RTC 32.768KHz
- * 5 = Internal PLL reset from susp disabled
- * 2 = GPO2 is SUSA#
- */
- pci_write_config8(dev, 0x94, 0xa0);
-
- /*
- * 7 = stp to sust delay 1msec
- * 6 = SUSST# Deasserted Before PWRGD for STD
- * 5 = Keyboard/Mouse Swap
- * 4 = PWRGOOD reset on VT8237A/S
- * 3 = GPO26/GPO27 is GPO
- * 2 = Disable Alert on Lan
- * 1 = SUSCLK/GPO4
- * 0 = USB Wakeup
- */
-
-#if CONFIG_EPIA_VT8237R_INIT
- pci_write_config8(dev, 0x95, 0xc2);
-#else
- pci_write_config8(dev, 0x95, 0xcc);
-#endif
-
- /* Disable GP3 timer. */
- pci_write_config8(dev, 0x98, 0);
-
- /* Enable ACPI accessm RTC signal gated with PSON. */
- pci_write_config8(dev, 0x81, 0x84);
-
- /* Clear status events. */
- outw(0xffff, VT8237R_ACPI_IO_BASE + 0x00);
- outw(0xffff, VT8237R_ACPI_IO_BASE + 0x20);
- outw(0xffff, VT8237R_ACPI_IO_BASE + 0x28);
- outl(0xffffffff, VT8237R_ACPI_IO_BASE + 0x30);
-
- /* Disable SCI on GPIO. */
- outw(0x0, VT8237R_ACPI_IO_BASE + 0x22);
-
- /* Disable SMI on GPIO. */
- outw(0x0, VT8237R_ACPI_IO_BASE + 0x24);
-
- /* Disable all global enable SMIs. */
- outw(0x0, VT8237R_ACPI_IO_BASE + 0x2a);
-
- /* All SMI off, both IDE buses ON, PSON rising edge. */
- outw(0x0, VT8237R_ACPI_IO_BASE + 0x2c);
-
- /* Primary activity SMI disable. */
- outl(0x0, VT8237R_ACPI_IO_BASE + 0x34);
-
- /* GP timer reload on none. */
- outl(0x0, VT8237R_ACPI_IO_BASE + 0x38);
-
- /* Disable extended IO traps. */
- outb(0x0, VT8237R_ACPI_IO_BASE + 0x42);
-
- /* SCI is generated for RTC/pwrBtn/slpBtn. */
- tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
-#if CONFIG_HAVE_ACPI_RESUME == 1
- acpi_slp_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
- printk(BIOS_DEBUG, "SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
-#endif
- /* clear sleep */
- tmp &= ~(7 << 10);
- tmp |= 1;
- outw(tmp, VT8237R_ACPI_IO_BASE + 0x04);
-}
-
-static void vt8237r_init(struct device *dev)
-{
- u8 enables;
-
-#if CONFIG_EPIA_VT8237R_INIT
- printk(BIOS_SPEW, "Entering vt8237r_init, for EPIA.\n");
- /*
- * TODO: Looks like stock BIOS can do this but causes a hang
- * Enable SATA LED, disable special CPU Frequency Change -
- * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
- * Setup to match EPIA default
- * PCS0# on Pin U1
- */
- enables = pci_read_config8(dev, 0xe5);
- enables |= 0x23;
- pci_write_config8(dev, 0xe5, enables);
-
- /*
- * Enable Flash Write Access.
- * Note EPIA-N Does not use REQ5 or PCISTP#(Hang)
- */
- enables = pci_read_config8(dev, 0xe4);
- enables |= 0x2B;
- pci_write_config8(dev, 0xe4, enables);
-
- /* Enables Extra RTC Ports */
- enables = pci_read_config8(dev, 0x4E);
- enables |= 0x80;
- pci_write_config8(dev, 0x4E, enables);
-
-#else
- printk(BIOS_SPEW, "Entering vt8237r_init.\n");
- /*
- * Enable SATA LED, disable special CPU Frequency Change -
- * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
- */
- pci_write_config8(dev, 0xe5, 0x09);
-
- /* REQ5 as PCI request input - should be together with INTE-INTH. */
- pci_write_config8(dev, 0xe4, 0x4);
-#endif
-
- /* Set bit 3 of 0x4f (use INIT# as CPU reset). */
- enables = pci_read_config8(dev, 0x4f);
- enables |= 0x08;
- pci_write_config8(dev, 0x4f, enables);
-
-#if CONFIG_EPIA_VT8237R_INIT
- /*
- * Set Read Pass Write Control Enable
- */
- pci_write_config8(dev, 0x48, 0x0c);
-#else
- /*
- * Set Read Pass Write Control Enable
- * (force A2 from APIC FSB to low).
- */
- pci_write_config8(dev, 0x48, 0x8c);
-#endif
-
- southbridge_init_common(dev);
-
-#if !CONFIG_EPIA_VT8237R_INIT
- /* FIXME: Intel needs more bit set for C2/C3. */
-
- /*
- * Allow SLP# signal to assert LDTSTOP_L.
- * Will work for C3 and for FID/VID change.
- */
- outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
-#endif
-
- printk(BIOS_SPEW, "Leaving %s.\n", __func__);
-}
-
-static void vt8237a_init(struct device *dev)
-{
- /*
- * FIXME: This is based on vt8237s_init() and the values the AMI
- * BIOS on my M2V wrote to these registers (by loking
- * at lspci -nxxx output).
- * Works for me.
- */
- u32 tmp;
-
- /* Set bit 3 of 0x4f (use INIT# as CPU reset). */
- tmp = pci_read_config8(dev, 0x4f);
- tmp |= 0x08;
- pci_write_config8(dev, 0x4f, tmp);
-
- /*
- * bit2: REQ5 as PCI request input - should be together with INTE-INTH.
- * bit5: usb power control lines as gpio
- */
- pci_write_config8(dev, 0xe4, 0x24);
- /*
- * Enable APIC wakeup from INTH
- * Enable SATA LED, disable special CPU Frequency Change -
- * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
- */
- pci_write_config8(dev, 0xe5, 0x69);
-
- /* Reduce further the STPCLK/LDTSTP signal to 5us. */
- pci_write_config8(dev, 0xec, 0x4);
-
- /* Host Bus Power Management Control, maybe not needed */
- pci_write_config8(dev, 0x8c, 0x5);
-
- /* Enable HPET at VT8237R_HPET_ADDR. */
- pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
-
- southbridge_init_common(dev);
-
- /* Share INTE-INTH with INTA-INTD for simplicity */
- pci_write_config8(dev, 0x46, 0x00);
-
- /* FIXME: Intel needs more bit set for C2/C3. */
-
- /*
- * Allow SLP# signal to assert LDTSTOP_L.
- * Will work for C3 and for FID/VID change.
- */
- outb(0x1, VT8237R_ACPI_IO_BASE + 0x11);
-
- dump_south(dev);
-}
-
-static void vt8237s_init(struct device *dev)
-{
- u32 tmp;
-
- /* Put SPI base VT8237S_SPI_MEM_BASE. */
- tmp = pci_read_config32(dev, 0xbc);
- pci_write_config32(dev, 0xbc,
- (VT8237S_SPI_MEM_BASE >> 8) | (tmp & 0xFF000000));
-
- /*
- * REQ5 as PCI request input - should be together with INTE-INTH.
- */
- pci_write_config8(dev, 0xe4, 0x04);
-
- /* Reduce further the STPCLK/LDTSTP signal to 5us. */
- pci_write_config8(dev, 0xec, 0x4);
-
- /* Host Bus Power Management Control, maybe not needed */
- pci_write_config8(dev, 0x8c, 0x5);
-
- /* Enable HPET at VT8237R_HPET_ADDR., does not work correctly on R. */
- pci_write_config32(dev, 0x68, (VT8237R_HPET_ADDR | 0x80));
-
- southbridge_init_common(dev);
-
- /* FIXME: Intel needs more bit set for C2/C3. */
-
- /*
- * Allow SLP# signal to assert LDTSTOP_L.
- * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2.
- */
- outb(0xff, VT8237R_ACPI_IO_BASE + 0x50);
-
- dump_south(dev);
-}
-
-static void vt8237_common_init(struct device *dev)
-{
- u8 enables, byte;
-
- /* Enable addr/data stepping. */
- byte = pci_read_config8(dev, PCI_COMMAND);
- byte |= PCI_COMMAND_WAIT;
- pci_write_config8(dev, PCI_COMMAND, byte);
-
-/* EPIA-N(L) Uses CN400 for BIOS Access */
-#if !CONFIG_EPIA_VT8237R_INIT
- /* Enable the internal I/O decode. */
- enables = pci_read_config8(dev, 0x6C);
- enables |= 0x80;
- pci_write_config8(dev, 0x6C, enables);
-
- /*
- * ROM decode
- * bit range
- * 7 000E0000h-000EFFFFh
- * 6 FFF00000h-FFF7FFFFh
- * 5 FFE80000h-FFEFFFFFh
- * 4 FFE00000h-FFE7FFFFh
- * 3 FFD80000h-FFDFFFFFh
- * 2 FFD00000h-FFD7FFFFh
- * 1 FFC80000h-FFCFFFFFh
- * 0 FFC00000h-FFC7FFFFh
- * So 0x7f here sets ROM decode to FFC00000-FFFFFFFF or 4Mbyte.
- */
- pci_write_config8(dev, 0x41, 0x7f);
-#endif
-
- /*
- * Set bit 6 of 0x40 (I/O recovery time).
- * IMPORTANT FIX - EISA = ECLR reg at 0x4d0! Decoding must be on so
- * that PCI interrupts can be properly marked as level triggered.
- */
- enables = pci_read_config8(dev, 0x40);
- enables |= 0x44;
- pci_write_config8(dev, 0x40, enables);
-
- /* Line buffer control */
- enables = pci_read_config8(dev, 0x42);
- enables |= 0xf8;
- pci_write_config8(dev, 0x42, enables);
-
- /* Delay transaction control */
- pci_write_config8(dev, 0x43, 0xb);
-
-#if CONFIG_EPIA_VT8237R_INIT
- /* I/O recovery time, default IDE routing */
- pci_write_config8(dev, 0x4c, 0x04);
-
- /* ROM memory cycles go to LPC. */
- pci_write_config8(dev, 0x59, 0x80);
-
- /*
- * Bit | Meaning
- * -------------
- * 3 | Bypass APIC De-Assert Message (1=Enable)
- * 1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI"
- * | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch
- * 0 | Dynamic Clock Gating Main Switch (1=Enable)
- */
- pci_write_config8(dev, 0x5b, 0x9);
-
- /* Set 0x58 to 0x42 APIC On and RTC Write Protect.*/
- pci_write_config8(dev, 0x58, 0x42);
-
- /* Enable serial IRQ, 6PCI clocks. */
- pci_write_config8(dev, 0x52, 0x9);
-#else
- /* I/O recovery time, default IDE routing */
- pci_write_config8(dev, 0x4c, 0x44);
-
- /* ROM memory cycles go to LPC. */
- pci_write_config8(dev, 0x59, 0x80);
-
- /*
- * Bit | Meaning
- * -------------
- * 3 | Bypass APIC De-Assert Message (1=Enable)
- * 1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI"
- * | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch
- * 0 | Dynamic Clock Gating Main Switch (1=Enable)
- */
- pci_write_config8(dev, 0x5b, 0xb);
-
- /* Set 0x58 to 0x43 APIC and RTC. */
- pci_write_config8(dev, 0x58, 0x43);
-
- /* Enable serial IRQ, 6PCI clocks. */
- pci_write_config8(dev, 0x52, 0x9);
-
-#endif
-
- /* Power management setup */
- setup_pm(dev);
-
- /* Start the RTC. */
- rtc_init(0);
-}
-
-static void vt8237r_read_resources(device_t dev)
-{
- struct resource *res;
-
- pci_dev_read_resources(dev);
-
- /* Fixed ACPI Base IO Base*/
- res = new_resource(dev, 0x88);
- res->base = VT8237R_ACPI_IO_BASE;
- res->size = 128;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- /* Fixed EISA ECLR I/O Regs */
- res = new_resource(dev, 3);
- res->base = 0x4d0;
- res->size = 2;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- /* Fixed System Management Bus I/O Resource */
- res = new_resource(dev, 0xD0);
- res->base = VT8237R_SMBUS_IO_BASE;
- res->size = 16;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- /* Fixed APIC resource */
- res = new_resource(dev, 0x44);
- res->base = IO_APIC_ADDR;
- res->size = 256;
- res->limit = 0xffffffffUL;
- res->align = 8;
- res->gran = 8;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- /* Fixed flashrom resource */
- res = new_resource(dev, 4);
- res->base = 0xff000000UL;
- res->size = 0x01000000UL; /* 16MB */
- res->limit = 0xffffffffUL;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_RESERVE |
- IORESOURCE_STORED | IORESOURCE_ASSIGNED;
-
- res = new_resource(dev, 1);
- res->base = 0x0UL;
- res->size = 0x1000UL;
- res->limit = 0xffffUL;
- res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
-}
-
-static void init_keyboard(struct device *dev)
-{
- u8 regval = pci_read_config8(dev, 0x51);
- if (regval & 0x1)
- pc_keyboard_init(0);
-}
-
-static void southbridge_init_common(struct device *dev)
-{
- vt8237_common_init(dev);
- pci_routing_fixup(dev);
- setup_ioapic(IO_APIC_ADDR, VT8237R_APIC_ID);
- setup_i8259();
- init_keyboard(dev);
-}
-
-static const struct device_operations vt8237r_lpc_ops_s = {
- .read_resources = vt8237r_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vt8237s_init,
- .scan_bus = scan_static_bus,
-};
-
-static const struct device_operations vt8237r_lpc_ops_r = {
- .read_resources = vt8237r_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vt8237r_init,
- .scan_bus = scan_static_bus,
-};
-
-static const struct device_operations vt8237r_lpc_ops_a = {
- .read_resources = vt8237r_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = vt8237a_init,
- .scan_bus = scan_static_bus,
-};
-
-static const struct pci_driver lpc_driver_r __pci_driver = {
- .ops = &vt8237r_lpc_ops_r,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237R_LPC,
-};
-
-static const struct pci_driver lpc_driver_a __pci_driver = {
- .ops = &vt8237r_lpc_ops_a,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237A_LPC,
-};
-
-static const struct pci_driver lpc_driver_s __pci_driver = {
- .ops = &vt8237r_lpc_ops_s,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237S_LPC,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
- * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "vt8237r.h"
-
-
-static void vt8237_eth_read_resources(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- struct resource *res;
-
- /* Fix the I/O Resources of the USB2.0 Interface */
- res = new_resource(dev, PCI_BASE_ADDRESS_0);
- res->base = 0xF6001000ULL;
- res->size = 256;
- res->align = 12;
- res->gran = 8;
- res->limit = res->base + res->size - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
- IORESOURCE_ASSIGNED;
-#else
- pci_dev_read_resources(dev);
-#endif
- return;
-}
-
-
-static const struct device_operations vt8237_eth_ops = {
- .read_resources = vt8237_eth_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = 0,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver vt8237r_driver_eth __pci_driver = {
- .ops = &vt8237_eth_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_8233_7,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007 Nikolay Petukhov <nikolay.petukhov@gmail.com>
- * Copyright (C) 2010 Tobias Diedrich <ranma+coreboot@tdiedrich.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <arch/pirq_routing.h>
-#include <console/console.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include <pc80/i8259.h>
-
-#if (CONFIG_PIRQ_ROUTE==1 && CONFIG_GENERATE_PIRQ_TABLE==1)
-void pirq_assign_irqs(const unsigned char route[4])
-{
- device_t pdev;
-
- pdev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237R_LPC, 0);
- if (!pdev)
- pdev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237S_LPC, 0);
- if (!pdev)
- pdev = dev_find_device(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_VT8237A_LPC, 0);
- if (!pdev)
- return;
-
- pci_write_config8(pdev, 0x55, route[0] << 4);
- pci_write_config8(pdev, 0x56, (route[2] << 4) | route[1]);
- pci_write_config8(pdev, 0x57, route[3] << 4);
-
- /* Enable INT[E-H] mapped to INT[A-D] for simplicity */
- pci_write_config8(pdev, 0x46, 0x00);
-}
-#endif
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-
-#define SATA_MISC_CTRL 0x45
-
-static void sata_i_init(struct device *dev)
-{
- u8 reg;
-
- printk(BIOS_DEBUG, "Configuring VIA SATA controller\n");
-
- /* Class IDE Disk */
- reg = pci_read_config8(dev, SATA_MISC_CTRL);
- reg &= 0x7f; /* Sub Class Write Protect off */
- pci_write_config8(dev, SATA_MISC_CTRL, reg);
-
- /* Change the device class to SATA from RAID. */
- pci_write_config8(dev, PCI_CLASS_DEVICE, 0x1);
- reg |= 0x80; /* Sub Class Write Protect on */
- pci_write_config8(dev, SATA_MISC_CTRL, reg);
-
- return;
-}
-
-static void sata_ii_init(struct device *dev)
-{
- u8 reg;
-
- sata_i_init(dev);
-
- /*
- * Analog black magic, you may or may not need to adjust 0x60-0x6f,
- * depends on PCB.
- */
-
- /*
- * Analog PHY - gen1
- * CDR bandwidth [6:5] = 3
- * Squelch Window Select [4:3] = 1
- * CDR Charge Pump [2:0] = 1
- */
-
- pci_write_config8(dev, 0x64, 0x49);
-
- /* Adjust driver current source value to 9. */
- reg = pci_read_config8(dev, 0x65);
- reg &= 0xf0;
- reg |= 0x9;
- pci_write_config8(dev, 0x65, reg);
-
- /* Set all manual termination 50ohm bits [2:0] and enable [4]. */
- reg = pci_read_config8(dev, 0x6a);
- reg |= 0xf;
- pci_write_config8(dev, 0x6a, reg);
-
- /*
- * Analog PHY - gen2
- * CDR bandwidth [5:4] = 2
- * Pre / De-emphasis Level [7:6] controls bits [3:2], rest in 0x6e
- * CDR Charge Pump [2:0] = 1
- */
-
- reg = pci_read_config8(dev, 0x6f);
- reg &= 0x08;
- reg |= 0x61;
- pci_write_config8(dev, 0x6f, reg);
-
- /* Check if staggered spinup is supported. */
- reg = pci_read_config8(dev, 0x83);
- if ((reg & 0x8) == 0) {
- /* Start OOB sequence on both drives. */
- reg |= 0x30;
- pci_write_config8(dev, 0x83, reg);
- }
-}
-
-static const struct device_operations sata_i_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_i_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct device_operations sata_ii_ops = {
- .read_resources = pci_dev_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = sata_ii_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver northbridge_driver_ii __pci_driver = {
- .ops = &sata_ii_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237_SATA,
-};
-
-static const struct pci_driver northbridge_driver_i_a __pci_driver = {
- .ops = &sata_i_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237A_SATA,
-};
-
-static const struct pci_driver northbridge_driver_i __pci_driver = {
- .ops = &sata_i_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT6420_SATA,
-};
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
- * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * 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/console.h>
-#include <device/device.h>
-#include <device/pci.h>
-#include <device/pci_ids.h>
-#include "vt8237r.h"
-
-#if CONFIG_EPIA_VT8237R_INIT
-u32 usb_io_addr[4] = {0xcc00, 0xd000, 0xd400, 0xd800};
-#endif
-
-static void usb_i_init(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- u8 reg8;
-
- printk(BIOS_DEBUG, "Entering %s\n", __func__);
-
- reg8 = pci_read_config8(dev, 0x04);
-
- printk(BIOS_SPEW, "%s Read %02X from PCI Command Reg\n", dev_path(dev), reg8);
-
- reg8 = reg8 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config8(dev, 0x04, reg8);
-
- printk(BIOS_SPEW, "%s Wrote %02X to PCI Command Reg\n", dev_path(dev), reg8);
-
- /* Set Cache Line Size and Latency Timer */
- pci_write_config8(dev, 0x0c, 0x08);
- pci_write_config8(dev, 0x0d, 0x20);
-
- /* Enable Sub Device ID Back Door and set Generic */
- reg8 = pci_read_config8(dev, 0x42);
- reg8 |= 0x10;
- pci_write_config8(dev, 0x42, reg8);
- pci_write_config16(dev, 0x2e, 0xAA07);
- reg8 &= ~0x10;
- pci_write_config8(dev, 0x42, reg8);
-
-
- pci_write_config8(dev, 0x41, 0x12);
-
- pci_write_config8(dev, 0x49, 0x0B);
-
- /* Clear PCI Status */
- pci_write_config16(dev, 0x06, 0x7A10);
-#endif
- return;
-}
-
-static void vt8237_usb_i_read_resources(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- struct resource *res;
- u8 function = (u8) dev->path.pci.devfn & 0x7;
-
- printk(BIOS_SPEW, "VT8237R Fixing USB 1.1 fn %d I/O resource = 0x%04X\n", function, usb_io_addr[function]);
-
- /* Fix the I/O Resources of the USB1.1 Interfaces */
- /* Auto PCI probe seems to size the resources */
- /* Incorrectly */
- res = new_resource(dev, PCI_BASE_ADDRESS_4);
- res->base = usb_io_addr[function];
- res->size = 256;
- res->limit = 0xffffUL;
- res->align = 10;
- res->gran = 8;
- res->flags = IORESOURCE_IO | IORESOURCE_FIXED |
- IORESOURCE_ASSIGNED;
-#else
- pci_dev_read_resources(dev);
-#endif
- return;
-}
-
-static void usb_ii_init(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- u8 reg8;
-
- printk(BIOS_DEBUG, "Entering %s\n", __func__);
-
- /* Set memory Write and Invalidate */
- reg8 = pci_read_config8(dev, 0x04);
- reg8 |= 0x10;
- pci_write_config8(dev, 0x04, reg8);
-
- /* Set Cache line Size and Latency Timer */
- pci_write_config8(dev, 0x0c, 0x08);
- pci_write_config8(dev, 0x0d, 0x20);
-
- /* Clear PCI Status */
- pci_write_config16(dev, 0x06, 0x7A10);
-#endif
-
-}
-
-static void vt8237_usb_ii_read_resources(struct device *dev)
-{
-#if CONFIG_EPIA_VT8237R_INIT
- struct resource *res;
-
- /* Fix the I/O Resources of the USB2.0 Interface */
- res = new_resource(dev, PCI_BASE_ADDRESS_0);
- res->base = 0xF6000000ULL;
- res->size = 256;
- res->align = 12;
- res->gran = 8;
- res->limit = res->base + res->size - 1;
- res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
- IORESOURCE_ASSIGNED;
-#else
- pci_dev_read_resources(dev);
-#endif
- return;
-}
-
-static const struct device_operations usb_i_ops = {
- .read_resources = vt8237_usb_i_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_i_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct device_operations usb_ii_ops = {
- .read_resources = vt8237_usb_ii_read_resources,
- .set_resources = pci_dev_set_resources,
- .enable_resources = pci_dev_enable_resources,
- .init = usb_ii_init,
- .enable = 0,
- .ops_pci = 0,
-};
-
-static const struct pci_driver vt8237r_driver_usbii __pci_driver = {
- .ops = &usb_ii_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237R_EHCI,
-};
-
-static const struct pci_driver vt8237r_driver_usbi __pci_driver = {
- .ops = &usb_i_ops,
- .vendor = PCI_VENDOR_ID_VIA,
- .device = PCI_DEVICE_ID_VIA_VT8237R_UHCI,
-};
--- /dev/null
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006-2007 Uwe Hermann <uwe@hermann-uwe.de>
+ * Copyright (C) 2007 Corey Osgood <corey_osgood@verizon.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This has been ported to the VIA VT82C686(A/B) from the SMSC FDC37M60x
+ * by Corey Osgood. See vt82c686.h for more information. */
+
+#include <arch/romcc_io.h>
+#include <device/pci_ids.h>
+#include "vt82c686.h"
+
+#define SIO_INDEX 0x3f0
+#define SIO_DATA 0x3f1
+
+/**
+ * Configure the chip by writing the byte 'value' into the register
+ * specified by 'index'.
+ *
+ * @param index The index of the register to modify.
+ * @param value The value to write into the register.
+ */
+static void vt82c686_sio_write(uint8_t index, uint8_t value)
+{
+ outb(index, SIO_INDEX);
+ outb(value, SIO_DATA);
+}
+
+/**
+ * Enable the serial port(s) of the VT82C686(A/B) Super I/O chip.
+ *
+ * @param dev TODO
+ * @param iobase TODO
+ */
+static void vt82c686_enable_serial(device_t dev, unsigned iobase)
+{
+ uint8_t reg;
+ device_t sbdev;
+
+ /* TODO: Use info from 'dev' and 'iobase'. */
+ /* TODO: Only enable one serial port (depending on config) or both? */
+
+ /* (1) Enter configuration mode (set Function 0 Rx85[1] = 1). */
+
+ /* Find the southbridge. Die upon error. */
+ sbdev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_82C686), 0);
+ // sbdev = PCI_DEV(0, 7, 0);
+ if (sbdev == PCI_DEV_INVALID) {
+ /* Serial output is not yet working at this point, but
+ * die() emits the POST code 0xff and halts the CPU, too. */
+ die("Southbridge not found.\n");
+ }
+
+ /* Enable Super-I/O (bit 0) and Super-I/O Configuration (bit 1). */
+ reg = pci_read_config8(sbdev, 0x85);
+ pci_write_config8(sbdev, 0x85, reg | 0x3); /* Set bits 0 and 1. */
+
+ /* (2) Configure the chip. */
+
+ /* Enable serial port 1 (set bit 2) and 2 (set bit 3). */
+ vt82c686_sio_write(VT82C686_FS, 0xf);
+
+ // vt82c686_sio_write(VT82C686_POWER, 0x00); /* No powerdown */
+ // vt82c686_sio_write(VT82C686_SP_CTRL, 0x00); /* Normal operation */
+ vt82c686_sio_write(VT82C686_SP1, 0xfe); /* SP1: 0x3f8 */
+ vt82c686_sio_write(VT82C686_SP2, 0xbe); /* SP2: 0x2f8 */
+
+ /* Enable high speed on serial port 1 (set bit 6) and 2 (set bit 7). */
+ vt82c686_sio_write(VT82C686_SP_CFG, 0xc0);
+
+ /* (3) Exit configuration mode (set Function 0 Rx85[1] = 0). */
+ reg = pci_read_config8(sbdev, 0x85);
+ pci_write_config8(sbdev, 0x85, reg & 0xfd); /* Clear bit 1. */
+}
+
+++ /dev/null
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2006-2007 Uwe Hermann <uwe@hermann-uwe.de>
- * Copyright (C) 2007 Corey Osgood <corey_osgood@verizon.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/* This has been ported to the VIA VT82C686(A/B) from the SMSC FDC37M60x
- * by Corey Osgood. See vt82c686.h for more information. */
-
-#include <arch/romcc_io.h>
-#include <device/pci_ids.h>
-#include "vt82c686.h"
-
-#define SIO_INDEX 0x3f0
-#define SIO_DATA 0x3f1
-
-/**
- * Configure the chip by writing the byte 'value' into the register
- * specified by 'index'.
- *
- * @param index The index of the register to modify.
- * @param value The value to write into the register.
- */
-static void vt82c686_sio_write(uint8_t index, uint8_t value)
-{
- outb(index, SIO_INDEX);
- outb(value, SIO_DATA);
-}
-
-/**
- * Enable the serial port(s) of the VT82C686(A/B) Super I/O chip.
- *
- * @param dev TODO
- * @param iobase TODO
- */
-static void vt82c686_enable_serial(device_t dev, unsigned iobase)
-{
- uint8_t reg;
- device_t sbdev;
-
- /* TODO: Use info from 'dev' and 'iobase'. */
- /* TODO: Only enable one serial port (depending on config) or both? */
-
- /* (1) Enter configuration mode (set Function 0 Rx85[1] = 1). */
-
- /* Find the southbridge. Die upon error. */
- sbdev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
- PCI_DEVICE_ID_VIA_82C686), 0);
- // sbdev = PCI_DEV(0, 7, 0);
- if (sbdev == PCI_DEV_INVALID) {
- /* Serial output is not yet working at this point, but
- * die() emits the POST code 0xff and halts the CPU, too. */
- die("Southbridge not found.\n");
- }
-
- /* Enable Super-I/O (bit 0) and Super-I/O Configuration (bit 1). */
- reg = pci_read_config8(sbdev, 0x85);
- pci_write_config8(sbdev, 0x85, reg | 0x3); /* Set bits 0 and 1. */
-
- /* (2) Configure the chip. */
-
- /* Enable serial port 1 (set bit 2) and 2 (set bit 3). */
- vt82c686_sio_write(VT82C686_FS, 0xf);
-
- // vt82c686_sio_write(VT82C686_POWER, 0x00); /* No powerdown */
- // vt82c686_sio_write(VT82C686_SP_CTRL, 0x00); /* Normal operation */
- vt82c686_sio_write(VT82C686_SP1, 0xfe); /* SP1: 0x3f8 */
- vt82c686_sio_write(VT82C686_SP2, 0xbe); /* SP2: 0x2f8 */
-
- /* Enable high speed on serial port 1 (set bit 6) and 2 (set bit 7). */
- vt82c686_sio_write(VT82C686_SP_CFG, 0xc0);
-
- /* (3) Exit configuration mode (set Function 0 Rx85[1] = 0). */
- reg = pci_read_config8(sbdev, 0x85);
- pci_write_config8(sbdev, 0x85, reg & 0xfd); /* Clear bit 1. */
-}
-