summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2019-01-12 17:43:14 +0800
committerIru Cai <mytbk920423@gmail.com>2020-05-13 21:18:24 +0800
commitb7e37fd69e0adfec24d90b97d17dc1f42ab9aae8 (patch)
tree11ffc6a06a23d8f6e7a2c9876ac55cdbada547c7
parentf0045eb373c5376510d111c5e1091134c186884e (diff)
downloadcoreboot-b7e37fd69e0adfec24d90b97d17dc1f42ab9aae8.tar.xz
autoport: Add support for Haswell-LynxPoint platform
It can generate a working source code for Clevo W650SZ and Lenovo ThinkPad T440p. Patchset 11: some fix up for the current coreboot code and LP PCH - calculate backlight frequency according in the latest Haswell devicetree - there's some small difference in reading flash chip size for LP PCH - only output 8 USB ports for LP PCH Unresolved issues: - Should we use DxxIR registers from the machine running factory firmware? TODO: - Support Lynx Point LP - GPIO - GPE support - Detect and generate the lengths and locations of the USB2 ports (need to read IOBP registers) Change-Id: I4f6e8c97b5122101de2f36bba8ba9f8ddd5b813a Signed-off-by: Iru Cai <mytbk920423@gmail.com>
-rw-r--r--util/autoport/azalia.go5
-rw-r--r--util/autoport/haswell.go126
-rw-r--r--util/autoport/lynxpoint.go531
-rw-r--r--util/autoport/main.go6
4 files changed, 668 insertions, 0 deletions
diff --git a/util/autoport/azalia.go b/util/autoport/azalia.go
index c98b03cdea..928f958664 100644
--- a/util/autoport/azalia.go
+++ b/util/autoport/azalia.go
@@ -61,4 +61,9 @@ func init() {
RegisterPCI(0x8086, 0x1c20, azalia{})
/* C216/ivybridge */
RegisterPCI(0x8086, 0x1e20, azalia{})
+ /* Haswell */
+ RegisterPCI(0x8086, 0x0c0c, azalia{})
+ /* Lynx Point */
+ RegisterPCI(0x8086, 0x8c20, azalia{})
+ RegisterPCI(0x8086, 0x9c20, azalia{})
}
diff --git a/util/autoport/haswell.go b/util/autoport/haswell.go
new file mode 100644
index 0000000000..d1bf9d5e2e
--- /dev/null
+++ b/util/autoport/haswell.go
@@ -0,0 +1,126 @@
+package main
+
+type haswellmc struct {
+ variant string
+}
+
+func (i haswellmc) Scan(ctx Context, addr PCIDevData) {
+ inteltool := ctx.InfoSource.GetInteltool()
+
+ /* FIXME:XX Move this somewhere else. */
+ MainboardIncludes = append(MainboardIncludes, "drivers/intel/gma/int15.h")
+ MainboardEnable += (` /* FIXME: fix those values*/
+ install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_EDP,
+ GMA_INT15_PANEL_FIT_DEFAULT,
+ GMA_INT15_BOOT_DISPLAY_DEFAULT, 0);
+`)
+
+ var refclk uint32
+ if i.variant == "ULT" {
+ refclk = 24000000
+ } else {
+ refclk = 135000000
+ }
+
+ DevTree = DevTreeNode{
+ Chip: "northbridge/intel/haswell",
+ MissingParent: "northbridge",
+ Comment: "FIXME: check gfx",
+ Registers: map[string]string{
+ "gpu_dp_b_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 2) & 7),
+ "gpu_dp_c_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 10) & 7),
+ "gpu_dp_d_hotplug": FormatInt32((inteltool.IGD[0xc4030] >> 18) & 7),
+ "gpu_panel_port_select": FormatInt32((inteltool.IGD[0xc7208] >> 30) & 3),
+ "gpu_panel_power_up_delay": FormatInt32((inteltool.IGD[0xc7208] >> 16) & 0x1fff),
+ "gpu_panel_power_backlight_on_delay": FormatInt32(inteltool.IGD[0xc7208] & 0x1fff),
+ "gpu_panel_power_down_delay": FormatInt32((inteltool.IGD[0xc720c] >> 16) & 0x1fff),
+ "gpu_panel_power_backlight_off_delay": FormatInt32(inteltool.IGD[0xc720c] & 0x1fff),
+ "gpu_panel_power_cycle_delay": FormatInt32(inteltool.IGD[0xc7210] & 0xff),
+ "gpu_pch_backlight_pwm_hz": FormatInt32(refclk / 128 / (inteltool.IGD[0xc8254] >> 16)),
+ "gpu_ddi_e_connected": FormatBool(((inteltool.IGD[0x64000] >> 4) & 1) == 0),
+ /* FIXME:XX hardcoded. */
+ "gfx": "GMA_STATIC_DISPLAYS(0)",
+ },
+ Children: []DevTreeNode{
+ {
+ Chip: "cpu_cluster",
+ Dev: 0,
+ Children: []DevTreeNode{
+ {
+ Chip: "cpu/intel/haswell",
+ Children: []DevTreeNode{
+ {
+ Chip: "lapic",
+ Dev: 0,
+ },
+ {
+ Chip: "lapic",
+ Dev: 0xacac,
+ Disabled: true,
+ },
+ },
+ Registers: map[string]string{
+ /* FIXME:XX hardcoded. */
+ "c1_acpower": "1",
+ "c2_acpower": "3",
+ "c3_acpower": "5",
+ "c1_battery": "1",
+ "c2_battery": "3",
+ "c3_battery": "5",
+ },
+ },
+ },
+ },
+
+ {
+ Chip: "domain",
+ Dev: 0,
+ PCIController: true,
+ ChildPCIBus: 0,
+ PCISlots: []PCISlot{
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x0, Func: 0}, writeEmpty: true, additionalComment: "Host bridge"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1, Func: 0}, writeEmpty: true, additionalComment: "PCIe Bridge for discrete graphics"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x2, Func: 0}, writeEmpty: true, additionalComment: "Internal graphics"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x3, Func: 0}, writeEmpty: true, additionalComment: "Mini-HD audio"},
+ },
+ },
+ },
+ }
+
+ PutPCIDev(addr, "Host bridge")
+
+ /* FIXME:XX some configs are unsupported. */
+
+ KconfigBool["CPU_INTEL_HASWELL"] = true
+ KconfigBool["NORTHBRIDGE_INTEL_HASWELL"] = true
+ KconfigBool["INTEL_INT15"] = true
+ KconfigBool["HAVE_ACPI_TABLES"] = true
+ KconfigBool["HAVE_ACPI_RESUME"] = true
+
+ KconfigInt["MAX_CPUS"] = 8
+
+ DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+ File: "cpu/intel/common/acpi/cpu.asl",
+ })
+
+ DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+ File: "northbridge/intel/haswell/acpi/haswell.asl",
+ }, DSDTInclude{
+ File: "drivers/intel/gma/acpi/default_brightness_levels.asl",
+ })
+}
+
+func init() {
+ RegisterPCI(0x8086, 0x0c00, haswellmc{variant: "Desktop"})
+ RegisterPCI(0x8086, 0x0c04, haswellmc{variant: "Mobile"})
+ RegisterPCI(0x8086, 0x0a04, haswellmc{variant: "ULT"})
+ RegisterPCI(0x8086, 0x0c08, haswellmc{variant: "Server"})
+ for _, id := range []uint16{
+ 0x0402, 0x0412, 0x0422,
+ 0x0406, 0x0416, 0x0426,
+ 0x0d16, 0x0d26, 0x0d36,
+ 0x0a06, 0x0a16, 0x0a26,
+ } {
+ RegisterPCI(0x8086, id, GenericVGA{GenericPCI{Comment: "VGA controller"}})
+ }
+}
diff --git a/util/autoport/lynxpoint.go b/util/autoport/lynxpoint.go
new file mode 100644
index 0000000000..83bcab66da
--- /dev/null
+++ b/util/autoport/lynxpoint.go
@@ -0,0 +1,531 @@
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+type lynxpoint struct {
+ variant string
+ node *DevTreeNode
+}
+
+func (b lynxpoint) writeGPIOSet(ctx Context, sb *os.File,
+ val uint32, set uint, partno int, constraint uint32) {
+
+ max := uint(32)
+ if set == 3 {
+ max = 12
+ }
+
+ bits := [6][2]string{
+ {"GPIO_MODE_NATIVE", "GPIO_MODE_GPIO"},
+ {"GPIO_DIR_OUTPUT", "GPIO_DIR_INPUT"},
+ {"GPIO_LEVEL_LOW", "GPIO_LEVEL_HIGH"},
+ {"GPIO_RESET_PWROK", "GPIO_RESET_RSMRST"},
+ {"GPIO_NO_INVERT", "GPIO_INVERT"},
+ {"GPIO_NO_BLINK", "GPIO_BLINK"},
+ }
+
+ for i := uint(0); i < max; i++ {
+ if ((constraint>>i)&1 == 1) {
+ fmt.Fprintf(sb, " .gpio%d = %s,\n",
+ (set-1)*32+i,
+ bits[partno][(val>>i)&1])
+ }
+ }
+}
+
+func (b lynxpoint) GPIO(ctx Context, inteltool InteltoolData) {
+ var constraint uint32
+ gpio := Create(ctx, "gpio.c")
+ defer gpio.Close()
+
+ AddROMStageFile("gpio.c", "")
+
+ Add_gpl(gpio)
+ gpio.WriteString("#include <southbridge/intel/common/gpio.h>\n\n")
+
+ /* TODO: different in LP PCH */
+ addresses := [3][6]int{
+ {0x00, 0x04, 0x0c, 0x60, 0x2c, 0x18},
+ {0x30, 0x34, 0x38, 0x64, -1, -1},
+ {0x40, 0x44, 0x48, 0x68, -1, -1},
+ }
+
+ for set := 1; set <= 3; set++ {
+ for partno, part := range []string{"mode", "direction", "level", "reset", "invert", "blink"} {
+ addr := addresses[set-1][partno]
+ if addr < 0 {
+ continue
+ }
+ fmt.Fprintf(gpio, "static const struct pch_gpio_set%d pch_gpio_set%d_%s = {\n",
+ set, set, part)
+
+ constraint = 0xffffffff
+ switch part {
+ case "direction":
+ /* Ignored on native mode */
+ constraint = inteltool.GPIO[uint16(addresses[set-1][0])]
+ case "level":
+ /* Level doesn't matter for input */
+ constraint = inteltool.GPIO[uint16(addresses[set-1][0])]
+ constraint &^= inteltool.GPIO[uint16(addresses[set-1][1])]
+ case "reset":
+ /* Only show reset */
+ constraint = inteltool.GPIO[uint16(addresses[set-1][3])]
+ case "invert":
+ /* Only on input and only show inverted GPIO */
+ constraint = inteltool.GPIO[uint16(addresses[set-1][0])]
+ constraint &= inteltool.GPIO[uint16(addresses[set-1][1])]
+ constraint &= inteltool.GPIO[uint16(addresses[set-1][4])]
+ case "blink":
+ /* Only on output and only show blinking GPIO */
+ constraint = inteltool.GPIO[uint16(addresses[set-1][0])]
+ constraint &^= inteltool.GPIO[uint16(addresses[set-1][1])]
+ constraint &= inteltool.GPIO[uint16(addresses[set-1][5])]
+ }
+ b.writeGPIOSet(ctx, gpio, inteltool.GPIO[uint16(addr)], uint(set), partno, constraint)
+ gpio.WriteString("};\n\n")
+ }
+ }
+
+ gpio.WriteString(`const struct pch_gpio_map mainboard_gpio_map = {
+ .set1 = {
+ .mode = &pch_gpio_set1_mode,
+ .direction = &pch_gpio_set1_direction,
+ .level = &pch_gpio_set1_level,
+ .blink = &pch_gpio_set1_blink,
+ .invert = &pch_gpio_set1_invert,
+ .reset = &pch_gpio_set1_reset,
+ },
+ .set2 = {
+ .mode = &pch_gpio_set2_mode,
+ .direction = &pch_gpio_set2_direction,
+ .level = &pch_gpio_set2_level,
+ .reset = &pch_gpio_set2_reset,
+ },
+ .set3 = {
+ .mode = &pch_gpio_set3_mode,
+ .direction = &pch_gpio_set3_direction,
+ .level = &pch_gpio_set3_level,
+ .reset = &pch_gpio_set3_reset,
+ },
+};
+`)
+}
+
+func (b lynxpoint) IsPCIeHotplug(ctx Context, port int) bool {
+ portDev, ok := PCIMap[PCIAddr{Bus: 0, Dev: 0x1c, Func: port}]
+ if !ok {
+ return false
+ }
+ return (portDev.ConfigDump[0xdb] & (1 << 6)) != 0
+}
+
+func lpPchGetFlashSize(ctx Context) {
+ inteltool := ctx.InfoSource.GetInteltool()
+ /* In LP PCH, Boot BIOS Straps field in GCS has only one bit. */
+ switch (inteltool.RCBA[0x3410] >> 10) & 1 {
+ case 0:
+ ROMProtocol = "SPI"
+ highflkb := uint32(0)
+ for reg := uint16(0); reg < 5; reg++ {
+ fl := (inteltool.RCBA[0x3854+4*reg] >> 16) & 0x1fff
+ flkb := (fl + 1) << 2
+ if flkb > highflkb {
+ highflkb = flkb
+ }
+ }
+ ROMSizeKB = int(highflkb)
+ /* Shared with ME. Flashrom is unable to handle it. */
+ FlashROMSupport = "n"
+ }
+}
+
+func (b lynxpoint) GetGPIOHeader() string {
+ return "southbridge/intel/lynxpoint/pch.h"
+}
+
+func (b lynxpoint) EnableGPE(in int) {
+ b.node.Registers[fmt.Sprintf("gpi%d_routing", in)] = "2"
+}
+
+func (b lynxpoint) EncodeGPE(in int) int {
+ return in + 0x10
+}
+
+func (b lynxpoint) DecodeGPE(in int) int {
+ return in - 0x10
+}
+
+func (b lynxpoint) NeedRouteGPIOManually() {
+ b.node.Comment += ", FIXME: set gpiX_routing for EC support"
+}
+
+func (b lynxpoint) Scan(ctx Context, addr PCIDevData) {
+
+ SouthBridge = &b
+
+ inteltool := ctx.InfoSource.GetInteltool()
+ b.GPIO(ctx, inteltool)
+
+ KconfigBool["SOUTHBRIDGE_INTEL_LYNXPOINT"] = true
+ if b.variant == "Lynx Point LP" {
+ KconfigBool["INTEL_LYNXPOINT_LP"] = true
+ }
+ KconfigBool["SERIRQ_CONTINUOUS_MODE"] = true
+ KconfigInt["USBDEBUG_HCD_INDEX"] = 2
+ KconfigComment["USBDEBUG_HCD_INDEX"] = "FIXME: check this"
+
+ if b.variant == "Lynx Point LP" {
+ lpPchGetFlashSize(ctx)
+ } else {
+ ich9GetFlashSize(ctx)
+ }
+
+ DSDTDefines = append(DSDTDefines,
+ DSDTDefine{
+ Key: "BRIGHTNESS_UP",
+ Value: "\\_SB.PCI0.GFX0.INCB",
+ },
+ DSDTDefine{
+ Key: "BRIGHTNESS_DOWN",
+ Value: "\\_SB.PCI0.GFX0.DECB",
+ },
+ DSDTDefine{
+ Key: "ACPI_VIDEO_DEVICE",
+ Value: "\\_SB.PCI0.GFX0",
+ })
+
+ cur := DevTreeNode{
+ Chip: "southbridge/intel/lynxpoint",
+ Comment: "Intel Series 8 Lynx Point PCH",
+
+ Registers: map[string]string{
+ "pirqa_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x60]),
+ "pirqb_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x61]),
+ "pirqc_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x62]),
+ "pirqd_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x63]),
+ "pirqe_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x68]),
+ "pirqf_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x69]),
+ "pirqg_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x6a]),
+ "pirqh_routing": FormatHex8(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x6b]),
+ "gen1_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x84:0x88]),
+ "gen2_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x88:0x8c]),
+ "gen3_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x8c:0x90]),
+ "gen4_dec": FormatHexLE32(PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 0}].ConfigDump[0x90:0x94]),
+ "sata_ahci": "1",
+ "sata_port_map": fmt.Sprintf("0x%x", PCIMap[PCIAddr{Bus: 0, Dev: 0x1f, Func: 2}].ConfigDump[0x92]&0x3f),
+ },
+ PCISlots: []PCISlot{
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x14, Func: 0}, writeEmpty: false, additionalComment: "xHCI Controller"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 0}, writeEmpty: true, additionalComment: "Management Engine Interface 1"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 1}, writeEmpty: true, additionalComment: "Management Engine Interface 2"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 2}, writeEmpty: true, additionalComment: "Management Engine IDE-R"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x16, Func: 3}, writeEmpty: true, additionalComment: "Management Engine KT"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x19, Func: 0}, writeEmpty: true, additionalComment: "Intel Gigabit Ethernet"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1a, Func: 0}, writeEmpty: true, additionalComment: "USB2 EHCI #2"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1b, Func: 0}, writeEmpty: true, additionalComment: "High Definition Audio"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 0}, writeEmpty: true, additionalComment: "PCIe Port #1"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 1}, writeEmpty: true, additionalComment: "PCIe Port #2"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 2}, writeEmpty: true, additionalComment: "PCIe Port #3"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 3}, writeEmpty: true, additionalComment: "PCIe Port #4"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 4}, writeEmpty: true, additionalComment: "PCIe Port #5"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 5}, writeEmpty: true, additionalComment: "PCIe Port #6"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 6}, writeEmpty: true, additionalComment: "PCIe Port #7"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1c, Func: 7}, writeEmpty: true, additionalComment: "PCIe Port #8"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1d, Func: 0}, writeEmpty: true, additionalComment: "USB2 EHCI #1"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 0}, writeEmpty: true, additionalComment: "LPC bridge"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 2}, writeEmpty: true, additionalComment: "SATA Controller 1"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 3}, writeEmpty: true, additionalComment: "SMBus"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 5}, writeEmpty: true, additionalComment: "SATA Controller 2"},
+ PCISlot{PCIAddr: PCIAddr{Dev: 0x1f, Func: 6}, writeEmpty: true, additionalComment: "Thermal"},
+ },
+ }
+
+ b.node = &cur
+
+ PutPCIChip(addr, cur)
+ PutPCIDevParent(addr, "PCI-LPC bridge", "lpc")
+
+ DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+ File: "southbridge/intel/common/acpi/platform.asl",
+ })
+ DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+ File: "southbridge/intel/lynxpoint/acpi/globalnvs.asl",
+ Comment: "global NVS and variables",
+ })
+ DSDTIncludes = append(DSDTIncludes, DSDTInclude{
+ File: "southbridge/intel/common/acpi/sleepstates.asl",
+ })
+ DSDTPCI0Includes = append(DSDTPCI0Includes, DSDTInclude{
+ File: "southbridge/intel/lynxpoint/acpi/pch.asl",
+ })
+
+ sb := Create(ctx, "romstage.c")
+ defer sb.Close()
+ Add_gpl(sb)
+ sb.WriteString(`#include <stdint.h>
+#include <arch/romstage.h>
+#include <cpu/intel/haswell/haswell.h>
+#include <northbridge/intel/haswell/haswell.h>
+#include <northbridge/intel/haswell/pei_data.h>
+#include <southbridge/intel/common/gpio.h>
+#include <southbridge/intel/lynxpoint/pch.h>
+
+static const struct rcba_config_instruction rcba_config[] = {
+`)
+ RestoreDIRRoute(sb, "D31IR", uint16(inteltool.RCBA[0x3140]))
+ RestoreDIRRoute(sb, "D29IR", uint16(inteltool.RCBA[0x3144]))
+ RestoreDIRRoute(sb, "D28IR", uint16(inteltool.RCBA[0x3146]))
+ RestoreDIRRoute(sb, "D27IR", uint16(inteltool.RCBA[0x3148]))
+ RestoreDIRRoute(sb, "D26IR", uint16(inteltool.RCBA[0x314c]))
+ RestoreDIRRoute(sb, "D25IR", uint16(inteltool.RCBA[0x3150]))
+ RestoreDIRRoute(sb, "D22IR", uint16(inteltool.RCBA[0x315c]))
+ RestoreDIRRoute(sb, "D20IR", uint16(inteltool.RCBA[0x3160]))
+
+ sb.WriteString(`
+ RCBA_RMW_REG_32(FD, ~0, PCH_DISABLE_ALWAYS),
+
+ RCBA_END_CONFIG,
+};`)
+
+ sb.WriteString(`
+
+void mainboard_config_superio(void)
+{
+}
+
+void mainboard_romstage_entry(void)
+{
+ struct pei_data pei_data = {
+ .pei_version = PEI_VERSION,
+ .mchbar = (uintptr_t)DEFAULT_MCHBAR,
+ .dmibar = (uintptr_t)DEFAULT_DMIBAR,
+ .epbar = DEFAULT_EPBAR,
+ .pciexbar = CONFIG_MMCONF_BASE_ADDRESS,
+ .smbusbar = SMBUS_IO_BASE,
+ .wdbbar = 0x4000000,
+ .wdbsize = 0x1000,
+ .hpet_address = HPET_ADDR,
+ .rcba = (uintptr_t)DEFAULT_RCBA,
+ .pmbase = DEFAULT_PMBASE,
+ .gpiobase = DEFAULT_GPIOBASE,
+ .temp_mmio_base = 0xfed08000,
+ .system_type = 1, /* desktop/server, FIXME: check this */
+ .tseg_size = CONFIG_SMM_TSEG_SIZE,
+ /* note that SPD addresses are left-shifted by 1. */
+ .spd_addresses = { 0xa0, 0xa2, 0xa4, 0xa6 }, /* FIXME: check this */
+ .ec_present = 0,
+ .gbe_enable = 0, /* FIXME: check this */
+ .dimm_channel0_disabled = 0, /* FIXME: leave channel 0 enabled */
+ .dimm_channel1_disabled = 0, /* FIXME: leave channel 1 enabled */
+ .max_ddr3_freq = 1600,
+ .usb2_ports = {
+ /* Length, Enable, OCn#, Location */
+`)
+
+ pdo1 := PCIMap[PCIAddr{Bus: 0, Dev: 0x1d, Func: 0}].ConfigDump[0x64]
+ ocmap1 := PCIMap[PCIAddr{Bus: 0, Dev: 0x1d, Func: 0}].ConfigDump[0x74:0x78]
+
+ var pdo2 uint8
+ var ocmap2 []uint8
+ var nPorts int
+ if b.variant != "Lynx Point LP" {
+ pdo2 = PCIMap[PCIAddr{Bus: 0, Dev: 0x1a, Func: 0}].ConfigDump[0x64]
+ ocmap2 = PCIMap[PCIAddr{Bus: 0, Dev: 0x1a, Func: 0}].ConfigDump[0x74:0x78]
+ nPorts = 14
+ } else {
+ nPorts = 8
+ }
+
+ xusb2pr := GetLE16(PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xd0:0xd4])
+
+ for port := 0; port < nPorts; port++ {
+ var port_oc int = -1
+ var port_pos string
+ var port_disable uint8
+
+ if port < 8 {
+ port_disable = ((pdo1 >> port) & (uint8(xusb2pr >> port) ^ 1)) & 1
+ for oc := 0; oc < 4; oc++ {
+ if ((ocmap1[oc] & (1 << port)) != 0) {
+ port_oc = oc
+ break
+ }
+ }
+ } else {
+ port_disable = ((pdo2 >> (port - 8)) & (uint8(xusb2pr >> port) ^ 1)) & 1
+ for oc := 0; oc < 4; oc++ {
+ if ((ocmap2[oc] & (1 << (port - 8))) != 0) {
+ port_oc = oc + 4
+ break
+ }
+ }
+ }
+ if port_disable == 1 {
+ port_pos = "USB_PORT_SKIP"
+ } else {
+ port_pos = "USB_PORT_BACK_PANEL"
+ }
+ if port_oc == -1 {
+ fmt.Fprintf(sb, " { 0x0040, %d, USB_OC_PIN_SKIP, %s },\n",
+ (port_disable ^ 1), port_pos)
+ } else {
+ fmt.Fprintf(sb, " { 0x0040, %d, %d, %s },\n",
+ (port_disable ^ 1), port_oc, port_pos)
+ }
+ }
+
+ sb.WriteString(` },
+ .usb3_ports = {
+`)
+
+ xpdo := PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xe8]
+ u3ocm := PCIMap[PCIAddr{Bus: 0, Dev: 0x14, Func: 0}].ConfigDump[0xc8:0xd0]
+
+ for port := uint(0); port < 6; port++ {
+ var port_oc int = -1
+ port_disable := (xpdo >> port) & 1
+ for oc := 0; oc < 8; oc++ {
+ if (u3ocm[oc] & (1 << port)) != 0 {
+ port_oc = oc
+ break
+ }
+ }
+ if port_oc == -1 {
+ fmt.Fprintf(sb, " { %d, USB_OC_PIN_SKIP },\n",
+ (port_disable ^ 1))
+ } else {
+ fmt.Fprintf(sb, " { %d, %d },\n",
+ (port_disable ^ 1), port_oc)
+ }
+ }
+
+ sb.WriteString(` },
+ };
+
+ struct romstage_params romstage_params = {
+ .pei_data = &pei_data,
+ .gpio_map = &mainboard_gpio_map,
+ .rcba_config = rcba_config,
+ };
+
+ romstage_common(&romstage_params);
+}`)
+
+ gnvs := Create(ctx, "acpi_tables.c")
+ defer gnvs.Close()
+
+ Add_gpl(gnvs)
+ gnvs.WriteString(`#include <southbridge/intel/lynxpoint/nvs.h>
+
+/* FIXME: check this function. */
+void acpi_create_gnvs(global_nvs_t *gnvs)
+{
+ /* Disable USB ports in S3 by default */
+ gnvs->s3u0 = 0;
+ gnvs->s3u1 = 0;
+
+ /* Disable USB ports in S5 by default */
+ gnvs->s5u0 = 0;
+ gnvs->s5u1 = 0;
+
+ // the lid is open by default.
+ gnvs->lids = 1;
+
+ gnvs->tcrt = 100;
+ gnvs->tpsv = 90;
+}
+`)
+
+}
+
+func init() {
+ for _, id := range []uint16 {
+ 0x8c41, 0x8c49, 0x8c4b, 0x8c4f,
+ } {
+ RegisterPCI(0x8086, uint16(id), lynxpoint{variant: "Lynx Point Mobile"})
+ }
+
+ for _, id := range []uint16 {
+ 0x8c42, 0x8c44, 0x8c46, 0x8c4a,
+ 0x8c4c, 0x8c4e, 0x8c50, 0x8c5c,
+ } {
+ RegisterPCI(0x8086, uint16(id), lynxpoint{variant: "Lynx Point Desktop"})
+ }
+
+ for _, id := range []uint16 {
+ 0x8c52, 0x8c54, 0x8c56,
+ } {
+ RegisterPCI(0x8086, uint16(id), lynxpoint{variant: "Lynx Point Server"})
+ }
+
+ for _, id := range []uint16 {
+ 0x9c41, 0x9c43, 0x9c45,
+ } {
+ RegisterPCI(0x8086, uint16(id), lynxpoint{variant: "Lynx Point LP"})
+ }
+
+ /* PCIe bridge */
+ for _, id := range []uint16{
+ 0x8c10, 0x8c12, 0x8c14, 0x8c16, 0x8c18, 0x8c1a, 0x8c1c, 0x8c1e,
+ 0x9c10, 0x9c12, 0x9c14, 0x9c16, 0x9c18, 0x9c1a,
+ } {
+ RegisterPCI(0x8086, id, GenericPCI{})
+ }
+
+ /* SMBus controller */
+ RegisterPCI(0x8086, 0x8c22, GenericPCI{MissingParent: "smbus"})
+ RegisterPCI(0x8086, 0x9c22, GenericPCI{MissingParent: "smbus"})
+
+ /* SATA */
+ for _, id := range []uint16{
+ 0x8c00, 0x8c02, 0x8c04, 0x8c06, 0x8c08, 0x8c0e,
+ 0x8c01, 0x8c03, 0x8c05, 0x8c07, 0x8c09, 0x8c0f,
+ 0x9c03, 0x9c05, 0x9c07, 0x9c0f,
+ } {
+ RegisterPCI(0x8086, id, GenericPCI{})
+ }
+
+ /* EHCI */
+ for _, id := range []uint16{
+ 0x9c26, 0x8c26, 0x8c2d,
+ } {
+ RegisterPCI(0x8086, id, GenericPCI{})
+ }
+
+ /* XHCI */
+ RegisterPCI(0x8086, 0x8c31, GenericPCI{})
+ RegisterPCI(0x8086, 0x9c31, GenericPCI{})
+
+ /* ME and children */
+ for _, id := range []uint16{
+ 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d,
+ 0x9c3a, 0x9c3b, 0x9c3c, 0x9c3d,
+ } {
+ RegisterPCI(0x8086, id, GenericPCI{})
+ }
+
+ /* Ethernet */
+ RegisterPCI(0x8086, 0x8c33, GenericPCI{})
+
+ /* Thermal */
+ RegisterPCI(0x8086, 0x8c24, GenericPCI{})
+ RegisterPCI(0x8086, 0x9c24, GenericPCI{})
+
+ /* LAN Controller on LP PCH (if EEPROM has 0x0000/0xffff in DID) */
+ RegisterPCI(0x8086, 0x155a, GenericPCI{})
+
+ /* SDIO */
+ RegisterPCI(0x8086, 0x9c35, GenericPCI{})
+
+ /* Smart Sound Technology Controller */
+ RegisterPCI(0x8086, 0x9c36, GenericPCI{})
+
+ /* Serial I/O */
+ for id := uint16(0x9c60); id <= 0x9c66; id++ {
+ RegisterPCI(0x8086, id, GenericPCI{})
+ }
+}
diff --git a/util/autoport/main.go b/util/autoport/main.go
index b2334e2b62..2de5349a0c 100644
--- a/util/autoport/main.go
+++ b/util/autoport/main.go
@@ -224,6 +224,12 @@ func RestorePCI16Simple(f *os.File, pcidev PCIDevData, addr uint16) {
pcidev.ConfigDump[addr])
}
+func RestoreDIRRoute(f *os.File, regname string, val uint16) {
+ fmt.Fprintf(f, " RCBA_SET_REG_16(%s, DIR_ROUTE(PIRQ%c, PIRQ%c, PIRQ%c, PIRQ%c)),\n",
+ regname, 'A' + (val & 7), 'A' + ((val >> 4) & 7),
+ 'A' + ((val >> 8) & 7), 'A' + ((val >> 12) & 7))
+}
+
func RestorePCI32Simple(f *os.File, pcidev PCIDevData, addr uint16) {
fmt.Fprintf(f, " pci_write_config32(PCI_DEV(%d, 0x%02x, %d), 0x%02x, 0x%02x%02x%02x%02x);\n",
pcidev.Bus, pcidev.Dev, pcidev.Func, addr,