Jens Rottmann (JRottmann(a)LiPPERTembedded.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2581
-gerrit
commit d234471d1e702ed816f33c7031aa6ddeabb6f728
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Fri Mar 1 19:41:41 2013 +0100
AMD Inagua: add GEC firmware, document Broadcom BCM57xx Selfboot Patch format
The Broadcom BCM5785 GbE MAC integrated in the AMD Hudson-E1 requires a
secret sauce firmware blob to work. As Broadcom wasn't willing to send us
any documentation (or a firmware adapted to our Micrel PHY) I had to figure
out everything by myself in many weeks of hard detective work.
In the end we had to settle for a different solution, the modified firmware
I devised for the Micrel KSZ9021 PHY on our early FrontRunner-AF prototypes
is no longer needed for the production version. However the information
contained here might be very useful for others who'd like to use a
competing PHYs instead of Broadcom's 50610, so it should not get lost. And
of course the unmodified, but now in large parts documented Selfboot Patch
is needed to get Ethernet on AMD Inagua.
The fun thing is: as Broadcom refused to do any business with us at all,
or send us any documentation, we never had to sign an NDA with them. This
leaves me free to publish everything I have found out. :-)
Change-Id: Ifa628751d14143f277b27cfd34b1d2771ca1302f
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
---
src/mainboard/amd/inagua/Makefile.inc | 2 +-
src/mainboard/amd/inagua/broadcom.c | 360 ++++++++++++++++++++++++++++++++++
src/mainboard/amd/inagua/mainboard.c | 4 +
3 files changed, 365 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/amd/inagua/Makefile.inc b/src/mainboard/amd/inagua/Makefile.inc
index 17443bc..b84a03a 100644
--- a/src/mainboard/amd/inagua/Makefile.inc
+++ b/src/mainboard/amd/inagua/Makefile.inc
@@ -35,4 +35,4 @@ ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
ramstage-y += reset.c
-
+ramstage-y += broadcom.c
diff --git a/src/mainboard/amd/inagua/broadcom.c b/src/mainboard/amd/inagua/broadcom.c
new file mode 100644
index 0000000..357fdbc
--- /dev/null
+++ b/src/mainboard/amd/inagua/broadcom.c
@@ -0,0 +1,360 @@
+/*
+ * Initialize Broadcom 5785 GbE MAC embedded in AMD A55E (Hudson-E1) Southbridge
+ * by uploading a Selfboot Patch to the A55E's shadow ROM area. The patch
+ * itself supports the Broadcom 50610(M) PHY on the AMD Inagua. It is
+ * equivalent to Broadcom's SelfBoot patch V1.11 (sb5785m1.11).
+ * A modified variant, selected by CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF supports
+ * the Micrel KSZ9021 PHY that was used on LiPPERT FrontRunner-AF (CFR-AF)
+ * revision 0v0, the first prototype. The board is history and this code now
+ * serves only to document the proprietary Selfboot Patch format and how to
+ * adapt it to a PHY unsupported by Broadcom.
+ *
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 LiPPERT ADLINK Technology GmbH
+ * (Written by Jens Rottmann <JRottmann(a)LiPPERTembedded.de>)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <arch/byteorder.h>
+#include <console/console.h>
+#include <device/device.h> //Coreboot device access
+#include <device/pci.h>
+#include <delay.h>
+
+#define be16(x) cpu_to_be16(x) //a little easier to type
+#define be(x) cpu_to_be32(x) //this is used a lot!
+
+/* C forces us to specify these before defining struct selfboot_patch :-( */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+#define INIT1_LENGTH 9
+#define INIT2_LENGTH 10
+#define INIT3_LENGTH 3
+#define INIT4_LENGTH 7 //this one may be 0
+#define PWRDN_LENGTH 5
+#else
+#define INIT1_LENGTH 13
+#define INIT2_LENGTH 6
+#define INIT3_LENGTH 3
+#define INIT4_LENGTH 11 //this one may be 0
+#define PWRDN_LENGTH 4
+#endif
+
+
+/* The AMD A55E (Hudson-E1) Southbridge contains an integrated Gigabit Ethernet
+ * MAC, however AMD's documentation merely defines the related balls (without
+ * fully describing their function) and states that only Broadcom 50610(M) PHYs
+ * will be supported, that's all. The Hudson register reference skips all MAC
+ * registers entirely, even AMD support doesn't seem to know more about it.
+ *
+ * As Broadcom refused to sell us any 50610 chips or provide any docs (or indeed
+ * even a price list) below $100K expected sales we had to figure out everything
+ * by ourselves. *Everything* below is the result of months of detective work,
+ * documented here lest it get lost:
+ *
+ * The AMD A55E's GbE MAC is a Broadcom 5785, which AMD obviously licensed as IP
+ * core. It uses a standard RGMII/MII interface and the Broadcom drivers will
+ * recognize it by its unchanged PCI ID 14E4:1699, however there are some
+ * specialties.
+ *
+ * The 5785 MAC can detect the link with 4 additional inputs, "phy_status[3:0]",
+ * 'snooping' on the PHY's LED outputs. Interpretation of the LEDs' patterns is
+ * programmed with register 0x5A4 of the MAC. AMD renamed them to "GBE_STAT" and
+ * won't say anything about their purpose. Appearently hardware designers are
+ * expected to blindly copy the Inagua reference schematic: GBE_STAT2:
+ * 0=activity; GBE_STAT[1:0]: 11=no link, 10=10Mbit, 01=100Mbit, 00=1Gbit.
+ *
+ * For package processing the 5785 also features a MIPS-based RISC CPU, booting
+ * from an internal ROM. The firmware loads config data and supplements (e.g. to
+ * support specific PHYs), named "Selfboot Patches", via the "NVRAM Interface",
+ * usually from an external EEPROM. The A55E doesn't have any balls for an ext.
+ * EEPROM, instead AMD added a small internal RAM. The BIOS is expected to copy
+ * the correct contents into this RAM (which only supports byte access!) upon
+ * each powerup. The A55E can trigger an SMI upon writes, enabling the BIOS to
+ * forward any changes to an actually 'NV' location, e.g. the BIOS's SPI flash,
+ * behind the scenes. AMD calls it "GEC shadow ROM", not describing what it's
+ * for nor mentioning the term "NVRAM". broadcom_init() below documents a
+ * procedure how to upload the patch. No SMI magic is installed, therefore
+ * 'NV'RAM writes won't be persistent.
+ *
+ * The "Selfboot Patch" can execute simple commands at various points during
+ * main firmware execution. This can be used to change config registers,
+ * initialize a specific PHY or work around firmware bugs. Broadcom provides
+ * suitable Patches only for their AC131 and 50610 PHYs (as binary blobs). I
+ * found them in DOS\sb_patch\5785\*\sb5785*.* in Driver_14_6_4_2.zip. (Note
+ * that every 32bit-word of these files must be byte-swapped before uploading
+ * them to the A55E.)
+ *
+ * Below is a derived Patch supporting the Micrel KSZ9021 PHY used on the
+ * LiPPERT CFR-AF PC/104 SBC instead, with detailled description of the format.
+ * (Here in correct order for upload.)
+ *
+ * This Patch made Ethernet work with Linux 3.3 - without having to modify the
+ * tg3.ko driver. Broadcom's Windows-Drivers still fail with "Code 10" however;
+ * disassembly showed they check the PHY ID and abort, because the Micrel PHY is
+ * not supported.
+ */
+
+static struct selfboot_patch { //Watch out: all values are *BIG-ENDIAN*!
+
+ struct { /* Global header */
+ u8 signature; //0xA5
+ u8 format; //bits 7-3: patch format; 2-0: revision
+ u8 mac_addr[6];
+ u16 subsys_device; //IDs will be loaded into PCI config space
+ u16 subsys_vendor;
+ u16 pci_device; //PCI device ID; vendor is always Broadcom (0x14E4)
+ u8 unknown1[8]; //?, noticed no effect
+ u16 basic_config; //?, see below
+ u8 checksum; //byte sum of header == 0
+ u8 unknown2; //?, patch rejected if changed
+ u16 patch_version; //10-8: major; 7-0: minor; 15-11: variant (1=a, 2=b, ...)
+ } header;
+
+ struct { /* Init code */
+ u8 checksum; //byte sum of init == 0
+ u8 unknown; //?, looks unused
+ u8 num_hunks; //0x60 = 3 hunks, 0x80 = 4 hunks, other values not supported
+ u8 size; //total size of all hunk#_code[] in bytes
+ u8 hunk1_when; //mark when hunk1_code gets executed
+ u8 hunk1_size; //sizeof(hunk1_code)
+ u8 hunk2_when;
+ u8 hunk2_size;
+ u8 hunk3_when;
+ u8 hunk3_size;
+ u8 hunk4_when; //0x00 (padding) if only 3 hunks
+ u8 hunk4_size; //dito
+ u32 hunk1_code[INIT1_LENGTH]; //actual commands, see below
+ u32 hunk2_code[INIT2_LENGTH];
+ u32 hunk3_code[INIT3_LENGTH];
+ u32 hunk4_code[INIT4_LENGTH]; //missing (zero length) if only 3 hunks
+ } init;
+
+ struct { /* Power down code */
+ u8 checksum; //byte sum of powerdown == 0
+ u8 unknown; //?, looks unused
+ u8 num_hunks; //0x20 = 1 hunk, other values not supported
+ u8 size; //total size of all hunk#_code[] in bytes
+ u8 hunk1_when; //mark when hunk1_code gets executed
+ u8 hunk1_size; //sizeof(hunk1_code)
+ u16 padding; //0x0000, hunk2 is not supported
+ u32 hunk1_code[PWRDN_LENGTH]; //commands, see below
+ } powerdown;
+
+} selfboot_patch = {
+
+/* Keep the following invariant for valid Selfboot patches */
+ .header.signature = 0xA5,
+ .header.format = 0x23, //format 1 revision 3
+ .header.unknown1 = { 0x61, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .header.checksum = 0, //calculated later
+ .header.unknown2 = 0x30,
+ .init.checksum = 0, //calculated later
+ .init.unknown = 0x00,
+ .init.num_hunks = sizeof(selfboot_patch.init.hunk4_code) ? 0x80 : 0x60,
+ .init.size = sizeof(selfboot_patch.init.hunk1_code)
+ + sizeof(selfboot_patch.init.hunk2_code)
+ + sizeof(selfboot_patch.init.hunk3_code)
+ + sizeof(selfboot_patch.init.hunk4_code),
+ .init.hunk1_size = sizeof(selfboot_patch.init.hunk1_code),
+ .init.hunk2_size = sizeof(selfboot_patch.init.hunk2_code),
+ .init.hunk3_size = sizeof(selfboot_patch.init.hunk3_code),
+ .init.hunk4_size = sizeof(selfboot_patch.init.hunk4_code),
+ .powerdown.checksum = 0, //calculated later
+ .powerdown.unknown = 0x00,
+ .powerdown.num_hunks = 0x20,
+ .powerdown.size = sizeof(selfboot_patch.powerdown.hunk1_code),
+ .powerdown.hunk1_size = sizeof(selfboot_patch.powerdown.hunk1_code),
+ .powerdown.padding = be16(0x0000),
+
+/* Only the lines below may be adapted to your needs ... */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.mac_addr = { 0x00, 0x10, 0x18, 0x00, 0x00, 0x00 }, //Broadcom
+ .header.subsys_device = be16(0x1699), //same as pci_device
+ .header.subsys_vendor = be16(0x14E4), //Broadcom
+#else
+ .header.mac_addr = { 0x00, 0x20, 0x9D, 0x00, 0x00, 0x00 }, //LiPPERT
+ .header.subsys_device = be16(0x1699), //simply kept this
+ .header.subsys_vendor = be16(0x121D), //LiPPERT
+#endif
+ .header.pci_device = be16(0x1699), //Broadcom 5785 with GbE PHY
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.patch_version = be16(0x010B), //1.11 (Broadcom's sb5785m1.11)
+#else
+ .header.patch_version = be16(0x110B), //1.11b, i.e. hacked :-)
+#endif
+ /* Bitfield enabling general features/codepaths in the firmware or
+ * selecting support for one of several supported PHYs?
+ * Bits not listed had no appearent effect:
+ * 14-11: any bit 1=firmware execution seemed delayed
+ * 10: 0=firmware execution seemed delayed
+ * 9,2,0: select PHY type, affects these registers, probably more
+ * 9 2 0 | reg 0x05A4 PHY reg 31 PHY 23,24,28 Notes
+ * -------+----------------------------------------------------------
+ * 0 0 0 | 0x331C71C1 - changed Inband Status enabled
+ * 0 1 0 | 0x3210C500 - changed -
+ * 0 X 1 | 0x33FF66C0 changed - 10/100 Mbit only
+ * 1 X 0 | 0x330C5180 - - -
+ * 1 X 1 | 0x391C6140 - - -
+ */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.basic_config = be16(0x0404), //original for B50610
+#else
+ .header.basic_config = be16(0x0604), //bit 9 set so not to mess up PHY regs, kept other bits unchanged
+#endif
+
+ /* Tag that defines when / on what occasion the commands are interpreted.
+ * Bits 2-0 = 0 i.e. possible values are 0x00, 08, 10, ..., F8.
+ * On a RISC CPU reset every tag except 0x38, A0, F0, F8 is used. 0x38
+ * seems to be run before a reset is performed(?), the other 3 I have
+ * never seen used. Generally, lower values appear to be run earlier.
+ * An "ifconfig up" with Linux' "tg3" driver causes the tags 0x50, 60,
+ * 68, 20, 70, 80 to be interpreted in this order.
+ * All tests were performed with .basic_config=0x0604.
+ */
+ .init.hunk1_when = 0x10, //only once at RISC CPU reset?
+ /* Instructions are obviously a specialized bytecode interpreted by the
+ * main firmware, rather than MIPS machine code. Commands consist of 1-3
+ * 32-bit words. In the following, 0-9,A-F = hex literals, a-z,_ = variable
+ * parts, each character = 4 bits.
+ * 0610offs newvalue: write (32-bit) <newvalue> to 5785-internal shared mem at <offs>
+ * 08rgvalu: write <valu> to PHY register, <rg> = 0x20 + register number
+ * C610rgnr newvalue: write <newvalue> to MAC register <rgnr>
+ * C1F0rgnr andvalue or_value: modify MAC register <rgnr> by ANDing with <andvalue> and then ORing with <or_value>
+ * C4btrgnr: clear bit in 32-bit MAC register <rgnr>, <bt> = bit number << 3
+ * C3btrgnr: set bit, see C4...; example: command 0xC3200454 sets bit 4 of 32-bit register 0x0454
+ * CBbtrgnr: run next command only if bit (see C4...) == 1 (so far only seen before F7F0...)
+ * F7F0skip: unconditional jump i.e. skip next <skip> code bytes (only seen small positive <skip>)
+ * F7Fxaddr: call function at <addr> in main firmware? <x> = 3 or 4, bool parameter?? Wild guess!
+ * F7FFFadr somvalue: also call func. at <adr>, but with <somvalue> as parameter?? More guessing!
+ * More commands probably exist, but all code I've ever seen was kept
+ * included below, commented out if not suitable for the CFR-AF. v1.xx
+ * is Broadcom's Selfboot patch version sb5785m1.xx where the command
+ * was added, for reference see Broadcom's changelog.
+ */
+ .init.hunk1_code = {
+#if CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x082B8104), //CFR-AF: PHY0B: KSZ9021 select PHY104
+ be(0x082CF0F0), //CFR-AF: PHY0C: KSZ9021 clk/ctl skew (advised by Micrel)
+ be(0x082B8105), //CFR-AF: PHY0B: KSZ9021 select PHY105
+ be(0x082C3333), //CFR-AF: PHY0C: KSZ9021 RX data skew (empirical)
+#endif
+ be(0xC1F005A0), be(0xFEFFEFFF), be(0x01001000), //v1.05 : 5A0.24,12=1: auto-clock-switch
+ be(0x06100D34), be(0x00000000), //v1.03 : MemD34: clear config vars
+ be(0x06100D38), be(0x00000000), //v1.03 : - |
+ be(0x06100D3C), be(0x00000000), //v1.03 : MemD3F|
+ }, //-->INIT1_LENGTH!
+
+ .init.hunk2_when = 0x30, //after global reset, PHY reset
+ .init.hunk2_code = {
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x08370F08), //v1.06 : PHY17: B50610 select reg. 08
+ be(0x08350001), //v1.06 : PHY15: B50610 slow link fix
+ be(0x08370F00), //v1.06 : PHY17: B50610 disable reg. 08
+ be(0x083C2C00), //v1.11 : PHY1C: B50610 Shadow 0B
+#endif
+ be(0xF7F301E6), //v1.09+: ?: subroutine calls to
+ be(0xF7FFF0B6), be(0x0000FFE7), //v1.09+: ?| restore Port Mode ???
+ be(0xF7FFF0F6), be(0x00008000), //v1.09+: ?|
+ be(0xF7F401E6), //v1.09+: ?|
+ }, //-->INIT2_LENGTH!
+
+ .init.hunk3_when = 0xA8, //?, I'd guess quite late
+ .init.hunk3_code = {
+ be(0xC1F03604), be(0xFFE0FFFF), be(0x00110000), //v1.08 : 3604.20-16: 10Mb clock = 12.5MHz
+ }, //-->INIT3_LENGTH!
+
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .init.hunk4_when = 0xD8, //original for B50610
+#else
+ .init.hunk4_when = 0x80, //run last, after Linux' "ifconfig up"
+#endif
+ .init.hunk4_code = {
+#if CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x083F4300), //CFR-AF: PHY1F: IRQ active high
+ be(0x083C0000), //CFR-AF: PHY1C: revert driver writes
+ be(0x08380000), //CFR-AF: PHY18|
+ be(0x083C0000), //CFR-AF: PHY1C|
+#endif
+ be(0xCB0005A4), be(0xF7F0000C), //v1.01 : if 5A4.0==1 -->skip next 12 bytes
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0xC61005A4), be(0x3210C500), //v1.01 : 5A4: PHY LED mode
+#else
+ be(0xC61005A4), be(0x331C71CE), //CFR-AF: 5A4: fake LED mode
+#endif
+ be(0xF7F00008), //v1.01 : -->skip next 8 bytes
+ be(0xC61005A4), be(0x331C71C1), //v1.01 : 5A4: inband LED mode
+ //be(0xC3200454), //CFR-AF: 454.4: auto link polling
+ }, //-->INIT4_LENGTH!
+
+ .powerdown.hunk1_when = 0x50, //prior to IDDQ MAC
+ .powerdown.hunk1_code = {
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x083CB001), //v1.10 : PHY1C: IDDQ B50610 PHY
+#endif
+ be(0xF7F30116), // IDDQ PHY
+ be(0xC40005A0), //v1.09 : 5A0.0=0: Port Mode = MII
+ be(0xC4180400), //v1.09 : 400.3=0|
+ be(0xC3100400), //v1.09 : 400.2=1|
+ }, //-->PWRDN_LENGTH!
+
+};
+
+/* Upload 'NV'RAM contents for BCM5785 GbE MAC integrated in A55E.
+ * Call this from mainboard.c.
+ */
+void broadcom_init(void)
+{
+ volatile u32 *gec_base; //Gigabit Ethernet Controller base addr
+ u8 *gec_shadow; //base addr of shadow 'NV'RAM for GbE MAC in A55E
+ u8 sum;
+ int i;
+
+ gec_base = (u32*)(long)dev_find_slot(0, PCI_DEVFN(0x14, 6))->resource_list->base;
+ gec_shadow = (u8*)(pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x14, 3)), 0x9C) & 0xFFFFFC00);
+ printk(BIOS_DEBUG, "Upload GbE 'NV'RAM contents @ 0x%08lx\n", (unsigned long)gec_shadow);
+
+ /* Halt RISC CPU before uploading the firmware patch */
+ for (i=10000; i > 0; i--) {
+ gec_base[0x5004/4] = 0xFFFFFFFF; //clear CPU state
+ gec_base[0x5000/4] |= (1<<10); //issue RISC halt
+ if (gec_base[0x5000/4] | (1<<10))
+ break;
+ udelay(10);
+ }
+ if (!i)
+ printk(BIOS_ERR, "Failed to halt RISC CPU!\n");
+
+ /* Calculate checksums (standard byte sum) */
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.header); i++)
+ sum -= ((u8*)&selfboot_patch.header)[i];
+ selfboot_patch.header.checksum = sum;
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.init); i++)
+ sum -= ((u8*)&selfboot_patch.init)[i];
+ selfboot_patch.init.checksum = sum;
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.powerdown); i++)
+ sum -= ((u8*)&selfboot_patch.powerdown)[i];
+ selfboot_patch.powerdown.checksum = sum;
+
+ /* Upload firmware patch to shadow 'NV'RAM */
+ for (i = 0; i < sizeof(selfboot_patch); i++)
+ gec_shadow[i] = ((u8*)&selfboot_patch)[i]; //access byte-wise!
+
+ /* Restart BCM5785's CPU */
+ gec_base[0x5004/4] = 0xFFFFFFFF; //clear CPU state
+ gec_base[0x5000/4] = 0x00000001; //reset RISC processor
+ //usually we'd have to wait for the reset bit to clear again ...
+}
diff --git a/src/mainboard/amd/inagua/mainboard.c b/src/mainboard/amd/inagua/mainboard.c
index 8e92d6a..7839ce7 100644
--- a/src/mainboard/amd/inagua/mainboard.c
+++ b/src/mainboard/amd/inagua/mainboard.c
@@ -27,6 +27,7 @@
#include <southbridge/amd/sb800/sb800.h>
#include "SBPLATFORM.h" /* Platfrom Specific Definitions */
+void broadcom_init(void);
void set_pcie_reset(void);
void set_pcie_dereset(void);
@@ -88,6 +89,9 @@ static void mainboard_enable(device_t dev)
*/
pm_iowrite(0x29, 0x80);
pm_iowrite(0x28, 0x61);
+
+ /* Upload AMD A55E GbE 'NV'RAM contents. */
+ broadcom_init();
}
struct chip_operations mainboard_ops = {
the following patch was just integrated into master:
commit e7ae96f48834d57fd1a6c8940fa3f64b97520ed9
Author: Marc Jones <marc.jones(a)se-eng.com>
Date: Tue Nov 13 15:07:45 2012 -0700
Add Intel Panther Point USB3 initialization
Add PEI updates and ACPI updates for supporting EHCI to XHCI
USB port support.
Change-Id: I9ace68a1b3950771aefb96c1319b8899291edd9a
Signed-off-by: Marc Jones <marc.jones(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2519
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Fri Mar 8 16:51:51 2013, giving +1
See http://review.coreboot.org/2519 for details.
-gerrit
Jens Rottmann (JRottmann(a)LiPPERTembedded.de) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2581
-gerrit
commit 7ae89c2ee20698137ef484cf867e8d3854ce1bbe
Author: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
Date: Fri Mar 1 19:41:41 2013 +0100
AMD Inagua: add GEC firmware, document Broadcom BCM57xx Selfboot Patch format
The Broadcom BCM5785 GbE MAC integrated in the AMD Hudson-E1 requires a
secret sauce firmware blob to work. As Broadcom wasn't willing to send us
any documentation (or a firmware adapted to our Micrel PHY) I had to figure
out everything by myself in many weeks of hard detective work.
In the end we had to settle for a different solution, the modified firmware
I devised for the Micrel KSZ9021 PHY on our early FrontRunner-AF prototypes
is no longer needed for the production version. However the information
contained here might be very useful for others who'd like to use a
competing PHYs instead of Broadcom's 50610, so it should not get lost. And
of course the unmodified, but now in large parts documented Selfboot Patch
is needed to get Ethernet on AMD Inagua.
The fun thing is: as Broadcom refused to do any business with us at all,
or send us any documentation, we never had to sign an NDA with them. This
leaves me free to publish everything I have found out. :-)
Change-Id: Ifa628751d14143f277b27cfd34b1d2771ca1302f
Signed-off-by: Jens Rottmann <JRottmann(a)LiPPERTembedded.de>
---
src/mainboard/amd/inagua/Makefile.inc | 2 +-
src/mainboard/amd/inagua/broadcom.c | 360 ++++++++++++++++++++++++++++++++++
src/mainboard/amd/inagua/mainboard.c | 4 +
3 files changed, 365 insertions(+), 1 deletion(-)
diff --git a/src/mainboard/amd/inagua/Makefile.inc b/src/mainboard/amd/inagua/Makefile.inc
index b1a3014..1f653b5 100644
--- a/src/mainboard/amd/inagua/Makefile.inc
+++ b/src/mainboard/amd/inagua/Makefile.inc
@@ -37,4 +37,4 @@ ramstage-y += BiosCallOuts.c
ramstage-y += PlatformGnbPcie.c
ramstage-y += reset.c
-
+ramstage-y += broadcom.c
diff --git a/src/mainboard/amd/inagua/broadcom.c b/src/mainboard/amd/inagua/broadcom.c
new file mode 100644
index 0000000..357fdbc
--- /dev/null
+++ b/src/mainboard/amd/inagua/broadcom.c
@@ -0,0 +1,360 @@
+/*
+ * Initialize Broadcom 5785 GbE MAC embedded in AMD A55E (Hudson-E1) Southbridge
+ * by uploading a Selfboot Patch to the A55E's shadow ROM area. The patch
+ * itself supports the Broadcom 50610(M) PHY on the AMD Inagua. It is
+ * equivalent to Broadcom's SelfBoot patch V1.11 (sb5785m1.11).
+ * A modified variant, selected by CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF supports
+ * the Micrel KSZ9021 PHY that was used on LiPPERT FrontRunner-AF (CFR-AF)
+ * revision 0v0, the first prototype. The board is history and this code now
+ * serves only to document the proprietary Selfboot Patch format and how to
+ * adapt it to a PHY unsupported by Broadcom.
+ *
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 LiPPERT ADLINK Technology GmbH
+ * (Written by Jens Rottmann <JRottmann(a)LiPPERTembedded.de>)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <arch/byteorder.h>
+#include <console/console.h>
+#include <device/device.h> //Coreboot device access
+#include <device/pci.h>
+#include <delay.h>
+
+#define be16(x) cpu_to_be16(x) //a little easier to type
+#define be(x) cpu_to_be32(x) //this is used a lot!
+
+/* C forces us to specify these before defining struct selfboot_patch :-( */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+#define INIT1_LENGTH 9
+#define INIT2_LENGTH 10
+#define INIT3_LENGTH 3
+#define INIT4_LENGTH 7 //this one may be 0
+#define PWRDN_LENGTH 5
+#else
+#define INIT1_LENGTH 13
+#define INIT2_LENGTH 6
+#define INIT3_LENGTH 3
+#define INIT4_LENGTH 11 //this one may be 0
+#define PWRDN_LENGTH 4
+#endif
+
+
+/* The AMD A55E (Hudson-E1) Southbridge contains an integrated Gigabit Ethernet
+ * MAC, however AMD's documentation merely defines the related balls (without
+ * fully describing their function) and states that only Broadcom 50610(M) PHYs
+ * will be supported, that's all. The Hudson register reference skips all MAC
+ * registers entirely, even AMD support doesn't seem to know more about it.
+ *
+ * As Broadcom refused to sell us any 50610 chips or provide any docs (or indeed
+ * even a price list) below $100K expected sales we had to figure out everything
+ * by ourselves. *Everything* below is the result of months of detective work,
+ * documented here lest it get lost:
+ *
+ * The AMD A55E's GbE MAC is a Broadcom 5785, which AMD obviously licensed as IP
+ * core. It uses a standard RGMII/MII interface and the Broadcom drivers will
+ * recognize it by its unchanged PCI ID 14E4:1699, however there are some
+ * specialties.
+ *
+ * The 5785 MAC can detect the link with 4 additional inputs, "phy_status[3:0]",
+ * 'snooping' on the PHY's LED outputs. Interpretation of the LEDs' patterns is
+ * programmed with register 0x5A4 of the MAC. AMD renamed them to "GBE_STAT" and
+ * won't say anything about their purpose. Appearently hardware designers are
+ * expected to blindly copy the Inagua reference schematic: GBE_STAT2:
+ * 0=activity; GBE_STAT[1:0]: 11=no link, 10=10Mbit, 01=100Mbit, 00=1Gbit.
+ *
+ * For package processing the 5785 also features a MIPS-based RISC CPU, booting
+ * from an internal ROM. The firmware loads config data and supplements (e.g. to
+ * support specific PHYs), named "Selfboot Patches", via the "NVRAM Interface",
+ * usually from an external EEPROM. The A55E doesn't have any balls for an ext.
+ * EEPROM, instead AMD added a small internal RAM. The BIOS is expected to copy
+ * the correct contents into this RAM (which only supports byte access!) upon
+ * each powerup. The A55E can trigger an SMI upon writes, enabling the BIOS to
+ * forward any changes to an actually 'NV' location, e.g. the BIOS's SPI flash,
+ * behind the scenes. AMD calls it "GEC shadow ROM", not describing what it's
+ * for nor mentioning the term "NVRAM". broadcom_init() below documents a
+ * procedure how to upload the patch. No SMI magic is installed, therefore
+ * 'NV'RAM writes won't be persistent.
+ *
+ * The "Selfboot Patch" can execute simple commands at various points during
+ * main firmware execution. This can be used to change config registers,
+ * initialize a specific PHY or work around firmware bugs. Broadcom provides
+ * suitable Patches only for their AC131 and 50610 PHYs (as binary blobs). I
+ * found them in DOS\sb_patch\5785\*\sb5785*.* in Driver_14_6_4_2.zip. (Note
+ * that every 32bit-word of these files must be byte-swapped before uploading
+ * them to the A55E.)
+ *
+ * Below is a derived Patch supporting the Micrel KSZ9021 PHY used on the
+ * LiPPERT CFR-AF PC/104 SBC instead, with detailled description of the format.
+ * (Here in correct order for upload.)
+ *
+ * This Patch made Ethernet work with Linux 3.3 - without having to modify the
+ * tg3.ko driver. Broadcom's Windows-Drivers still fail with "Code 10" however;
+ * disassembly showed they check the PHY ID and abort, because the Micrel PHY is
+ * not supported.
+ */
+
+static struct selfboot_patch { //Watch out: all values are *BIG-ENDIAN*!
+
+ struct { /* Global header */
+ u8 signature; //0xA5
+ u8 format; //bits 7-3: patch format; 2-0: revision
+ u8 mac_addr[6];
+ u16 subsys_device; //IDs will be loaded into PCI config space
+ u16 subsys_vendor;
+ u16 pci_device; //PCI device ID; vendor is always Broadcom (0x14E4)
+ u8 unknown1[8]; //?, noticed no effect
+ u16 basic_config; //?, see below
+ u8 checksum; //byte sum of header == 0
+ u8 unknown2; //?, patch rejected if changed
+ u16 patch_version; //10-8: major; 7-0: minor; 15-11: variant (1=a, 2=b, ...)
+ } header;
+
+ struct { /* Init code */
+ u8 checksum; //byte sum of init == 0
+ u8 unknown; //?, looks unused
+ u8 num_hunks; //0x60 = 3 hunks, 0x80 = 4 hunks, other values not supported
+ u8 size; //total size of all hunk#_code[] in bytes
+ u8 hunk1_when; //mark when hunk1_code gets executed
+ u8 hunk1_size; //sizeof(hunk1_code)
+ u8 hunk2_when;
+ u8 hunk2_size;
+ u8 hunk3_when;
+ u8 hunk3_size;
+ u8 hunk4_when; //0x00 (padding) if only 3 hunks
+ u8 hunk4_size; //dito
+ u32 hunk1_code[INIT1_LENGTH]; //actual commands, see below
+ u32 hunk2_code[INIT2_LENGTH];
+ u32 hunk3_code[INIT3_LENGTH];
+ u32 hunk4_code[INIT4_LENGTH]; //missing (zero length) if only 3 hunks
+ } init;
+
+ struct { /* Power down code */
+ u8 checksum; //byte sum of powerdown == 0
+ u8 unknown; //?, looks unused
+ u8 num_hunks; //0x20 = 1 hunk, other values not supported
+ u8 size; //total size of all hunk#_code[] in bytes
+ u8 hunk1_when; //mark when hunk1_code gets executed
+ u8 hunk1_size; //sizeof(hunk1_code)
+ u16 padding; //0x0000, hunk2 is not supported
+ u32 hunk1_code[PWRDN_LENGTH]; //commands, see below
+ } powerdown;
+
+} selfboot_patch = {
+
+/* Keep the following invariant for valid Selfboot patches */
+ .header.signature = 0xA5,
+ .header.format = 0x23, //format 1 revision 3
+ .header.unknown1 = { 0x61, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ .header.checksum = 0, //calculated later
+ .header.unknown2 = 0x30,
+ .init.checksum = 0, //calculated later
+ .init.unknown = 0x00,
+ .init.num_hunks = sizeof(selfboot_patch.init.hunk4_code) ? 0x80 : 0x60,
+ .init.size = sizeof(selfboot_patch.init.hunk1_code)
+ + sizeof(selfboot_patch.init.hunk2_code)
+ + sizeof(selfboot_patch.init.hunk3_code)
+ + sizeof(selfboot_patch.init.hunk4_code),
+ .init.hunk1_size = sizeof(selfboot_patch.init.hunk1_code),
+ .init.hunk2_size = sizeof(selfboot_patch.init.hunk2_code),
+ .init.hunk3_size = sizeof(selfboot_patch.init.hunk3_code),
+ .init.hunk4_size = sizeof(selfboot_patch.init.hunk4_code),
+ .powerdown.checksum = 0, //calculated later
+ .powerdown.unknown = 0x00,
+ .powerdown.num_hunks = 0x20,
+ .powerdown.size = sizeof(selfboot_patch.powerdown.hunk1_code),
+ .powerdown.hunk1_size = sizeof(selfboot_patch.powerdown.hunk1_code),
+ .powerdown.padding = be16(0x0000),
+
+/* Only the lines below may be adapted to your needs ... */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.mac_addr = { 0x00, 0x10, 0x18, 0x00, 0x00, 0x00 }, //Broadcom
+ .header.subsys_device = be16(0x1699), //same as pci_device
+ .header.subsys_vendor = be16(0x14E4), //Broadcom
+#else
+ .header.mac_addr = { 0x00, 0x20, 0x9D, 0x00, 0x00, 0x00 }, //LiPPERT
+ .header.subsys_device = be16(0x1699), //simply kept this
+ .header.subsys_vendor = be16(0x121D), //LiPPERT
+#endif
+ .header.pci_device = be16(0x1699), //Broadcom 5785 with GbE PHY
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.patch_version = be16(0x010B), //1.11 (Broadcom's sb5785m1.11)
+#else
+ .header.patch_version = be16(0x110B), //1.11b, i.e. hacked :-)
+#endif
+ /* Bitfield enabling general features/codepaths in the firmware or
+ * selecting support for one of several supported PHYs?
+ * Bits not listed had no appearent effect:
+ * 14-11: any bit 1=firmware execution seemed delayed
+ * 10: 0=firmware execution seemed delayed
+ * 9,2,0: select PHY type, affects these registers, probably more
+ * 9 2 0 | reg 0x05A4 PHY reg 31 PHY 23,24,28 Notes
+ * -------+----------------------------------------------------------
+ * 0 0 0 | 0x331C71C1 - changed Inband Status enabled
+ * 0 1 0 | 0x3210C500 - changed -
+ * 0 X 1 | 0x33FF66C0 changed - 10/100 Mbit only
+ * 1 X 0 | 0x330C5180 - - -
+ * 1 X 1 | 0x391C6140 - - -
+ */
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .header.basic_config = be16(0x0404), //original for B50610
+#else
+ .header.basic_config = be16(0x0604), //bit 9 set so not to mess up PHY regs, kept other bits unchanged
+#endif
+
+ /* Tag that defines when / on what occasion the commands are interpreted.
+ * Bits 2-0 = 0 i.e. possible values are 0x00, 08, 10, ..., F8.
+ * On a RISC CPU reset every tag except 0x38, A0, F0, F8 is used. 0x38
+ * seems to be run before a reset is performed(?), the other 3 I have
+ * never seen used. Generally, lower values appear to be run earlier.
+ * An "ifconfig up" with Linux' "tg3" driver causes the tags 0x50, 60,
+ * 68, 20, 70, 80 to be interpreted in this order.
+ * All tests were performed with .basic_config=0x0604.
+ */
+ .init.hunk1_when = 0x10, //only once at RISC CPU reset?
+ /* Instructions are obviously a specialized bytecode interpreted by the
+ * main firmware, rather than MIPS machine code. Commands consist of 1-3
+ * 32-bit words. In the following, 0-9,A-F = hex literals, a-z,_ = variable
+ * parts, each character = 4 bits.
+ * 0610offs newvalue: write (32-bit) <newvalue> to 5785-internal shared mem at <offs>
+ * 08rgvalu: write <valu> to PHY register, <rg> = 0x20 + register number
+ * C610rgnr newvalue: write <newvalue> to MAC register <rgnr>
+ * C1F0rgnr andvalue or_value: modify MAC register <rgnr> by ANDing with <andvalue> and then ORing with <or_value>
+ * C4btrgnr: clear bit in 32-bit MAC register <rgnr>, <bt> = bit number << 3
+ * C3btrgnr: set bit, see C4...; example: command 0xC3200454 sets bit 4 of 32-bit register 0x0454
+ * CBbtrgnr: run next command only if bit (see C4...) == 1 (so far only seen before F7F0...)
+ * F7F0skip: unconditional jump i.e. skip next <skip> code bytes (only seen small positive <skip>)
+ * F7Fxaddr: call function at <addr> in main firmware? <x> = 3 or 4, bool parameter?? Wild guess!
+ * F7FFFadr somvalue: also call func. at <adr>, but with <somvalue> as parameter?? More guessing!
+ * More commands probably exist, but all code I've ever seen was kept
+ * included below, commented out if not suitable for the CFR-AF. v1.xx
+ * is Broadcom's Selfboot patch version sb5785m1.xx where the command
+ * was added, for reference see Broadcom's changelog.
+ */
+ .init.hunk1_code = {
+#if CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x082B8104), //CFR-AF: PHY0B: KSZ9021 select PHY104
+ be(0x082CF0F0), //CFR-AF: PHY0C: KSZ9021 clk/ctl skew (advised by Micrel)
+ be(0x082B8105), //CFR-AF: PHY0B: KSZ9021 select PHY105
+ be(0x082C3333), //CFR-AF: PHY0C: KSZ9021 RX data skew (empirical)
+#endif
+ be(0xC1F005A0), be(0xFEFFEFFF), be(0x01001000), //v1.05 : 5A0.24,12=1: auto-clock-switch
+ be(0x06100D34), be(0x00000000), //v1.03 : MemD34: clear config vars
+ be(0x06100D38), be(0x00000000), //v1.03 : - |
+ be(0x06100D3C), be(0x00000000), //v1.03 : MemD3F|
+ }, //-->INIT1_LENGTH!
+
+ .init.hunk2_when = 0x30, //after global reset, PHY reset
+ .init.hunk2_code = {
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x08370F08), //v1.06 : PHY17: B50610 select reg. 08
+ be(0x08350001), //v1.06 : PHY15: B50610 slow link fix
+ be(0x08370F00), //v1.06 : PHY17: B50610 disable reg. 08
+ be(0x083C2C00), //v1.11 : PHY1C: B50610 Shadow 0B
+#endif
+ be(0xF7F301E6), //v1.09+: ?: subroutine calls to
+ be(0xF7FFF0B6), be(0x0000FFE7), //v1.09+: ?| restore Port Mode ???
+ be(0xF7FFF0F6), be(0x00008000), //v1.09+: ?|
+ be(0xF7F401E6), //v1.09+: ?|
+ }, //-->INIT2_LENGTH!
+
+ .init.hunk3_when = 0xA8, //?, I'd guess quite late
+ .init.hunk3_code = {
+ be(0xC1F03604), be(0xFFE0FFFF), be(0x00110000), //v1.08 : 3604.20-16: 10Mb clock = 12.5MHz
+ }, //-->INIT3_LENGTH!
+
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ .init.hunk4_when = 0xD8, //original for B50610
+#else
+ .init.hunk4_when = 0x80, //run last, after Linux' "ifconfig up"
+#endif
+ .init.hunk4_code = {
+#if CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x083F4300), //CFR-AF: PHY1F: IRQ active high
+ be(0x083C0000), //CFR-AF: PHY1C: revert driver writes
+ be(0x08380000), //CFR-AF: PHY18|
+ be(0x083C0000), //CFR-AF: PHY1C|
+#endif
+ be(0xCB0005A4), be(0xF7F0000C), //v1.01 : if 5A4.0==1 -->skip next 12 bytes
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0xC61005A4), be(0x3210C500), //v1.01 : 5A4: PHY LED mode
+#else
+ be(0xC61005A4), be(0x331C71CE), //CFR-AF: 5A4: fake LED mode
+#endif
+ be(0xF7F00008), //v1.01 : -->skip next 8 bytes
+ be(0xC61005A4), be(0x331C71C1), //v1.01 : 5A4: inband LED mode
+ //be(0xC3200454), //CFR-AF: 454.4: auto link polling
+ }, //-->INIT4_LENGTH!
+
+ .powerdown.hunk1_when = 0x50, //prior to IDDQ MAC
+ .powerdown.hunk1_code = {
+#if !CONFIG_BOARD_LIPPERT_FRONTRUNNER_AF
+ be(0x083CB001), //v1.10 : PHY1C: IDDQ B50610 PHY
+#endif
+ be(0xF7F30116), // IDDQ PHY
+ be(0xC40005A0), //v1.09 : 5A0.0=0: Port Mode = MII
+ be(0xC4180400), //v1.09 : 400.3=0|
+ be(0xC3100400), //v1.09 : 400.2=1|
+ }, //-->PWRDN_LENGTH!
+
+};
+
+/* Upload 'NV'RAM contents for BCM5785 GbE MAC integrated in A55E.
+ * Call this from mainboard.c.
+ */
+void broadcom_init(void)
+{
+ volatile u32 *gec_base; //Gigabit Ethernet Controller base addr
+ u8 *gec_shadow; //base addr of shadow 'NV'RAM for GbE MAC in A55E
+ u8 sum;
+ int i;
+
+ gec_base = (u32*)(long)dev_find_slot(0, PCI_DEVFN(0x14, 6))->resource_list->base;
+ gec_shadow = (u8*)(pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x14, 3)), 0x9C) & 0xFFFFFC00);
+ printk(BIOS_DEBUG, "Upload GbE 'NV'RAM contents @ 0x%08lx\n", (unsigned long)gec_shadow);
+
+ /* Halt RISC CPU before uploading the firmware patch */
+ for (i=10000; i > 0; i--) {
+ gec_base[0x5004/4] = 0xFFFFFFFF; //clear CPU state
+ gec_base[0x5000/4] |= (1<<10); //issue RISC halt
+ if (gec_base[0x5000/4] | (1<<10))
+ break;
+ udelay(10);
+ }
+ if (!i)
+ printk(BIOS_ERR, "Failed to halt RISC CPU!\n");
+
+ /* Calculate checksums (standard byte sum) */
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.header); i++)
+ sum -= ((u8*)&selfboot_patch.header)[i];
+ selfboot_patch.header.checksum = sum;
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.init); i++)
+ sum -= ((u8*)&selfboot_patch.init)[i];
+ selfboot_patch.init.checksum = sum;
+ for (sum = 0, i = 0; i < sizeof(selfboot_patch.powerdown); i++)
+ sum -= ((u8*)&selfboot_patch.powerdown)[i];
+ selfboot_patch.powerdown.checksum = sum;
+
+ /* Upload firmware patch to shadow 'NV'RAM */
+ for (i = 0; i < sizeof(selfboot_patch); i++)
+ gec_shadow[i] = ((u8*)&selfboot_patch)[i]; //access byte-wise!
+
+ /* Restart BCM5785's CPU */
+ gec_base[0x5004/4] = 0xFFFFFFFF; //clear CPU state
+ gec_base[0x5000/4] = 0x00000001; //reset RISC processor
+ //usually we'd have to wait for the reset bit to clear again ...
+}
diff --git a/src/mainboard/amd/inagua/mainboard.c b/src/mainboard/amd/inagua/mainboard.c
index 8907ebb..af2f3c7 100644
--- a/src/mainboard/amd/inagua/mainboard.c
+++ b/src/mainboard/amd/inagua/mainboard.c
@@ -27,6 +27,7 @@
//#include <southbridge/amd/sb800/sb800.h>
#include "SBPLATFORM.h" /* Platfrom Specific Definitions */
+void broadcom_init(void);
void set_pcie_reset(void);
void set_pcie_dereset(void);
@@ -79,6 +80,9 @@ static void mainboard_enable(device_t dev)
/* Inagua mainboard specific setting */
set_pcie_dereset();
+
+ /* Upload AMD A55E GbE 'NV'RAM contents. */
+ broadcom_init();
}
struct chip_operations mainboard_ops = {
the following patch was just integrated into master:
commit 4733c647bc64cef86f03efd64a145e4da6fef123
Author: Mike Loptien <mike.loptien(a)se-eng.com>
Date: Tue Mar 5 14:21:28 2013 -0700
Persimmon DSDT: Add secondary bus range to PCI0
Adding the 'WordBusNumber' macro to the PCI0
CRES ResourceTemplate in the Persimmon DSDT.
This sets up the bus number for the PCI0 device
and the secondary bus number in the CRS method.
This change came in response to a 'dmesg' error
which states:
'[FIRMWARE BUG]: ACPI: no secondary bus range in _CRS'
By adding the 'WordBusNumber' macro, ACPI can set
up a valid range for the PCIe downstream busses,
thereby relieving the Linux kernel from "guessing"
the valid range based off _BBN or assuming [0-0xFF].
The Linux kernel code that checks this bus range is
in `drivers/acpi/pci_root.c`. PCI busses can have
up to 256 secondary busses connected to them via
a PCI-PCI bridge. However, these busses do not
have to be sequentially numbered, so leaving out a
section of the range (eg. allowing [0-0x7F]) will
unnecessarily restrict the downstream busses.
This change will apply to other AMD mainboards and
will be in a different commit.
Change-Id: I44f22bc03a0dcbcd2594d4291508826cc2146860
Signed-off-by: Mike Loptien <mike.loptien(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2592
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Reviewed-by: Marc Jones <marc.jones(a)se-eng.com>
Build-Tested: build bot (Jenkins) at Fri Mar 8 01:00:19 2013, giving +1
Reviewed-By: Marc Jones <marc.jones(a)se-eng.com> at Fri Mar 8 23:59:13 2013, giving +2
See http://review.coreboot.org/2592 for details.
-gerrit
the following patch was just integrated into master:
commit ae0e8d3613ad9cb6872c58cd95fc9774b3b17f5b
Author: David Hendricks <dhendrix(a)chromium.org>
Date: Wed Mar 6 20:43:55 2013 -0800
Eliminate do_div().
This eliminates the use of do_div() in favor of using libgcc
functions.
This was tested by building and booting on Google Snow (ARMv7)
and Qemu (x86). printk()s which use division in vtxprintf() look good.
Change-Id: Icad001d84a3c05bfbf77098f3d644816280b4a4d
Signed-off-by: Gabe Black <gabeblack(a)chromium.org>
Signed-off-by: David Hendricks <dhendrix(a)chromium.org>
Reviewed-on: http://review.coreboot.org/2606
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Reviewed-by: Ronald G. Minnich <rminnich(a)gmail.com>
Build-Tested: build bot (Jenkins) at Thu Mar 7 22:09:42 2013, giving +1
Reviewed-By: David Hendricks <dhendrix(a)chromium.org> at Thu Mar 7 22:34:20 2013, giving +1
Reviewed-By: Ronald G. Minnich <rminnich(a)gmail.com> at Fri Mar 8 00:43:59 2013, giving +1
See http://review.coreboot.org/2606 for details.
-gerrit
the following patch was just integrated into master:
commit 31c5e07a04e90c03822d216d2dc92454b42e21ce
Author: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Date: Wed Mar 6 16:18:09 2013 -0700
AMD Inagua: Use SPD read code from F14 wrapper
Changes:
- Get rid of the inagua mainboard specific code and use the
platform generic function wrapper that was added in change
http://review.coreboot.org/#/c/2497/
AMD f14: Add SPD read functions to wrapper code
- Move DIMM addresses into devicetree.cb
- Add the ASF init that used to be in the SPD read code into
mainboard_enable()
Notes:
- The DIMM reads only happen in romstage, so the function is not
available in ramstage. Point the read-SPD callback to a generic
function in ramstage.
Change-Id: Id05227fcf18c6ab94ffe1beb50b533ab7b0535db
Signed-off-by: Kimarie Hoot <kimarie.hoot(a)se-eng.com>
Reviewed-on: http://review.coreboot.org/2607
Reviewed-by: Martin Roth <martin.roth(a)se-eng.com>
Tested-by: build bot (Jenkins)
Reviewed-by: Paul Menzel <paulepanter(a)users.sourceforge.net>
Build-Tested: build bot (Jenkins) at Fri Mar 8 22:29:10 2013, giving +1
Reviewed-By: Martin Roth <martin.roth(a)se-eng.com> at Fri Mar 8 22:20:34 2013, giving +2
See http://review.coreboot.org/2607 for details.
-gerrit