From 836ae29ee325b1e3d28ff59468cc50913b1e24ce Mon Sep 17 00:00:00 2001 From: stepan Date: Wed, 8 Dec 2010 05:42:47 +0000 Subject: first round name simplification. drop the _ prefix. the prefix was introduced in the early v2 tree many years ago because our old build system "newconfig" could not handle two files with the same name in different paths like /path/to/usb.c and /another/path/to/usb.c correctly. Only one of the files would end up being compiled into the final image. Since Kconfig (actually since shortly before we switched to Kconfig) we don't suffer from that problem anymore. So we could drop the sb700_ prefix from all those filenames (or, the _ prefix in general) - makes it easier to fork off a new chipset - makes it easier to diff against other chipsets - storing redundant information in filenames seems wrong Signed-off-by: Acked-by: Patrick Georgi Acked-by: Peter Stuge git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6149 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/amd/amd8111/Makefile.inc | 20 +- src/southbridge/amd/amd8111/ac97.c | 52 + src/southbridge/amd/amd8111/acpi.c | 220 ++++ src/southbridge/amd/amd8111/amd8111_ac97.c | 52 - src/southbridge/amd/amd8111/amd8111_acpi.c | 220 ---- src/southbridge/amd/amd8111/amd8111_early_ctrl.c | 83 -- src/southbridge/amd/amd8111/amd8111_early_smbus.c | 48 - src/southbridge/amd/amd8111/amd8111_enable_rom.c | 42 - src/southbridge/amd/amd8111/amd8111_ide.c | 66 - src/southbridge/amd/amd8111/amd8111_lpc.c | 133 -- src/southbridge/amd/amd8111/amd8111_nic.c | 90 -- src/southbridge/amd/amd8111/amd8111_pci.c | 68 - src/southbridge/amd/amd8111/amd8111_reset.c | 76 -- src/southbridge/amd/amd8111/amd8111_smbus.c | 41 - src/southbridge/amd/amd8111/amd8111_usb.c | 37 - src/southbridge/amd/amd8111/amd8111_usb2.c | 45 - src/southbridge/amd/amd8111/bootblock.c | 2 +- src/southbridge/amd/amd8111/early_ctrl.c | 83 ++ src/southbridge/amd/amd8111/early_smbus.c | 48 + src/southbridge/amd/amd8111/enable_rom.c | 42 + src/southbridge/amd/amd8111/ide.c | 66 + src/southbridge/amd/amd8111/lpc.c | 133 ++ src/southbridge/amd/amd8111/nic.c | 90 ++ src/southbridge/amd/amd8111/pci.c | 68 + src/southbridge/amd/amd8111/reset.c | 76 ++ src/southbridge/amd/amd8111/smbus.c | 41 + src/southbridge/amd/amd8111/usb.c | 37 + src/southbridge/amd/amd8111/usb2.c | 45 + .../amd/amd8131-disable/amd8131_bridge.c | 116 -- src/southbridge/amd/amd8131-disable/bridge.c | 116 ++ src/southbridge/amd/amd8131/Makefile.inc | 2 +- src/southbridge/amd/amd8131/amd8131_bridge.c | 432 ------- src/southbridge/amd/amd8131/bridge.c | 432 +++++++ src/southbridge/amd/amd8132/Makefile.inc | 2 +- src/southbridge/amd/amd8132/amd8132_bridge.c | 433 ------- src/southbridge/amd/amd8132/bridge.c | 433 +++++++ src/southbridge/amd/amd8151/Makefile.inc | 2 +- src/southbridge/amd/amd8151/agp3.c | 90 ++ src/southbridge/amd/amd8151/amd8151_agp3.c | 90 -- src/southbridge/amd/cs5530/Makefile.inc | 8 +- src/southbridge/amd/cs5530/cs5530_enable_rom.c | 47 - src/southbridge/amd/cs5530/cs5530_ide.c | 78 -- src/southbridge/amd/cs5530/cs5530_isa.c | 64 - src/southbridge/amd/cs5530/cs5530_pirq.c | 39 - src/southbridge/amd/cs5530/cs5530_vga.c | 495 -------- src/southbridge/amd/cs5530/enable_rom.c | 47 + src/southbridge/amd/cs5530/ide.c | 78 ++ src/southbridge/amd/cs5530/isa.c | 64 + src/southbridge/amd/cs5530/pirq.c | 39 + src/southbridge/amd/cs5530/vga.c | 495 ++++++++ src/southbridge/amd/cs5535/Makefile.inc | 4 +- src/southbridge/amd/cs5535/cs5535_early_setup.c | 149 --- src/southbridge/amd/cs5535/cs5535_early_smbus.c | 22 - src/southbridge/amd/cs5535/cs5535_ide.c | 30 - src/southbridge/amd/cs5535/cs5535_smbus.h | 46 - src/southbridge/amd/cs5535/early_setup.c | 149 +++ src/southbridge/amd/cs5535/early_smbus.c | 22 + src/southbridge/amd/cs5535/ide.c | 30 + src/southbridge/amd/cs5535/smbus.h | 46 + src/southbridge/amd/cs5536/Makefile.inc | 4 +- src/southbridge/amd/cs5536/cs5536_early_setup.c | 275 ---- src/southbridge/amd/cs5536/cs5536_early_smbus.c | 213 ---- src/southbridge/amd/cs5536/cs5536_ide.c | 61 - src/southbridge/amd/cs5536/cs5536_pirq.c | 39 - src/southbridge/amd/cs5536/cs5536_smbus2.h | 317 ----- src/southbridge/amd/cs5536/early_setup.c | 275 ++++ src/southbridge/amd/cs5536/early_smbus.c | 213 ++++ src/southbridge/amd/cs5536/ide.c | 61 + src/southbridge/amd/cs5536/pirq.c | 39 + src/southbridge/amd/cs5536/smbus2.h | 317 +++++ src/southbridge/amd/rs690/Makefile.inc | 8 +- src/southbridge/amd/rs690/cmn.c | 324 +++++ src/southbridge/amd/rs690/early_setup.c | 484 +++++++ src/southbridge/amd/rs690/gfx.c | 625 +++++++++ src/southbridge/amd/rs690/ht.c | 90 ++ src/southbridge/amd/rs690/pcie.c | 401 ++++++ src/southbridge/amd/rs690/rs690_cmn.c | 324 ----- src/southbridge/amd/rs690/rs690_early_setup.c | 484 ------- src/southbridge/amd/rs690/rs690_gfx.c | 625 --------- src/southbridge/amd/rs690/rs690_ht.c | 90 -- src/southbridge/amd/rs690/rs690_pcie.c | 401 ------ src/southbridge/amd/rs780/Makefile.inc | 8 +- src/southbridge/amd/rs780/cmn.c | 403 ++++++ src/southbridge/amd/rs780/early_setup.c | 675 ++++++++++ src/southbridge/amd/rs780/gfx.c | 1340 ++++++++++++++++++++ src/southbridge/amd/rs780/ht.c | 90 ++ src/southbridge/amd/rs780/pcie.c | 392 ++++++ src/southbridge/amd/rs780/rev.h | 27 + src/southbridge/amd/rs780/rs780.h | 2 +- src/southbridge/amd/rs780/rs780_cmn.c | 403 ------ src/southbridge/amd/rs780/rs780_early_setup.c | 675 ---------- src/southbridge/amd/rs780/rs780_gfx.c | 1340 -------------------- src/southbridge/amd/rs780/rs780_ht.c | 90 -- src/southbridge/amd/rs780/rs780_pcie.c | 392 ------ src/southbridge/amd/rs780/rs780_rev.h | 27 - src/southbridge/amd/sb600/Makefile.inc | 20 +- src/southbridge/amd/sb600/ac97.c | 61 + src/southbridge/amd/sb600/bootblock.c | 2 +- src/southbridge/amd/sb600/early_setup.c | 660 ++++++++++ src/southbridge/amd/sb600/enable_rom.c | 65 + src/southbridge/amd/sb600/enable_usbdebug.c | 45 + src/southbridge/amd/sb600/hda.c | 331 +++++ src/southbridge/amd/sb600/ide.c | 72 ++ src/southbridge/amd/sb600/lpc.c | 225 ++++ src/southbridge/amd/sb600/pci.c | 142 +++ src/southbridge/amd/sb600/reset.c | 33 + src/southbridge/amd/sb600/sata.c | 265 ++++ src/southbridge/amd/sb600/sb600_ac97.c | 61 - src/southbridge/amd/sb600/sb600_early_setup.c | 660 ---------- src/southbridge/amd/sb600/sb600_enable_rom.c | 65 - src/southbridge/amd/sb600/sb600_enable_usbdebug.c | 45 - src/southbridge/amd/sb600/sb600_hda.c | 331 ----- src/southbridge/amd/sb600/sb600_ide.c | 72 -- src/southbridge/amd/sb600/sb600_lpc.c | 225 ---- src/southbridge/amd/sb600/sb600_pci.c | 142 --- src/southbridge/amd/sb600/sb600_reset.c | 33 - src/southbridge/amd/sb600/sb600_sata.c | 265 ---- src/southbridge/amd/sb600/sb600_sm.c | 375 ------ src/southbridge/amd/sb600/sb600_smbus.c | 214 ---- src/southbridge/amd/sb600/sb600_smbus.h | 64 - src/southbridge/amd/sb600/sb600_usb.c | 203 --- src/southbridge/amd/sb600/sm.c | 375 ++++++ src/southbridge/amd/sb600/smbus.c | 214 ++++ src/southbridge/amd/sb600/smbus.h | 64 + src/southbridge/amd/sb600/usb.c | 203 +++ src/southbridge/amd/sb700/Makefile.inc | 18 +- src/southbridge/amd/sb700/early_setup.c | 619 +++++++++ src/southbridge/amd/sb700/enable_usbdebug.c | 63 + src/southbridge/amd/sb700/hda.c | 232 ++++ src/southbridge/amd/sb700/ide.c | 85 ++ src/southbridge/amd/sb700/lpc.c | 238 ++++ src/southbridge/amd/sb700/pci.c | 128 ++ src/southbridge/amd/sb700/reset.c | 33 + src/southbridge/amd/sb700/sata.c | 294 +++++ src/southbridge/amd/sb700/sb700_early_setup.c | 619 --------- src/southbridge/amd/sb700/sb700_enable_usbdebug.c | 63 - src/southbridge/amd/sb700/sb700_hda.c | 232 ---- src/southbridge/amd/sb700/sb700_ide.c | 85 -- src/southbridge/amd/sb700/sb700_lpc.c | 238 ---- src/southbridge/amd/sb700/sb700_pci.c | 128 -- src/southbridge/amd/sb700/sb700_reset.c | 33 - src/southbridge/amd/sb700/sb700_sata.c | 294 ----- src/southbridge/amd/sb700/sb700_sm.c | 381 ------ src/southbridge/amd/sb700/sb700_smbus.c | 224 ---- src/southbridge/amd/sb700/sb700_smbus.h | 65 - src/southbridge/amd/sb700/sb700_usb.c | 253 ---- src/southbridge/amd/sb700/sm.c | 381 ++++++ src/southbridge/amd/sb700/smbus.c | 224 ++++ src/southbridge/amd/sb700/smbus.h | 65 + src/southbridge/amd/sb700/usb.c | 253 ++++ src/southbridge/broadcom/bcm21000/Makefile.inc | 2 +- src/southbridge/broadcom/bcm21000/bcm21000_pcie.c | 79 -- src/southbridge/broadcom/bcm21000/pcie.c | 79 ++ src/southbridge/broadcom/bcm5780/Makefile.inc | 6 +- src/southbridge/broadcom/bcm5780/bcm5780_nic.c | 64 - src/southbridge/broadcom/bcm5780/bcm5780_pcie.c | 60 - src/southbridge/broadcom/bcm5780/bcm5780_pcix.c | 52 - src/southbridge/broadcom/bcm5780/nic.c | 64 + src/southbridge/broadcom/bcm5780/pcie.c | 60 + src/southbridge/broadcom/bcm5780/pcix.c | 52 + src/southbridge/broadcom/bcm5785/Makefile.inc | 12 +- .../broadcom/bcm5785/bcm5785_early_setup.c | 223 ---- .../broadcom/bcm5785/bcm5785_early_smbus.c | 61 - .../broadcom/bcm5785/bcm5785_enable_rom.c | 39 - src/southbridge/broadcom/bcm5785/bcm5785_ide.c | 67 - src/southbridge/broadcom/bcm5785/bcm5785_lpc.c | 148 --- src/southbridge/broadcom/bcm5785/bcm5785_reset.c | 56 - src/southbridge/broadcom/bcm5785/bcm5785_sata.c | 100 -- .../broadcom/bcm5785/bcm5785_sb_pci_main.c | 168 --- src/southbridge/broadcom/bcm5785/bcm5785_smbus.h | 196 --- src/southbridge/broadcom/bcm5785/bcm5785_usb.c | 64 - src/southbridge/broadcom/bcm5785/bootblock.c | 2 +- src/southbridge/broadcom/bcm5785/early_setup.c | 223 ++++ src/southbridge/broadcom/bcm5785/early_smbus.c | 61 + src/southbridge/broadcom/bcm5785/enable_rom.c | 39 + src/southbridge/broadcom/bcm5785/ide.c | 67 + src/southbridge/broadcom/bcm5785/lpc.c | 148 +++ src/southbridge/broadcom/bcm5785/reset.c | 56 + src/southbridge/broadcom/bcm5785/sata.c | 100 ++ src/southbridge/broadcom/bcm5785/sb_pci_main.c | 168 +++ src/southbridge/broadcom/bcm5785/smbus.h | 196 +++ src/southbridge/broadcom/bcm5785/usb.c | 64 + src/southbridge/intel/esb6300/Makefile.inc | 22 +- src/southbridge/intel/esb6300/ac97.c | 37 + src/southbridge/intel/esb6300/bridge1c.c | 47 + src/southbridge/intel/esb6300/early_smbus.c | 98 ++ src/southbridge/intel/esb6300/ehci.c | 50 + src/southbridge/intel/esb6300/esb6300_ac97.c | 37 - src/southbridge/intel/esb6300/esb6300_bridge1c.c | 47 - .../intel/esb6300/esb6300_early_smbus.c | 98 -- src/southbridge/intel/esb6300/esb6300_ehci.c | 50 - src/southbridge/intel/esb6300/esb6300_ide.c | 56 - src/southbridge/intel/esb6300/esb6300_lpc.c | 374 ------ src/southbridge/intel/esb6300/esb6300_pci.c | 37 - src/southbridge/intel/esb6300/esb6300_pic.c | 68 - src/southbridge/intel/esb6300/esb6300_reset.c | 27 - src/southbridge/intel/esb6300/esb6300_sata.c | 75 -- src/southbridge/intel/esb6300/esb6300_smbus.c | 49 - src/southbridge/intel/esb6300/esb6300_smbus.h | 101 -- src/southbridge/intel/esb6300/esb6300_uhci.c | 57 - src/southbridge/intel/esb6300/ide.c | 56 + src/southbridge/intel/esb6300/lpc.c | 374 ++++++ src/southbridge/intel/esb6300/pci.c | 37 + src/southbridge/intel/esb6300/pic.c | 68 + src/southbridge/intel/esb6300/reset.c | 27 + src/southbridge/intel/esb6300/sata.c | 75 ++ src/southbridge/intel/esb6300/smbus.c | 49 + src/southbridge/intel/esb6300/smbus.h | 101 ++ src/southbridge/intel/esb6300/uhci.c | 57 + src/southbridge/intel/i3100/Makefile.inc | 16 +- src/southbridge/intel/i3100/early_lpc.c | 46 + src/southbridge/intel/i3100/early_smbus.c | 43 + src/southbridge/intel/i3100/ehci.c | 68 + src/southbridge/intel/i3100/i3100_early_lpc.c | 46 - src/southbridge/intel/i3100/i3100_early_smbus.c | 43 - src/southbridge/intel/i3100/i3100_ehci.c | 68 - src/southbridge/intel/i3100/i3100_lpc.c | 433 ------- src/southbridge/intel/i3100/i3100_pci.c | 46 - src/southbridge/intel/i3100/i3100_pciexp_portb.c | 94 -- src/southbridge/intel/i3100/i3100_reset.c | 27 - src/southbridge/intel/i3100/i3100_sata.c | 129 -- src/southbridge/intel/i3100/i3100_smbus.c | 79 -- src/southbridge/intel/i3100/i3100_smbus.h | 112 -- src/southbridge/intel/i3100/i3100_uhci.c | 68 - src/southbridge/intel/i3100/lpc.c | 433 +++++++ src/southbridge/intel/i3100/pci.c | 46 + src/southbridge/intel/i3100/pciexp_portb.c | 94 ++ src/southbridge/intel/i3100/reset.c | 27 + src/southbridge/intel/i3100/sata.c | 129 ++ src/southbridge/intel/i3100/smbus.c | 79 ++ src/southbridge/intel/i3100/smbus.h | 112 ++ src/southbridge/intel/i3100/uhci.c | 68 + src/southbridge/intel/i82371eb/Makefile.inc | 16 +- src/southbridge/intel/i82371eb/bootblock.c | 2 +- src/southbridge/intel/i82371eb/early_pm.c | 51 + src/southbridge/intel/i82371eb/early_smbus.c | 60 + src/southbridge/intel/i82371eb/enable_rom.c | 49 + src/southbridge/intel/i82371eb/fadt.c | 222 ++++ src/southbridge/intel/i82371eb/i82371eb_early_pm.c | 51 - .../intel/i82371eb/i82371eb_early_smbus.c | 60 - .../intel/i82371eb/i82371eb_enable_rom.c | 49 - src/southbridge/intel/i82371eb/i82371eb_fadt.c | 222 ---- src/southbridge/intel/i82371eb/i82371eb_ide.c | 201 --- src/southbridge/intel/i82371eb/i82371eb_isa.c | 147 --- src/southbridge/intel/i82371eb/i82371eb_reset.c | 30 - src/southbridge/intel/i82371eb/i82371eb_smbus.c | 137 -- src/southbridge/intel/i82371eb/i82371eb_smbus.h | 115 -- src/southbridge/intel/i82371eb/i82371eb_usb.c | 66 - src/southbridge/intel/i82371eb/ide.c | 201 +++ src/southbridge/intel/i82371eb/isa.c | 147 +++ src/southbridge/intel/i82371eb/reset.c | 30 + src/southbridge/intel/i82371eb/smbus.c | 137 ++ src/southbridge/intel/i82371eb/smbus.h | 115 ++ src/southbridge/intel/i82371eb/usb.c | 66 + src/southbridge/intel/i82801ax/Makefile.inc | 18 +- src/southbridge/intel/i82801ax/ac97.c | 61 + src/southbridge/intel/i82801ax/early_smbus.c | 61 + src/southbridge/intel/i82801ax/i82801ax_ac97.c | 61 - .../intel/i82801ax/i82801ax_early_smbus.c | 61 - src/southbridge/intel/i82801ax/i82801ax_ide.c | 75 -- src/southbridge/intel/i82801ax/i82801ax_lpc.c | 296 ----- src/southbridge/intel/i82801ax/i82801ax_pci.c | 57 - src/southbridge/intel/i82801ax/i82801ax_reset.c | 28 - src/southbridge/intel/i82801ax/i82801ax_smbus.c | 68 - src/southbridge/intel/i82801ax/i82801ax_smbus.h | 101 -- src/southbridge/intel/i82801ax/i82801ax_usb.c | 53 - src/southbridge/intel/i82801ax/i82801ax_watchdog.c | 55 - src/southbridge/intel/i82801ax/ide.c | 75 ++ src/southbridge/intel/i82801ax/lpc.c | 296 +++++ src/southbridge/intel/i82801ax/pci.c | 57 + src/southbridge/intel/i82801ax/reset.c | 28 + src/southbridge/intel/i82801ax/smbus.c | 68 + src/southbridge/intel/i82801ax/smbus.h | 101 ++ src/southbridge/intel/i82801ax/usb.c | 53 + src/southbridge/intel/i82801ax/watchdog.c | 55 + src/southbridge/intel/i82801bx/Makefile.inc | 20 +- src/southbridge/intel/i82801bx/ac97.c | 48 + src/southbridge/intel/i82801bx/early_smbus.c | 60 + src/southbridge/intel/i82801bx/i82801bx_ac97.c | 48 - .../intel/i82801bx/i82801bx_early_smbus.c | 60 - src/southbridge/intel/i82801bx/i82801bx_ide.c | 68 - src/southbridge/intel/i82801bx/i82801bx_lpc.c | 307 ----- src/southbridge/intel/i82801bx/i82801bx_nic.c | 39 - src/southbridge/intel/i82801bx/i82801bx_pci.c | 55 - src/southbridge/intel/i82801bx/i82801bx_reset.c | 28 - src/southbridge/intel/i82801bx/i82801bx_smbus.c | 61 - src/southbridge/intel/i82801bx/i82801bx_smbus.h | 98 -- src/southbridge/intel/i82801bx/i82801bx_usb.c | 52 - src/southbridge/intel/i82801bx/i82801bx_watchdog.c | 55 - src/southbridge/intel/i82801bx/ide.c | 68 + src/southbridge/intel/i82801bx/lpc.c | 307 +++++ src/southbridge/intel/i82801bx/nic.c | 39 + src/southbridge/intel/i82801bx/pci.c | 55 + src/southbridge/intel/i82801bx/reset.c | 28 + src/southbridge/intel/i82801bx/smbus.c | 61 + src/southbridge/intel/i82801bx/smbus.h | 98 ++ src/southbridge/intel/i82801bx/usb.c | 52 + src/southbridge/intel/i82801bx/watchdog.c | 55 + src/southbridge/intel/i82801cx/Makefile.inc | 14 +- src/southbridge/intel/i82801cx/ac97.c | 41 + src/southbridge/intel/i82801cx/early_smbus.c | 134 ++ src/southbridge/intel/i82801cx/i82801cx_ac97.c | 41 - .../intel/i82801cx/i82801cx_early_smbus.c | 134 -- src/southbridge/intel/i82801cx/i82801cx_ide.c | 48 - src/southbridge/intel/i82801cx/i82801cx_lpc.c | 245 ---- src/southbridge/intel/i82801cx/i82801cx_nic.c | 21 - src/southbridge/intel/i82801cx/i82801cx_pci.c | 30 - src/southbridge/intel/i82801cx/i82801cx_reset.c | 9 - src/southbridge/intel/i82801cx/i82801cx_smbus.c | 83 -- src/southbridge/intel/i82801cx/i82801cx_usb.c | 49 - src/southbridge/intel/i82801cx/ide.c | 48 + src/southbridge/intel/i82801cx/lpc.c | 245 ++++ src/southbridge/intel/i82801cx/nic.c | 21 + src/southbridge/intel/i82801cx/pci.c | 30 + src/southbridge/intel/i82801cx/reset.c | 9 + src/southbridge/intel/i82801cx/smbus.c | 83 ++ src/southbridge/intel/i82801cx/usb.c | 49 + src/southbridge/intel/i82801dx/Makefile.inc | 18 +- src/southbridge/intel/i82801dx/ac97.c | 285 +++++ src/southbridge/intel/i82801dx/early_smbus.c | 196 +++ src/southbridge/intel/i82801dx/i82801dx_ac97.c | 285 ----- .../intel/i82801dx/i82801dx_early_smbus.c | 196 --- src/southbridge/intel/i82801dx/i82801dx_ide.c | 82 -- src/southbridge/intel/i82801dx/i82801dx_lpc.c | 347 ----- src/southbridge/intel/i82801dx/i82801dx_nvs.h | 138 -- src/southbridge/intel/i82801dx/i82801dx_pci.c | 58 - src/southbridge/intel/i82801dx/i82801dx_reset.c | 27 - src/southbridge/intel/i82801dx/i82801dx_smbus.c | 105 -- src/southbridge/intel/i82801dx/i82801dx_smi.c | 368 ------ .../intel/i82801dx/i82801dx_smihandler.c | 667 ---------- .../intel/i82801dx/i82801dx_tco_timer.c | 36 - src/southbridge/intel/i82801dx/i82801dx_usb.c | 68 - src/southbridge/intel/i82801dx/i82801dx_usb2.c | 54 - src/southbridge/intel/i82801dx/ide.c | 82 ++ src/southbridge/intel/i82801dx/lpc.c | 347 +++++ src/southbridge/intel/i82801dx/nvs.h | 138 ++ src/southbridge/intel/i82801dx/pci.c | 58 + src/southbridge/intel/i82801dx/reset.c | 27 + src/southbridge/intel/i82801dx/smbus.c | 105 ++ src/southbridge/intel/i82801dx/smi.c | 368 ++++++ src/southbridge/intel/i82801dx/smihandler.c | 667 ++++++++++ src/southbridge/intel/i82801dx/tco_timer.c | 36 + src/southbridge/intel/i82801dx/usb.c | 68 + src/southbridge/intel/i82801dx/usb2.c | 54 + src/southbridge/intel/i82801ex/Makefile.inc | 20 +- src/southbridge/intel/i82801ex/ac97.c | 37 + src/southbridge/intel/i82801ex/early_smbus.c | 130 ++ src/southbridge/intel/i82801ex/ehci.c | 50 + src/southbridge/intel/i82801ex/i82801ex_ac97.c | 37 - .../intel/i82801ex/i82801ex_early_smbus.c | 130 -- src/southbridge/intel/i82801ex/i82801ex_ehci.c | 50 - src/southbridge/intel/i82801ex/i82801ex_ide.c | 43 - src/southbridge/intel/i82801ex/i82801ex_lpc.c | 358 ------ src/southbridge/intel/i82801ex/i82801ex_pci.c | 45 - src/southbridge/intel/i82801ex/i82801ex_reset.c | 8 - src/southbridge/intel/i82801ex/i82801ex_sata.c | 60 - src/southbridge/intel/i82801ex/i82801ex_smbus.c | 49 - src/southbridge/intel/i82801ex/i82801ex_smbus.h | 105 -- src/southbridge/intel/i82801ex/i82801ex_uhci.c | 56 - src/southbridge/intel/i82801ex/i82801ex_watchdog.c | 29 - src/southbridge/intel/i82801ex/ide.c | 43 + src/southbridge/intel/i82801ex/lpc.c | 358 ++++++ src/southbridge/intel/i82801ex/pci.c | 45 + src/southbridge/intel/i82801ex/reset.c | 8 + src/southbridge/intel/i82801ex/sata.c | 60 + src/southbridge/intel/i82801ex/smbus.c | 49 + src/southbridge/intel/i82801ex/smbus.h | 105 ++ src/southbridge/intel/i82801ex/uhci.c | 56 + src/southbridge/intel/i82801ex/watchdog.c | 29 + src/southbridge/intel/i82801gx/Makefile.inc | 34 +- src/southbridge/intel/i82801gx/ac97.c | 303 +++++ src/southbridge/intel/i82801gx/acpi/ac97.asl | 40 + src/southbridge/intel/i82801gx/acpi/audio.asl | 36 + src/southbridge/intel/i82801gx/acpi/ich7.asl | 18 +- src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl | 40 - src/southbridge/intel/i82801gx/acpi/ich7_audio.asl | 36 - .../intel/i82801gx/acpi/ich7_irqlinks.asl | 493 ------- src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl | 290 ----- src/southbridge/intel/i82801gx/acpi/ich7_pata.asl | 80 -- src/southbridge/intel/i82801gx/acpi/ich7_pci.asl | 77 -- src/southbridge/intel/i82801gx/acpi/ich7_pcie.asl | 186 --- src/southbridge/intel/i82801gx/acpi/ich7_sata.asl | 83 -- src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl | 242 ---- src/southbridge/intel/i82801gx/acpi/ich7_usb.asl | 217 ---- src/southbridge/intel/i82801gx/acpi/irqlinks.asl | 493 +++++++ src/southbridge/intel/i82801gx/acpi/lpc.asl | 290 +++++ src/southbridge/intel/i82801gx/acpi/pata.asl | 80 ++ src/southbridge/intel/i82801gx/acpi/pci.asl | 77 ++ src/southbridge/intel/i82801gx/acpi/pcie.asl | 186 +++ src/southbridge/intel/i82801gx/acpi/sata.asl | 83 ++ src/southbridge/intel/i82801gx/acpi/smbus.asl | 242 ++++ src/southbridge/intel/i82801gx/acpi/usb.asl | 217 ++++ src/southbridge/intel/i82801gx/azalia.c | 347 +++++ src/southbridge/intel/i82801gx/early_smbus.c | 63 + src/southbridge/intel/i82801gx/i82801gx_ac97.c | 303 ----- src/southbridge/intel/i82801gx/i82801gx_azalia.c | 347 ----- .../intel/i82801gx/i82801gx_early_smbus.c | 63 - src/southbridge/intel/i82801gx/i82801gx_ide.c | 128 -- src/southbridge/intel/i82801gx/i82801gx_lpc.c | 536 -------- src/southbridge/intel/i82801gx/i82801gx_nic.c | 48 - src/southbridge/intel/i82801gx/i82801gx_nvs.h | 138 -- src/southbridge/intel/i82801gx/i82801gx_pci.c | 154 --- src/southbridge/intel/i82801gx/i82801gx_pcie.c | 164 --- src/southbridge/intel/i82801gx/i82801gx_reset.c | 41 - src/southbridge/intel/i82801gx/i82801gx_sata.c | 258 ---- src/southbridge/intel/i82801gx/i82801gx_smbus.c | 93 -- src/southbridge/intel/i82801gx/i82801gx_smbus.h | 100 -- src/southbridge/intel/i82801gx/i82801gx_smi.c | 368 ------ .../intel/i82801gx/i82801gx_smihandler.c | 647 ---------- src/southbridge/intel/i82801gx/i82801gx_usb.c | 100 -- .../intel/i82801gx/i82801gx_usb_debug.c | 50 - src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c | 129 -- src/southbridge/intel/i82801gx/i82801gx_watchdog.c | 53 - src/southbridge/intel/i82801gx/ide.c | 128 ++ src/southbridge/intel/i82801gx/lpc.c | 536 ++++++++ src/southbridge/intel/i82801gx/nic.c | 48 + src/southbridge/intel/i82801gx/nvs.h | 138 ++ src/southbridge/intel/i82801gx/pci.c | 154 +++ src/southbridge/intel/i82801gx/pcie.c | 164 +++ src/southbridge/intel/i82801gx/reset.c | 41 + src/southbridge/intel/i82801gx/sata.c | 258 ++++ src/southbridge/intel/i82801gx/smbus.c | 93 ++ src/southbridge/intel/i82801gx/smbus.h | 100 ++ src/southbridge/intel/i82801gx/smi.c | 368 ++++++ src/southbridge/intel/i82801gx/smihandler.c | 647 ++++++++++ src/southbridge/intel/i82801gx/usb.c | 100 ++ src/southbridge/intel/i82801gx/usb_debug.c | 50 + src/southbridge/intel/i82801gx/usb_ehci.c | 129 ++ src/southbridge/intel/i82801gx/watchdog.c | 53 + src/southbridge/intel/i82870/Makefile.inc | 6 +- src/southbridge/intel/i82870/ioapic.c | 98 ++ src/southbridge/intel/i82870/p64h2_ioapic.c | 98 -- src/southbridge/intel/i82870/p64h2_pci_parity.c | 25 - src/southbridge/intel/i82870/p64h2_pcibridge.c | 39 - src/southbridge/intel/i82870/pci_parity.c | 25 + src/southbridge/intel/i82870/pcibridge.c | 39 + src/southbridge/intel/pxhd/Makefile.inc | 2 +- src/southbridge/intel/pxhd/bridge.c | 212 ++++ src/southbridge/intel/pxhd/pxhd_bridge.c | 212 ---- src/southbridge/nvidia/ck804/Makefile.inc | 30 +- src/southbridge/nvidia/ck804/ac97.c | 58 + src/southbridge/nvidia/ck804/bootblock.c | 2 +- src/southbridge/nvidia/ck804/ck804_ac97.c | 58 - src/southbridge/nvidia/ck804/ck804_early_setup.c | 338 ----- .../nvidia/ck804/ck804_early_setup_car.c | 365 ------ .../nvidia/ck804/ck804_early_setup_ss.h | 220 ---- src/southbridge/nvidia/ck804/ck804_early_smbus.c | 80 -- src/southbridge/nvidia/ck804/ck804_early_smbus.h | 5 - src/southbridge/nvidia/ck804/ck804_enable_rom.c | 40 - .../nvidia/ck804/ck804_enable_usbdebug.c | 61 - src/southbridge/nvidia/ck804/ck804_fadt.c | 147 --- src/southbridge/nvidia/ck804/ck804_ht.c | 41 - src/southbridge/nvidia/ck804/ck804_ide.c | 82 -- src/southbridge/nvidia/ck804/ck804_lpc.c | 345 ----- src/southbridge/nvidia/ck804/ck804_nic.c | 136 -- src/southbridge/nvidia/ck804/ck804_pci.c | 94 -- src/southbridge/nvidia/ck804/ck804_pcie.c | 52 - src/southbridge/nvidia/ck804/ck804_reset.c | 55 - src/southbridge/nvidia/ck804/ck804_sata.c | 187 --- src/southbridge/nvidia/ck804/ck804_smbus.c | 110 -- src/southbridge/nvidia/ck804/ck804_smbus.h | 229 ---- src/southbridge/nvidia/ck804/ck804_usb.c | 61 - src/southbridge/nvidia/ck804/ck804_usb2.c | 50 - src/southbridge/nvidia/ck804/early_setup.c | 338 +++++ src/southbridge/nvidia/ck804/early_setup_car.c | 365 ++++++ src/southbridge/nvidia/ck804/early_setup_ss.h | 220 ++++ src/southbridge/nvidia/ck804/early_smbus.c | 80 ++ src/southbridge/nvidia/ck804/early_smbus.h | 5 + src/southbridge/nvidia/ck804/enable_rom.c | 40 + src/southbridge/nvidia/ck804/enable_usbdebug.c | 61 + src/southbridge/nvidia/ck804/fadt.c | 147 +++ src/southbridge/nvidia/ck804/ht.c | 41 + src/southbridge/nvidia/ck804/ide.c | 82 ++ src/southbridge/nvidia/ck804/lpc.c | 345 +++++ src/southbridge/nvidia/ck804/nic.c | 136 ++ src/southbridge/nvidia/ck804/pci.c | 94 ++ src/southbridge/nvidia/ck804/pcie.c | 52 + src/southbridge/nvidia/ck804/reset.c | 55 + src/southbridge/nvidia/ck804/sata.c | 187 +++ src/southbridge/nvidia/ck804/smbus.c | 110 ++ src/southbridge/nvidia/ck804/smbus.h | 229 ++++ src/southbridge/nvidia/ck804/usb.c | 61 + src/southbridge/nvidia/ck804/usb2.c | 50 + src/southbridge/nvidia/mcp55/Makefile.inc | 28 +- src/southbridge/nvidia/mcp55/azalia.c | 297 +++++ src/southbridge/nvidia/mcp55/bootblock.c | 2 +- src/southbridge/nvidia/mcp55/early_ctrl.c | 61 + src/southbridge/nvidia/mcp55/early_setup_car.c | 402 ++++++ src/southbridge/nvidia/mcp55/early_setup_ss.h | 222 ++++ src/southbridge/nvidia/mcp55/early_smbus.c | 87 ++ src/southbridge/nvidia/mcp55/enable_rom.c | 54 + src/southbridge/nvidia/mcp55/enable_usbdebug.c | 55 + src/southbridge/nvidia/mcp55/fadt.c | 173 +++ src/southbridge/nvidia/mcp55/ht.c | 45 + src/southbridge/nvidia/mcp55/ide.c | 87 ++ src/southbridge/nvidia/mcp55/lpc.c | 316 +++++ src/southbridge/nvidia/mcp55/mcp55_azalia.c | 297 ----- src/southbridge/nvidia/mcp55/mcp55_early_ctrl.c | 61 - .../nvidia/mcp55/mcp55_early_setup_car.c | 402 ------ .../nvidia/mcp55/mcp55_early_setup_ss.h | 222 ---- src/southbridge/nvidia/mcp55/mcp55_early_smbus.c | 87 -- src/southbridge/nvidia/mcp55/mcp55_enable_rom.c | 54 - .../nvidia/mcp55/mcp55_enable_usbdebug.c | 55 - src/southbridge/nvidia/mcp55/mcp55_fadt.c | 173 --- src/southbridge/nvidia/mcp55/mcp55_ht.c | 45 - src/southbridge/nvidia/mcp55/mcp55_ide.c | 87 -- src/southbridge/nvidia/mcp55/mcp55_lpc.c | 316 ----- src/southbridge/nvidia/mcp55/mcp55_nic.c | 201 --- src/southbridge/nvidia/mcp55/mcp55_pci.c | 103 -- src/southbridge/nvidia/mcp55/mcp55_pcie.c | 79 -- src/southbridge/nvidia/mcp55/mcp55_reset.c | 60 - src/southbridge/nvidia/mcp55/mcp55_sata.c | 92 -- src/southbridge/nvidia/mcp55/mcp55_smbus.c | 141 -- src/southbridge/nvidia/mcp55/mcp55_smbus.h | 177 --- src/southbridge/nvidia/mcp55/mcp55_usb.c | 46 - src/southbridge/nvidia/mcp55/mcp55_usb2.c | 79 -- src/southbridge/nvidia/mcp55/nic.c | 201 +++ src/southbridge/nvidia/mcp55/pci.c | 103 ++ src/southbridge/nvidia/mcp55/pcie.c | 79 ++ src/southbridge/nvidia/mcp55/reset.c | 60 + src/southbridge/nvidia/mcp55/sata.c | 92 ++ src/southbridge/nvidia/mcp55/smbus.c | 141 ++ src/southbridge/nvidia/mcp55/smbus.h | 177 +++ src/southbridge/nvidia/mcp55/usb.c | 46 + src/southbridge/nvidia/mcp55/usb2.c | 79 ++ src/southbridge/sis/sis966/Makefile.inc | 20 +- src/southbridge/sis/sis966/aza.c | 330 +++++ src/southbridge/sis/sis966/early_ctrl.c | 60 + src/southbridge/sis/sis966/early_setup_car.c | 63 + src/southbridge/sis/sis966/early_setup_ss.h | 222 ++++ src/southbridge/sis/sis966/early_smbus.c | 743 +++++++++++ src/southbridge/sis/sis966/enable_rom.c | 41 + src/southbridge/sis/sis966/enable_usbdebug.c | 63 + src/southbridge/sis/sis966/ide.c | 196 +++ src/southbridge/sis/sis966/lpc.c | 283 +++++ src/southbridge/sis/sis966/nic.c | 365 ++++++ src/southbridge/sis/sis966/pcie.c | 66 + src/southbridge/sis/sis966/reset.c | 60 + src/southbridge/sis/sis966/sata.c | 197 +++ src/southbridge/sis/sis966/sis966_aza.c | 330 ----- src/southbridge/sis/sis966/sis966_early_ctrl.c | 60 - .../sis/sis966/sis966_early_setup_car.c | 63 - src/southbridge/sis/sis966/sis966_early_setup_ss.h | 222 ---- src/southbridge/sis/sis966/sis966_early_smbus.c | 743 ----------- src/southbridge/sis/sis966/sis966_enable_rom.c | 41 - .../sis/sis966/sis966_enable_usbdebug.c | 63 - src/southbridge/sis/sis966/sis966_ide.c | 196 --- src/southbridge/sis/sis966/sis966_lpc.c | 283 ----- src/southbridge/sis/sis966/sis966_nic.c | 365 ------ src/southbridge/sis/sis966/sis966_pcie.c | 66 - src/southbridge/sis/sis966/sis966_reset.c | 60 - src/southbridge/sis/sis966/sis966_sata.c | 197 --- src/southbridge/sis/sis966/sis966_smbus.h | 46 - src/southbridge/sis/sis966/sis966_usb.c | 120 -- src/southbridge/sis/sis966/sis966_usb2.c | 168 --- src/southbridge/sis/sis966/smbus.h | 46 + src/southbridge/sis/sis966/usb.c | 120 ++ src/southbridge/sis/sis966/usb2.c | 168 +++ src/southbridge/ti/pci7420/Makefile.inc | 4 +- src/southbridge/ti/pci7420/cardbus.c | 128 ++ src/southbridge/ti/pci7420/firewire.c | 66 + src/southbridge/ti/pci7420/pci7420_cardbus.c | 128 -- src/southbridge/ti/pci7420/pci7420_firewire.c | 66 - src/southbridge/via/k8t890/Makefile.inc | 18 +- src/southbridge/via/k8t890/bridge.c | 70 + src/southbridge/via/k8t890/chrome.c | 174 +++ src/southbridge/via/k8t890/ctrl.c | 192 +++ src/southbridge/via/k8t890/dram.c | 183 +++ src/southbridge/via/k8t890/early_car.c | 161 +++ src/southbridge/via/k8t890/error.c | 61 + src/southbridge/via/k8t890/host.c | 89 ++ src/southbridge/via/k8t890/host_ctrl.c | 151 +++ src/southbridge/via/k8t890/k8m890_chrome.c | 174 --- src/southbridge/via/k8t890/k8t890_bridge.c | 70 - src/southbridge/via/k8t890/k8t890_ctrl.c | 192 --- src/southbridge/via/k8t890/k8t890_dram.c | 183 --- src/southbridge/via/k8t890/k8t890_early_car.c | 161 --- src/southbridge/via/k8t890/k8t890_error.c | 61 - src/southbridge/via/k8t890/k8t890_host.c | 89 -- src/southbridge/via/k8t890/k8t890_host_ctrl.c | 151 --- src/southbridge/via/k8t890/k8t890_pcie.c | 176 --- src/southbridge/via/k8t890/k8t890_traf_ctrl.c | 157 --- src/southbridge/via/k8t890/pcie.c | 176 +++ src/southbridge/via/k8t890/traf_ctrl.c | 157 +++ src/southbridge/via/vt8231/Makefile.inc | 10 +- src/southbridge/via/vt8231/acpi.c | 43 + src/southbridge/via/vt8231/early_serial.c | 74 ++ src/southbridge/via/vt8231/early_smbus.c | 295 +++++ src/southbridge/via/vt8231/enable_rom.c | 47 + src/southbridge/via/vt8231/ide.c | 113 ++ src/southbridge/via/vt8231/lpc.c | 165 +++ src/southbridge/via/vt8231/nic.c | 36 + src/southbridge/via/vt8231/usb.c | 52 + src/southbridge/via/vt8231/vt8231_acpi.c | 43 - src/southbridge/via/vt8231/vt8231_early_serial.c | 74 -- src/southbridge/via/vt8231/vt8231_early_smbus.c | 295 ----- src/southbridge/via/vt8231/vt8231_enable_rom.c | 47 - src/southbridge/via/vt8231/vt8231_ide.c | 113 -- src/southbridge/via/vt8231/vt8231_lpc.c | 165 --- src/southbridge/via/vt8231/vt8231_nic.c | 36 - src/southbridge/via/vt8231/vt8231_usb.c | 52 - src/southbridge/via/vt8235/Makefile.inc | 8 +- src/southbridge/via/vt8235/early_serial.c | 77 ++ src/southbridge/via/vt8235/early_smbus.c | 249 ++++ src/southbridge/via/vt8235/ide.c | 113 ++ src/southbridge/via/vt8235/lpc.c | 261 ++++ src/southbridge/via/vt8235/nic.c | 36 + src/southbridge/via/vt8235/usb.c | 44 + src/southbridge/via/vt8235/vt8235_early_serial.c | 77 -- src/southbridge/via/vt8235/vt8235_early_smbus.c | 249 ---- src/southbridge/via/vt8235/vt8235_ide.c | 113 -- src/southbridge/via/vt8235/vt8235_lpc.c | 261 ---- src/southbridge/via/vt8235/vt8235_nic.c | 36 - src/southbridge/via/vt8235/vt8235_usb.c | 44 - src/southbridge/via/vt8237r/Makefile.inc | 14 +- src/southbridge/via/vt8237r/ctrl.c | 289 +++++ src/southbridge/via/vt8237r/early_smbus.c | 498 ++++++++ src/southbridge/via/vt8237r/fadt.c | 173 +++ src/southbridge/via/vt8237r/ide.c | 132 ++ src/southbridge/via/vt8237r/lpc.c | 624 +++++++++ src/southbridge/via/vt8237r/nic.c | 62 + src/southbridge/via/vt8237r/pirq.c | 51 + src/southbridge/via/vt8237r/sata.c | 132 ++ src/southbridge/via/vt8237r/usb.c | 165 +++ src/southbridge/via/vt8237r/vt8237_ctrl.c | 289 ----- src/southbridge/via/vt8237r/vt8237_fadt.c | 173 --- src/southbridge/via/vt8237r/vt8237r_early_smbus.c | 498 -------- src/southbridge/via/vt8237r/vt8237r_ide.c | 132 -- src/southbridge/via/vt8237r/vt8237r_lpc.c | 624 --------- src/southbridge/via/vt8237r/vt8237r_nic.c | 62 - src/southbridge/via/vt8237r/vt8237r_pirq.c | 51 - src/southbridge/via/vt8237r/vt8237r_sata.c | 132 -- src/southbridge/via/vt8237r/vt8237r_usb.c | 165 --- src/southbridge/via/vt82c686/early_serial.c | 92 ++ .../via/vt82c686/vt82c686_early_serial.c | 92 -- 635 files changed, 44689 insertions(+), 44689 deletions(-) create mode 100644 src/southbridge/amd/amd8111/ac97.c create mode 100644 src/southbridge/amd/amd8111/acpi.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_ac97.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_acpi.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_early_ctrl.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_early_smbus.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_enable_rom.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_ide.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_lpc.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_nic.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_pci.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_reset.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_smbus.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_usb.c delete mode 100644 src/southbridge/amd/amd8111/amd8111_usb2.c create mode 100644 src/southbridge/amd/amd8111/early_ctrl.c create mode 100644 src/southbridge/amd/amd8111/early_smbus.c create mode 100644 src/southbridge/amd/amd8111/enable_rom.c create mode 100644 src/southbridge/amd/amd8111/ide.c create mode 100644 src/southbridge/amd/amd8111/lpc.c create mode 100644 src/southbridge/amd/amd8111/nic.c create mode 100644 src/southbridge/amd/amd8111/pci.c create mode 100644 src/southbridge/amd/amd8111/reset.c create mode 100644 src/southbridge/amd/amd8111/smbus.c create mode 100644 src/southbridge/amd/amd8111/usb.c create mode 100644 src/southbridge/amd/amd8111/usb2.c delete mode 100644 src/southbridge/amd/amd8131-disable/amd8131_bridge.c create mode 100644 src/southbridge/amd/amd8131-disable/bridge.c delete mode 100644 src/southbridge/amd/amd8131/amd8131_bridge.c create mode 100644 src/southbridge/amd/amd8131/bridge.c delete mode 100644 src/southbridge/amd/amd8132/amd8132_bridge.c create mode 100644 src/southbridge/amd/amd8132/bridge.c create mode 100644 src/southbridge/amd/amd8151/agp3.c delete mode 100644 src/southbridge/amd/amd8151/amd8151_agp3.c delete mode 100644 src/southbridge/amd/cs5530/cs5530_enable_rom.c delete mode 100644 src/southbridge/amd/cs5530/cs5530_ide.c delete mode 100644 src/southbridge/amd/cs5530/cs5530_isa.c delete mode 100644 src/southbridge/amd/cs5530/cs5530_pirq.c delete mode 100644 src/southbridge/amd/cs5530/cs5530_vga.c create mode 100644 src/southbridge/amd/cs5530/enable_rom.c create mode 100644 src/southbridge/amd/cs5530/ide.c create mode 100644 src/southbridge/amd/cs5530/isa.c create mode 100644 src/southbridge/amd/cs5530/pirq.c create mode 100644 src/southbridge/amd/cs5530/vga.c delete mode 100644 src/southbridge/amd/cs5535/cs5535_early_setup.c delete mode 100644 src/southbridge/amd/cs5535/cs5535_early_smbus.c delete mode 100644 src/southbridge/amd/cs5535/cs5535_ide.c delete mode 100644 src/southbridge/amd/cs5535/cs5535_smbus.h create mode 100644 src/southbridge/amd/cs5535/early_setup.c create mode 100644 src/southbridge/amd/cs5535/early_smbus.c create mode 100644 src/southbridge/amd/cs5535/ide.c create mode 100644 src/southbridge/amd/cs5535/smbus.h delete mode 100644 src/southbridge/amd/cs5536/cs5536_early_setup.c delete mode 100644 src/southbridge/amd/cs5536/cs5536_early_smbus.c delete mode 100644 src/southbridge/amd/cs5536/cs5536_ide.c delete mode 100644 src/southbridge/amd/cs5536/cs5536_pirq.c delete mode 100644 src/southbridge/amd/cs5536/cs5536_smbus2.h create mode 100644 src/southbridge/amd/cs5536/early_setup.c create mode 100644 src/southbridge/amd/cs5536/early_smbus.c create mode 100644 src/southbridge/amd/cs5536/ide.c create mode 100644 src/southbridge/amd/cs5536/pirq.c create mode 100644 src/southbridge/amd/cs5536/smbus2.h create mode 100644 src/southbridge/amd/rs690/cmn.c create mode 100644 src/southbridge/amd/rs690/early_setup.c create mode 100644 src/southbridge/amd/rs690/gfx.c create mode 100644 src/southbridge/amd/rs690/ht.c create mode 100644 src/southbridge/amd/rs690/pcie.c delete mode 100644 src/southbridge/amd/rs690/rs690_cmn.c delete mode 100644 src/southbridge/amd/rs690/rs690_early_setup.c delete mode 100644 src/southbridge/amd/rs690/rs690_gfx.c delete mode 100644 src/southbridge/amd/rs690/rs690_ht.c delete mode 100644 src/southbridge/amd/rs690/rs690_pcie.c create mode 100644 src/southbridge/amd/rs780/cmn.c create mode 100644 src/southbridge/amd/rs780/early_setup.c create mode 100644 src/southbridge/amd/rs780/gfx.c create mode 100644 src/southbridge/amd/rs780/ht.c create mode 100644 src/southbridge/amd/rs780/pcie.c create mode 100644 src/southbridge/amd/rs780/rev.h delete mode 100644 src/southbridge/amd/rs780/rs780_cmn.c delete mode 100644 src/southbridge/amd/rs780/rs780_early_setup.c delete mode 100644 src/southbridge/amd/rs780/rs780_gfx.c delete mode 100644 src/southbridge/amd/rs780/rs780_ht.c delete mode 100644 src/southbridge/amd/rs780/rs780_pcie.c delete mode 100644 src/southbridge/amd/rs780/rs780_rev.h create mode 100644 src/southbridge/amd/sb600/ac97.c create mode 100644 src/southbridge/amd/sb600/early_setup.c create mode 100644 src/southbridge/amd/sb600/enable_rom.c create mode 100644 src/southbridge/amd/sb600/enable_usbdebug.c create mode 100644 src/southbridge/amd/sb600/hda.c create mode 100644 src/southbridge/amd/sb600/ide.c create mode 100644 src/southbridge/amd/sb600/lpc.c create mode 100644 src/southbridge/amd/sb600/pci.c create mode 100644 src/southbridge/amd/sb600/reset.c create mode 100644 src/southbridge/amd/sb600/sata.c delete mode 100644 src/southbridge/amd/sb600/sb600_ac97.c delete mode 100644 src/southbridge/amd/sb600/sb600_early_setup.c delete mode 100644 src/southbridge/amd/sb600/sb600_enable_rom.c delete mode 100644 src/southbridge/amd/sb600/sb600_enable_usbdebug.c delete mode 100644 src/southbridge/amd/sb600/sb600_hda.c delete mode 100644 src/southbridge/amd/sb600/sb600_ide.c delete mode 100644 src/southbridge/amd/sb600/sb600_lpc.c delete mode 100644 src/southbridge/amd/sb600/sb600_pci.c delete mode 100644 src/southbridge/amd/sb600/sb600_reset.c delete mode 100644 src/southbridge/amd/sb600/sb600_sata.c delete mode 100644 src/southbridge/amd/sb600/sb600_sm.c delete mode 100644 src/southbridge/amd/sb600/sb600_smbus.c delete mode 100644 src/southbridge/amd/sb600/sb600_smbus.h delete mode 100644 src/southbridge/amd/sb600/sb600_usb.c create mode 100644 src/southbridge/amd/sb600/sm.c create mode 100644 src/southbridge/amd/sb600/smbus.c create mode 100644 src/southbridge/amd/sb600/smbus.h create mode 100644 src/southbridge/amd/sb600/usb.c create mode 100644 src/southbridge/amd/sb700/early_setup.c create mode 100644 src/southbridge/amd/sb700/enable_usbdebug.c create mode 100644 src/southbridge/amd/sb700/hda.c create mode 100644 src/southbridge/amd/sb700/ide.c create mode 100644 src/southbridge/amd/sb700/lpc.c create mode 100644 src/southbridge/amd/sb700/pci.c create mode 100644 src/southbridge/amd/sb700/reset.c create mode 100644 src/southbridge/amd/sb700/sata.c delete mode 100644 src/southbridge/amd/sb700/sb700_early_setup.c delete mode 100644 src/southbridge/amd/sb700/sb700_enable_usbdebug.c delete mode 100644 src/southbridge/amd/sb700/sb700_hda.c delete mode 100644 src/southbridge/amd/sb700/sb700_ide.c delete mode 100644 src/southbridge/amd/sb700/sb700_lpc.c delete mode 100644 src/southbridge/amd/sb700/sb700_pci.c delete mode 100644 src/southbridge/amd/sb700/sb700_reset.c delete mode 100644 src/southbridge/amd/sb700/sb700_sata.c delete mode 100644 src/southbridge/amd/sb700/sb700_sm.c delete mode 100644 src/southbridge/amd/sb700/sb700_smbus.c delete mode 100644 src/southbridge/amd/sb700/sb700_smbus.h delete mode 100644 src/southbridge/amd/sb700/sb700_usb.c create mode 100644 src/southbridge/amd/sb700/sm.c create mode 100644 src/southbridge/amd/sb700/smbus.c create mode 100644 src/southbridge/amd/sb700/smbus.h create mode 100644 src/southbridge/amd/sb700/usb.c delete mode 100644 src/southbridge/broadcom/bcm21000/bcm21000_pcie.c create mode 100644 src/southbridge/broadcom/bcm21000/pcie.c delete mode 100644 src/southbridge/broadcom/bcm5780/bcm5780_nic.c delete mode 100644 src/southbridge/broadcom/bcm5780/bcm5780_pcie.c delete mode 100644 src/southbridge/broadcom/bcm5780/bcm5780_pcix.c create mode 100644 src/southbridge/broadcom/bcm5780/nic.c create mode 100644 src/southbridge/broadcom/bcm5780/pcie.c create mode 100644 src/southbridge/broadcom/bcm5780/pcix.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_enable_rom.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_ide.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_lpc.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_reset.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_sata.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_smbus.h delete mode 100644 src/southbridge/broadcom/bcm5785/bcm5785_usb.c create mode 100644 src/southbridge/broadcom/bcm5785/early_setup.c create mode 100644 src/southbridge/broadcom/bcm5785/early_smbus.c create mode 100644 src/southbridge/broadcom/bcm5785/enable_rom.c create mode 100644 src/southbridge/broadcom/bcm5785/ide.c create mode 100644 src/southbridge/broadcom/bcm5785/lpc.c create mode 100644 src/southbridge/broadcom/bcm5785/reset.c create mode 100644 src/southbridge/broadcom/bcm5785/sata.c create mode 100644 src/southbridge/broadcom/bcm5785/sb_pci_main.c create mode 100644 src/southbridge/broadcom/bcm5785/smbus.h create mode 100644 src/southbridge/broadcom/bcm5785/usb.c create mode 100644 src/southbridge/intel/esb6300/ac97.c create mode 100644 src/southbridge/intel/esb6300/bridge1c.c create mode 100644 src/southbridge/intel/esb6300/early_smbus.c create mode 100644 src/southbridge/intel/esb6300/ehci.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_ac97.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_bridge1c.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_early_smbus.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_ehci.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_ide.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_lpc.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_pci.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_pic.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_reset.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_sata.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_smbus.c delete mode 100644 src/southbridge/intel/esb6300/esb6300_smbus.h delete mode 100644 src/southbridge/intel/esb6300/esb6300_uhci.c create mode 100644 src/southbridge/intel/esb6300/ide.c create mode 100644 src/southbridge/intel/esb6300/lpc.c create mode 100644 src/southbridge/intel/esb6300/pci.c create mode 100644 src/southbridge/intel/esb6300/pic.c create mode 100644 src/southbridge/intel/esb6300/reset.c create mode 100644 src/southbridge/intel/esb6300/sata.c create mode 100644 src/southbridge/intel/esb6300/smbus.c create mode 100644 src/southbridge/intel/esb6300/smbus.h create mode 100644 src/southbridge/intel/esb6300/uhci.c create mode 100644 src/southbridge/intel/i3100/early_lpc.c create mode 100644 src/southbridge/intel/i3100/early_smbus.c create mode 100644 src/southbridge/intel/i3100/ehci.c delete mode 100644 src/southbridge/intel/i3100/i3100_early_lpc.c delete mode 100644 src/southbridge/intel/i3100/i3100_early_smbus.c delete mode 100644 src/southbridge/intel/i3100/i3100_ehci.c delete mode 100644 src/southbridge/intel/i3100/i3100_lpc.c delete mode 100644 src/southbridge/intel/i3100/i3100_pci.c delete mode 100644 src/southbridge/intel/i3100/i3100_pciexp_portb.c delete mode 100644 src/southbridge/intel/i3100/i3100_reset.c delete mode 100644 src/southbridge/intel/i3100/i3100_sata.c delete mode 100644 src/southbridge/intel/i3100/i3100_smbus.c delete mode 100644 src/southbridge/intel/i3100/i3100_smbus.h delete mode 100644 src/southbridge/intel/i3100/i3100_uhci.c create mode 100644 src/southbridge/intel/i3100/lpc.c create mode 100644 src/southbridge/intel/i3100/pci.c create mode 100644 src/southbridge/intel/i3100/pciexp_portb.c create mode 100644 src/southbridge/intel/i3100/reset.c create mode 100644 src/southbridge/intel/i3100/sata.c create mode 100644 src/southbridge/intel/i3100/smbus.c create mode 100644 src/southbridge/intel/i3100/smbus.h create mode 100644 src/southbridge/intel/i3100/uhci.c create mode 100644 src/southbridge/intel/i82371eb/early_pm.c create mode 100644 src/southbridge/intel/i82371eb/early_smbus.c create mode 100644 src/southbridge/intel/i82371eb/enable_rom.c create mode 100644 src/southbridge/intel/i82371eb/fadt.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_early_pm.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_early_smbus.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_enable_rom.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_fadt.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_ide.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_isa.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_reset.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_smbus.c delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_smbus.h delete mode 100644 src/southbridge/intel/i82371eb/i82371eb_usb.c create mode 100644 src/southbridge/intel/i82371eb/ide.c create mode 100644 src/southbridge/intel/i82371eb/isa.c create mode 100644 src/southbridge/intel/i82371eb/reset.c create mode 100644 src/southbridge/intel/i82371eb/smbus.c create mode 100644 src/southbridge/intel/i82371eb/smbus.h create mode 100644 src/southbridge/intel/i82371eb/usb.c create mode 100644 src/southbridge/intel/i82801ax/ac97.c create mode 100644 src/southbridge/intel/i82801ax/early_smbus.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_ac97.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_early_smbus.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_ide.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_lpc.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_pci.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_reset.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_smbus.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_smbus.h delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_usb.c delete mode 100644 src/southbridge/intel/i82801ax/i82801ax_watchdog.c create mode 100644 src/southbridge/intel/i82801ax/ide.c create mode 100644 src/southbridge/intel/i82801ax/lpc.c create mode 100644 src/southbridge/intel/i82801ax/pci.c create mode 100644 src/southbridge/intel/i82801ax/reset.c create mode 100644 src/southbridge/intel/i82801ax/smbus.c create mode 100644 src/southbridge/intel/i82801ax/smbus.h create mode 100644 src/southbridge/intel/i82801ax/usb.c create mode 100644 src/southbridge/intel/i82801ax/watchdog.c create mode 100644 src/southbridge/intel/i82801bx/ac97.c create mode 100644 src/southbridge/intel/i82801bx/early_smbus.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_ac97.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_early_smbus.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_ide.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_lpc.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_nic.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_pci.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_reset.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_smbus.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_smbus.h delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_usb.c delete mode 100644 src/southbridge/intel/i82801bx/i82801bx_watchdog.c create mode 100644 src/southbridge/intel/i82801bx/ide.c create mode 100644 src/southbridge/intel/i82801bx/lpc.c create mode 100644 src/southbridge/intel/i82801bx/nic.c create mode 100644 src/southbridge/intel/i82801bx/pci.c create mode 100644 src/southbridge/intel/i82801bx/reset.c create mode 100644 src/southbridge/intel/i82801bx/smbus.c create mode 100644 src/southbridge/intel/i82801bx/smbus.h create mode 100644 src/southbridge/intel/i82801bx/usb.c create mode 100644 src/southbridge/intel/i82801bx/watchdog.c create mode 100644 src/southbridge/intel/i82801cx/ac97.c create mode 100644 src/southbridge/intel/i82801cx/early_smbus.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_ac97.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_early_smbus.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_ide.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_lpc.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_nic.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_pci.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_reset.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_smbus.c delete mode 100644 src/southbridge/intel/i82801cx/i82801cx_usb.c create mode 100644 src/southbridge/intel/i82801cx/ide.c create mode 100644 src/southbridge/intel/i82801cx/lpc.c create mode 100644 src/southbridge/intel/i82801cx/nic.c create mode 100644 src/southbridge/intel/i82801cx/pci.c create mode 100644 src/southbridge/intel/i82801cx/reset.c create mode 100644 src/southbridge/intel/i82801cx/smbus.c create mode 100644 src/southbridge/intel/i82801cx/usb.c create mode 100644 src/southbridge/intel/i82801dx/ac97.c create mode 100644 src/southbridge/intel/i82801dx/early_smbus.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_ac97.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_early_smbus.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_ide.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_lpc.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_nvs.h delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_pci.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_reset.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_smbus.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_smi.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_smihandler.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_tco_timer.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_usb.c delete mode 100644 src/southbridge/intel/i82801dx/i82801dx_usb2.c create mode 100644 src/southbridge/intel/i82801dx/ide.c create mode 100644 src/southbridge/intel/i82801dx/lpc.c create mode 100644 src/southbridge/intel/i82801dx/nvs.h create mode 100644 src/southbridge/intel/i82801dx/pci.c create mode 100644 src/southbridge/intel/i82801dx/reset.c create mode 100644 src/southbridge/intel/i82801dx/smbus.c create mode 100644 src/southbridge/intel/i82801dx/smi.c create mode 100644 src/southbridge/intel/i82801dx/smihandler.c create mode 100644 src/southbridge/intel/i82801dx/tco_timer.c create mode 100644 src/southbridge/intel/i82801dx/usb.c create mode 100644 src/southbridge/intel/i82801dx/usb2.c create mode 100644 src/southbridge/intel/i82801ex/ac97.c create mode 100644 src/southbridge/intel/i82801ex/early_smbus.c create mode 100644 src/southbridge/intel/i82801ex/ehci.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_ac97.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_early_smbus.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_ehci.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_ide.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_lpc.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_pci.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_reset.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_sata.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_smbus.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_smbus.h delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_uhci.c delete mode 100644 src/southbridge/intel/i82801ex/i82801ex_watchdog.c create mode 100644 src/southbridge/intel/i82801ex/ide.c create mode 100644 src/southbridge/intel/i82801ex/lpc.c create mode 100644 src/southbridge/intel/i82801ex/pci.c create mode 100644 src/southbridge/intel/i82801ex/reset.c create mode 100644 src/southbridge/intel/i82801ex/sata.c create mode 100644 src/southbridge/intel/i82801ex/smbus.c create mode 100644 src/southbridge/intel/i82801ex/smbus.h create mode 100644 src/southbridge/intel/i82801ex/uhci.c create mode 100644 src/southbridge/intel/i82801ex/watchdog.c create mode 100644 src/southbridge/intel/i82801gx/ac97.c create mode 100644 src/southbridge/intel/i82801gx/acpi/ac97.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/audio.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_audio.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_irqlinks.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_pata.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_pci.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_pcie.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_sata.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl delete mode 100644 src/southbridge/intel/i82801gx/acpi/ich7_usb.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/irqlinks.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/lpc.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/pata.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/pci.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/pcie.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/sata.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/smbus.asl create mode 100644 src/southbridge/intel/i82801gx/acpi/usb.asl create mode 100644 src/southbridge/intel/i82801gx/azalia.c create mode 100644 src/southbridge/intel/i82801gx/early_smbus.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_ac97.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_azalia.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_early_smbus.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_ide.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_lpc.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_nic.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_nvs.h delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_pci.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_pcie.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_reset.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_sata.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_smbus.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_smbus.h delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_smi.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_smihandler.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_usb.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_usb_debug.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c delete mode 100644 src/southbridge/intel/i82801gx/i82801gx_watchdog.c create mode 100644 src/southbridge/intel/i82801gx/ide.c create mode 100644 src/southbridge/intel/i82801gx/lpc.c create mode 100644 src/southbridge/intel/i82801gx/nic.c create mode 100644 src/southbridge/intel/i82801gx/nvs.h create mode 100644 src/southbridge/intel/i82801gx/pci.c create mode 100644 src/southbridge/intel/i82801gx/pcie.c create mode 100644 src/southbridge/intel/i82801gx/reset.c create mode 100644 src/southbridge/intel/i82801gx/sata.c create mode 100644 src/southbridge/intel/i82801gx/smbus.c create mode 100644 src/southbridge/intel/i82801gx/smbus.h create mode 100644 src/southbridge/intel/i82801gx/smi.c create mode 100644 src/southbridge/intel/i82801gx/smihandler.c create mode 100644 src/southbridge/intel/i82801gx/usb.c create mode 100644 src/southbridge/intel/i82801gx/usb_debug.c create mode 100644 src/southbridge/intel/i82801gx/usb_ehci.c create mode 100644 src/southbridge/intel/i82801gx/watchdog.c create mode 100644 src/southbridge/intel/i82870/ioapic.c delete mode 100644 src/southbridge/intel/i82870/p64h2_ioapic.c delete mode 100644 src/southbridge/intel/i82870/p64h2_pci_parity.c delete mode 100644 src/southbridge/intel/i82870/p64h2_pcibridge.c create mode 100644 src/southbridge/intel/i82870/pci_parity.c create mode 100644 src/southbridge/intel/i82870/pcibridge.c create mode 100644 src/southbridge/intel/pxhd/bridge.c delete mode 100644 src/southbridge/intel/pxhd/pxhd_bridge.c create mode 100644 src/southbridge/nvidia/ck804/ac97.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_ac97.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_early_setup.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_early_setup_car.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_early_setup_ss.h delete mode 100644 src/southbridge/nvidia/ck804/ck804_early_smbus.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_early_smbus.h delete mode 100644 src/southbridge/nvidia/ck804/ck804_enable_rom.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_enable_usbdebug.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_fadt.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_ht.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_ide.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_lpc.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_nic.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_pci.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_pcie.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_reset.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_sata.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_smbus.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_smbus.h delete mode 100644 src/southbridge/nvidia/ck804/ck804_usb.c delete mode 100644 src/southbridge/nvidia/ck804/ck804_usb2.c create mode 100644 src/southbridge/nvidia/ck804/early_setup.c create mode 100644 src/southbridge/nvidia/ck804/early_setup_car.c create mode 100644 src/southbridge/nvidia/ck804/early_setup_ss.h create mode 100644 src/southbridge/nvidia/ck804/early_smbus.c create mode 100644 src/southbridge/nvidia/ck804/early_smbus.h create mode 100644 src/southbridge/nvidia/ck804/enable_rom.c create mode 100644 src/southbridge/nvidia/ck804/enable_usbdebug.c create mode 100644 src/southbridge/nvidia/ck804/fadt.c create mode 100644 src/southbridge/nvidia/ck804/ht.c create mode 100644 src/southbridge/nvidia/ck804/ide.c create mode 100644 src/southbridge/nvidia/ck804/lpc.c create mode 100644 src/southbridge/nvidia/ck804/nic.c create mode 100644 src/southbridge/nvidia/ck804/pci.c create mode 100644 src/southbridge/nvidia/ck804/pcie.c create mode 100644 src/southbridge/nvidia/ck804/reset.c create mode 100644 src/southbridge/nvidia/ck804/sata.c create mode 100644 src/southbridge/nvidia/ck804/smbus.c create mode 100644 src/southbridge/nvidia/ck804/smbus.h create mode 100644 src/southbridge/nvidia/ck804/usb.c create mode 100644 src/southbridge/nvidia/ck804/usb2.c create mode 100644 src/southbridge/nvidia/mcp55/azalia.c create mode 100644 src/southbridge/nvidia/mcp55/early_ctrl.c create mode 100644 src/southbridge/nvidia/mcp55/early_setup_car.c create mode 100644 src/southbridge/nvidia/mcp55/early_setup_ss.h create mode 100644 src/southbridge/nvidia/mcp55/early_smbus.c create mode 100644 src/southbridge/nvidia/mcp55/enable_rom.c create mode 100644 src/southbridge/nvidia/mcp55/enable_usbdebug.c create mode 100644 src/southbridge/nvidia/mcp55/fadt.c create mode 100644 src/southbridge/nvidia/mcp55/ht.c create mode 100644 src/southbridge/nvidia/mcp55/ide.c create mode 100644 src/southbridge/nvidia/mcp55/lpc.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_azalia.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_early_ctrl.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_early_setup_ss.h delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_early_smbus.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_enable_rom.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_enable_usbdebug.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_fadt.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_ht.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_ide.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_lpc.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_nic.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_pci.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_pcie.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_reset.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_sata.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_smbus.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_smbus.h delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_usb.c delete mode 100644 src/southbridge/nvidia/mcp55/mcp55_usb2.c create mode 100644 src/southbridge/nvidia/mcp55/nic.c create mode 100644 src/southbridge/nvidia/mcp55/pci.c create mode 100644 src/southbridge/nvidia/mcp55/pcie.c create mode 100644 src/southbridge/nvidia/mcp55/reset.c create mode 100644 src/southbridge/nvidia/mcp55/sata.c create mode 100644 src/southbridge/nvidia/mcp55/smbus.c create mode 100644 src/southbridge/nvidia/mcp55/smbus.h create mode 100644 src/southbridge/nvidia/mcp55/usb.c create mode 100644 src/southbridge/nvidia/mcp55/usb2.c create mode 100644 src/southbridge/sis/sis966/aza.c create mode 100644 src/southbridge/sis/sis966/early_ctrl.c create mode 100644 src/southbridge/sis/sis966/early_setup_car.c create mode 100644 src/southbridge/sis/sis966/early_setup_ss.h create mode 100644 src/southbridge/sis/sis966/early_smbus.c create mode 100644 src/southbridge/sis/sis966/enable_rom.c create mode 100644 src/southbridge/sis/sis966/enable_usbdebug.c create mode 100644 src/southbridge/sis/sis966/ide.c create mode 100644 src/southbridge/sis/sis966/lpc.c create mode 100644 src/southbridge/sis/sis966/nic.c create mode 100644 src/southbridge/sis/sis966/pcie.c create mode 100644 src/southbridge/sis/sis966/reset.c create mode 100644 src/southbridge/sis/sis966/sata.c delete mode 100644 src/southbridge/sis/sis966/sis966_aza.c delete mode 100644 src/southbridge/sis/sis966/sis966_early_ctrl.c delete mode 100644 src/southbridge/sis/sis966/sis966_early_setup_car.c delete mode 100644 src/southbridge/sis/sis966/sis966_early_setup_ss.h delete mode 100644 src/southbridge/sis/sis966/sis966_early_smbus.c delete mode 100644 src/southbridge/sis/sis966/sis966_enable_rom.c delete mode 100644 src/southbridge/sis/sis966/sis966_enable_usbdebug.c delete mode 100644 src/southbridge/sis/sis966/sis966_ide.c delete mode 100644 src/southbridge/sis/sis966/sis966_lpc.c delete mode 100644 src/southbridge/sis/sis966/sis966_nic.c delete mode 100644 src/southbridge/sis/sis966/sis966_pcie.c delete mode 100644 src/southbridge/sis/sis966/sis966_reset.c delete mode 100644 src/southbridge/sis/sis966/sis966_sata.c delete mode 100644 src/southbridge/sis/sis966/sis966_smbus.h delete mode 100644 src/southbridge/sis/sis966/sis966_usb.c delete mode 100644 src/southbridge/sis/sis966/sis966_usb2.c create mode 100644 src/southbridge/sis/sis966/smbus.h create mode 100644 src/southbridge/sis/sis966/usb.c create mode 100644 src/southbridge/sis/sis966/usb2.c create mode 100644 src/southbridge/ti/pci7420/cardbus.c create mode 100644 src/southbridge/ti/pci7420/firewire.c delete mode 100644 src/southbridge/ti/pci7420/pci7420_cardbus.c delete mode 100644 src/southbridge/ti/pci7420/pci7420_firewire.c create mode 100644 src/southbridge/via/k8t890/bridge.c create mode 100644 src/southbridge/via/k8t890/chrome.c create mode 100644 src/southbridge/via/k8t890/ctrl.c create mode 100644 src/southbridge/via/k8t890/dram.c create mode 100644 src/southbridge/via/k8t890/early_car.c create mode 100644 src/southbridge/via/k8t890/error.c create mode 100644 src/southbridge/via/k8t890/host.c create mode 100644 src/southbridge/via/k8t890/host_ctrl.c delete mode 100644 src/southbridge/via/k8t890/k8m890_chrome.c delete mode 100644 src/southbridge/via/k8t890/k8t890_bridge.c delete mode 100644 src/southbridge/via/k8t890/k8t890_ctrl.c delete mode 100644 src/southbridge/via/k8t890/k8t890_dram.c delete mode 100644 src/southbridge/via/k8t890/k8t890_early_car.c delete mode 100644 src/southbridge/via/k8t890/k8t890_error.c delete mode 100644 src/southbridge/via/k8t890/k8t890_host.c delete mode 100644 src/southbridge/via/k8t890/k8t890_host_ctrl.c delete mode 100644 src/southbridge/via/k8t890/k8t890_pcie.c delete mode 100644 src/southbridge/via/k8t890/k8t890_traf_ctrl.c create mode 100644 src/southbridge/via/k8t890/pcie.c create mode 100644 src/southbridge/via/k8t890/traf_ctrl.c create mode 100644 src/southbridge/via/vt8231/acpi.c create mode 100644 src/southbridge/via/vt8231/early_serial.c create mode 100644 src/southbridge/via/vt8231/early_smbus.c create mode 100644 src/southbridge/via/vt8231/enable_rom.c create mode 100644 src/southbridge/via/vt8231/ide.c create mode 100644 src/southbridge/via/vt8231/lpc.c create mode 100644 src/southbridge/via/vt8231/nic.c create mode 100644 src/southbridge/via/vt8231/usb.c delete mode 100644 src/southbridge/via/vt8231/vt8231_acpi.c delete mode 100644 src/southbridge/via/vt8231/vt8231_early_serial.c delete mode 100644 src/southbridge/via/vt8231/vt8231_early_smbus.c delete mode 100644 src/southbridge/via/vt8231/vt8231_enable_rom.c delete mode 100644 src/southbridge/via/vt8231/vt8231_ide.c delete mode 100644 src/southbridge/via/vt8231/vt8231_lpc.c delete mode 100644 src/southbridge/via/vt8231/vt8231_nic.c delete mode 100644 src/southbridge/via/vt8231/vt8231_usb.c create mode 100644 src/southbridge/via/vt8235/early_serial.c create mode 100644 src/southbridge/via/vt8235/early_smbus.c create mode 100644 src/southbridge/via/vt8235/ide.c create mode 100644 src/southbridge/via/vt8235/lpc.c create mode 100644 src/southbridge/via/vt8235/nic.c create mode 100644 src/southbridge/via/vt8235/usb.c delete mode 100644 src/southbridge/via/vt8235/vt8235_early_serial.c delete mode 100644 src/southbridge/via/vt8235/vt8235_early_smbus.c delete mode 100644 src/southbridge/via/vt8235/vt8235_ide.c delete mode 100644 src/southbridge/via/vt8235/vt8235_lpc.c delete mode 100644 src/southbridge/via/vt8235/vt8235_nic.c delete mode 100644 src/southbridge/via/vt8235/vt8235_usb.c create mode 100644 src/southbridge/via/vt8237r/ctrl.c create mode 100644 src/southbridge/via/vt8237r/early_smbus.c create mode 100644 src/southbridge/via/vt8237r/fadt.c create mode 100644 src/southbridge/via/vt8237r/ide.c create mode 100644 src/southbridge/via/vt8237r/lpc.c create mode 100644 src/southbridge/via/vt8237r/nic.c create mode 100644 src/southbridge/via/vt8237r/pirq.c create mode 100644 src/southbridge/via/vt8237r/sata.c create mode 100644 src/southbridge/via/vt8237r/usb.c delete mode 100644 src/southbridge/via/vt8237r/vt8237_ctrl.c delete mode 100644 src/southbridge/via/vt8237r/vt8237_fadt.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_early_smbus.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_ide.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_lpc.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_nic.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_pirq.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_sata.c delete mode 100644 src/southbridge/via/vt8237r/vt8237r_usb.c create mode 100644 src/southbridge/via/vt82c686/early_serial.c delete mode 100644 src/southbridge/via/vt82c686/vt82c686_early_serial.c (limited to 'src/southbridge') diff --git a/src/southbridge/amd/amd8111/Makefile.inc b/src/southbridge/amd/amd8111/Makefile.inc index b58fbaac88..cdad4a62ab 100644 --- a/src/southbridge/amd/amd8111/Makefile.inc +++ b/src/southbridge/amd/amd8111/Makefile.inc @@ -1,11 +1,11 @@ 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 diff --git a/src/southbridge/amd/amd8111/ac97.c b/src/southbridge/amd/amd8111/ac97.c new file mode 100644 index 0000000000..f49c9bfd5f --- /dev/null +++ b/src/southbridge/amd/amd8111/ac97.c @@ -0,0 +1,52 @@ +/* + * (C) 2003 Linux Networx + */ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8111/acpi.c b/src/southbridge/amd/amd8111/acpi.c new file mode 100644 index 0000000000..2ad54b78f6 --- /dev/null +++ b/src/southbridge/amd/amd8111/acpi.c @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/amd/amd8111/amd8111_ac97.c b/src/southbridge/amd/amd8111/amd8111_ac97.c deleted file mode 100644 index f49c9bfd5f..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_ac97.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * (C) 2003 Linux Networx - */ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/amd8111_acpi.c b/src/southbridge/amd/amd8111/amd8111_acpi.c deleted file mode 100644 index 2ad54b78f6..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_acpi.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/amd/amd8111/amd8111_early_ctrl.c b/src/southbridge/amd/amd8111/amd8111_early_ctrl.c deleted file mode 100644 index ece99ed40a..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_early_ctrl.c +++ /dev/null @@ -1,83 +0,0 @@ -#include "amd8111.h" -#include - -/* 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); - -} diff --git a/src/southbridge/amd/amd8111/amd8111_early_smbus.c b/src/southbridge/amd/amd8111/amd8111_early_smbus.c deleted file mode 100644 index e6d70847ea..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_early_smbus.c +++ /dev/null @@ -1,48 +0,0 @@ -#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); -} - diff --git a/src/southbridge/amd/amd8111/amd8111_enable_rom.c b/src/southbridge/amd/amd8111/amd8111_enable_rom.c deleted file mode 100644 index 3e73112b47..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_enable_rom.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2003 Linux Networx - * (Written by Eric Biederman 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 -#include -#include -#include - -/* 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); -} diff --git a/src/southbridge/amd/amd8111/amd8111_ide.c b/src/southbridge/amd/amd8111/amd8111_ide.c deleted file mode 100644 index 3299875187..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_ide.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/amd/amd8111/amd8111_lpc.c b/src/southbridge/amd/amd8111/amd8111_lpc.c deleted file mode 100644 index e9bd5fc42b..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_lpc.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * (C) 2003 Linux Networx, SuSE Linux AG - * 2006.1 yhlu add dest apicid for IRQ0 - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/amd8111_nic.c b/src/southbridge/amd/amd8111/amd8111_nic.c deleted file mode 100644 index 4ab7212eda..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_nic.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * (C) 2003 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/amd8111_pci.c b/src/southbridge/amd/amd8111/amd8111_pci.c deleted file mode 100644 index 9e7724980f..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_pci.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/amd/amd8111/amd8111_reset.c b/src/southbridge/amd/amd8111/amd8111_reset.c deleted file mode 100644 index c96e898aea..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_reset.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include - -#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); -} diff --git a/src/southbridge/amd/amd8111/amd8111_smbus.c b/src/southbridge/amd/amd8111/amd8111_smbus.c deleted file mode 100644 index 0a0c58dce3..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_smbus.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/amd8111_usb.c b/src/southbridge/amd/amd8111/amd8111_usb.c deleted file mode 100644 index 13dccf435b..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_usb.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/amd8111_usb2.c b/src/southbridge/amd/amd8111/amd8111_usb2.c deleted file mode 100644 index 89115c3bbe..0000000000 --- a/src/southbridge/amd/amd8111/amd8111_usb2.c +++ /dev/null @@ -1,45 +0,0 @@ -//2003 Copywright Tyan - -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/amd8111/bootblock.c b/src/southbridge/amd/amd8111/bootblock.c index 695f49898b..a11d1d30f4 100644 --- a/src/southbridge/amd/amd8111/bootblock.c +++ b/src/southbridge/amd/amd8111/bootblock.c @@ -1,4 +1,4 @@ -#include "southbridge/amd/amd8111/amd8111_enable_rom.c" +#include "southbridge/amd/amd8111/enable_rom.c" static void bootblock_southbridge_init(void) { diff --git a/src/southbridge/amd/amd8111/early_ctrl.c b/src/southbridge/amd/amd8111/early_ctrl.c new file mode 100644 index 0000000000..ece99ed40a --- /dev/null +++ b/src/southbridge/amd/amd8111/early_ctrl.c @@ -0,0 +1,83 @@ +#include "amd8111.h" +#include + +/* 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); + +} diff --git a/src/southbridge/amd/amd8111/early_smbus.c b/src/southbridge/amd/amd8111/early_smbus.c new file mode 100644 index 0000000000..e6d70847ea --- /dev/null +++ b/src/southbridge/amd/amd8111/early_smbus.c @@ -0,0 +1,48 @@ +#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); +} + diff --git a/src/southbridge/amd/amd8111/enable_rom.c b/src/southbridge/amd/amd8111/enable_rom.c new file mode 100644 index 0000000000..3e73112b47 --- /dev/null +++ b/src/southbridge/amd/amd8111/enable_rom.c @@ -0,0 +1,42 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2003 Linux Networx + * (Written by Eric Biederman 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 +#include +#include +#include + +/* 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); +} diff --git a/src/southbridge/amd/amd8111/ide.c b/src/southbridge/amd/amd8111/ide.c new file mode 100644 index 0000000000..3299875187 --- /dev/null +++ b/src/southbridge/amd/amd8111/ide.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/amd/amd8111/lpc.c b/src/southbridge/amd/amd8111/lpc.c new file mode 100644 index 0000000000..e9bd5fc42b --- /dev/null +++ b/src/southbridge/amd/amd8111/lpc.c @@ -0,0 +1,133 @@ +/* + * (C) 2003 Linux Networx, SuSE Linux AG + * 2006.1 yhlu add dest apicid for IRQ0 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8111/nic.c b/src/southbridge/amd/amd8111/nic.c new file mode 100644 index 0000000000..4ab7212eda --- /dev/null +++ b/src/southbridge/amd/amd8111/nic.c @@ -0,0 +1,90 @@ +/* + * (C) 2003 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8111/pci.c b/src/southbridge/amd/amd8111/pci.c new file mode 100644 index 0000000000..9e7724980f --- /dev/null +++ b/src/southbridge/amd/amd8111/pci.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/amd/amd8111/reset.c b/src/southbridge/amd/amd8111/reset.c new file mode 100644 index 0000000000..c96e898aea --- /dev/null +++ b/src/southbridge/amd/amd8111/reset.c @@ -0,0 +1,76 @@ +#include +#include +#include + +#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); +} diff --git a/src/southbridge/amd/amd8111/smbus.c b/src/southbridge/amd/amd8111/smbus.c new file mode 100644 index 0000000000..0a0c58dce3 --- /dev/null +++ b/src/southbridge/amd/amd8111/smbus.c @@ -0,0 +1,41 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8111/usb.c b/src/southbridge/amd/amd8111/usb.c new file mode 100644 index 0000000000..13dccf435b --- /dev/null +++ b/src/southbridge/amd/amd8111/usb.c @@ -0,0 +1,37 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8111/usb2.c b/src/southbridge/amd/amd8111/usb2.c new file mode 100644 index 0000000000..89115c3bbe --- /dev/null +++ b/src/southbridge/amd/amd8111/usb2.c @@ -0,0 +1,45 @@ +//2003 Copywright Tyan + +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/amd8131-disable/amd8131_bridge.c b/src/southbridge/amd/amd8131-disable/amd8131_bridge.c deleted file mode 100644 index e90f497d95..0000000000 --- a/src/southbridge/amd/amd8131-disable/amd8131_bridge.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include - -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, - -}; diff --git a/src/southbridge/amd/amd8131-disable/bridge.c b/src/southbridge/amd/amd8131-disable/bridge.c new file mode 100644 index 0000000000..e90f497d95 --- /dev/null +++ b/src/southbridge/amd/amd8131-disable/bridge.c @@ -0,0 +1,116 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include + +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, + +}; diff --git a/src/southbridge/amd/amd8131/Makefile.inc b/src/southbridge/amd/amd8131/Makefile.inc index 395f0e0e0c..d5b3a5f88e 100644 --- a/src/southbridge/amd/amd8131/Makefile.inc +++ b/src/southbridge/amd/amd8131/Makefile.inc @@ -1 +1 @@ -driver-y += amd8131_bridge.c +driver-y += bridge.c diff --git a/src/southbridge/amd/amd8131/amd8131_bridge.c b/src/southbridge/amd/amd8131/amd8131_bridge.c deleted file mode 100644 index d258450a06..0000000000 --- a/src/southbridge/amd/amd8131/amd8131_bridge.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * (C) 2003-2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#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, - -}; diff --git a/src/southbridge/amd/amd8131/bridge.c b/src/southbridge/amd/amd8131/bridge.c new file mode 100644 index 0000000000..d258450a06 --- /dev/null +++ b/src/southbridge/amd/amd8131/bridge.c @@ -0,0 +1,432 @@ +/* + * (C) 2003-2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#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, + +}; diff --git a/src/southbridge/amd/amd8132/Makefile.inc b/src/southbridge/amd/amd8132/Makefile.inc index f1e844af10..d5b3a5f88e 100644 --- a/src/southbridge/amd/amd8132/Makefile.inc +++ b/src/southbridge/amd/amd8132/Makefile.inc @@ -1 +1 @@ -driver-y += amd8132_bridge.c +driver-y += bridge.c diff --git a/src/southbridge/amd/amd8132/amd8132_bridge.c b/src/southbridge/amd/amd8132/amd8132_bridge.c deleted file mode 100644 index 192137a18e..0000000000 --- a/src/southbridge/amd/amd8132/amd8132_bridge.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -#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, - -}; diff --git a/src/southbridge/amd/amd8132/bridge.c b/src/southbridge/amd/amd8132/bridge.c new file mode 100644 index 0000000000..192137a18e --- /dev/null +++ b/src/southbridge/amd/amd8132/bridge.c @@ -0,0 +1,433 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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, + +}; diff --git a/src/southbridge/amd/amd8151/Makefile.inc b/src/southbridge/amd/amd8151/Makefile.inc index d9b46989c6..b25139108a 100644 --- a/src/southbridge/amd/amd8151/Makefile.inc +++ b/src/southbridge/amd/amd8151/Makefile.inc @@ -1 +1 @@ -driver-y += amd8151_agp3.c +driver-y += agp3.c diff --git a/src/southbridge/amd/amd8151/agp3.c b/src/southbridge/amd/amd8151/agp3.c new file mode 100644 index 0000000000..a2df7035c9 --- /dev/null +++ b/src/southbridge/amd/amd8151/agp3.c @@ -0,0 +1,90 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2003 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include + +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 +}; diff --git a/src/southbridge/amd/amd8151/amd8151_agp3.c b/src/southbridge/amd/amd8151/amd8151_agp3.c deleted file mode 100644 index a2df7035c9..0000000000 --- a/src/southbridge/amd/amd8151/amd8151_agp3.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2003 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include - -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 -}; diff --git a/src/southbridge/amd/cs5530/Makefile.inc b/src/southbridge/amd/cs5530/Makefile.inc index f51369fac1..4bde476743 100644 --- a/src/southbridge/amd/cs5530/Makefile.inc +++ b/src/southbridge/amd/cs5530/Makefile.inc @@ -19,7 +19,7 @@ ## 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 diff --git a/src/southbridge/amd/cs5530/cs5530_enable_rom.c b/src/southbridge/amd/cs5530/cs5530_enable_rom.c deleted file mode 100644 index 09ec3ed791..0000000000 --- a/src/southbridge/amd/cs5530/cs5530_enable_rom.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This program is free software; 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 -#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); -} diff --git a/src/southbridge/amd/cs5530/cs5530_ide.c b/src/southbridge/amd/cs5530/cs5530_ide.c deleted file mode 100644 index a1fa2dc2c3..0000000000 --- a/src/southbridge/amd/cs5530/cs5530_ide.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/cs5530/cs5530_isa.c b/src/southbridge/amd/cs5530/cs5530_isa.c deleted file mode 100644 index ff1617ddc3..0000000000 --- a/src/southbridge/amd/cs5530/cs5530_isa.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/cs5530/cs5530_pirq.c b/src/southbridge/amd/cs5530/cs5530_pirq.c deleted file mode 100644 index 693f7c4721..0000000000 --- a/src/southbridge/amd/cs5530/cs5530_pirq.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Nikolay Petukhov - * - * This program is free software; 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 -#include -#include -#include - -#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 diff --git a/src/southbridge/amd/cs5530/cs5530_vga.c b/src/southbridge/amd/cs5530/cs5530_vga.c deleted file mode 100644 index 4a26251084..0000000000 --- a/src/southbridge/amd/cs5530/cs5530_vga.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Juergen Beisert - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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 -#include -#include -#include -#include -#include -#include -#include - -#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 */ diff --git a/src/southbridge/amd/cs5530/enable_rom.c b/src/southbridge/amd/cs5530/enable_rom.c new file mode 100644 index 0000000000..09ec3ed791 --- /dev/null +++ b/src/southbridge/amd/cs5530/enable_rom.c @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This program is free software; 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 +#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); +} diff --git a/src/southbridge/amd/cs5530/ide.c b/src/southbridge/amd/cs5530/ide.c new file mode 100644 index 0000000000..a1fa2dc2c3 --- /dev/null +++ b/src/southbridge/amd/cs5530/ide.c @@ -0,0 +1,78 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/cs5530/isa.c b/src/southbridge/amd/cs5530/isa.c new file mode 100644 index 0000000000..ff1617ddc3 --- /dev/null +++ b/src/southbridge/amd/cs5530/isa.c @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/cs5530/pirq.c b/src/southbridge/amd/cs5530/pirq.c new file mode 100644 index 0000000000..693f7c4721 --- /dev/null +++ b/src/southbridge/amd/cs5530/pirq.c @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Nikolay Petukhov + * + * This program is free software; 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 +#include +#include +#include + +#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 diff --git a/src/southbridge/amd/cs5530/vga.c b/src/southbridge/amd/cs5530/vga.c new file mode 100644 index 0000000000..4a26251084 --- /dev/null +++ b/src/southbridge/amd/cs5530/vga.c @@ -0,0 +1,495 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Juergen Beisert + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 +#include +#include +#include +#include +#include +#include +#include + +#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 */ diff --git a/src/southbridge/amd/cs5535/Makefile.inc b/src/southbridge/amd/cs5535/Makefile.inc index ba092f125b..5fecea8e7e 100644 --- a/src/southbridge/amd/cs5535/Makefile.inc +++ b/src/southbridge/amd/cs5535/Makefile.inc @@ -1,4 +1,4 @@ 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 diff --git a/src/southbridge/amd/cs5535/cs5535_early_setup.c b/src/southbridge/amd/cs5535/cs5535_early_setup.c deleted file mode 100644 index 1a612cc55f..0000000000 --- a/src/southbridge/amd/cs5535/cs5535_early_setup.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * - * 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(); -} diff --git a/src/southbridge/amd/cs5535/cs5535_early_smbus.c b/src/southbridge/amd/cs5535/cs5535_early_smbus.c deleted file mode 100644 index 0aab46f6a3..0000000000 --- a/src/southbridge/amd/cs5535/cs5535_early_smbus.c +++ /dev/null @@ -1,22 +0,0 @@ -#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); -} diff --git a/src/southbridge/amd/cs5535/cs5535_ide.c b/src/southbridge/amd/cs5535/cs5535_ide.c deleted file mode 100644 index b997ca2463..0000000000 --- a/src/southbridge/amd/cs5535/cs5535_ide.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/cs5535/cs5535_smbus.h b/src/southbridge/amd/cs5535/cs5535_smbus.h deleted file mode 100644 index db35f6ee7b..0000000000 --- a/src/southbridge/amd/cs5535/cs5535_smbus.h +++ /dev/null @@ -1,46 +0,0 @@ -//#include -#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 diff --git a/src/southbridge/amd/cs5535/early_setup.c b/src/southbridge/amd/cs5535/early_setup.c new file mode 100644 index 0000000000..1a612cc55f --- /dev/null +++ b/src/southbridge/amd/cs5535/early_setup.c @@ -0,0 +1,149 @@ +/* + * + * 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(); +} diff --git a/src/southbridge/amd/cs5535/early_smbus.c b/src/southbridge/amd/cs5535/early_smbus.c new file mode 100644 index 0000000000..25b6951daa --- /dev/null +++ b/src/southbridge/amd/cs5535/early_smbus.c @@ -0,0 +1,22 @@ +#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); +} diff --git a/src/southbridge/amd/cs5535/ide.c b/src/southbridge/amd/cs5535/ide.c new file mode 100644 index 0000000000..b997ca2463 --- /dev/null +++ b/src/southbridge/amd/cs5535/ide.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/cs5535/smbus.h b/src/southbridge/amd/cs5535/smbus.h new file mode 100644 index 0000000000..db35f6ee7b --- /dev/null +++ b/src/southbridge/amd/cs5535/smbus.h @@ -0,0 +1,46 @@ +//#include +#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 diff --git a/src/southbridge/amd/cs5536/Makefile.inc b/src/southbridge/amd/cs5536/Makefile.inc index a1a36833fc..75c6e5c930 100644 --- a/src/southbridge/amd/cs5536/Makefile.inc +++ b/src/southbridge/amd/cs5536/Makefile.inc @@ -18,5 +18,5 @@ ## driver-y += cs5536.c -driver-y += cs5536_ide.c -driver-y += cs5536_pirq.c +driver-y += ide.c +driver-y += pirq.c diff --git a/src/southbridge/amd/cs5536/cs5536_early_setup.c b/src/southbridge/amd/cs5536/cs5536_early_setup.c deleted file mode 100644 index 047c1a21a0..0000000000 --- a/src/southbridge/amd/cs5536/cs5536_early_setup.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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(); -} diff --git a/src/southbridge/amd/cs5536/cs5536_early_smbus.c b/src/southbridge/amd/cs5536/cs5536_early_smbus.c deleted file mode 100644 index 5cb815d250..0000000000 --- a/src/southbridge/amd/cs5536/cs5536_early_smbus.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/amd/cs5536/cs5536_ide.c b/src/southbridge/amd/cs5536/cs5536_ide.c deleted file mode 100644 index c4cc652e93..0000000000 --- a/src/southbridge/amd/cs5536/cs5536_ide.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/cs5536/cs5536_pirq.c b/src/southbridge/amd/cs5536/cs5536_pirq.c deleted file mode 100644 index b2ae1fe3af..0000000000 --- a/src/southbridge/amd/cs5536/cs5536_pirq.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Nikolay Petukhov - * - * This program is free software; 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 -#include -#include -#include - -#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 diff --git a/src/southbridge/amd/cs5536/cs5536_smbus2.h b/src/southbridge/amd/cs5536/cs5536_smbus2.h deleted file mode 100644 index dea08a437c..0000000000 --- a/src/southbridge/amd/cs5536/cs5536_smbus2.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/amd/cs5536/early_setup.c b/src/southbridge/amd/cs5536/early_setup.c new file mode 100644 index 0000000000..047c1a21a0 --- /dev/null +++ b/src/southbridge/amd/cs5536/early_setup.c @@ -0,0 +1,275 @@ +/* + * 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(); +} diff --git a/src/southbridge/amd/cs5536/early_smbus.c b/src/southbridge/amd/cs5536/early_smbus.c new file mode 100644 index 0000000000..5cb815d250 --- /dev/null +++ b/src/southbridge/amd/cs5536/early_smbus.c @@ -0,0 +1,213 @@ +/* + * 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); +} diff --git a/src/southbridge/amd/cs5536/ide.c b/src/southbridge/amd/cs5536/ide.c new file mode 100644 index 0000000000..c4cc652e93 --- /dev/null +++ b/src/southbridge/amd/cs5536/ide.c @@ -0,0 +1,61 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/cs5536/pirq.c b/src/southbridge/amd/cs5536/pirq.c new file mode 100644 index 0000000000..b2ae1fe3af --- /dev/null +++ b/src/southbridge/amd/cs5536/pirq.c @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Nikolay Petukhov + * + * This program is free software; 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 +#include +#include +#include + +#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 diff --git a/src/southbridge/amd/cs5536/smbus2.h b/src/southbridge/amd/cs5536/smbus2.h new file mode 100644 index 0000000000..dea08a437c --- /dev/null +++ b/src/southbridge/amd/cs5536/smbus2.h @@ -0,0 +1,317 @@ +/* + * 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); +} diff --git a/src/southbridge/amd/rs690/Makefile.inc b/src/southbridge/amd/rs690/Makefile.inc index c728be56a4..5849340ce0 100644 --- a/src/southbridge/amd/rs690/Makefile.inc +++ b/src/southbridge/amd/rs690/Makefile.inc @@ -1,5 +1,5 @@ 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 diff --git a/src/southbridge/amd/rs690/cmn.c b/src/southbridge/amd/rs690/cmn.c new file mode 100644 index 0000000000..5e06d4f9d8 --- /dev/null +++ b/src/southbridge/amd/rs690/cmn.c @@ -0,0 +1,324 @@ +/* + * 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#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); +} + diff --git a/src/southbridge/amd/rs690/early_setup.c b/src/southbridge/amd/rs690/early_setup.c new file mode 100644 index 0000000000..f29d136791 --- /dev/null +++ b/src/southbridge/amd/rs690/early_setup.c @@ -0,0 +1,484 @@ +/* + * 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); +} diff --git a/src/southbridge/amd/rs690/gfx.c b/src/southbridge/amd/rs690/gfx.c new file mode 100644 index 0000000000..c55f2bc3d3 --- /dev/null +++ b/src/southbridge/amd/rs690/gfx.c @@ -0,0 +1,625 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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; + } +} diff --git a/src/southbridge/amd/rs690/ht.c b/src/southbridge/amd/rs690/ht.c new file mode 100644 index 0000000000..26824b5322 --- /dev/null +++ b/src/southbridge/amd/rs690/ht.c @@ -0,0 +1,90 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/rs690/pcie.c b/src/southbridge/amd/rs690/pcie.c new file mode 100644 index 0000000000..f02e0d73b4 --- /dev/null +++ b/src/southbridge/amd/rs690/pcie.c @@ -0,0 +1,401 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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 diff --git a/src/southbridge/amd/rs690/rs690_cmn.c b/src/southbridge/amd/rs690/rs690_cmn.c deleted file mode 100644 index 5e06d4f9d8..0000000000 --- a/src/southbridge/amd/rs690/rs690_cmn.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * 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 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#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); -} - diff --git a/src/southbridge/amd/rs690/rs690_early_setup.c b/src/southbridge/amd/rs690/rs690_early_setup.c deleted file mode 100644 index f29d136791..0000000000 --- a/src/southbridge/amd/rs690/rs690_early_setup.c +++ /dev/null @@ -1,484 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/amd/rs690/rs690_gfx.c b/src/southbridge/amd/rs690/rs690_gfx.c deleted file mode 100644 index c55f2bc3d3..0000000000 --- a/src/southbridge/amd/rs690/rs690_gfx.c +++ /dev/null @@ -1,625 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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; - } -} diff --git a/src/southbridge/amd/rs690/rs690_ht.c b/src/southbridge/amd/rs690/rs690_ht.c deleted file mode 100644 index 26824b5322..0000000000 --- a/src/southbridge/amd/rs690/rs690_ht.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/rs690/rs690_pcie.c b/src/southbridge/amd/rs690/rs690_pcie.c deleted file mode 100644 index f02e0d73b4..0000000000 --- a/src/southbridge/amd/rs690/rs690_pcie.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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 diff --git a/src/southbridge/amd/rs780/Makefile.inc b/src/southbridge/amd/rs780/Makefile.inc index f76e517c82..db425702d6 100644 --- a/src/southbridge/amd/rs780/Makefile.inc +++ b/src/southbridge/amd/rs780/Makefile.inc @@ -1,5 +1,5 @@ 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 diff --git a/src/southbridge/amd/rs780/cmn.c b/src/southbridge/amd/rs780/cmn.c new file mode 100644 index 0000000000..4bd870bbf2 --- /dev/null +++ b/src/southbridge/amd/rs780/cmn.c @@ -0,0 +1,403 @@ +/* + * 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/src/southbridge/amd/rs780/early_setup.c b/src/southbridge/amd/rs780/early_setup.c new file mode 100644 index 0000000000..a93ba83172 --- /dev/null +++ b/src/southbridge/amd/rs780/early_setup.c @@ -0,0 +1,675 @@ +/* + * 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); +} diff --git a/src/southbridge/amd/rs780/gfx.c b/src/southbridge/amd/rs780/gfx.c new file mode 100644 index 0000000000..1763c36047 --- /dev/null +++ b/src/southbridge/amd/rs780/gfx.c @@ -0,0 +1,1340 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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> 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>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> 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; + } +} diff --git a/src/southbridge/amd/rs780/ht.c b/src/southbridge/amd/rs780/ht.c new file mode 100644 index 0000000000..03d4f84645 --- /dev/null +++ b/src/southbridge/amd/rs780/ht.c @@ -0,0 +1,90 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/rs780/pcie.c b/src/southbridge/amd/rs780/pcie.c new file mode 100644 index 0000000000..9cbd832661 --- /dev/null +++ b/src/southbridge/amd/rs780/pcie.c @@ -0,0 +1,392 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/amd/rs780/rev.h b/src/southbridge/amd/rs780/rev.h new file mode 100644 index 0000000000..94ab752f9f --- /dev/null +++ b/src/southbridge/amd/rs780/rev.h @@ -0,0 +1,27 @@ +/* + * 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__ */ diff --git a/src/southbridge/amd/rs780/rs780.h b/src/southbridge/amd/rs780/rs780.h index c91a4b3022..aba3e6929b 100644 --- a/src/southbridge/amd/rs780/rs780.h +++ b/src/southbridge/amd/rs780/rs780.h @@ -23,7 +23,7 @@ #include #include #include "chip.h" -#include "rs780_rev.h" +#include "rev.h" #define NBMISC_INDEX 0x60 #define NBHTIU_INDEX 0x94 diff --git a/src/southbridge/amd/rs780/rs780_cmn.c b/src/southbridge/amd/rs780/rs780_cmn.c deleted file mode 100644 index 4bd870bbf2..0000000000 --- a/src/southbridge/amd/rs780/rs780_cmn.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff --git a/src/southbridge/amd/rs780/rs780_early_setup.c b/src/southbridge/amd/rs780/rs780_early_setup.c deleted file mode 100644 index 57a7b62427..0000000000 --- a/src/southbridge/amd/rs780/rs780_early_setup.c +++ /dev/null @@ -1,675 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/amd/rs780/rs780_gfx.c b/src/southbridge/amd/rs780/rs780_gfx.c deleted file mode 100644 index 1763c36047..0000000000 --- a/src/southbridge/amd/rs780/rs780_gfx.c +++ /dev/null @@ -1,1340 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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> 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>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> 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; - } -} diff --git a/src/southbridge/amd/rs780/rs780_ht.c b/src/southbridge/amd/rs780/rs780_ht.c deleted file mode 100644 index 03d4f84645..0000000000 --- a/src/southbridge/amd/rs780/rs780_ht.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/rs780/rs780_pcie.c b/src/southbridge/amd/rs780/rs780_pcie.c deleted file mode 100644 index 9cbd832661..0000000000 --- a/src/southbridge/amd/rs780/rs780_pcie.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/amd/rs780/rs780_rev.h b/src/southbridge/amd/rs780/rs780_rev.h deleted file mode 100644 index 94ab752f9f..0000000000 --- a/src/southbridge/amd/rs780/rs780_rev.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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__ */ diff --git a/src/southbridge/amd/sb600/Makefile.inc b/src/southbridge/amd/sb600/Makefile.inc index 854539b9b3..b5903616c0 100644 --- a/src/southbridge/amd/sb600/Makefile.inc +++ b/src/southbridge/amd/sb600/Makefile.inc @@ -1,11 +1,11 @@ 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 diff --git a/src/southbridge/amd/sb600/ac97.c b/src/southbridge/amd/sb600/ac97.c new file mode 100644 index 0000000000..e9eae65fb6 --- /dev/null +++ b/src/southbridge/amd/sb600/ac97.c @@ -0,0 +1,61 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/bootblock.c b/src/southbridge/amd/sb600/bootblock.c index dd943d79b7..a5eb2f2fac 100644 --- a/src/southbridge/amd/sb600/bootblock.c +++ b/src/southbridge/amd/sb600/bootblock.c @@ -18,7 +18,7 @@ * 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) { diff --git a/src/southbridge/amd/sb600/early_setup.c b/src/southbridge/amd/sb600/early_setup.c new file mode 100644 index 0000000000..45b29c1d58 --- /dev/null +++ b/src/southbridge/amd/sb600/early_setup.c @@ -0,0 +1,660 @@ +/* + * 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 +#include +#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); +} + diff --git a/src/southbridge/amd/sb600/enable_rom.c b/src/southbridge/amd/sb600/enable_rom.c new file mode 100644 index 0000000000..b2668420ce --- /dev/null +++ b/src/southbridge/amd/sb600/enable_rom.c @@ -0,0 +1,65 @@ +/* + * 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 +#include +#include +#include + +/* + * 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); +} diff --git a/src/southbridge/amd/sb600/enable_usbdebug.c b/src/southbridge/amd/sb600/enable_usbdebug.c new file mode 100644 index 0000000000..b4d97b0da2 --- /dev/null +++ b/src/southbridge/amd/sb600/enable_usbdebug.c @@ -0,0 +1,45 @@ +/* + * 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 +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/amd/sb600/hda.c b/src/southbridge/amd/sb600/hda.c new file mode 100644 index 0000000000..84df3f169f --- /dev/null +++ b/src/southbridge/amd/sb600/hda.c @@ -0,0 +1,331 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/ide.c b/src/southbridge/amd/sb600/ide.c new file mode 100644 index 0000000000..e38e83fdd7 --- /dev/null +++ b/src/southbridge/amd/sb600/ide.c @@ -0,0 +1,72 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/lpc.c b/src/southbridge/amd/sb600/lpc.c new file mode 100644 index 0000000000..6a17f72318 --- /dev/null +++ b/src/southbridge/amd/sb600/lpc.c @@ -0,0 +1,225 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/pci.c b/src/southbridge/amd/sb600/pci.c new file mode 100644 index 0000000000..66ca29bd78 --- /dev/null +++ b/src/southbridge/amd/sb600/pci.c @@ -0,0 +1,142 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/reset.c b/src/southbridge/amd/sb600/reset.c new file mode 100644 index 0000000000..af80576204 --- /dev/null +++ b/src/southbridge/amd/sb600/reset.c @@ -0,0 +1,33 @@ +/* + * 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 +#include +#include + +#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); +} diff --git a/src/southbridge/amd/sb600/sata.c b/src/southbridge/amd/sb600/sata.c new file mode 100644 index 0000000000..055e7daa85 --- /dev/null +++ b/src/southbridge/amd/sb600/sata.c @@ -0,0 +1,265 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/sb600_ac97.c b/src/southbridge/amd/sb600/sb600_ac97.c deleted file mode 100644 index e9eae65fb6..0000000000 --- a/src/southbridge/amd/sb600/sb600_ac97.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_early_setup.c b/src/southbridge/amd/sb600/sb600_early_setup.c deleted file mode 100644 index 3ed8dd85de..0000000000 --- a/src/southbridge/amd/sb600/sb600_early_setup.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * 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 -#include -#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); -} - diff --git a/src/southbridge/amd/sb600/sb600_enable_rom.c b/src/southbridge/amd/sb600/sb600_enable_rom.c deleted file mode 100644 index b2668420ce..0000000000 --- a/src/southbridge/amd/sb600/sb600_enable_rom.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 -#include -#include -#include - -/* - * 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); -} diff --git a/src/southbridge/amd/sb600/sb600_enable_usbdebug.c b/src/southbridge/amd/sb600/sb600_enable_usbdebug.c deleted file mode 100644 index b4d97b0da2..0000000000 --- a/src/southbridge/amd/sb600/sb600_enable_usbdebug.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/amd/sb600/sb600_hda.c b/src/southbridge/amd/sb600/sb600_hda.c deleted file mode 100644 index 84df3f169f..0000000000 --- a/src/southbridge/amd/sb600/sb600_hda.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_ide.c b/src/southbridge/amd/sb600/sb600_ide.c deleted file mode 100644 index e38e83fdd7..0000000000 --- a/src/southbridge/amd/sb600/sb600_ide.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_lpc.c b/src/southbridge/amd/sb600/sb600_lpc.c deleted file mode 100644 index 6a17f72318..0000000000 --- a/src/southbridge/amd/sb600/sb600_lpc.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_pci.c b/src/southbridge/amd/sb600/sb600_pci.c deleted file mode 100644 index 66ca29bd78..0000000000 --- a/src/southbridge/amd/sb600/sb600_pci.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_reset.c b/src/southbridge/amd/sb600/sb600_reset.c deleted file mode 100644 index af80576204..0000000000 --- a/src/southbridge/amd/sb600/sb600_reset.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 -#include -#include - -#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); -} diff --git a/src/southbridge/amd/sb600/sb600_sata.c b/src/southbridge/amd/sb600/sb600_sata.c deleted file mode 100644 index 055e7daa85..0000000000 --- a/src/southbridge/amd/sb600/sb600_sata.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_sm.c b/src/southbridge/amd/sb600/sb600_sm.c deleted file mode 100644 index b074edb89e..0000000000 --- a/src/southbridge/amd/sb600/sb600_sm.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb600/sb600_smbus.c b/src/southbridge/amd/sb600/sb600_smbus.c deleted file mode 100644 index 0cc0e62c04..0000000000 --- a/src/southbridge/amd/sb600/sb600_smbus.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/amd/sb600/sb600_smbus.h b/src/southbridge/amd/sb600/sb600_smbus.h deleted file mode 100644 index 684d0e62c4..0000000000 --- a/src/southbridge/amd/sb600/sb600_smbus.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 diff --git a/src/southbridge/amd/sb600/sb600_usb.c b/src/southbridge/amd/sb600/sb600_usb.c deleted file mode 100644 index 7539f083c6..0000000000 --- a/src/southbridge/amd/sb600/sb600_usb.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/amd/sb600/sm.c b/src/southbridge/amd/sb600/sm.c new file mode 100644 index 0000000000..1a0d6acdd8 --- /dev/null +++ b/src/southbridge/amd/sb600/sm.c @@ -0,0 +1,375 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb600/smbus.c b/src/southbridge/amd/sb600/smbus.c new file mode 100644 index 0000000000..cdd1930b5f --- /dev/null +++ b/src/southbridge/amd/sb600/smbus.c @@ -0,0 +1,214 @@ +/* + * 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); +} diff --git a/src/southbridge/amd/sb600/smbus.h b/src/southbridge/amd/sb600/smbus.h new file mode 100644 index 0000000000..684d0e62c4 --- /dev/null +++ b/src/southbridge/amd/sb600/smbus.h @@ -0,0 +1,64 @@ +/* + * 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 diff --git a/src/southbridge/amd/sb600/usb.c b/src/southbridge/amd/sb600/usb.c new file mode 100644 index 0000000000..7539f083c6 --- /dev/null +++ b/src/southbridge/amd/sb600/usb.c @@ -0,0 +1,203 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/amd/sb700/Makefile.inc b/src/southbridge/amd/sb700/Makefile.inc index dd97df31e6..8d1c20813a 100644 --- a/src/southbridge/amd/sb700/Makefile.inc +++ b/src/southbridge/amd/sb700/Makefile.inc @@ -1,10 +1,10 @@ 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 diff --git a/src/southbridge/amd/sb700/early_setup.c b/src/southbridge/amd/sb700/early_setup.c new file mode 100644 index 0000000000..81ffc1c7d5 --- /dev/null +++ b/src/southbridge/amd/sb700/early_setup.c @@ -0,0 +1,619 @@ +/* + * 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 +#include +#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 diff --git a/src/southbridge/amd/sb700/enable_usbdebug.c b/src/southbridge/amd/sb700/enable_usbdebug.c new file mode 100644 index 0000000000..d74a9bbc9f --- /dev/null +++ b/src/southbridge/amd/sb700/enable_usbdebug.c @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Advanced Micro Devices, Inc. + * Copyright (C) 2010 Uwe Hermann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/amd/sb700/hda.c b/src/southbridge/amd/sb700/hda.c new file mode 100644 index 0000000000..417d513e90 --- /dev/null +++ b/src/southbridge/amd/sb700/hda.c @@ -0,0 +1,232 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/ide.c b/src/southbridge/amd/sb700/ide.c new file mode 100644 index 0000000000..4652ca2539 --- /dev/null +++ b/src/southbridge/amd/sb700/ide.c @@ -0,0 +1,85 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/lpc.c b/src/southbridge/amd/sb700/lpc.c new file mode 100644 index 0000000000..a3a50c6c9b --- /dev/null +++ b/src/southbridge/amd/sb700/lpc.c @@ -0,0 +1,238 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/pci.c b/src/southbridge/amd/sb700/pci.c new file mode 100644 index 0000000000..d1e9851b9d --- /dev/null +++ b/src/southbridge/amd/sb700/pci.c @@ -0,0 +1,128 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/reset.c b/src/southbridge/amd/sb700/reset.c new file mode 100644 index 0000000000..32ee66b4b5 --- /dev/null +++ b/src/southbridge/amd/sb700/reset.c @@ -0,0 +1,33 @@ +/* + * 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 +#include +#include + +#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); +} diff --git a/src/southbridge/amd/sb700/sata.c b/src/southbridge/amd/sb700/sata.c new file mode 100644 index 0000000000..08b9aa8ad9 --- /dev/null +++ b/src/southbridge/amd/sb700/sata.c @@ -0,0 +1,294 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/sb700_early_setup.c b/src/southbridge/amd/sb700/sb700_early_setup.c deleted file mode 100644 index 9f8d44f6c7..0000000000 --- a/src/southbridge/amd/sb700/sb700_early_setup.c +++ /dev/null @@ -1,619 +0,0 @@ -/* - * 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 -#include -#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 diff --git a/src/southbridge/amd/sb700/sb700_enable_usbdebug.c b/src/southbridge/amd/sb700/sb700_enable_usbdebug.c deleted file mode 100644 index d74a9bbc9f..0000000000 --- a/src/southbridge/amd/sb700/sb700_enable_usbdebug.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. - * Copyright (C) 2010 Uwe Hermann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/amd/sb700/sb700_hda.c b/src/southbridge/amd/sb700/sb700_hda.c deleted file mode 100644 index 417d513e90..0000000000 --- a/src/southbridge/amd/sb700/sb700_hda.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_ide.c b/src/southbridge/amd/sb700/sb700_ide.c deleted file mode 100644 index 4652ca2539..0000000000 --- a/src/southbridge/amd/sb700/sb700_ide.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_lpc.c b/src/southbridge/amd/sb700/sb700_lpc.c deleted file mode 100644 index a3a50c6c9b..0000000000 --- a/src/southbridge/amd/sb700/sb700_lpc.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_pci.c b/src/southbridge/amd/sb700/sb700_pci.c deleted file mode 100644 index d1e9851b9d..0000000000 --- a/src/southbridge/amd/sb700/sb700_pci.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_reset.c b/src/southbridge/amd/sb700/sb700_reset.c deleted file mode 100644 index 32ee66b4b5..0000000000 --- a/src/southbridge/amd/sb700/sb700_reset.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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 -#include -#include - -#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); -} diff --git a/src/southbridge/amd/sb700/sb700_sata.c b/src/southbridge/amd/sb700/sb700_sata.c deleted file mode 100644 index 08b9aa8ad9..0000000000 --- a/src/southbridge/amd/sb700/sb700_sata.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_sm.c b/src/southbridge/amd/sb700/sb700_sm.c deleted file mode 100644 index e700c0b5f3..0000000000 --- a/src/southbridge/amd/sb700/sb700_sm.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/amd/sb700/sb700_smbus.c b/src/southbridge/amd/sb700/sb700_smbus.c deleted file mode 100644 index ee1653df3e..0000000000 --- a/src/southbridge/amd/sb700/sb700_smbus.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * 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 diff --git a/src/southbridge/amd/sb700/sb700_smbus.h b/src/southbridge/amd/sb700/sb700_smbus.h deleted file mode 100644 index c21a1dc0a2..0000000000 --- a/src/southbridge/amd/sb700/sb700_smbus.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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 diff --git a/src/southbridge/amd/sb700/sb700_usb.c b/src/southbridge/amd/sb700/sb700_usb.c deleted file mode 100644 index 3b3ad584a7..0000000000 --- a/src/southbridge/amd/sb700/sb700_usb.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, - * }; - */ diff --git a/src/southbridge/amd/sb700/sm.c b/src/southbridge/amd/sb700/sm.c new file mode 100644 index 0000000000..69df215f52 --- /dev/null +++ b/src/southbridge/amd/sb700/sm.c @@ -0,0 +1,381 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/amd/sb700/smbus.c b/src/southbridge/amd/sb700/smbus.c new file mode 100644 index 0000000000..e47bceed47 --- /dev/null +++ b/src/southbridge/amd/sb700/smbus.c @@ -0,0 +1,224 @@ +/* + * 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 diff --git a/src/southbridge/amd/sb700/smbus.h b/src/southbridge/amd/sb700/smbus.h new file mode 100644 index 0000000000..c21a1dc0a2 --- /dev/null +++ b/src/southbridge/amd/sb700/smbus.h @@ -0,0 +1,65 @@ +/* + * 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 diff --git a/src/southbridge/amd/sb700/usb.c b/src/southbridge/amd/sb700/usb.c new file mode 100644 index 0000000000..3b3ad584a7 --- /dev/null +++ b/src/southbridge/amd/sb700/usb.c @@ -0,0 +1,253 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, + * }; + */ diff --git a/src/southbridge/broadcom/bcm21000/Makefile.inc b/src/southbridge/broadcom/bcm21000/Makefile.inc index 246be282e2..8e5ba7411b 100644 --- a/src/southbridge/broadcom/bcm21000/Makefile.inc +++ b/src/southbridge/broadcom/bcm21000/Makefile.inc @@ -1 +1 @@ -driver-y += bcm21000_pcie.c +driver-y += pcie.c diff --git a/src/southbridge/broadcom/bcm21000/bcm21000_pcie.c b/src/southbridge/broadcom/bcm21000/bcm21000_pcie.c deleted file mode 100644 index 72ee95b8cf..0000000000 --- a/src/southbridge/broadcom/bcm21000/bcm21000_pcie.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 University of Heidelberg - * Written by Mondrian Nuessle 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 -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/broadcom/bcm21000/pcie.c b/src/southbridge/broadcom/bcm21000/pcie.c new file mode 100644 index 0000000000..72ee95b8cf --- /dev/null +++ b/src/southbridge/broadcom/bcm21000/pcie.c @@ -0,0 +1,79 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 University of Heidelberg + * Written by Mondrian Nuessle 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 +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/broadcom/bcm5780/Makefile.inc b/src/southbridge/broadcom/bcm5780/Makefile.inc index 55c6e11ec1..b8a1b96c27 100644 --- a/src/southbridge/broadcom/bcm5780/Makefile.inc +++ b/src/southbridge/broadcom/bcm5780/Makefile.inc @@ -1,3 +1,3 @@ -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 diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_nic.c b/src/southbridge/broadcom/bcm5780/bcm5780_nic.c deleted file mode 100644 index 387c402215..0000000000 --- a/src/southbridge/broadcom/bcm5780/bcm5780_nic.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c b/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c deleted file mode 100644 index 786ad4f431..0000000000 --- a/src/southbridge/broadcom/bcm5780/bcm5780_pcie.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c b/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c deleted file mode 100644 index e500542c33..0000000000 --- a/src/southbridge/broadcom/bcm5780/bcm5780_pcix.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/broadcom/bcm5780/nic.c b/src/southbridge/broadcom/bcm5780/nic.c new file mode 100644 index 0000000000..387c402215 --- /dev/null +++ b/src/southbridge/broadcom/bcm5780/nic.c @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/broadcom/bcm5780/pcie.c b/src/southbridge/broadcom/bcm5780/pcie.c new file mode 100644 index 0000000000..786ad4f431 --- /dev/null +++ b/src/southbridge/broadcom/bcm5780/pcie.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/broadcom/bcm5780/pcix.c b/src/southbridge/broadcom/bcm5780/pcix.c new file mode 100644 index 0000000000..e500542c33 --- /dev/null +++ b/src/southbridge/broadcom/bcm5780/pcix.c @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/broadcom/bcm5785/Makefile.inc b/src/southbridge/broadcom/bcm5785/Makefile.inc index e80ed35a34..9ad67ccf1f 100644 --- a/src/southbridge/broadcom/bcm5785/Makefile.inc +++ b/src/southbridge/broadcom/bcm5785/Makefile.inc @@ -1,7 +1,7 @@ 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 diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c b/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c deleted file mode 100644 index e3edfd8635..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_early_setup.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#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); -} diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c b/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c deleted file mode 100644 index 3cc1292574..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_early_smbus.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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); -} diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_enable_rom.c b/src/southbridge/broadcom/bcm5785/bcm5785_enable_rom.c deleted file mode 100644 index 1cd28498b9..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_enable_rom.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include - -/* 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); -} diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_ide.c b/src/southbridge/broadcom/bcm5785/bcm5785_ide.c deleted file mode 100644 index a40094afde..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_ide.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c b/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c deleted file mode 100644 index adf546245f..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_lpc.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_reset.c b/src/southbridge/broadcom/bcm5785/bcm5785_reset.c deleted file mode 100644 index a59b23992e..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_reset.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include - -#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); -} diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_sata.c b/src/southbridge/broadcom/bcm5785/bcm5785_sata.c deleted file mode 100644 index 573e8475ce..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_sata.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c b/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c deleted file mode 100644 index 6c65fad4cf..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_sb_pci_main.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h b/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h deleted file mode 100644 index f6dfffa878..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_smbus.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 - -#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; -} diff --git a/src/southbridge/broadcom/bcm5785/bcm5785_usb.c b/src/southbridge/broadcom/bcm5785/bcm5785_usb.c deleted file mode 100644 index a16d6fe11b..0000000000 --- a/src/southbridge/broadcom/bcm5785/bcm5785_usb.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/broadcom/bcm5785/bootblock.c b/src/southbridge/broadcom/bcm5785/bootblock.c index 40201c6072..f51fcd0ff9 100644 --- a/src/southbridge/broadcom/bcm5785/bootblock.c +++ b/src/southbridge/broadcom/bcm5785/bootblock.c @@ -18,7 +18,7 @@ * 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) { diff --git a/src/southbridge/broadcom/bcm5785/early_setup.c b/src/southbridge/broadcom/bcm5785/early_setup.c new file mode 100644 index 0000000000..e3edfd8635 --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/early_setup.c @@ -0,0 +1,223 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#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); +} diff --git a/src/southbridge/broadcom/bcm5785/early_smbus.c b/src/southbridge/broadcom/bcm5785/early_smbus.c new file mode 100644 index 0000000000..f235e58888 --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/early_smbus.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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); +} diff --git a/src/southbridge/broadcom/bcm5785/enable_rom.c b/src/southbridge/broadcom/bcm5785/enable_rom.c new file mode 100644 index 0000000000..1cd28498b9 --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/enable_rom.c @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include + +/* 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); +} diff --git a/src/southbridge/broadcom/bcm5785/ide.c b/src/southbridge/broadcom/bcm5785/ide.c new file mode 100644 index 0000000000..a40094afde --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/ide.c @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/broadcom/bcm5785/lpc.c b/src/southbridge/broadcom/bcm5785/lpc.c new file mode 100644 index 0000000000..adf546245f --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/lpc.c @@ -0,0 +1,148 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/broadcom/bcm5785/reset.c b/src/southbridge/broadcom/bcm5785/reset.c new file mode 100644 index 0000000000..a59b23992e --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/reset.c @@ -0,0 +1,56 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include + +#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); +} diff --git a/src/southbridge/broadcom/bcm5785/sata.c b/src/southbridge/broadcom/bcm5785/sata.c new file mode 100644 index 0000000000..573e8475ce --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/sata.c @@ -0,0 +1,100 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/broadcom/bcm5785/sb_pci_main.c b/src/southbridge/broadcom/bcm5785/sb_pci_main.c new file mode 100644 index 0000000000..fe809c4974 --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/sb_pci_main.c @@ -0,0 +1,168 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/broadcom/bcm5785/smbus.h b/src/southbridge/broadcom/bcm5785/smbus.h new file mode 100644 index 0000000000..f6dfffa878 --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/smbus.h @@ -0,0 +1,196 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 + +#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; +} diff --git a/src/southbridge/broadcom/bcm5785/usb.c b/src/southbridge/broadcom/bcm5785/usb.c new file mode 100644 index 0000000000..a16d6fe11b --- /dev/null +++ b/src/southbridge/broadcom/bcm5785/usb.c @@ -0,0 +1,64 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/esb6300/Makefile.inc b/src/southbridge/intel/esb6300/Makefile.inc index 53cdb7e804..004ff13a55 100644 --- a/src/southbridge/intel/esb6300/Makefile.inc +++ b/src/southbridge/intel/esb6300/Makefile.inc @@ -1,12 +1,12 @@ 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 diff --git a/src/southbridge/intel/esb6300/ac97.c b/src/southbridge/intel/esb6300/ac97.c new file mode 100644 index 0000000000..7b7795f5df --- /dev/null +++ b/src/southbridge/intel/esb6300/ac97.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/esb6300/bridge1c.c b/src/southbridge/intel/esb6300/bridge1c.c new file mode 100644 index 0000000000..54c2717d89 --- /dev/null +++ b/src/southbridge/intel/esb6300/bridge1c.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/early_smbus.c b/src/southbridge/intel/esb6300/early_smbus.c new file mode 100644 index 0000000000..d0b9632f83 --- /dev/null +++ b/src/southbridge/intel/esb6300/early_smbus.c @@ -0,0 +1,98 @@ +#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;i3) + 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 + diff --git a/src/southbridge/intel/esb6300/ehci.c b/src/southbridge/intel/esb6300/ehci.c new file mode 100644 index 0000000000..c103c4bd2f --- /dev/null +++ b/src/southbridge/intel/esb6300/ehci.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/esb6300/esb6300_ac97.c b/src/southbridge/intel/esb6300/esb6300_ac97.c deleted file mode 100644 index 7b7795f5df..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_ac97.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/esb6300/esb6300_bridge1c.c b/src/southbridge/intel/esb6300/esb6300_bridge1c.c deleted file mode 100644 index 54c2717d89..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_bridge1c.c +++ /dev/null @@ -1,47 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_early_smbus.c b/src/southbridge/intel/esb6300/esb6300_early_smbus.c deleted file mode 100644 index f8587856e8..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_early_smbus.c +++ /dev/null @@ -1,98 +0,0 @@ -#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;i3) - 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 - diff --git a/src/southbridge/intel/esb6300/esb6300_ehci.c b/src/southbridge/intel/esb6300/esb6300_ehci.c deleted file mode 100644 index c103c4bd2f..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_ehci.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/esb6300/esb6300_ide.c b/src/southbridge/intel/esb6300/esb6300_ide.c deleted file mode 100644 index abe86a811d..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_ide.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_lpc.c b/src/southbridge/intel/esb6300/esb6300_lpc.c deleted file mode 100644 index 67bcadc961..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_lpc.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/esb6300/esb6300_pci.c b/src/southbridge/intel/esb6300/esb6300_pci.c deleted file mode 100644 index 64aeb0db46..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_pci.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_pic.c b/src/southbridge/intel/esb6300/esb6300_pic.c deleted file mode 100644 index b9bfdf1fe3..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_pic.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_reset.c b/src/southbridge/intel/esb6300/esb6300_reset.c deleted file mode 100644 index 8dbe6cb1d7..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_reset.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 -#include - -void hard_reset(void) -{ - /* Try rebooting through port 0xcf9 */ - outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9); -} diff --git a/src/southbridge/intel/esb6300/esb6300_sata.c b/src/southbridge/intel/esb6300/esb6300_sata.c deleted file mode 100644 index 6dce2d2f3a..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_sata.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.c b/src/southbridge/intel/esb6300/esb6300_smbus.c deleted file mode 100644 index 5b1940f93e..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_smbus.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/esb6300_smbus.h b/src/southbridge/intel/esb6300/esb6300_smbus.h deleted file mode 100644 index 4f4ec5c999..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_smbus.h +++ /dev/null @@ -1,101 +0,0 @@ -#include - -#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 - -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; -} - diff --git a/src/southbridge/intel/esb6300/esb6300_uhci.c b/src/southbridge/intel/esb6300/esb6300_uhci.c deleted file mode 100644 index a8bcd888f1..0000000000 --- a/src/southbridge/intel/esb6300/esb6300_uhci.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/esb6300/ide.c b/src/southbridge/intel/esb6300/ide.c new file mode 100644 index 0000000000..abe86a811d --- /dev/null +++ b/src/southbridge/intel/esb6300/ide.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/lpc.c b/src/southbridge/intel/esb6300/lpc.c new file mode 100644 index 0000000000..67bcadc961 --- /dev/null +++ b/src/southbridge/intel/esb6300/lpc.c @@ -0,0 +1,374 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/esb6300/pci.c b/src/southbridge/intel/esb6300/pci.c new file mode 100644 index 0000000000..64aeb0db46 --- /dev/null +++ b/src/southbridge/intel/esb6300/pci.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/pic.c b/src/southbridge/intel/esb6300/pic.c new file mode 100644 index 0000000000..b9bfdf1fe3 --- /dev/null +++ b/src/southbridge/intel/esb6300/pic.c @@ -0,0 +1,68 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/reset.c b/src/southbridge/intel/esb6300/reset.c new file mode 100644 index 0000000000..8dbe6cb1d7 --- /dev/null +++ b/src/southbridge/intel/esb6300/reset.c @@ -0,0 +1,27 @@ +/* + * 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 +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9 */ + outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9); +} diff --git a/src/southbridge/intel/esb6300/sata.c b/src/southbridge/intel/esb6300/sata.c new file mode 100644 index 0000000000..6dce2d2f3a --- /dev/null +++ b/src/southbridge/intel/esb6300/sata.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/smbus.c b/src/southbridge/intel/esb6300/smbus.c new file mode 100644 index 0000000000..c7ed04f136 --- /dev/null +++ b/src/southbridge/intel/esb6300/smbus.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/esb6300/smbus.h b/src/southbridge/intel/esb6300/smbus.h new file mode 100644 index 0000000000..4f4ec5c999 --- /dev/null +++ b/src/southbridge/intel/esb6300/smbus.h @@ -0,0 +1,101 @@ +#include + +#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 + +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; +} + diff --git a/src/southbridge/intel/esb6300/uhci.c b/src/southbridge/intel/esb6300/uhci.c new file mode 100644 index 0000000000..a8bcd888f1 --- /dev/null +++ b/src/southbridge/intel/esb6300/uhci.c @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i3100/Makefile.inc b/src/southbridge/intel/i3100/Makefile.inc index dcc1fb7357..fa6caf1b52 100644 --- a/src/southbridge/intel/i3100/Makefile.inc +++ b/src/southbridge/intel/i3100/Makefile.inc @@ -1,9 +1,9 @@ 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 diff --git a/src/southbridge/intel/i3100/early_lpc.c b/src/southbridge/intel/i3100/early_lpc.c new file mode 100644 index 0000000000..3397aff1f8 --- /dev/null +++ b/src/southbridge/intel/i3100/early_lpc.c @@ -0,0 +1,46 @@ +/* + * 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)); +} diff --git a/src/southbridge/intel/i3100/early_smbus.c b/src/southbridge/intel/i3100/early_smbus.c new file mode 100644 index 0000000000..f3d4450c5e --- /dev/null +++ b/src/southbridge/intel/i3100/early_smbus.c @@ -0,0 +1,43 @@ +/* + * 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); +} diff --git a/src/southbridge/intel/i3100/ehci.c b/src/southbridge/intel/i3100/ehci.c new file mode 100644 index 0000000000..195ea99cd1 --- /dev/null +++ b/src/southbridge/intel/i3100/ehci.c @@ -0,0 +1,68 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i3100/i3100_early_lpc.c b/src/southbridge/intel/i3100/i3100_early_lpc.c deleted file mode 100644 index 3397aff1f8..0000000000 --- a/src/southbridge/intel/i3100/i3100_early_lpc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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)); -} diff --git a/src/southbridge/intel/i3100/i3100_early_smbus.c b/src/southbridge/intel/i3100/i3100_early_smbus.c deleted file mode 100644 index 79825d153a..0000000000 --- a/src/southbridge/intel/i3100/i3100_early_smbus.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/intel/i3100/i3100_ehci.c b/src/southbridge/intel/i3100/i3100_ehci.c deleted file mode 100644 index 195ea99cd1..0000000000 --- a/src/southbridge/intel/i3100/i3100_ehci.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i3100/i3100_lpc.c b/src/southbridge/intel/i3100/i3100_lpc.c deleted file mode 100644 index 1544ecd44f..0000000000 --- a/src/southbridge/intel/i3100/i3100_lpc.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i3100/i3100_pci.c b/src/southbridge/intel/i3100/i3100_pci.c deleted file mode 100644 index 99fc95d0f6..0000000000 --- a/src/southbridge/intel/i3100/i3100_pci.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i3100/i3100_pciexp_portb.c b/src/southbridge/intel/i3100/i3100_pciexp_portb.c deleted file mode 100644 index 31502a46de..0000000000 --- a/src/southbridge/intel/i3100/i3100_pciexp_portb.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include "chip.h" -#include - -#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, -}; diff --git a/src/southbridge/intel/i3100/i3100_reset.c b/src/southbridge/intel/i3100/i3100_reset.c deleted file mode 100644 index 3f35f5fb83..0000000000 --- a/src/southbridge/intel/i3100/i3100_reset.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 -#include - -void hard_reset(void) -{ - outb(0x06, 0xcf9); -} diff --git a/src/southbridge/intel/i3100/i3100_sata.c b/src/southbridge/intel/i3100/i3100_sata.c deleted file mode 100644 index af22600f90..0000000000 --- a/src/southbridge/intel/i3100/i3100_sata.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i3100/i3100_smbus.c b/src/southbridge/intel/i3100/i3100_smbus.c deleted file mode 100644 index f51363d92a..0000000000 --- a/src/southbridge/intel/i3100/i3100_smbus.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i3100/i3100_smbus.h b/src/southbridge/intel/i3100/i3100_smbus.h deleted file mode 100644 index 7023a5b751..0000000000 --- a/src/southbridge/intel/i3100/i3100_smbus.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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 - -#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; -} diff --git a/src/southbridge/intel/i3100/i3100_uhci.c b/src/southbridge/intel/i3100/i3100_uhci.c deleted file mode 100644 index 5453509769..0000000000 --- a/src/southbridge/intel/i3100/i3100_uhci.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i3100/lpc.c b/src/southbridge/intel/i3100/lpc.c new file mode 100644 index 0000000000..1544ecd44f --- /dev/null +++ b/src/southbridge/intel/i3100/lpc.c @@ -0,0 +1,433 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i3100/pci.c b/src/southbridge/intel/i3100/pci.c new file mode 100644 index 0000000000..99fc95d0f6 --- /dev/null +++ b/src/southbridge/intel/i3100/pci.c @@ -0,0 +1,46 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i3100/pciexp_portb.c b/src/southbridge/intel/i3100/pciexp_portb.c new file mode 100644 index 0000000000..31502a46de --- /dev/null +++ b/src/southbridge/intel/i3100/pciexp_portb.c @@ -0,0 +1,94 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include "chip.h" +#include + +#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, +}; diff --git a/src/southbridge/intel/i3100/reset.c b/src/southbridge/intel/i3100/reset.c new file mode 100644 index 0000000000..3f35f5fb83 --- /dev/null +++ b/src/southbridge/intel/i3100/reset.c @@ -0,0 +1,27 @@ +/* + * 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 +#include + +void hard_reset(void) +{ + outb(0x06, 0xcf9); +} diff --git a/src/southbridge/intel/i3100/sata.c b/src/southbridge/intel/i3100/sata.c new file mode 100644 index 0000000000..af22600f90 --- /dev/null +++ b/src/southbridge/intel/i3100/sata.c @@ -0,0 +1,129 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i3100/smbus.c b/src/southbridge/intel/i3100/smbus.c new file mode 100644 index 0000000000..23602acb21 --- /dev/null +++ b/src/southbridge/intel/i3100/smbus.c @@ -0,0 +1,79 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i3100/smbus.h b/src/southbridge/intel/i3100/smbus.h new file mode 100644 index 0000000000..7023a5b751 --- /dev/null +++ b/src/southbridge/intel/i3100/smbus.h @@ -0,0 +1,112 @@ +/* + * 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 + +#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; +} diff --git a/src/southbridge/intel/i3100/uhci.c b/src/southbridge/intel/i3100/uhci.c new file mode 100644 index 0000000000..5453509769 --- /dev/null +++ b/src/southbridge/intel/i3100/uhci.c @@ -0,0 +1,68 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82371eb/Makefile.inc b/src/southbridge/intel/i82371eb/Makefile.inc index b5ac581ff1..6b27af3c4a 100644 --- a/src/southbridge/intel/i82371eb/Makefile.inc +++ b/src/southbridge/intel/i82371eb/Makefile.inc @@ -19,13 +19,13 @@ ## 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 diff --git a/src/southbridge/intel/i82371eb/bootblock.c b/src/southbridge/intel/i82371eb/bootblock.c index c818691639..f83b4073c1 100644 --- a/src/southbridge/intel/i82371eb/bootblock.c +++ b/src/southbridge/intel/i82371eb/bootblock.c @@ -18,7 +18,7 @@ * 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) { diff --git a/src/southbridge/intel/i82371eb/early_pm.c b/src/southbridge/intel/i82371eb/early_pm.c new file mode 100644 index 0000000000..5e52985428 --- /dev/null +++ b/src/southbridge/intel/i82371eb/early_pm.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82371eb/early_smbus.c b/src/southbridge/intel/i82371eb/early_smbus.c new file mode 100644 index 0000000000..d11b06c4f1 --- /dev/null +++ b/src/southbridge/intel/i82371eb/early_smbus.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82371eb/enable_rom.c b/src/southbridge/intel/i82371eb/enable_rom.c new file mode 100644 index 0000000000..46b0144f28 --- /dev/null +++ b/src/southbridge/intel/i82371eb/enable_rom.c @@ -0,0 +1,49 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82371eb/fadt.c b/src/southbridge/intel/i82371eb/fadt.c new file mode 100644 index 0000000000..5891440d2e --- /dev/null +++ b/src/southbridge/intel/i82371eb/fadt.c @@ -0,0 +1,222 @@ +/* + * This file is part of the coreboot project. + * + * Based on src/southbridge/via/vt8237r/vt8237_fadt.c + * + * Copyright (C) 2004 Nick Barker + * Copyright (C) 2007, 2009 Rudolf Marek + * + * This program is free software; 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 +#include +#include +#include +#include +#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)); +} diff --git a/src/southbridge/intel/i82371eb/i82371eb_early_pm.c b/src/southbridge/intel/i82371eb/i82371eb_early_pm.c deleted file mode 100644 index 5e52985428..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_early_pm.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c b/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c deleted file mode 100644 index 8505762933..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_early_smbus.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82371eb/i82371eb_enable_rom.c b/src/southbridge/intel/i82371eb/i82371eb_enable_rom.c deleted file mode 100644 index 46b0144f28..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_enable_rom.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2009 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82371eb/i82371eb_fadt.c b/src/southbridge/intel/i82371eb/i82371eb_fadt.c deleted file mode 100644 index 5891440d2e..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_fadt.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Based on src/southbridge/via/vt8237r/vt8237_fadt.c - * - * Copyright (C) 2004 Nick Barker - * Copyright (C) 2007, 2009 Rudolf Marek - * - * This program is free software; 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 -#include -#include -#include -#include -#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)); -} diff --git a/src/southbridge/intel/i82371eb/i82371eb_ide.c b/src/southbridge/intel/i82371eb/i82371eb_ide.c deleted file mode 100644 index f72bcb63c6..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_ide.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82371eb/i82371eb_isa.c b/src/southbridge/intel/i82371eb/i82371eb_isa.c deleted file mode 100644 index d025bf2393..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_isa.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82371eb/i82371eb_reset.c b/src/southbridge/intel/i82371eb/i82371eb_reset.c deleted file mode 100644 index baff05b143..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_reset.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include "i82371eb.h" - -/** - * Initiate a hard reset. - */ -void i82371eb_hard_reset(void) -{ - outb(SRST | RCPU, RC); -} diff --git a/src/southbridge/intel/i82371eb/i82371eb_smbus.c b/src/southbridge/intel/i82371eb/i82371eb_smbus.c deleted file mode 100644 index 4dfd2f4caf..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_smbus.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * Copyright (C) 2010 Keith Hui - * Copyright (C) 2010 Idwer Vollering - * Copyright (C) 2010 Tobias Diedrich - * - * This program is free software; 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82371eb/i82371eb_smbus.h b/src/southbridge/intel/i82371eb/i82371eb_smbus.h deleted file mode 100644 index f82f2edc73..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_smbus.h +++ /dev/null @@ -1,115 +0,0 @@ -#include -#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; -} - diff --git a/src/southbridge/intel/i82371eb/i82371eb_usb.c b/src/southbridge/intel/i82371eb/i82371eb_usb.c deleted file mode 100644 index 1a903a95b0..0000000000 --- a/src/southbridge/intel/i82371eb/i82371eb_usb.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Uwe Hermann - * - * This program is free software; 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82371eb/ide.c b/src/southbridge/intel/i82371eb/ide.c new file mode 100644 index 0000000000..f72bcb63c6 --- /dev/null +++ b/src/southbridge/intel/i82371eb/ide.c @@ -0,0 +1,201 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82371eb/isa.c b/src/southbridge/intel/i82371eb/isa.c new file mode 100644 index 0000000000..d025bf2393 --- /dev/null +++ b/src/southbridge/intel/i82371eb/isa.c @@ -0,0 +1,147 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82371eb/reset.c b/src/southbridge/intel/i82371eb/reset.c new file mode 100644 index 0000000000..baff05b143 --- /dev/null +++ b/src/southbridge/intel/i82371eb/reset.c @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include "i82371eb.h" + +/** + * Initiate a hard reset. + */ +void i82371eb_hard_reset(void) +{ + outb(SRST | RCPU, RC); +} diff --git a/src/southbridge/intel/i82371eb/smbus.c b/src/southbridge/intel/i82371eb/smbus.c new file mode 100644 index 0000000000..b1a51c6a8a --- /dev/null +++ b/src/southbridge/intel/i82371eb/smbus.c @@ -0,0 +1,137 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * Copyright (C) 2010 Keith Hui + * Copyright (C) 2010 Idwer Vollering + * Copyright (C) 2010 Tobias Diedrich + * + * This program is free software; 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82371eb/smbus.h b/src/southbridge/intel/i82371eb/smbus.h new file mode 100644 index 0000000000..f82f2edc73 --- /dev/null +++ b/src/southbridge/intel/i82371eb/smbus.h @@ -0,0 +1,115 @@ +#include +#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; +} + diff --git a/src/southbridge/intel/i82371eb/usb.c b/src/southbridge/intel/i82371eb/usb.c new file mode 100644 index 0000000000..1a903a95b0 --- /dev/null +++ b/src/southbridge/intel/i82371eb/usb.c @@ -0,0 +1,66 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Uwe Hermann + * + * This program is free software; 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/Makefile.inc b/src/southbridge/intel/i82801ax/Makefile.inc index a282dd1e36..de0c7228ed 100644 --- a/src/southbridge/intel/i82801ax/Makefile.inc +++ b/src/southbridge/intel/i82801ax/Makefile.inc @@ -19,15 +19,15 @@ ## 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 diff --git a/src/southbridge/intel/i82801ax/ac97.c b/src/southbridge/intel/i82801ax/ac97.c new file mode 100644 index 0000000000..826264bbfe --- /dev/null +++ b/src/southbridge/intel/i82801ax/ac97.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/early_smbus.c b/src/southbridge/intel/i82801ax/early_smbus.c new file mode 100644 index 0000000000..e894c37095 --- /dev/null +++ b/src/southbridge/intel/i82801ax/early_smbus.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu for Tyan Computer) + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#include +#include +#include +#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); +} + diff --git a/src/southbridge/intel/i82801ax/i82801ax_ac97.c b/src/southbridge/intel/i82801ax/i82801ax_ac97.c deleted file mode 100644 index 826264bbfe..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_ac97.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_early_smbus.c b/src/southbridge/intel/i82801ax/i82801ax_early_smbus.c deleted file mode 100644 index dca3a28eec..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_early_smbus.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu for Tyan Computer) - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#include -#include -#include -#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); -} - diff --git a/src/southbridge/intel/i82801ax/i82801ax_ide.c b/src/southbridge/intel/i82801ax/i82801ax_ide.c deleted file mode 100644 index c5bd2882b4..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_ide.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu for Tyan Computer) - * Copyright (C) 2005 Digital Design Corporation - * (Written by Steven J. Magnani 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_lpc.c b/src/southbridge/intel/i82801ax/i82801ax_lpc.c deleted file mode 100644 index c9404ed3c0..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_lpc.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_pci.c b/src/southbridge/intel/i82801ax/i82801ax_pci.c deleted file mode 100644 index 293ce582c2..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_pci.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu 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 -#include -#include -#include - -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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_reset.c b/src/southbridge/intel/i82801ax/i82801ax_reset.c deleted file mode 100644 index b30db9d9c0..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_reset.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2002 Eric Biederman - * - * This program is free software; 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 -#include - -void hard_reset(void) -{ - /* Try rebooting through port 0xcf9. */ - outb((1 << 2) | (1 << 1), 0xcf9); -} diff --git a/src/southbridge/intel/i82801ax/i82801ax_smbus.c b/src/southbridge/intel/i82801ax/i82801ax_smbus.c deleted file mode 100644 index 8a3155f540..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_smbus.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Yinghai Lu - * - * This program is free software; 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_smbus.h b/src/southbridge/intel/i82801ax/i82801ax_smbus.h deleted file mode 100644 index 26893a76d9..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_smbus.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Yinghai Lu - * - * This program is free software; 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 -#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; -} diff --git a/src/southbridge/intel/i82801ax/i82801ax_usb.c b/src/southbridge/intel/i82801ax/i82801ax_usb.c deleted file mode 100644 index 78aadb0a3e..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_usb.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ax/i82801ax_watchdog.c b/src/southbridge/intel/i82801ax/i82801ax_watchdog.c deleted file mode 100644 index cd0c20d98e..0000000000 --- a/src/southbridge/intel/i82801ax/i82801ax_watchdog.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006 John Dufresne - * - * This program is free software; 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 -#include -#include -#include -#include - -/* 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"); -} diff --git a/src/southbridge/intel/i82801ax/ide.c b/src/southbridge/intel/i82801ax/ide.c new file mode 100644 index 0000000000..c5bd2882b4 --- /dev/null +++ b/src/southbridge/intel/i82801ax/ide.c @@ -0,0 +1,75 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu for Tyan Computer) + * Copyright (C) 2005 Digital Design Corporation + * (Written by Steven J. Magnani 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/lpc.c b/src/southbridge/intel/i82801ax/lpc.c new file mode 100644 index 0000000000..c9404ed3c0 --- /dev/null +++ b/src/southbridge/intel/i82801ax/lpc.c @@ -0,0 +1,296 @@ +/* + * 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 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/pci.c b/src/southbridge/intel/i82801ax/pci.c new file mode 100644 index 0000000000..293ce582c2 --- /dev/null +++ b/src/southbridge/intel/i82801ax/pci.c @@ -0,0 +1,57 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu 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 +#include +#include +#include + +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, +}; diff --git a/src/southbridge/intel/i82801ax/reset.c b/src/southbridge/intel/i82801ax/reset.c new file mode 100644 index 0000000000..b30db9d9c0 --- /dev/null +++ b/src/southbridge/intel/i82801ax/reset.c @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2002 Eric Biederman + * + * This program is free software; 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 +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9. */ + outb((1 << 2) | (1 << 1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801ax/smbus.c b/src/southbridge/intel/i82801ax/smbus.c new file mode 100644 index 0000000000..d9fa970dfa --- /dev/null +++ b/src/southbridge/intel/i82801ax/smbus.c @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * + * This program is free software; 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/smbus.h b/src/southbridge/intel/i82801ax/smbus.h new file mode 100644 index 0000000000..26893a76d9 --- /dev/null +++ b/src/southbridge/intel/i82801ax/smbus.h @@ -0,0 +1,101 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * + * This program is free software; 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 +#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; +} diff --git a/src/southbridge/intel/i82801ax/usb.c b/src/southbridge/intel/i82801ax/usb.c new file mode 100644 index 0000000000..78aadb0a3e --- /dev/null +++ b/src/southbridge/intel/i82801ax/usb.c @@ -0,0 +1,53 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ax/watchdog.c b/src/southbridge/intel/i82801ax/watchdog.c new file mode 100644 index 0000000000..cd0c20d98e --- /dev/null +++ b/src/southbridge/intel/i82801ax/watchdog.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006 John Dufresne + * + * This program is free software; 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 +#include +#include +#include +#include + +/* 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"); +} diff --git a/src/southbridge/intel/i82801bx/Makefile.inc b/src/southbridge/intel/i82801bx/Makefile.inc index 313a0896df..b3587f2228 100644 --- a/src/southbridge/intel/i82801bx/Makefile.inc +++ b/src/southbridge/intel/i82801bx/Makefile.inc @@ -19,16 +19,16 @@ ## 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 diff --git a/src/southbridge/intel/i82801bx/ac97.c b/src/southbridge/intel/i82801bx/ac97.c new file mode 100644 index 0000000000..5e2acd3310 --- /dev/null +++ b/src/southbridge/intel/i82801bx/ac97.c @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/early_smbus.c b/src/southbridge/intel/i82801bx/early_smbus.c new file mode 100644 index 0000000000..4ff8d61cda --- /dev/null +++ b/src/southbridge/intel/i82801bx/early_smbus.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu for Tyan Computer) + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82801bx/i82801bx_ac97.c b/src/southbridge/intel/i82801bx/i82801bx_ac97.c deleted file mode 100644 index 5e2acd3310..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_ac97.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_early_smbus.c b/src/southbridge/intel/i82801bx/i82801bx_early_smbus.c deleted file mode 100644 index 6a2097ea14..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_early_smbus.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu for Tyan Computer) - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82801bx/i82801bx_ide.c b/src/southbridge/intel/i82801bx/i82801bx_ide.c deleted file mode 100644 index 413984b5f4..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_ide.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu for Tyan Computer) - * Copyright (C) 2005 Digital Design Corporation - * (Written by Steven J. Magnani 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_lpc.c b/src/southbridge/intel/i82801bx/i82801bx_lpc.c deleted file mode 100644 index 0ff44e6054..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_lpc.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_nic.c b/src/southbridge/intel/i82801bx/i82801bx_nic.c deleted file mode 100644 index b843aca328..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_nic.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#include -#include - -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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_pci.c b/src/southbridge/intel/i82801bx/i82801bx_pci.c deleted file mode 100644 index 828a668197..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_pci.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Tyan Computer - * (Written by Yinghai Lu 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_reset.c b/src/southbridge/intel/i82801bx/i82801bx_reset.c deleted file mode 100644 index 8d85cdca75..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_reset.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2002 Eric Biederman - * - * This program is free software; 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 -#include - -void hard_reset(void) -{ - /* Try rebooting through port 0xcf9. */ - outb((1 << 2) | (1 << 1), 0xcf9); -} diff --git a/src/southbridge/intel/i82801bx/i82801bx_smbus.c b/src/southbridge/intel/i82801bx/i82801bx_smbus.c deleted file mode 100644 index db27b094c3..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_smbus.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Yinghai Lu - * - * This program is free software; 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_smbus.h b/src/southbridge/intel/i82801bx/i82801bx_smbus.h deleted file mode 100644 index c04e9dc8d3..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_smbus.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Yinghai Lu - * - * This program is free software; 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 - -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; -} diff --git a/src/southbridge/intel/i82801bx/i82801bx_usb.c b/src/southbridge/intel/i82801bx/i82801bx_usb.c deleted file mode 100644 index f90f6a6906..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_usb.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801bx/i82801bx_watchdog.c b/src/southbridge/intel/i82801bx/i82801bx_watchdog.c deleted file mode 100644 index cd0c20d98e..0000000000 --- a/src/southbridge/intel/i82801bx/i82801bx_watchdog.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006 John Dufresne - * - * This program is free software; 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 -#include -#include -#include -#include - -/* 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"); -} diff --git a/src/southbridge/intel/i82801bx/ide.c b/src/southbridge/intel/i82801bx/ide.c new file mode 100644 index 0000000000..413984b5f4 --- /dev/null +++ b/src/southbridge/intel/i82801bx/ide.c @@ -0,0 +1,68 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu for Tyan Computer) + * Copyright (C) 2005 Digital Design Corporation + * (Written by Steven J. Magnani 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/lpc.c b/src/southbridge/intel/i82801bx/lpc.c new file mode 100644 index 0000000000..0ff44e6054 --- /dev/null +++ b/src/southbridge/intel/i82801bx/lpc.c @@ -0,0 +1,307 @@ +/* + * 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 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/nic.c b/src/southbridge/intel/i82801bx/nic.c new file mode 100644 index 0000000000..b843aca328 --- /dev/null +++ b/src/southbridge/intel/i82801bx/nic.c @@ -0,0 +1,39 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#include +#include + +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, +}; diff --git a/src/southbridge/intel/i82801bx/pci.c b/src/southbridge/intel/i82801bx/pci.c new file mode 100644 index 0000000000..828a668197 --- /dev/null +++ b/src/southbridge/intel/i82801bx/pci.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Tyan Computer + * (Written by Yinghai Lu 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/reset.c b/src/southbridge/intel/i82801bx/reset.c new file mode 100644 index 0000000000..8d85cdca75 --- /dev/null +++ b/src/southbridge/intel/i82801bx/reset.c @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2002 Eric Biederman + * + * This program is free software; 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 +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9. */ + outb((1 << 2) | (1 << 1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801bx/smbus.c b/src/southbridge/intel/i82801bx/smbus.c new file mode 100644 index 0000000000..d4a609ae3f --- /dev/null +++ b/src/southbridge/intel/i82801bx/smbus.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * + * This program is free software; 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/smbus.h b/src/southbridge/intel/i82801bx/smbus.h new file mode 100644 index 0000000000..c04e9dc8d3 --- /dev/null +++ b/src/southbridge/intel/i82801bx/smbus.h @@ -0,0 +1,98 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * + * This program is free software; 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 + +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; +} diff --git a/src/southbridge/intel/i82801bx/usb.c b/src/southbridge/intel/i82801bx/usb.c new file mode 100644 index 0000000000..f90f6a6906 --- /dev/null +++ b/src/southbridge/intel/i82801bx/usb.c @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801bx/watchdog.c b/src/southbridge/intel/i82801bx/watchdog.c new file mode 100644 index 0000000000..cd0c20d98e --- /dev/null +++ b/src/southbridge/intel/i82801bx/watchdog.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006 John Dufresne + * + * This program is free software; 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 +#include +#include +#include +#include + +/* 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"); +} diff --git a/src/southbridge/intel/i82801cx/Makefile.inc b/src/southbridge/intel/i82801cx/Makefile.inc index 1e30c681a0..9c5c7fbc45 100644 --- a/src/southbridge/intel/i82801cx/Makefile.inc +++ b/src/southbridge/intel/i82801cx/Makefile.inc @@ -1,8 +1,8 @@ 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 diff --git a/src/southbridge/intel/i82801cx/ac97.c b/src/southbridge/intel/i82801cx/ac97.c new file mode 100644 index 0000000000..5de44fc382 --- /dev/null +++ b/src/southbridge/intel/i82801cx/ac97.c @@ -0,0 +1,41 @@ +/* + * (C) 2003 Linux Networx + */ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801cx/early_smbus.c b/src/southbridge/intel/i82801cx/early_smbus.c new file mode 100644 index 0000000000..b62db80f9c --- /dev/null +++ b/src/southbridge/intel/i82801cx/early_smbus.c @@ -0,0 +1,134 @@ +#include +#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; +} diff --git a/src/southbridge/intel/i82801cx/i82801cx_ac97.c b/src/southbridge/intel/i82801cx/i82801cx_ac97.c deleted file mode 100644 index 5de44fc382..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_ac97.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * (C) 2003 Linux Networx - */ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801cx/i82801cx_early_smbus.c b/src/southbridge/intel/i82801cx/i82801cx_early_smbus.c deleted file mode 100644 index b62db80f9c..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_early_smbus.c +++ /dev/null @@ -1,134 +0,0 @@ -#include -#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; -} diff --git a/src/southbridge/intel/i82801cx/i82801cx_ide.c b/src/southbridge/intel/i82801cx/i82801cx_ide.c deleted file mode 100644 index 74c442c52c..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_ide.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801cx/i82801cx_lpc.c b/src/southbridge/intel/i82801cx/i82801cx_lpc.c deleted file mode 100644 index a1ffb8f540..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_lpc.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * (C) 2003 Linux Networx, SuSE Linux AG - * (C) 2004 Tyan Computer - * (c) 2005 Digital Design Corporation - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801cx/i82801cx_nic.c b/src/southbridge/intel/i82801cx/i82801cx_nic.c deleted file mode 100644 index 00ce038143..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_nic.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801cx/i82801cx_pci.c b/src/southbridge/intel/i82801cx/i82801cx_pci.c deleted file mode 100644 index 842b214fc8..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_pci.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801cx/i82801cx_reset.c b/src/southbridge/intel/i82801cx/i82801cx_reset.c deleted file mode 100644 index bd479de758..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_reset.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#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); -} diff --git a/src/southbridge/intel/i82801cx/i82801cx_smbus.c b/src/southbridge/intel/i82801cx/i82801cx_smbus.c deleted file mode 100644 index 324f82f286..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_smbus.c +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#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 -} diff --git a/src/southbridge/intel/i82801cx/i82801cx_usb.c b/src/southbridge/intel/i82801cx/i82801cx_usb.c deleted file mode 100644 index 28cb3572e5..0000000000 --- a/src/southbridge/intel/i82801cx/i82801cx_usb.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801cx/ide.c b/src/southbridge/intel/i82801cx/ide.c new file mode 100644 index 0000000000..74c442c52c --- /dev/null +++ b/src/southbridge/intel/i82801cx/ide.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801cx/lpc.c b/src/southbridge/intel/i82801cx/lpc.c new file mode 100644 index 0000000000..a1ffb8f540 --- /dev/null +++ b/src/southbridge/intel/i82801cx/lpc.c @@ -0,0 +1,245 @@ +/* + * (C) 2003 Linux Networx, SuSE Linux AG + * (C) 2004 Tyan Computer + * (c) 2005 Digital Design Corporation + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801cx/nic.c b/src/southbridge/intel/i82801cx/nic.c new file mode 100644 index 0000000000..00ce038143 --- /dev/null +++ b/src/southbridge/intel/i82801cx/nic.c @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801cx/pci.c b/src/southbridge/intel/i82801cx/pci.c new file mode 100644 index 0000000000..842b214fc8 --- /dev/null +++ b/src/southbridge/intel/i82801cx/pci.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801cx/reset.c b/src/southbridge/intel/i82801cx/reset.c new file mode 100644 index 0000000000..bd479de758 --- /dev/null +++ b/src/southbridge/intel/i82801cx/reset.c @@ -0,0 +1,9 @@ +#include +#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); +} diff --git a/src/southbridge/intel/i82801cx/smbus.c b/src/southbridge/intel/i82801cx/smbus.c new file mode 100644 index 0000000000..324f82f286 --- /dev/null +++ b/src/southbridge/intel/i82801cx/smbus.c @@ -0,0 +1,83 @@ +#include +#include +#include +#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 +} diff --git a/src/southbridge/intel/i82801cx/usb.c b/src/southbridge/intel/i82801cx/usb.c new file mode 100644 index 0000000000..28cb3572e5 --- /dev/null +++ b/src/southbridge/intel/i82801cx/usb.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801dx/Makefile.inc b/src/southbridge/intel/i82801dx/Makefile.inc index 7952b3b25c..9070158d0d 100644 --- a/src/southbridge/intel/i82801dx/Makefile.inc +++ b/src/southbridge/intel/i82801dx/Makefile.inc @@ -20,14 +20,14 @@ ## 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 diff --git a/src/southbridge/intel/i82801dx/ac97.c b/src/southbridge/intel/i82801dx/ac97.c new file mode 100644 index 0000000000..ccfccd3421 --- /dev/null +++ b/src/southbridge/intel/i82801dx/ac97.c @@ -0,0 +1,285 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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, +}; + + diff --git a/src/southbridge/intel/i82801dx/early_smbus.c b/src/southbridge/intel/i82801dx/early_smbus.c new file mode 100644 index 0000000000..f58cd86342 --- /dev/null +++ b/src/southbridge/intel/i82801dx/early_smbus.c @@ -0,0 +1,196 @@ +/* + * 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 diff --git a/src/southbridge/intel/i82801dx/i82801dx_ac97.c b/src/southbridge/intel/i82801dx/i82801dx_ac97.c deleted file mode 100644 index ccfccd3421..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_ac97.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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, -}; - - diff --git a/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c b/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c deleted file mode 100644 index f58cd86342..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_early_smbus.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * 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 diff --git a/src/southbridge/intel/i82801dx/i82801dx_ide.c b/src/southbridge/intel/i82801dx/i82801dx_ide.c deleted file mode 100644 index 75350da058..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_ide.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801dx/i82801dx_lpc.c b/src/southbridge/intel/i82801dx/i82801dx_lpc.c deleted file mode 100644 index 768e70096b..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_lpc.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 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 - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801dx/i82801dx_nvs.h b/src/southbridge/intel/i82801dx/i82801dx_nvs.h deleted file mode 100644 index 03f8de74ea..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_nvs.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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; - diff --git a/src/southbridge/intel/i82801dx/i82801dx_pci.c b/src/southbridge/intel/i82801dx/i82801dx_pci.c deleted file mode 100644 index 610ec1e5df..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_pci.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801dx/i82801dx_reset.c b/src/southbridge/intel/i82801dx/i82801dx_reset.c deleted file mode 100644 index 8dbe6cb1d7..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_reset.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 -#include - -void hard_reset(void) -{ - /* Try rebooting through port 0xcf9 */ - outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9); -} diff --git a/src/southbridge/intel/i82801dx/i82801dx_smbus.c b/src/southbridge/intel/i82801dx/i82801dx_smbus.c deleted file mode 100644 index 1f7e47be95..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_smbus.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 -#include -#include - -#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; -} diff --git a/src/southbridge/intel/i82801dx/i82801dx_smi.c b/src/southbridge/intel/i82801dx/i82801dx_smi.c deleted file mode 100644 index 55d8a70965..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_smi.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82801dx/i82801dx_smihandler.c b/src/southbridge/intel/i82801dx/i82801dx_smihandler.c deleted file mode 100644 index 5b7520f553..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_smihandler.c +++ /dev/null @@ -1,667 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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); - } - -} diff --git a/src/southbridge/intel/i82801dx/i82801dx_tco_timer.c b/src/southbridge/intel/i82801dx/i82801dx_tco_timer.c deleted file mode 100644 index a778d0851d..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_tco_timer.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Joseph Smith - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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); -} diff --git a/src/southbridge/intel/i82801dx/i82801dx_usb.c b/src/southbridge/intel/i82801dx/i82801dx_usb.c deleted file mode 100644 index be44a293dc..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_usb.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801dx/i82801dx_usb2.c b/src/southbridge/intel/i82801dx/i82801dx_usb2.c deleted file mode 100644 index a0ea5f64e1..0000000000 --- a/src/southbridge/intel/i82801dx/i82801dx_usb2.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801dx/ide.c b/src/southbridge/intel/i82801dx/ide.c new file mode 100644 index 0000000000..75350da058 --- /dev/null +++ b/src/southbridge/intel/i82801dx/ide.c @@ -0,0 +1,82 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801dx/lpc.c b/src/southbridge/intel/i82801dx/lpc.c new file mode 100644 index 0000000000..768e70096b --- /dev/null +++ b/src/southbridge/intel/i82801dx/lpc.c @@ -0,0 +1,347 @@ +/* + * 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 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801dx/nvs.h b/src/southbridge/intel/i82801dx/nvs.h new file mode 100644 index 0000000000..03f8de74ea --- /dev/null +++ b/src/southbridge/intel/i82801dx/nvs.h @@ -0,0 +1,138 @@ +/* + * 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; + diff --git a/src/southbridge/intel/i82801dx/pci.c b/src/southbridge/intel/i82801dx/pci.c new file mode 100644 index 0000000000..610ec1e5df --- /dev/null +++ b/src/southbridge/intel/i82801dx/pci.c @@ -0,0 +1,58 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801dx/reset.c b/src/southbridge/intel/i82801dx/reset.c new file mode 100644 index 0000000000..8dbe6cb1d7 --- /dev/null +++ b/src/southbridge/intel/i82801dx/reset.c @@ -0,0 +1,27 @@ +/* + * 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 +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9 */ + outb((0 << 3) | (1 << 2) | (1 << 1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801dx/smbus.c b/src/southbridge/intel/i82801dx/smbus.c new file mode 100644 index 0000000000..1f7e47be95 --- /dev/null +++ b/src/southbridge/intel/i82801dx/smbus.c @@ -0,0 +1,105 @@ +/* + * 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 +#include +#include + +#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; +} diff --git a/src/southbridge/intel/i82801dx/smi.c b/src/southbridge/intel/i82801dx/smi.c new file mode 100644 index 0000000000..55d8a70965 --- /dev/null +++ b/src/southbridge/intel/i82801dx/smi.c @@ -0,0 +1,368 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82801dx/smihandler.c b/src/southbridge/intel/i82801dx/smihandler.c new file mode 100644 index 0000000000..4875ba7480 --- /dev/null +++ b/src/southbridge/intel/i82801dx/smihandler.c @@ -0,0 +1,667 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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); + } + +} diff --git a/src/southbridge/intel/i82801dx/tco_timer.c b/src/southbridge/intel/i82801dx/tco_timer.c new file mode 100644 index 0000000000..a778d0851d --- /dev/null +++ b/src/southbridge/intel/i82801dx/tco_timer.c @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Joseph Smith + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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); +} diff --git a/src/southbridge/intel/i82801dx/usb.c b/src/southbridge/intel/i82801dx/usb.c new file mode 100644 index 0000000000..be44a293dc --- /dev/null +++ b/src/southbridge/intel/i82801dx/usb.c @@ -0,0 +1,68 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801dx/usb2.c b/src/southbridge/intel/i82801dx/usb2.c new file mode 100644 index 0000000000..a0ea5f64e1 --- /dev/null +++ b/src/southbridge/intel/i82801dx/usb2.c @@ -0,0 +1,54 @@ +/* + * 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ex/Makefile.inc b/src/southbridge/intel/i82801ex/Makefile.inc index ddddae37b6..e0d3148755 100644 --- a/src/southbridge/intel/i82801ex/Makefile.inc +++ b/src/southbridge/intel/i82801ex/Makefile.inc @@ -1,11 +1,11 @@ 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 diff --git a/src/southbridge/intel/i82801ex/ac97.c b/src/southbridge/intel/i82801ex/ac97.c new file mode 100644 index 0000000000..08efe1534d --- /dev/null +++ b/src/southbridge/intel/i82801ex/ac97.c @@ -0,0 +1,37 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ex/early_smbus.c b/src/southbridge/intel/i82801ex/early_smbus.c new file mode 100644 index 0000000000..cdf1f62c57 --- /dev/null +++ b/src/southbridge/intel/i82801ex/early_smbus.c @@ -0,0 +1,130 @@ +#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;i3) + 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 diff --git a/src/southbridge/intel/i82801ex/ehci.c b/src/southbridge/intel/i82801ex/ehci.c new file mode 100644 index 0000000000..8ae921d194 --- /dev/null +++ b/src/southbridge/intel/i82801ex/ehci.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ex/i82801ex_ac97.c b/src/southbridge/intel/i82801ex/i82801ex_ac97.c deleted file mode 100644 index 08efe1534d..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_ac97.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ex/i82801ex_early_smbus.c b/src/southbridge/intel/i82801ex/i82801ex_early_smbus.c deleted file mode 100644 index b07c77a94f..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_early_smbus.c +++ /dev/null @@ -1,130 +0,0 @@ -#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;i3) - 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 diff --git a/src/southbridge/intel/i82801ex/i82801ex_ehci.c b/src/southbridge/intel/i82801ex/i82801ex_ehci.c deleted file mode 100644 index 8ae921d194..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_ehci.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ex/i82801ex_ide.c b/src/southbridge/intel/i82801ex/i82801ex_ide.c deleted file mode 100644 index bbab6f1cc0..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_ide.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801ex/i82801ex_lpc.c b/src/southbridge/intel/i82801ex/i82801ex_lpc.c deleted file mode 100644 index 998360ce07..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_lpc.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * (C) 2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801ex/i82801ex_pci.c b/src/southbridge/intel/i82801ex/i82801ex_pci.c deleted file mode 100644 index 80c6e49bc0..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_pci.c +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801ex/i82801ex_reset.c b/src/southbridge/intel/i82801ex/i82801ex_reset.c deleted file mode 100644 index 9936892efe..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_reset.c +++ /dev/null @@ -1,8 +0,0 @@ -#include -#include - -void hard_reset(void) -{ - /* Try rebooting through port 0xcf9 */ - outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); -} diff --git a/src/southbridge/intel/i82801ex/i82801ex_sata.c b/src/southbridge/intel/i82801ex/i82801ex_sata.c deleted file mode 100644 index 9b340e9afd..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_sata.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801ex/i82801ex_smbus.c b/src/southbridge/intel/i82801ex/i82801ex_smbus.c deleted file mode 100644 index 377df11cd0..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_smbus.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801ex/i82801ex_smbus.h b/src/southbridge/intel/i82801ex/i82801ex_smbus.h deleted file mode 100644 index f330c0a5de..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_smbus.h +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#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; -} - diff --git a/src/southbridge/intel/i82801ex/i82801ex_uhci.c b/src/southbridge/intel/i82801ex/i82801ex_uhci.c deleted file mode 100644 index 56536b7273..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_uhci.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801ex/i82801ex_watchdog.c b/src/southbridge/intel/i82801ex/i82801ex_watchdog.c deleted file mode 100644 index 26f6644763..0000000000 --- a/src/southbridge/intel/i82801ex/i82801ex_watchdog.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include -#include -#include - -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"); -} - diff --git a/src/southbridge/intel/i82801ex/ide.c b/src/southbridge/intel/i82801ex/ide.c new file mode 100644 index 0000000000..bbab6f1cc0 --- /dev/null +++ b/src/southbridge/intel/i82801ex/ide.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801ex/lpc.c b/src/southbridge/intel/i82801ex/lpc.c new file mode 100644 index 0000000000..998360ce07 --- /dev/null +++ b/src/southbridge/intel/i82801ex/lpc.c @@ -0,0 +1,358 @@ +/* + * (C) 2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801ex/pci.c b/src/southbridge/intel/i82801ex/pci.c new file mode 100644 index 0000000000..80c6e49bc0 --- /dev/null +++ b/src/southbridge/intel/i82801ex/pci.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801ex/reset.c b/src/southbridge/intel/i82801ex/reset.c new file mode 100644 index 0000000000..9936892efe --- /dev/null +++ b/src/southbridge/intel/i82801ex/reset.c @@ -0,0 +1,8 @@ +#include +#include + +void hard_reset(void) +{ + /* Try rebooting through port 0xcf9 */ + outb((0 <<3)|(1<<2)|(1<<1), 0xcf9); +} diff --git a/src/southbridge/intel/i82801ex/sata.c b/src/southbridge/intel/i82801ex/sata.c new file mode 100644 index 0000000000..9b340e9afd --- /dev/null +++ b/src/southbridge/intel/i82801ex/sata.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801ex/smbus.c b/src/southbridge/intel/i82801ex/smbus.c new file mode 100644 index 0000000000..6bb48993b6 --- /dev/null +++ b/src/southbridge/intel/i82801ex/smbus.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801ex/smbus.h b/src/southbridge/intel/i82801ex/smbus.h new file mode 100644 index 0000000000..f330c0a5de --- /dev/null +++ b/src/southbridge/intel/i82801ex/smbus.h @@ -0,0 +1,105 @@ +#include + +#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; +} + diff --git a/src/southbridge/intel/i82801ex/uhci.c b/src/southbridge/intel/i82801ex/uhci.c new file mode 100644 index 0000000000..56536b7273 --- /dev/null +++ b/src/southbridge/intel/i82801ex/uhci.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801ex/watchdog.c b/src/southbridge/intel/i82801ex/watchdog.c new file mode 100644 index 0000000000..26f6644763 --- /dev/null +++ b/src/southbridge/intel/i82801ex/watchdog.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include +#include + +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"); +} + diff --git a/src/southbridge/intel/i82801gx/Makefile.inc b/src/southbridge/intel/i82801gx/Makefile.inc index dfc9c4d3b6..d3a731b2ac 100644 --- a/src/southbridge/intel/i82801gx/Makefile.inc +++ b/src/southbridge/intel/i82801gx/Makefile.inc @@ -18,24 +18,24 @@ ## 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 diff --git a/src/southbridge/intel/i82801gx/ac97.c b/src/southbridge/intel/i82801gx/ac97.c new file mode 100644 index 0000000000..602014bb2e --- /dev/null +++ b/src/southbridge/intel/i82801gx/ac97.c @@ -0,0 +1,303 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/acpi/ac97.asl b/src/southbridge/intel/i82801gx/acpi/ac97.asl new file mode 100644 index 0000000000..8a8cf82217 --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/ac97.asl @@ -0,0 +1,40 @@ +/* + * 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 }) +} + + diff --git a/src/southbridge/intel/i82801gx/acpi/audio.asl b/src/southbridge/intel/i82801gx/acpi/audio.asl new file mode 100644 index 0000000000..d03be4fdd3 --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/audio.asl @@ -0,0 +1,36 @@ +/* + * 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. + }) +} + diff --git a/src/southbridge/intel/i82801gx/acpi/ich7.asl b/src/southbridge/intel/i82801gx/acpi/ich7.asl index a37208c021..8387b20037 100644 --- a/src/southbridge/intel/i82801gx/acpi/ich7.asl +++ b/src/southbridge/intel/i82801gx/acpi/ich7.asl @@ -159,30 +159,30 @@ Scope(\) } // 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" diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl b/src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl deleted file mode 100644 index 8a8cf82217..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_ac97.asl +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 }) -} - - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_audio.asl b/src/southbridge/intel/i82801gx/acpi/ich7_audio.asl deleted file mode 100644 index d03be4fdd3..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_audio.asl +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - }) -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_irqlinks.asl b/src/southbridge/intel/i82801gx/acpi/ich7_irqlinks.asl deleted file mode 100644 index 5fcee45f29..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_irqlinks.asl +++ /dev/null @@ -1,493 +0,0 @@ -/* - * 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) - } - } -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl b/src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl deleted file mode 100644 index a18673c679..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_lpc.asl +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 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 -} diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_pata.asl b/src/southbridge/intel/i82801gx/acpi/ich7_pata.asl deleted file mode 100644 index 1905ed26d2..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_pata.asl +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 ? - } - - } -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_pci.asl b/src/southbridge/intel/i82801gx/acpi/ich7_pci.asl deleted file mode 100644 index d253d51a78..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_pci.asl +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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" - } - -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_pcie.asl b/src/southbridge/intel/i82801gx/acpi/ich7_pcie.asl deleted file mode 100644 index a76c7fbe4d..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_pcie.asl +++ /dev/null @@ -1,186 +0,0 @@ -/* - * 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 } - }) - - } - - } -} - - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_sata.asl b/src/southbridge/intel/i82801gx/acpi/ich7_sata.asl deleted file mode 100644 index e0c336ac5d..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_sata.asl +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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 ? - } - - } -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl b/src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl deleted file mode 100644 index b6d2d6a2ab..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_smbus.asl +++ /dev/null @@ -1,242 +0,0 @@ -/* - * 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 -} - diff --git a/src/southbridge/intel/i82801gx/acpi/ich7_usb.asl b/src/southbridge/intel/i82801gx/acpi/ich7_usb.asl deleted file mode 100644 index 9ae9909a9e..0000000000 --- a/src/southbridge/intel/i82801gx/acpi/ich7_usb.asl +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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 - } -} - - diff --git a/src/southbridge/intel/i82801gx/acpi/irqlinks.asl b/src/southbridge/intel/i82801gx/acpi/irqlinks.asl new file mode 100644 index 0000000000..5fcee45f29 --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/irqlinks.asl @@ -0,0 +1,493 @@ +/* + * 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) + } + } +} + diff --git a/src/southbridge/intel/i82801gx/acpi/lpc.asl b/src/southbridge/intel/i82801gx/acpi/lpc.asl new file mode 100644 index 0000000000..3166a89baf --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/lpc.asl @@ -0,0 +1,290 @@ +/* + * 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 +} diff --git a/src/southbridge/intel/i82801gx/acpi/pata.asl b/src/southbridge/intel/i82801gx/acpi/pata.asl new file mode 100644 index 0000000000..1905ed26d2 --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/pata.asl @@ -0,0 +1,80 @@ +/* + * 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 ? + } + + } +} + diff --git a/src/southbridge/intel/i82801gx/acpi/pci.asl b/src/southbridge/intel/i82801gx/acpi/pci.asl new file mode 100644 index 0000000000..d253d51a78 --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/pci.asl @@ -0,0 +1,77 @@ +/* + * 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" + } + +} + diff --git a/src/southbridge/intel/i82801gx/acpi/pcie.asl b/src/southbridge/intel/i82801gx/acpi/pcie.asl new file mode 100644 index 0000000000..a76c7fbe4d --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/pcie.asl @@ -0,0 +1,186 @@ +/* + * 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 } + }) + + } + + } +} + + diff --git a/src/southbridge/intel/i82801gx/acpi/sata.asl b/src/southbridge/intel/i82801gx/acpi/sata.asl new file mode 100644 index 0000000000..e0c336ac5d --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/sata.asl @@ -0,0 +1,83 @@ +/* + * 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 ? + } + + } +} + diff --git a/src/southbridge/intel/i82801gx/acpi/smbus.asl b/src/southbridge/intel/i82801gx/acpi/smbus.asl new file mode 100644 index 0000000000..b6d2d6a2ab --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/smbus.asl @@ -0,0 +1,242 @@ +/* + * 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 +} + diff --git a/src/southbridge/intel/i82801gx/acpi/usb.asl b/src/southbridge/intel/i82801gx/acpi/usb.asl new file mode 100644 index 0000000000..9ae9909a9e --- /dev/null +++ b/src/southbridge/intel/i82801gx/acpi/usb.asl @@ -0,0 +1,217 @@ +/* + * 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 + } +} + + diff --git a/src/southbridge/intel/i82801gx/azalia.c b/src/southbridge/intel/i82801gx/azalia.c new file mode 100644 index 0000000000..362ffa3aa8 --- /dev/null +++ b/src/southbridge/intel/i82801gx/azalia.c @@ -0,0 +1,347 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/i82801gx/early_smbus.c b/src/southbridge/intel/i82801gx/early_smbus.c new file mode 100644 index 0000000000..1fa88730bc --- /dev/null +++ b/src/southbridge/intel/i82801gx/early_smbus.c @@ -0,0 +1,63 @@ +/* + * 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 +#include +#include +#include +#include +#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); +} + diff --git a/src/southbridge/intel/i82801gx/i82801gx_ac97.c b/src/southbridge/intel/i82801gx/i82801gx_ac97.c deleted file mode 100644 index 602014bb2e..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_ac97.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_azalia.c b/src/southbridge/intel/i82801gx/i82801gx_azalia.c deleted file mode 100644 index 362ffa3aa8..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_azalia.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c b/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c deleted file mode 100644 index 0298cc94cd..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_early_smbus.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#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); -} - diff --git a/src/southbridge/intel/i82801gx/i82801gx_ide.c b/src/southbridge/intel/i82801gx/i82801gx_ide.c deleted file mode 100644 index 6e05e0d9b5..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_ide.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_lpc.c b/src/southbridge/intel/i82801gx/i82801gx_lpc.c deleted file mode 100644 index f486c1ebf8..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_lpc.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_nic.c b/src/southbridge/intel/i82801gx/i82801gx_nic.c deleted file mode 100644 index 0405294cb7..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_nic.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 -#include -#include -#include - -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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_nvs.h b/src/southbridge/intel/i82801gx/i82801gx_nvs.h deleted file mode 100644 index 03f8de74ea..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_nvs.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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; - diff --git a/src/southbridge/intel/i82801gx/i82801gx_pci.c b/src/southbridge/intel/i82801gx/i82801gx_pci.c deleted file mode 100644 index 4c44e1e153..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_pci.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_pcie.c b/src/southbridge/intel/i82801gx/i82801gx_pcie.c deleted file mode 100644 index d69bc6d07d..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_pcie.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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 -#include -#include -#include - -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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_reset.c b/src/southbridge/intel/i82801gx/i82801gx_reset.c deleted file mode 100644 index 29b69ff43a..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_reset.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 -#include - -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); -} diff --git a/src/southbridge/intel/i82801gx/i82801gx_sata.c b/src/southbridge/intel/i82801gx/i82801gx_sata.c deleted file mode 100644 index c3908489eb..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_sata.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_smbus.c b/src/southbridge/intel/i82801gx/i82801gx_smbus.c deleted file mode 100644 index 50c6d0f342..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_smbus.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_smbus.h b/src/southbridge/intel/i82801gx/i82801gx_smbus.h deleted file mode 100644 index a03e4cd957..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_smbus.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2005 Yinghai Lu - * 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 -#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; -} - diff --git a/src/southbridge/intel/i82801gx/i82801gx_smi.c b/src/southbridge/intel/i82801gx/i82801gx_smi.c deleted file mode 100644 index 39d5c4dca2..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_smi.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82801gx/i82801gx_smihandler.c b/src/southbridge/intel/i82801gx/i82801gx_smihandler.c deleted file mode 100644 index 997ec0fd5c..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_smihandler.c +++ /dev/null @@ -1,647 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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); - } - -} diff --git a/src/southbridge/intel/i82801gx/i82801gx_usb.c b/src/southbridge/intel/i82801gx/i82801gx_usb.c deleted file mode 100644 index 00fddf7c65..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_usb.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c b/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c deleted file mode 100644 index 991aa5adaa..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_usb_debug.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c b/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c deleted file mode 100644 index cd74e2b8f6..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_usb_ehci.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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 -#include -#include -#include -#include "i82801gx.h" -#include -#include - -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, -}; diff --git a/src/southbridge/intel/i82801gx/i82801gx_watchdog.c b/src/southbridge/intel/i82801gx/i82801gx_watchdog.c deleted file mode 100644 index a26786d7d0..0000000000 --- a/src/southbridge/intel/i82801gx/i82801gx_watchdog.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -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"); -} diff --git a/src/southbridge/intel/i82801gx/ide.c b/src/southbridge/intel/i82801gx/ide.c new file mode 100644 index 0000000000..6e05e0d9b5 --- /dev/null +++ b/src/southbridge/intel/i82801gx/ide.c @@ -0,0 +1,128 @@ +/* + * 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c new file mode 100644 index 0000000000..f486c1ebf8 --- /dev/null +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -0,0 +1,536 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/nic.c b/src/southbridge/intel/i82801gx/nic.c new file mode 100644 index 0000000000..0405294cb7 --- /dev/null +++ b/src/southbridge/intel/i82801gx/nic.c @@ -0,0 +1,48 @@ +/* + * 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 +#include +#include +#include + +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, +}; diff --git a/src/southbridge/intel/i82801gx/nvs.h b/src/southbridge/intel/i82801gx/nvs.h new file mode 100644 index 0000000000..03f8de74ea --- /dev/null +++ b/src/southbridge/intel/i82801gx/nvs.h @@ -0,0 +1,138 @@ +/* + * 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; + diff --git a/src/southbridge/intel/i82801gx/pci.c b/src/southbridge/intel/i82801gx/pci.c new file mode 100644 index 0000000000..4c44e1e153 --- /dev/null +++ b/src/southbridge/intel/i82801gx/pci.c @@ -0,0 +1,154 @@ +/* + * 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/pcie.c b/src/southbridge/intel/i82801gx/pcie.c new file mode 100644 index 0000000000..d69bc6d07d --- /dev/null +++ b/src/southbridge/intel/i82801gx/pcie.c @@ -0,0 +1,164 @@ +/* + * 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 +#include +#include +#include + +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, +}; diff --git a/src/southbridge/intel/i82801gx/reset.c b/src/southbridge/intel/i82801gx/reset.c new file mode 100644 index 0000000000..29b69ff43a --- /dev/null +++ b/src/southbridge/intel/i82801gx/reset.c @@ -0,0 +1,41 @@ +/* + * 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 +#include + +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); +} diff --git a/src/southbridge/intel/i82801gx/sata.c b/src/southbridge/intel/i82801gx/sata.c new file mode 100644 index 0000000000..c3908489eb --- /dev/null +++ b/src/southbridge/intel/i82801gx/sata.c @@ -0,0 +1,258 @@ +/* + * 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/smbus.c b/src/southbridge/intel/i82801gx/smbus.c new file mode 100644 index 0000000000..834f310c6c --- /dev/null +++ b/src/southbridge/intel/i82801gx/smbus.c @@ -0,0 +1,93 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/smbus.h b/src/southbridge/intel/i82801gx/smbus.h new file mode 100644 index 0000000000..a03e4cd957 --- /dev/null +++ b/src/southbridge/intel/i82801gx/smbus.h @@ -0,0 +1,100 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2005 Yinghai Lu + * 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 +#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; +} + diff --git a/src/southbridge/intel/i82801gx/smi.c b/src/southbridge/intel/i82801gx/smi.c new file mode 100644 index 0000000000..39d5c4dca2 --- /dev/null +++ b/src/southbridge/intel/i82801gx/smi.c @@ -0,0 +1,368 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82801gx/smihandler.c b/src/southbridge/intel/i82801gx/smihandler.c new file mode 100644 index 0000000000..aefa283571 --- /dev/null +++ b/src/southbridge/intel/i82801gx/smihandler.c @@ -0,0 +1,647 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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); + } + +} diff --git a/src/southbridge/intel/i82801gx/usb.c b/src/southbridge/intel/i82801gx/usb.c new file mode 100644 index 0000000000..00fddf7c65 --- /dev/null +++ b/src/southbridge/intel/i82801gx/usb.c @@ -0,0 +1,100 @@ +/* + * 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/i82801gx/usb_debug.c b/src/southbridge/intel/i82801gx/usb_debug.c new file mode 100644 index 0000000000..991aa5adaa --- /dev/null +++ b/src/southbridge/intel/i82801gx/usb_debug.c @@ -0,0 +1,50 @@ +/* + * 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 +#include +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/intel/i82801gx/usb_ehci.c b/src/southbridge/intel/i82801gx/usb_ehci.c new file mode 100644 index 0000000000..cd74e2b8f6 --- /dev/null +++ b/src/southbridge/intel/i82801gx/usb_ehci.c @@ -0,0 +1,129 @@ +/* + * 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 +#include +#include +#include +#include "i82801gx.h" +#include +#include + +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, +}; diff --git a/src/southbridge/intel/i82801gx/watchdog.c b/src/southbridge/intel/i82801gx/watchdog.c new file mode 100644 index 0000000000..a26786d7d0 --- /dev/null +++ b/src/southbridge/intel/i82801gx/watchdog.c @@ -0,0 +1,53 @@ +/* + * 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 +#include +#include +#include +#include + +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"); +} diff --git a/src/southbridge/intel/i82870/Makefile.inc b/src/southbridge/intel/i82870/Makefile.inc index 8f4964573e..7ca6fb5b07 100644 --- a/src/southbridge/intel/i82870/Makefile.inc +++ b/src/southbridge/intel/i82870/Makefile.inc @@ -1,3 +1,3 @@ -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 diff --git a/src/southbridge/intel/i82870/ioapic.c b/src/southbridge/intel/i82870/ioapic.c new file mode 100644 index 0000000000..6a0f0d222f --- /dev/null +++ b/src/southbridge/intel/i82870/ioapic.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include +#include +#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, + +}; diff --git a/src/southbridge/intel/i82870/p64h2_ioapic.c b/src/southbridge/intel/i82870/p64h2_ioapic.c deleted file mode 100644 index 6a0f0d222f..0000000000 --- a/src/southbridge/intel/i82870/p64h2_ioapic.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#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, - -}; diff --git a/src/southbridge/intel/i82870/p64h2_pci_parity.c b/src/southbridge/intel/i82870/p64h2_pci_parity.c deleted file mode 100644 index fe27abf280..0000000000 --- a/src/southbridge/intel/i82870/p64h2_pci_parity.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -# - -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; -} - - diff --git a/src/southbridge/intel/i82870/p64h2_pcibridge.c b/src/southbridge/intel/i82870/p64h2_pcibridge.c deleted file mode 100644 index 89b86f5966..0000000000 --- a/src/southbridge/intel/i82870/p64h2_pcibridge.c +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/intel/i82870/pci_parity.c b/src/southbridge/intel/i82870/pci_parity.c new file mode 100644 index 0000000000..fe27abf280 --- /dev/null +++ b/src/southbridge/intel/i82870/pci_parity.c @@ -0,0 +1,25 @@ +#include +#include +#include +# + +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; +} + + diff --git a/src/southbridge/intel/i82870/pcibridge.c b/src/southbridge/intel/i82870/pcibridge.c new file mode 100644 index 0000000000..89b86f5966 --- /dev/null +++ b/src/southbridge/intel/i82870/pcibridge.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/intel/pxhd/Makefile.inc b/src/southbridge/intel/pxhd/Makefile.inc index 30f1f69a63..d5b3a5f88e 100644 --- a/src/southbridge/intel/pxhd/Makefile.inc +++ b/src/southbridge/intel/pxhd/Makefile.inc @@ -1 +1 @@ -driver-y += pxhd_bridge.c +driver-y += bridge.c diff --git a/src/southbridge/intel/pxhd/bridge.c b/src/southbridge/intel/pxhd/bridge.c new file mode 100644 index 0000000000..1134f8f2f8 --- /dev/null +++ b/src/southbridge/intel/pxhd/bridge.c @@ -0,0 +1,212 @@ +/* + * (C) 2003-2004 Linux Networx + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/intel/pxhd/pxhd_bridge.c b/src/southbridge/intel/pxhd/pxhd_bridge.c deleted file mode 100644 index 1134f8f2f8..0000000000 --- a/src/southbridge/intel/pxhd/pxhd_bridge.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * (C) 2003-2004 Linux Networx - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/Makefile.inc b/src/southbridge/nvidia/ck804/Makefile.inc index 09b20708af..b1577f553a 100644 --- a/src/southbridge/nvidia/ck804/Makefile.inc +++ b/src/southbridge/nvidia/ck804/Makefile.inc @@ -1,22 +1,22 @@ 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 diff --git a/src/southbridge/nvidia/ck804/ac97.c b/src/southbridge/nvidia/ck804/ac97.c new file mode 100644 index 0000000000..20b3cfb4b2 --- /dev/null +++ b/src/southbridge/nvidia/ck804/ac97.c @@ -0,0 +1,58 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/bootblock.c b/src/southbridge/nvidia/ck804/bootblock.c index 5c829e121d..6d4b6a4777 100644 --- a/src/southbridge/nvidia/ck804/bootblock.c +++ b/src/southbridge/nvidia/ck804/bootblock.c @@ -20,7 +20,7 @@ #include #include -#include "southbridge/nvidia/ck804/ck804_enable_rom.c" +#include "southbridge/nvidia/ck804/enable_rom.c" static void bootblock_southbridge_init(void) { diff --git a/src/southbridge/nvidia/ck804/ck804_ac97.c b/src/southbridge/nvidia/ck804/ck804_ac97.c deleted file mode 100644 index 20b3cfb4b2..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_ac97.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_early_setup.c b/src/southbridge/nvidia/ck804/ck804_early_setup.c deleted file mode 100644 index 53d35feecc..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_early_setup.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 - -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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_early_setup_car.c b/src/southbridge/nvidia/ck804/ck804_early_setup_car.c deleted file mode 100644 index 23a83ff400..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_early_setup_car.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h b/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h deleted file mode 100644 index 39ae8c1a17..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_early_setup_ss.h +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_early_smbus.c b/src/southbridge/nvidia/ck804/ck804_early_smbus.c deleted file mode 100644 index 05dcd98014..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_early_smbus.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include - -#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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_early_smbus.h b/src/southbridge/nvidia/ck804/ck804_early_smbus.h deleted file mode 100644 index cf25403fdd..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_early_smbus.h +++ /dev/null @@ -1,5 +0,0 @@ -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); diff --git a/src/southbridge/nvidia/ck804/ck804_enable_rom.c b/src/southbridge/nvidia/ck804/ck804_enable_rom.c deleted file mode 100644 index facf7959eb..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_enable_rom.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_enable_usbdebug.c b/src/southbridge/nvidia/ck804/ck804_enable_usbdebug.c deleted file mode 100644 index 3cccded343..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_enable_usbdebug.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_fadt.c b/src/southbridge/nvidia/ck804/ck804_fadt.c deleted file mode 100644 index a315a32b96..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_fadt.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * ACPI - create the Fixed ACPI Description Tables (FADT) - * (C) Copyright 2005 Stefan Reinauer - */ - -#include -#include -#include - -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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_ht.c b/src/southbridge/nvidia/ck804/ck804_ht.c deleted file mode 100644 index 7a63d97b56..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_ht.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_ide.c b/src/southbridge/nvidia/ck804/ck804_ide.c deleted file mode 100644 index 47f451e6eb..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_ide.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_lpc.c b/src/southbridge/nvidia/ck804/ck804_lpc.c deleted file mode 100644 index b3f14bfe18..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_lpc.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * 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 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 diff --git a/src/southbridge/nvidia/ck804/ck804_nic.c b/src/southbridge/nvidia/ck804/ck804_nic.c deleted file mode 100644 index 8e1bddf9e2..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_nic.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_pci.c b/src/southbridge/nvidia/ck804/ck804_pci.c deleted file mode 100644 index 044c7100d4..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_pci.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_pcie.c b/src/southbridge/nvidia/ck804/ck804_pcie.c deleted file mode 100644 index cbde9cf57c..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_pcie.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_reset.c b/src/southbridge/nvidia/ck804/ck804_reset.c deleted file mode 100644 index 7f73e68d35..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_reset.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include - -#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); -} diff --git a/src/southbridge/nvidia/ck804/ck804_sata.c b/src/southbridge/nvidia/ck804/ck804_sata.c deleted file mode 100644 index b3ec80422d..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_sata.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_smbus.c b/src/southbridge/nvidia/ck804/ck804_smbus.c deleted file mode 100644 index ca5305065f..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_smbus.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_smbus.h b/src/southbridge/nvidia/ck804/ck804_smbus.h deleted file mode 100644 index 2cdcadce80..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_smbus.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 - -#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; -} diff --git a/src/southbridge/nvidia/ck804/ck804_usb.c b/src/southbridge/nvidia/ck804/ck804_usb.c deleted file mode 100644 index 45ee734eb1..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_usb.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/ck804_usb2.c b/src/southbridge/nvidia/ck804/ck804_usb2.c deleted file mode 100644 index e53f38f019..0000000000 --- a/src/southbridge/nvidia/ck804/ck804_usb2.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/ck804/early_setup.c b/src/southbridge/nvidia/ck804/early_setup.c new file mode 100644 index 0000000000..53d35feecc --- /dev/null +++ b/src/southbridge/nvidia/ck804/early_setup.c @@ -0,0 +1,338 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 + +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); +} diff --git a/src/southbridge/nvidia/ck804/early_setup_car.c b/src/southbridge/nvidia/ck804/early_setup_car.c new file mode 100644 index 0000000000..23a83ff400 --- /dev/null +++ b/src/southbridge/nvidia/ck804/early_setup_car.c @@ -0,0 +1,365 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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); +} diff --git a/src/southbridge/nvidia/ck804/early_setup_ss.h b/src/southbridge/nvidia/ck804/early_setup_ss.h new file mode 100644 index 0000000000..39ae8c1a17 --- /dev/null +++ b/src/southbridge/nvidia/ck804/early_setup_ss.h @@ -0,0 +1,220 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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, +}; diff --git a/src/southbridge/nvidia/ck804/early_smbus.c b/src/southbridge/nvidia/ck804/early_smbus.c new file mode 100644 index 0000000000..70f8744c25 --- /dev/null +++ b/src/southbridge/nvidia/ck804/early_smbus.c @@ -0,0 +1,80 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include + +#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); +} diff --git a/src/southbridge/nvidia/ck804/early_smbus.h b/src/southbridge/nvidia/ck804/early_smbus.h new file mode 100644 index 0000000000..cf25403fdd --- /dev/null +++ b/src/southbridge/nvidia/ck804/early_smbus.h @@ -0,0 +1,5 @@ +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); diff --git a/src/southbridge/nvidia/ck804/enable_rom.c b/src/southbridge/nvidia/ck804/enable_rom.c new file mode 100644 index 0000000000..facf7959eb --- /dev/null +++ b/src/southbridge/nvidia/ck804/enable_rom.c @@ -0,0 +1,40 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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); +} diff --git a/src/southbridge/nvidia/ck804/enable_usbdebug.c b/src/southbridge/nvidia/ck804/enable_usbdebug.c new file mode 100644 index 0000000000..3cccded343 --- /dev/null +++ b/src/southbridge/nvidia/ck804/enable_usbdebug.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/nvidia/ck804/fadt.c b/src/southbridge/nvidia/ck804/fadt.c new file mode 100644 index 0000000000..a315a32b96 --- /dev/null +++ b/src/southbridge/nvidia/ck804/fadt.c @@ -0,0 +1,147 @@ +/* + * ACPI - create the Fixed ACPI Description Tables (FADT) + * (C) Copyright 2005 Stefan Reinauer + */ + +#include +#include +#include + +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); +} diff --git a/src/southbridge/nvidia/ck804/ht.c b/src/southbridge/nvidia/ck804/ht.c new file mode 100644 index 0000000000..7a63d97b56 --- /dev/null +++ b/src/southbridge/nvidia/ck804/ht.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/ide.c b/src/southbridge/nvidia/ck804/ide.c new file mode 100644 index 0000000000..47f451e6eb --- /dev/null +++ b/src/southbridge/nvidia/ck804/ide.c @@ -0,0 +1,82 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/lpc.c b/src/southbridge/nvidia/ck804/lpc.c new file mode 100644 index 0000000000..b3f14bfe18 --- /dev/null +++ b/src/southbridge/nvidia/ck804/lpc.c @@ -0,0 +1,345 @@ +/* + * 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 diff --git a/src/southbridge/nvidia/ck804/nic.c b/src/southbridge/nvidia/ck804/nic.c new file mode 100644 index 0000000000..8e1bddf9e2 --- /dev/null +++ b/src/southbridge/nvidia/ck804/nic.c @@ -0,0 +1,136 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/pci.c b/src/southbridge/nvidia/ck804/pci.c new file mode 100644 index 0000000000..044c7100d4 --- /dev/null +++ b/src/southbridge/nvidia/ck804/pci.c @@ -0,0 +1,94 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/pcie.c b/src/southbridge/nvidia/ck804/pcie.c new file mode 100644 index 0000000000..cbde9cf57c --- /dev/null +++ b/src/southbridge/nvidia/ck804/pcie.c @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/reset.c b/src/southbridge/nvidia/ck804/reset.c new file mode 100644 index 0000000000..7f73e68d35 --- /dev/null +++ b/src/southbridge/nvidia/ck804/reset.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include + +#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); +} diff --git a/src/southbridge/nvidia/ck804/sata.c b/src/southbridge/nvidia/ck804/sata.c new file mode 100644 index 0000000000..b3ec80422d --- /dev/null +++ b/src/southbridge/nvidia/ck804/sata.c @@ -0,0 +1,187 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/smbus.c b/src/southbridge/nvidia/ck804/smbus.c new file mode 100644 index 0000000000..b1c6e28530 --- /dev/null +++ b/src/southbridge/nvidia/ck804/smbus.c @@ -0,0 +1,110 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/smbus.h b/src/southbridge/nvidia/ck804/smbus.h new file mode 100644 index 0000000000..2cdcadce80 --- /dev/null +++ b/src/southbridge/nvidia/ck804/smbus.h @@ -0,0 +1,229 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 + +#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; +} diff --git a/src/southbridge/nvidia/ck804/usb.c b/src/southbridge/nvidia/ck804/usb.c new file mode 100644 index 0000000000..45ee734eb1 --- /dev/null +++ b/src/southbridge/nvidia/ck804/usb.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/ck804/usb2.c b/src/southbridge/nvidia/ck804/usb2.c new file mode 100644 index 0000000000..e53f38f019 --- /dev/null +++ b/src/southbridge/nvidia/ck804/usb2.c @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/mcp55/Makefile.inc b/src/southbridge/nvidia/mcp55/Makefile.inc index a9dcf7f40f..a59e1486fa 100644 --- a/src/southbridge/nvidia/mcp55/Makefile.inc +++ b/src/southbridge/nvidia/mcp55/Makefile.inc @@ -1,21 +1,21 @@ 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 diff --git a/src/southbridge/nvidia/mcp55/azalia.c b/src/southbridge/nvidia/mcp55/azalia.c new file mode 100644 index 0000000000..493c98f7b2 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/azalia.c @@ -0,0 +1,297 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/bootblock.c b/src/southbridge/nvidia/mcp55/bootblock.c index e735b4702c..139f93c99d 100644 --- a/src/southbridge/nvidia/mcp55/bootblock.c +++ b/src/southbridge/nvidia/mcp55/bootblock.c @@ -18,7 +18,7 @@ * 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) { diff --git a/src/southbridge/nvidia/mcp55/early_ctrl.c b/src/southbridge/nvidia/mcp55/early_ctrl.c new file mode 100644 index 0000000000..5c5f07c81a --- /dev/null +++ b/src/southbridge/nvidia/mcp55/early_ctrl.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu 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 +#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 */ +} + diff --git a/src/southbridge/nvidia/mcp55/early_setup_car.c b/src/southbridge/nvidia/mcp55/early_setup_car.c new file mode 100644 index 0000000000..bf778a93fa --- /dev/null +++ b/src/southbridge/nvidia/mcp55/early_setup_car.c @@ -0,0 +1,402 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006 AMD + * Written by Yinghai Lu 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; j1) ) { + 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 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, +}; + + diff --git a/src/southbridge/nvidia/mcp55/early_smbus.c b/src/southbridge/nvidia/mcp55/early_smbus.c new file mode 100644 index 0000000000..b351b58022 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/early_smbus.c @@ -0,0 +1,87 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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); +} + diff --git a/src/southbridge/nvidia/mcp55/enable_rom.c b/src/southbridge/nvidia/mcp55/enable_rom.c new file mode 100644 index 0000000000..d08b1d486b --- /dev/null +++ b/src/southbridge/nvidia/mcp55/enable_rom.c @@ -0,0 +1,54 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#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); +} diff --git a/src/southbridge/nvidia/mcp55/enable_usbdebug.c b/src/southbridge/nvidia/mcp55/enable_usbdebug.c new file mode 100644 index 0000000000..2e78fa1ff6 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/enable_usbdebug.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/nvidia/mcp55/fadt.c b/src/southbridge/nvidia/mcp55/fadt.c new file mode 100644 index 0000000000..753a663239 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/fadt.c @@ -0,0 +1,173 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Nick Barker + * Copyright (C) 2007 Rudolf Marek + * Copyright (C) 2009 Harald Gutmann + * + * This program is free software; 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 +#include +#include +#include +#include +#include + +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); +} diff --git a/src/southbridge/nvidia/mcp55/ht.c b/src/southbridge/nvidia/mcp55/ht.c new file mode 100644 index 0000000000..8b0248f8a6 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/ht.c @@ -0,0 +1,45 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/ide.c b/src/southbridge/nvidia/mcp55/ide.c new file mode 100644 index 0000000000..90dd2bf48d --- /dev/null +++ b/src/southbridge/nvidia/mcp55/ide.c @@ -0,0 +1,87 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/lpc.c b/src/southbridge/nvidia/mcp55/lpc.c new file mode 100644 index 0000000000..3132eedbd2 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/lpc.c @@ -0,0 +1,316 @@ +/* + * 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 for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_early_ctrl.c b/src/southbridge/nvidia/mcp55/mcp55_early_ctrl.c deleted file mode 100644 index 5c5f07c81a..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_early_ctrl.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 AMD - * Written by Yinghai Lu 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 -#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 */ -} - diff --git a/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c b/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c deleted file mode 100644 index bf778a93fa..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_early_setup_car.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006 AMD - * Written by Yinghai Lu 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; j1) ) { - 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 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, -}; - - diff --git a/src/southbridge/nvidia/mcp55/mcp55_early_smbus.c b/src/southbridge/nvidia/mcp55/mcp55_early_smbus.c deleted file mode 100644 index 469aa7e964..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_early_smbus.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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); -} - diff --git a/src/southbridge/nvidia/mcp55/mcp55_enable_rom.c b/src/southbridge/nvidia/mcp55/mcp55_enable_rom.c deleted file mode 100644 index d08b1d486b..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_enable_rom.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#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); -} diff --git a/src/southbridge/nvidia/mcp55/mcp55_enable_usbdebug.c b/src/southbridge/nvidia/mcp55/mcp55_enable_usbdebug.c deleted file mode 100644 index 2e78fa1ff6..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_enable_usbdebug.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/nvidia/mcp55/mcp55_fadt.c b/src/southbridge/nvidia/mcp55/mcp55_fadt.c deleted file mode 100644 index 753a663239..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_fadt.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Nick Barker - * Copyright (C) 2007 Rudolf Marek - * Copyright (C) 2009 Harald Gutmann - * - * This program is free software; 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 -#include -#include -#include -#include -#include - -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); -} diff --git a/src/southbridge/nvidia/mcp55/mcp55_ht.c b/src/southbridge/nvidia/mcp55/mcp55_ht.c deleted file mode 100644 index 8b0248f8a6..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_ht.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_ide.c b/src/southbridge/nvidia/mcp55/mcp55_ide.c deleted file mode 100644 index 90dd2bf48d..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_ide.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_lpc.c b/src/southbridge/nvidia/mcp55/mcp55_lpc.c deleted file mode 100644 index 3132eedbd2..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_lpc.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * 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 for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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 for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/mcp55/mcp55_pci.c b/src/southbridge/nvidia/mcp55/mcp55_pci.c deleted file mode 100644 index 510d21d10b..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_pci.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_pcie.c b/src/southbridge/nvidia/mcp55/mcp55_pcie.c deleted file mode 100644 index cb60f3143a..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_pcie.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_reset.c b/src/southbridge/nvidia/mcp55/mcp55_reset.c deleted file mode 100644 index afc592c26b..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_reset.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include - -#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); -} - diff --git a/src/southbridge/nvidia/mcp55/mcp55_sata.c b/src/southbridge/nvidia/mcp55/mcp55_sata.c deleted file mode 100644 index eebc61e26f..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_sata.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/nvidia/mcp55/mcp55_smbus.c b/src/southbridge/nvidia/mcp55/mcp55_smbus.c deleted file mode 100644 index 47c422f08a..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_smbus.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_smbus.h b/src/southbridge/nvidia/mcp55/mcp55_smbus.h deleted file mode 100644 index d1dade9c45..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_smbus.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 - -#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; -} - diff --git a/src/southbridge/nvidia/mcp55/mcp55_usb.c b/src/southbridge/nvidia/mcp55/mcp55_usb.c deleted file mode 100644 index c005c91743..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_usb.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/nvidia/mcp55/mcp55_usb2.c b/src/southbridge/nvidia/mcp55/mcp55_usb2.c deleted file mode 100644 index cd4fe25f17..0000000000 --- a/src/southbridge/nvidia/mcp55/mcp55_usb2.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#include "mcp55.h" -#include - -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, -}; diff --git a/src/southbridge/nvidia/mcp55/nic.c b/src/southbridge/nvidia/mcp55/nic.c new file mode 100644 index 0000000000..3533e4e25a --- /dev/null +++ b/src/southbridge/nvidia/mcp55/nic.c @@ -0,0 +1,201 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/mcp55/pci.c b/src/southbridge/nvidia/mcp55/pci.c new file mode 100644 index 0000000000..510d21d10b --- /dev/null +++ b/src/southbridge/nvidia/mcp55/pci.c @@ -0,0 +1,103 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/pcie.c b/src/southbridge/nvidia/mcp55/pcie.c new file mode 100644 index 0000000000..cb60f3143a --- /dev/null +++ b/src/southbridge/nvidia/mcp55/pcie.c @@ -0,0 +1,79 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/reset.c b/src/southbridge/nvidia/mcp55/reset.c new file mode 100644 index 0000000000..afc592c26b --- /dev/null +++ b/src/southbridge/nvidia/mcp55/reset.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include + +#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); +} + diff --git a/src/southbridge/nvidia/mcp55/sata.c b/src/southbridge/nvidia/mcp55/sata.c new file mode 100644 index 0000000000..eebc61e26f --- /dev/null +++ b/src/southbridge/nvidia/mcp55/sata.c @@ -0,0 +1,92 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/nvidia/mcp55/smbus.c b/src/southbridge/nvidia/mcp55/smbus.c new file mode 100644 index 0000000000..ceb5f16df9 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/smbus.c @@ -0,0 +1,141 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/smbus.h b/src/southbridge/nvidia/mcp55/smbus.h new file mode 100644 index 0000000000..d1dade9c45 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/smbus.h @@ -0,0 +1,177 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 + +#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; +} + diff --git a/src/southbridge/nvidia/mcp55/usb.c b/src/southbridge/nvidia/mcp55/usb.c new file mode 100644 index 0000000000..c005c91743 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/usb.c @@ -0,0 +1,46 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/nvidia/mcp55/usb2.c b/src/southbridge/nvidia/mcp55/usb2.c new file mode 100644 index 0000000000..cd4fe25f17 --- /dev/null +++ b/src/southbridge/nvidia/mcp55/usb2.c @@ -0,0 +1,79 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#include "mcp55.h" +#include + +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, +}; diff --git a/src/southbridge/sis/sis966/Makefile.inc b/src/southbridge/sis/sis966/Makefile.inc index e51c81fa83..f796047a6f 100644 --- a/src/southbridge/sis/sis966/Makefile.inc +++ b/src/southbridge/sis/sis966/Makefile.inc @@ -1,15 +1,15 @@ 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 diff --git a/src/southbridge/sis/sis966/aza.c b/src/southbridge/sis/sis966/aza.c new file mode 100644 index 0000000000..c7573a3f7a --- /dev/null +++ b/src/southbridge/sis/sis966/aza.c @@ -0,0 +1,330 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#include +#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\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, +}; + diff --git a/src/southbridge/sis/sis966/early_ctrl.c b/src/southbridge/sis/sis966/early_ctrl.c new file mode 100644 index 0000000000..05b53365de --- /dev/null +++ b/src/southbridge/sis/sis966/early_ctrl.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 AMD + * Written by Yinghai Lu 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 + +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); + +} + diff --git a/src/southbridge/sis/sis966/early_setup_car.c b/src/southbridge/sis/sis966/early_setup_car.c new file mode 100644 index 0000000000..9de33137a7 --- /dev/null +++ b/src/southbridge/sis/sis966/early_setup_car.c @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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); +} + diff --git a/src/southbridge/sis/sis966/early_setup_ss.h b/src/southbridge/sis/sis966/early_setup_ss.h new file mode 100644 index 0000000000..c68e198639 --- /dev/null +++ b/src/southbridge/sis/sis966/early_setup_ss.h @@ -0,0 +1,222 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu 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, +}; + + diff --git a/src/southbridge/sis/sis966/early_smbus.c b/src/southbridge/sis/sis966/early_smbus.c new file mode 100644 index 0000000000..8ab65483f6 --- /dev/null +++ b/src/southbridge/sis/sis966/early_smbus.c @@ -0,0 +1,743 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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); +} + diff --git a/src/southbridge/sis/sis966/enable_rom.c b/src/southbridge/sis/sis966/enable_rom.c new file mode 100644 index 0000000000..63ef616563 --- /dev/null +++ b/src/southbridge/sis/sis966/enable_rom.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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); +} diff --git a/src/southbridge/sis/sis966/enable_usbdebug.c b/src/southbridge/sis/sis966/enable_usbdebug.c new file mode 100644 index 0000000000..a82e941b3a --- /dev/null +++ b/src/southbridge/sis/sis966/enable_usbdebug.c @@ -0,0 +1,63 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include +#include +#include +#include +#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); +} diff --git a/src/southbridge/sis/sis966/ide.c b/src/southbridge/sis/sis966/ide.c new file mode 100644 index 0000000000..c57be5ade7 --- /dev/null +++ b/src/southbridge/sis/sis966/ide.c @@ -0,0 +1,196 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/sis/sis966/lpc.c b/src/southbridge/sis/sis966/lpc.c new file mode 100644 index 0000000000..26f60dd3af --- /dev/null +++ b/src/southbridge/sis/sis966/lpc.c @@ -0,0 +1,283 @@ +/* + * 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 for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sis966.h" +#include + +#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 for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/sis/sis966/pcie.c b/src/southbridge/sis/sis966/pcie.c new file mode 100644 index 0000000000..dedbefdbf4 --- /dev/null +++ b/src/southbridge/sis/sis966/pcie.c @@ -0,0 +1,66 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#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, +}; + diff --git a/src/southbridge/sis/sis966/reset.c b/src/southbridge/sis/sis966/reset.c new file mode 100644 index 0000000000..afc592c26b --- /dev/null +++ b/src/southbridge/sis/sis966/reset.c @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu 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 +#include + +#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); +} + diff --git a/src/southbridge/sis/sis966/sata.c b/src/southbridge/sis/sis966/sata.c new file mode 100644 index 0000000000..57a2d8870f --- /dev/null +++ b/src/southbridge/sis/sis966/sata.c @@ -0,0 +1,197 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#include "sis966.h" +#include + +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, +}; diff --git a/src/southbridge/sis/sis966/sis966_aza.c b/src/southbridge/sis/sis966/sis966_aza.c deleted file mode 100644 index c7573a3f7a..0000000000 --- a/src/southbridge/sis/sis966/sis966_aza.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#include -#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\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, -}; - diff --git a/src/southbridge/sis/sis966/sis966_early_ctrl.c b/src/southbridge/sis/sis966/sis966_early_ctrl.c deleted file mode 100644 index 05b53365de..0000000000 --- a/src/southbridge/sis/sis966/sis966_early_ctrl.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 AMD - * Written by Yinghai Lu 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 - -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); - -} - diff --git a/src/southbridge/sis/sis966/sis966_early_setup_car.c b/src/southbridge/sis/sis966/sis966_early_setup_car.c deleted file mode 100644 index 9de33137a7..0000000000 --- a/src/southbridge/sis/sis966/sis966_early_setup_car.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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); -} - diff --git a/src/southbridge/sis/sis966/sis966_early_setup_ss.h b/src/southbridge/sis/sis966/sis966_early_setup_ss.h deleted file mode 100644 index c68e198639..0000000000 --- a/src/southbridge/sis/sis966/sis966_early_setup_ss.h +++ /dev/null @@ -1,222 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu 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, -}; - - diff --git a/src/southbridge/sis/sis966/sis966_early_smbus.c b/src/southbridge/sis/sis966/sis966_early_smbus.c deleted file mode 100644 index 1c81bf16fd..0000000000 --- a/src/southbridge/sis/sis966/sis966_early_smbus.c +++ /dev/null @@ -1,743 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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); -} - diff --git a/src/southbridge/sis/sis966/sis966_enable_rom.c b/src/southbridge/sis/sis966/sis966_enable_rom.c deleted file mode 100644 index 63ef616563..0000000000 --- a/src/southbridge/sis/sis966/sis966_enable_rom.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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); -} diff --git a/src/southbridge/sis/sis966/sis966_enable_usbdebug.c b/src/southbridge/sis/sis966/sis966_enable_usbdebug.c deleted file mode 100644 index a82e941b3a..0000000000 --- a/src/southbridge/sis/sis966/sis966_enable_usbdebug.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include -#include -#include -#include -#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); -} diff --git a/src/southbridge/sis/sis966/sis966_ide.c b/src/southbridge/sis/sis966/sis966_ide.c deleted file mode 100644 index c57be5ade7..0000000000 --- a/src/southbridge/sis/sis966/sis966_ide.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/sis/sis966/sis966_lpc.c b/src/southbridge/sis/sis966/sis966_lpc.c deleted file mode 100644 index 26f60dd3af..0000000000 --- a/src/southbridge/sis/sis966/sis966_lpc.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 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 for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sis966.h" -#include - -#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 for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/sis/sis966/sis966_pcie.c b/src/southbridge/sis/sis966/sis966_pcie.c deleted file mode 100644 index dedbefdbf4..0000000000 --- a/src/southbridge/sis/sis966/sis966_pcie.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#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, -}; - diff --git a/src/southbridge/sis/sis966/sis966_reset.c b/src/southbridge/sis/sis966/sis966_reset.c deleted file mode 100644 index afc592c26b..0000000000 --- a/src/southbridge/sis/sis966/sis966_reset.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu 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 -#include - -#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); -} - diff --git a/src/southbridge/sis/sis966/sis966_sata.c b/src/southbridge/sis/sis966/sis966_sata.c deleted file mode 100644 index 57a2d8870f..0000000000 --- a/src/southbridge/sis/sis966/sis966_sata.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#include "sis966.h" -#include - -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, -}; diff --git a/src/southbridge/sis/sis966/sis966_smbus.h b/src/southbridge/sis/sis966/sis966_smbus.h deleted file mode 100644 index 087ea47f23..0000000000 --- a/src/southbridge/sis/sis966/sis966_smbus.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 - -#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); - diff --git a/src/southbridge/sis/sis966/sis966_usb.c b/src/southbridge/sis/sis966/sis966_usb.c deleted file mode 100644 index d49f2aabb4..0000000000 --- a/src/southbridge/sis/sis966/sis966_usb.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/sis/sis966/sis966_usb2.c b/src/southbridge/sis/sis966/sis966_usb2.c deleted file mode 100644 index 6ede023837..0000000000 --- a/src/southbridge/sis/sis966/sis966_usb2.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Tyan Computer - * Written by Yinghai Lu for Tyan Computer. - * Copyright (C) 2006,2007 AMD - * Written by Yinghai Lu for AMD. - * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) - * Written by Morgan Tsai 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 -#include -#include -#include -#include -#include -#include "sis966.h" -#include - -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, -}; diff --git a/src/southbridge/sis/sis966/smbus.h b/src/southbridge/sis/sis966/smbus.h new file mode 100644 index 0000000000..087ea47f23 --- /dev/null +++ b/src/southbridge/sis/sis966/smbus.h @@ -0,0 +1,46 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 + +#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); + diff --git a/src/southbridge/sis/sis966/usb.c b/src/southbridge/sis/sis966/usb.c new file mode 100644 index 0000000000..d49f2aabb4 --- /dev/null +++ b/src/southbridge/sis/sis966/usb.c @@ -0,0 +1,120 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/sis/sis966/usb2.c b/src/southbridge/sis/sis966/usb2.c new file mode 100644 index 0000000000..6ede023837 --- /dev/null +++ b/src/southbridge/sis/sis966/usb2.c @@ -0,0 +1,168 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Tyan Computer + * Written by Yinghai Lu for Tyan Computer. + * Copyright (C) 2006,2007 AMD + * Written by Yinghai Lu for AMD. + * Copyright (C) 2007 Silicon Integrated Systems Corp. (SiS) + * Written by Morgan Tsai 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 +#include +#include +#include +#include +#include +#include "sis966.h" +#include + +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, +}; diff --git a/src/southbridge/ti/pci7420/Makefile.inc b/src/southbridge/ti/pci7420/Makefile.inc index 2a208f7c89..5081694808 100644 --- a/src/southbridge/ti/pci7420/Makefile.inc +++ b/src/southbridge/ti/pci7420/Makefile.inc @@ -17,6 +17,6 @@ ## 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 diff --git a/src/southbridge/ti/pci7420/cardbus.c b/src/southbridge/ti/pci7420/cardbus.c new file mode 100644 index 0000000000..2ab383b511 --- /dev/null +++ b/src/southbridge/ti/pci7420/cardbus.c @@ -0,0 +1,128 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/ti/pci7420/firewire.c b/src/southbridge/ti/pci7420/firewire.c new file mode 100644 index 0000000000..bd09c2fde7 --- /dev/null +++ b/src/southbridge/ti/pci7420/firewire.c @@ -0,0 +1,66 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/ti/pci7420/pci7420_cardbus.c b/src/southbridge/ti/pci7420/pci7420_cardbus.c deleted file mode 100644 index 2ab383b511..0000000000 --- a/src/southbridge/ti/pci7420/pci7420_cardbus.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/ti/pci7420/pci7420_firewire.c b/src/southbridge/ti/pci7420/pci7420_firewire.c deleted file mode 100644 index bd09c2fde7..0000000000 --- a/src/southbridge/ti/pci7420/pci7420_firewire.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/Makefile.inc b/src/southbridge/via/k8t890/Makefile.inc index b549d4af33..972ff70074 100644 --- a/src/southbridge/via/k8t890/Makefile.inc +++ b/src/southbridge/via/k8t890/Makefile.inc @@ -1,12 +1,12 @@ -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 diff --git a/src/southbridge/via/k8t890/bridge.c b/src/southbridge/via/k8t890/bridge.c new file mode 100644 index 0000000000..3e1e81730d --- /dev/null +++ b/src/southbridge/via/k8t890/bridge.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/k8t890/chrome.c b/src/southbridge/via/k8t890/chrome.c new file mode 100644 index 0000000000..5880026552 --- /dev/null +++ b/src/southbridge/via/k8t890/chrome.c @@ -0,0 +1,174 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 Luc Verhaegen + * + * This program is free software; 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 +#include +#include +#include +#include /* for memset */ +#include "k8t890.h" + +#if CONFIG_VGA +#include +#include +#include + +/* + * + */ +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, +}; diff --git a/src/southbridge/via/k8t890/ctrl.c b/src/southbridge/via/k8t890/ctrl.c new file mode 100644 index 0000000000..bb3cc02217 --- /dev/null +++ b/src/southbridge/via/k8t890/ctrl.c @@ -0,0 +1,192 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +/* 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, +}; diff --git a/src/southbridge/via/k8t890/dram.c b/src/southbridge/via/k8t890/dram.c new file mode 100644 index 0000000000..6c52fb1d02 --- /dev/null +++ b/src/southbridge/via/k8t890/dram.c @@ -0,0 +1,183 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/k8t890/early_car.c b/src/southbridge/via/k8t890/early_car.c new file mode 100644 index 0000000000..94162cb90c --- /dev/null +++ b/src/southbridge/via/k8t890/early_car.c @@ -0,0 +1,161 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 +#include +#include +#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)) diff --git a/src/southbridge/via/k8t890/error.c b/src/southbridge/via/k8t890/error.c new file mode 100644 index 0000000000..a9b10d56bc --- /dev/null +++ b/src/southbridge/via/k8t890/error.c @@ -0,0 +1,61 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/via/k8t890/host.c b/src/southbridge/via/k8t890/host.c new file mode 100644 index 0000000000..9a0118c778 --- /dev/null +++ b/src/southbridge/via/k8t890/host.c @@ -0,0 +1,89 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/k8t890/host_ctrl.c b/src/southbridge/via/k8t890/host_ctrl.c new file mode 100644 index 0000000000..43d01ee369 --- /dev/null +++ b/src/southbridge/via/k8t890/host_ctrl.c @@ -0,0 +1,151 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/k8t890/k8m890_chrome.c b/src/southbridge/via/k8t890/k8m890_chrome.c deleted file mode 100644 index 5880026552..0000000000 --- a/src/southbridge/via/k8t890/k8m890_chrome.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2009 Luc Verhaegen - * - * This program is free software; 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 -#include -#include -#include -#include /* for memset */ -#include "k8t890.h" - -#if CONFIG_VGA -#include -#include -#include - -/* - * - */ -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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_bridge.c b/src/southbridge/via/k8t890/k8t890_bridge.c deleted file mode 100644 index 3e1e81730d..0000000000 --- a/src/southbridge/via/k8t890/k8t890_bridge.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_ctrl.c b/src/southbridge/via/k8t890/k8t890_ctrl.c deleted file mode 100644 index bb3cc02217..0000000000 --- a/src/southbridge/via/k8t890/k8t890_ctrl.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -/* 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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_dram.c b/src/southbridge/via/k8t890/k8t890_dram.c deleted file mode 100644 index 6c52fb1d02..0000000000 --- a/src/southbridge/via/k8t890/k8t890_dram.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_early_car.c b/src/southbridge/via/k8t890/k8t890_early_car.c deleted file mode 100644 index 94162cb90c..0000000000 --- a/src/southbridge/via/k8t890/k8t890_early_car.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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 -#include -#include -#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)) diff --git a/src/southbridge/via/k8t890/k8t890_error.c b/src/southbridge/via/k8t890/k8t890_error.c deleted file mode 100644 index a9b10d56bc..0000000000 --- a/src/southbridge/via/k8t890/k8t890_error.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_host.c b/src/southbridge/via/k8t890/k8t890_host.c deleted file mode 100644 index 9a0118c778..0000000000 --- a/src/southbridge/via/k8t890/k8t890_host.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_host_ctrl.c b/src/southbridge/via/k8t890/k8t890_host_ctrl.c deleted file mode 100644 index 43d01ee369..0000000000 --- a/src/southbridge/via/k8t890/k8t890_host_ctrl.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_pcie.c b/src/southbridge/via/k8t890/k8t890_pcie.c deleted file mode 100644 index 2840bf3b2d..0000000000 --- a/src/southbridge/via/k8t890/k8t890_pcie.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/k8t890/k8t890_traf_ctrl.c b/src/southbridge/via/k8t890/k8t890_traf_ctrl.c deleted file mode 100644 index 55b3a13ac7..0000000000 --- a/src/southbridge/via/k8t890/k8t890_traf_ctrl.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#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, ""); - - /* 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, -}; diff --git a/src/southbridge/via/k8t890/pcie.c b/src/southbridge/via/k8t890/pcie.c new file mode 100644 index 0000000000..2840bf3b2d --- /dev/null +++ b/src/southbridge/via/k8t890/pcie.c @@ -0,0 +1,176 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/k8t890/traf_ctrl.c b/src/southbridge/via/k8t890/traf_ctrl.c new file mode 100644 index 0000000000..55b3a13ac7 --- /dev/null +++ b/src/southbridge/via/k8t890/traf_ctrl.c @@ -0,0 +1,157 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#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, ""); + + /* 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, +}; diff --git a/src/southbridge/via/vt8231/Makefile.inc b/src/southbridge/via/vt8231/Makefile.inc index 938d3cebe3..b9e7ef6f1d 100644 --- a/src/southbridge/via/vt8231/Makefile.inc +++ b/src/southbridge/via/vt8231/Makefile.inc @@ -18,8 +18,8 @@ ## 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 diff --git a/src/southbridge/via/vt8231/acpi.c b/src/southbridge/via/vt8231/acpi.c new file mode 100644 index 0000000000..647910aef6 --- /dev/null +++ b/src/southbridge/via/vt8231/acpi.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include + +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, +}; diff --git a/src/southbridge/via/vt8231/early_serial.c b/src/southbridge/via/vt8231/early_serial.c new file mode 100644 index 0000000000..af5a7729ee --- /dev/null +++ b/src/southbridge/via/vt8231/early_serial.c @@ -0,0 +1,74 @@ +/* + * 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); +} diff --git a/src/southbridge/via/vt8231/early_smbus.c b/src/southbridge/via/vt8231/early_smbus.c new file mode 100644 index 0000000000..7bf1267b75 --- /dev/null +++ b/src/southbridge/via/vt8231/early_smbus.c @@ -0,0 +1,295 @@ +#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 diff --git a/src/southbridge/via/vt8231/enable_rom.c b/src/southbridge/via/vt8231/enable_rom.c new file mode 100644 index 0000000000..bb43420610 --- /dev/null +++ b/src/southbridge/via/vt8231/enable_rom.c @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Uwe Hermann + * + * This program is free software; 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 +#include +#include + +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)); +} diff --git a/src/southbridge/via/vt8231/ide.c b/src/southbridge/via/vt8231/ide.c new file mode 100644 index 0000000000..46479c4af3 --- /dev/null +++ b/src/southbridge/via/vt8231/ide.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8231/lpc.c b/src/southbridge/via/vt8231/lpc.c new file mode 100644 index 0000000000..40854dbcf7 --- /dev/null +++ b/src/southbridge/via/vt8231/lpc.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8231/nic.c b/src/southbridge/via/vt8231/nic.c new file mode 100644 index 0000000000..5cd6cd8ca1 --- /dev/null +++ b/src/southbridge/via/vt8231/nic.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +/* + * 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, +}; diff --git a/src/southbridge/via/vt8231/usb.c b/src/southbridge/via/vt8231/usb.c new file mode 100644 index 0000000000..e12a8db85a --- /dev/null +++ b/src/southbridge/via/vt8231/usb.c @@ -0,0 +1,52 @@ + +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); + } +} diff --git a/src/southbridge/via/vt8231/vt8231_acpi.c b/src/southbridge/via/vt8231/vt8231_acpi.c deleted file mode 100644 index 647910aef6..0000000000 --- a/src/southbridge/via/vt8231/vt8231_acpi.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include -#include - -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, -}; diff --git a/src/southbridge/via/vt8231/vt8231_early_serial.c b/src/southbridge/via/vt8231/vt8231_early_serial.c deleted file mode 100644 index af5a7729ee..0000000000 --- a/src/southbridge/via/vt8231/vt8231_early_serial.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/via/vt8231/vt8231_early_smbus.c b/src/southbridge/via/vt8231/vt8231_early_smbus.c deleted file mode 100644 index 7bf1267b75..0000000000 --- a/src/southbridge/via/vt8231/vt8231_early_smbus.c +++ /dev/null @@ -1,295 +0,0 @@ -#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 diff --git a/src/southbridge/via/vt8231/vt8231_enable_rom.c b/src/southbridge/via/vt8231/vt8231_enable_rom.c deleted file mode 100644 index bb43420610..0000000000 --- a/src/southbridge/via/vt8231/vt8231_enable_rom.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Uwe Hermann - * - * This program is free software; 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 -#include -#include - -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)); -} diff --git a/src/southbridge/via/vt8231/vt8231_ide.c b/src/southbridge/via/vt8231/vt8231_ide.c deleted file mode 100644 index 46479c4af3..0000000000 --- a/src/southbridge/via/vt8231/vt8231_ide.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8231/vt8231_lpc.c b/src/southbridge/via/vt8231/vt8231_lpc.c deleted file mode 100644 index 40854dbcf7..0000000000 --- a/src/southbridge/via/vt8231/vt8231_lpc.c +++ /dev/null @@ -1,165 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8231/vt8231_nic.c b/src/southbridge/via/vt8231/vt8231_nic.c deleted file mode 100644 index 5cd6cd8ca1..0000000000 --- a/src/southbridge/via/vt8231/vt8231_nic.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include - -/* - * 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, -}; diff --git a/src/southbridge/via/vt8231/vt8231_usb.c b/src/southbridge/via/vt8231/vt8231_usb.c deleted file mode 100644 index e12a8db85a..0000000000 --- a/src/southbridge/via/vt8231/vt8231_usb.c +++ /dev/null @@ -1,52 +0,0 @@ - -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); - } -} diff --git a/src/southbridge/via/vt8235/Makefile.inc b/src/southbridge/via/vt8235/Makefile.inc index 06d533560b..02e22640bf 100644 --- a/src/southbridge/via/vt8235/Makefile.inc +++ b/src/southbridge/via/vt8235/Makefile.inc @@ -18,7 +18,7 @@ ## 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 diff --git a/src/southbridge/via/vt8235/early_serial.c b/src/southbridge/via/vt8235/early_serial.c new file mode 100644 index 0000000000..11f98fae39 --- /dev/null +++ b/src/southbridge/via/vt8235/early_serial.c @@ -0,0 +1,77 @@ +/* + * 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); +} diff --git a/src/southbridge/via/vt8235/early_smbus.c b/src/southbridge/via/vt8235/early_smbus.c new file mode 100644 index 0000000000..d091099fdb --- /dev/null +++ b/src/southbridge/via/vt8235/early_smbus.c @@ -0,0 +1,249 @@ +#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 + diff --git a/src/southbridge/via/vt8235/ide.c b/src/southbridge/via/vt8235/ide.c new file mode 100644 index 0000000000..961f860fed --- /dev/null +++ b/src/southbridge/via/vt8235/ide.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8235/lpc.c b/src/southbridge/via/vt8235/lpc.c new file mode 100644 index 0000000000..b355ad0d88 --- /dev/null +++ b/src/southbridge/via/vt8235/lpc.c @@ -0,0 +1,261 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8235/nic.c b/src/southbridge/via/vt8235/nic.c new file mode 100644 index 0000000000..71f169c055 --- /dev/null +++ b/src/southbridge/via/vt8235/nic.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +/* + * 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, +}; diff --git a/src/southbridge/via/vt8235/usb.c b/src/southbridge/via/vt8235/usb.c new file mode 100644 index 0000000000..c712136c72 --- /dev/null +++ b/src/southbridge/via/vt8235/usb.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include + +/* 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, +}; + diff --git a/src/southbridge/via/vt8235/vt8235_early_serial.c b/src/southbridge/via/vt8235/vt8235_early_serial.c deleted file mode 100644 index 11f98fae39..0000000000 --- a/src/southbridge/via/vt8235/vt8235_early_serial.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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); -} diff --git a/src/southbridge/via/vt8235/vt8235_early_smbus.c b/src/southbridge/via/vt8235/vt8235_early_smbus.c deleted file mode 100644 index d091099fdb..0000000000 --- a/src/southbridge/via/vt8235/vt8235_early_smbus.c +++ /dev/null @@ -1,249 +0,0 @@ -#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 - diff --git a/src/southbridge/via/vt8235/vt8235_ide.c b/src/southbridge/via/vt8235/vt8235_ide.c deleted file mode 100644 index 961f860fed..0000000000 --- a/src/southbridge/via/vt8235/vt8235_ide.c +++ /dev/null @@ -1,113 +0,0 @@ -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8235/vt8235_lpc.c b/src/southbridge/via/vt8235/vt8235_lpc.c deleted file mode 100644 index b355ad0d88..0000000000 --- a/src/southbridge/via/vt8235/vt8235_lpc.c +++ /dev/null @@ -1,261 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8235/vt8235_nic.c b/src/southbridge/via/vt8235/vt8235_nic.c deleted file mode 100644 index 71f169c055..0000000000 --- a/src/southbridge/via/vt8235/vt8235_nic.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include - -/* - * 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, -}; diff --git a/src/southbridge/via/vt8235/vt8235_usb.c b/src/southbridge/via/vt8235/vt8235_usb.c deleted file mode 100644 index c712136c72..0000000000 --- a/src/southbridge/via/vt8235/vt8235_usb.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include - -/* 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, -}; - diff --git a/src/southbridge/via/vt8237r/Makefile.inc b/src/southbridge/via/vt8237r/Makefile.inc index 04adb4b6d9..dd14a00fdc 100644 --- a/src/southbridge/via/vt8237r/Makefile.inc +++ b/src/southbridge/via/vt8237r/Makefile.inc @@ -18,10 +18,10 @@ ## 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 diff --git a/src/southbridge/via/vt8237r/ctrl.c b/src/southbridge/via/vt8237r/ctrl.c new file mode 100644 index 0000000000..f3cc30ed88 --- /dev/null +++ b/src/southbridge/via/vt8237r/ctrl.c @@ -0,0 +1,289 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8237r/early_smbus.c b/src/southbridge/via/vt8237r/early_smbus.c new file mode 100644 index 0000000000..a298e84676 --- /dev/null +++ b/src/southbridge/via/vt8237r/early_smbus.c @@ -0,0 +1,498 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Corey Osgood + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; 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 +#include +#include +#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 diff --git a/src/southbridge/via/vt8237r/fadt.c b/src/southbridge/via/vt8237r/fadt.c new file mode 100644 index 0000000000..6976f4d447 --- /dev/null +++ b/src/southbridge/via/vt8237r/fadt.c @@ -0,0 +1,173 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2004 Nick Barker + * Copyright (C) 2007, 2009 Rudolf Marek + * + * This program is free software; 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 +#include +#include +#include +#include +#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)); +} diff --git a/src/southbridge/via/vt8237r/ide.c b/src/southbridge/via/vt8237r/ide.c new file mode 100644 index 0000000000..209437b729 --- /dev/null +++ b/src/southbridge/via/vt8237r/ide.c @@ -0,0 +1,132 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8237r/lpc.c b/src/southbridge/via/vt8237r/lpc.c new file mode 100644 index 0000000000..72b85b37d5 --- /dev/null +++ b/src/southbridge/via/vt8237r/lpc.c @@ -0,0 +1,624 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007, 2008 Rudolf Marek + * Copyright (C) 2009 Jon Harrison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8237r/nic.c b/src/southbridge/via/vt8237r/nic.c new file mode 100644 index 0000000000..6771895916 --- /dev/null +++ b/src/southbridge/via/vt8237r/nic.c @@ -0,0 +1,62 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007, 2008 Rudolf Marek + * Copyright (C) 2009 Jon Harrison + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8237r/pirq.c b/src/southbridge/via/vt8237r/pirq.c new file mode 100644 index 0000000000..9915da4835 --- /dev/null +++ b/src/southbridge/via/vt8237r/pirq.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Nikolay Petukhov + * Copyright (C) 2010 Tobias Diedrich + * + * This program is free software; 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 +#include +#include +#include +#include + +#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 diff --git a/src/southbridge/via/vt8237r/sata.c b/src/southbridge/via/vt8237r/sata.c new file mode 100644 index 0000000000..777d605a6b --- /dev/null +++ b/src/southbridge/via/vt8237r/sata.c @@ -0,0 +1,132 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007, 2008 Rudolf Marek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#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, +}; diff --git a/src/southbridge/via/vt8237r/usb.c b/src/southbridge/via/vt8237r/usb.c new file mode 100644 index 0000000000..6e8d9e5dd0 --- /dev/null +++ b/src/southbridge/via/vt8237r/usb.c @@ -0,0 +1,165 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007, 2008 Rudolf Marek + * Copyright (C) 2009 Jon Harrison + * + * This program is free software; 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 +#include +#include +#include +#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, +}; diff --git a/src/southbridge/via/vt8237r/vt8237_ctrl.c b/src/southbridge/via/vt8237r/vt8237_ctrl.c deleted file mode 100644 index f3cc30ed88..0000000000 --- a/src/southbridge/via/vt8237r/vt8237_ctrl.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8237r/vt8237_fadt.c b/src/southbridge/via/vt8237r/vt8237_fadt.c deleted file mode 100644 index 6976f4d447..0000000000 --- a/src/southbridge/via/vt8237r/vt8237_fadt.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2004 Nick Barker - * Copyright (C) 2007, 2009 Rudolf Marek - * - * This program is free software; 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 -#include -#include -#include -#include -#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)); -} diff --git a/src/southbridge/via/vt8237r/vt8237r_early_smbus.c b/src/southbridge/via/vt8237r/vt8237r_early_smbus.c deleted file mode 100644 index a298e84676..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_early_smbus.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Corey Osgood - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; 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 -#include -#include -#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 diff --git a/src/southbridge/via/vt8237r/vt8237r_ide.c b/src/southbridge/via/vt8237r/vt8237r_ide.c deleted file mode 100644 index 209437b729..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_ide.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8237r/vt8237r_lpc.c b/src/southbridge/via/vt8237r/vt8237r_lpc.c deleted file mode 100644 index 72b85b37d5..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_lpc.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007, 2008 Rudolf Marek - * Copyright (C) 2009 Jon Harrison - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8237r/vt8237r_nic.c b/src/southbridge/via/vt8237r/vt8237r_nic.c deleted file mode 100644 index 6771895916..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_nic.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007, 2008 Rudolf Marek - * Copyright (C) 2009 Jon Harrison - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt8237r/vt8237r_pirq.c b/src/southbridge/via/vt8237r/vt8237r_pirq.c deleted file mode 100644 index 9915da4835..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_pirq.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Nikolay Petukhov - * Copyright (C) 2010 Tobias Diedrich - * - * This program is free software; 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 -#include -#include -#include -#include - -#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 diff --git a/src/southbridge/via/vt8237r/vt8237r_sata.c b/src/southbridge/via/vt8237r/vt8237r_sata.c deleted file mode 100644 index 777d605a6b..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_sata.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007, 2008 Rudolf Marek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#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, -}; diff --git a/src/southbridge/via/vt8237r/vt8237r_usb.c b/src/southbridge/via/vt8237r/vt8237r_usb.c deleted file mode 100644 index 6e8d9e5dd0..0000000000 --- a/src/southbridge/via/vt8237r/vt8237r_usb.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007, 2008 Rudolf Marek - * Copyright (C) 2009 Jon Harrison - * - * This program is free software; 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 -#include -#include -#include -#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, -}; diff --git a/src/southbridge/via/vt82c686/early_serial.c b/src/southbridge/via/vt82c686/early_serial.c new file mode 100644 index 0000000000..70c68aaaf5 --- /dev/null +++ b/src/southbridge/via/vt82c686/early_serial.c @@ -0,0 +1,92 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2006-2007 Uwe Hermann + * Copyright (C) 2007 Corey Osgood + * + * This program is free software; 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 +#include +#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. */ +} + diff --git a/src/southbridge/via/vt82c686/vt82c686_early_serial.c b/src/southbridge/via/vt82c686/vt82c686_early_serial.c deleted file mode 100644 index 70c68aaaf5..0000000000 --- a/src/southbridge/via/vt82c686/vt82c686_early_serial.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2006-2007 Uwe Hermann - * Copyright (C) 2007 Corey Osgood - * - * This program is free software; 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 -#include -#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. */ -} - -- cgit v1.2.3