Re: [U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices
Hi Bin, On 11 November 2014 18:33, Bin Meng wrote: > Hi Simon, > > On Wed, Nov 12, 2014 at 12:15 AM, Simon Glass wrote: >> Hi Bin, >> >> On 11 November 2014 07:52, Bin Meng wrote: >>> Hi Simon, >>> >>> On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass wrote: Many PCH devices are hard-coded to a particular PCI address. Set these up early in case they are needed. Signed-off-by: Simon Glass --- arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/cpu.c | 142 + arch/x86/cpu/ivybridge/early_init.c | 145 ++ arch/x86/include/asm/arch-ivybridge/pch.h | 121 +- arch/x86/include/asm/arch-ivybridge/sandybridge.h | 107 arch/x86/include/asm/global_data.h| 8 ++ arch/x86/include/asm/post.h | 2 + 7 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/ivybridge/early_init.c create mode 100644 arch/x86/include/asm/arch-ivybridge/sandybridge.h diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index a3ea566..4bfb03a 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -6,6 +6,7 @@ obj-y += car.o obj-y += cpu.o +obj-y += early_init.o obj-y += lpc.o obj-y += microcode_intel.o obj-y += sdram.o diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index bd2660f..a435520 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -4,6 +4,7 @@ * Graeme Russ, graeme.r...@gmail.com. * * Some portions from coreboot src/mainboard/google/link/romstage.c + * and src/cpu/intel/model_206ax/bootblock.c * Copyright (C) 2007-2010 coresystems GmbH * Copyright (C) 2011 Google Inc. * @@ -16,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -178,6 +181,83 @@ int arch_cpu_init(void) return 0; } +static int enable_smbus(void) +{ + pci_dev_t dev; + uint16_t value; + + /* Set the SMBus device statically. */ + dev = PCI_BDF(0x0, 0x1f, 0x3); + + /* Check to make sure we've got the right device. */ + value = pci_read_config16(dev, 0x0); + if (value != 0x8086) { + printf("SMBus controller not found\n"); + return -ENOSYS; + } + + /* 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); + debug("SMBus controller enabled\n"); + + return 0; +} + +#define PCH_EHCI0_TEMP_BAR0 0xe800 +#define PCH_EHCI1_TEMP_BAR0 0xe8000400 +#define PCH_XHCI_TEMP_BAR0 0xe8001000 + +/* + * Setup USB controller MMIO BAR to prevent the reference code from + * resetting the controller. + * + * The BAR will be re-assigned during device enumeration so these are only + * temporary. + * + * This is used to speed up the resume path. + */ +static void enable_usb_bar(void) +{ + pci_dev_t usb0 = PCH_EHCI1_DEV; + pci_dev_t usb1 = PCH_EHCI2_DEV; + pci_dev_t usb3 = PCH_XHCI_DEV; + u32 cmd; + + /* USB Controller 1 */ + pci_write_config32(usb0, PCI_BASE_ADDRESS_0, + PCH_EHCI0_TEMP_BAR0); + cmd = pci_read_config32(usb0, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config32(usb0, PCI_COMMAND, cmd); + + /* USB Controller 1 */ + pci_write_config32(usb1, PCI_BASE_ADDRESS_0, + PCH_EHCI1_TEMP_BAR0); + cmd = pci_read_config32(usb1, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config32(usb1, PCI_COMMAND, cmd); + + /* USB3 Controller */ + pci_write_config32(usb3, PCI_BASE_ADDRESS_0, +
Re: [U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices
Hi Simon, On Wed, Nov 12, 2014 at 12:15 AM, Simon Glass wrote: > Hi Bin, > > On 11 November 2014 07:52, Bin Meng wrote: >> Hi Simon, >> >> On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass wrote: >>> Many PCH devices are hard-coded to a particular PCI address. Set these >>> up early in case they are needed. >>> >>> Signed-off-by: Simon Glass >>> --- >>> >>> arch/x86/cpu/ivybridge/Makefile | 1 + >>> arch/x86/cpu/ivybridge/cpu.c | 142 >>> + >>> arch/x86/cpu/ivybridge/early_init.c | 145 >>> ++ >>> arch/x86/include/asm/arch-ivybridge/pch.h | 121 +- >>> arch/x86/include/asm/arch-ivybridge/sandybridge.h | 107 >>> arch/x86/include/asm/global_data.h| 8 ++ >>> arch/x86/include/asm/post.h | 2 + >>> 7 files changed, 525 insertions(+), 1 deletion(-) >>> create mode 100644 arch/x86/cpu/ivybridge/early_init.c >>> create mode 100644 arch/x86/include/asm/arch-ivybridge/sandybridge.h >>> >>> diff --git a/arch/x86/cpu/ivybridge/Makefile >>> b/arch/x86/cpu/ivybridge/Makefile >>> index a3ea566..4bfb03a 100644 >>> --- a/arch/x86/cpu/ivybridge/Makefile >>> +++ b/arch/x86/cpu/ivybridge/Makefile >>> @@ -6,6 +6,7 @@ >>> >>> obj-y += car.o >>> obj-y += cpu.o >>> +obj-y += early_init.o >>> obj-y += lpc.o >>> obj-y += microcode_intel.o >>> obj-y += sdram.o >>> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c >>> index bd2660f..a435520 100644 >>> --- a/arch/x86/cpu/ivybridge/cpu.c >>> +++ b/arch/x86/cpu/ivybridge/cpu.c >>> @@ -4,6 +4,7 @@ >>> * Graeme Russ, graeme.r...@gmail.com. >>> * >>> * Some portions from coreboot src/mainboard/google/link/romstage.c >>> + * and src/cpu/intel/model_206ax/bootblock.c >>> * Copyright (C) 2007-2010 coresystems GmbH >>> * Copyright (C) 2011 Google Inc. >>> * >>> @@ -16,11 +17,13 @@ >>> #include >>> #include >>> #include >>> +#include >>> #include >>> #include >>> #include >>> #include >>> #include >>> +#include >>> >>> DECLARE_GLOBAL_DATA_PTR; >>> >>> @@ -178,6 +181,83 @@ int arch_cpu_init(void) >>> return 0; >>> } >>> >>> +static int enable_smbus(void) >>> +{ >>> + pci_dev_t dev; >>> + uint16_t value; >>> + >>> + /* Set the SMBus device statically. */ >>> + dev = PCI_BDF(0x0, 0x1f, 0x3); >>> + >>> + /* Check to make sure we've got the right device. */ >>> + value = pci_read_config16(dev, 0x0); >>> + if (value != 0x8086) { >>> + printf("SMBus controller not found\n"); >>> + return -ENOSYS; >>> + } >>> + >>> + /* 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); >>> + debug("SMBus controller enabled\n"); >>> + >>> + return 0; >>> +} >>> + >>> +#define PCH_EHCI0_TEMP_BAR0 0xe800 >>> +#define PCH_EHCI1_TEMP_BAR0 0xe8000400 >>> +#define PCH_XHCI_TEMP_BAR0 0xe8001000 >>> + >>> +/* >>> + * Setup USB controller MMIO BAR to prevent the reference code from >>> + * resetting the controller. >>> + * >>> + * The BAR will be re-assigned during device enumeration so these are only >>> + * temporary. >>> + * >>> + * This is used to speed up the resume path. >>> + */ >>> +static void enable_usb_bar(void) >>> +{ >>> + pci_dev_t usb0 = PCH_EHCI1_DEV; >>> + pci_dev_t usb1 = PCH_EHCI2_DEV; >>> + pci_dev_t usb3 = PCH_XHCI_DEV; >>> + u32 cmd; >>> + >>> + /* USB Controller 1 */ >>> + pci_write_config32(usb0, PCI_BASE_ADDRESS_0, >>> + PCH_EHCI0_TEMP_BAR0); >>> + cmd = pci_read_config32(usb0, PCI_COMMAND); >>> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >>> + pci_write_config32(usb0, PCI_COMMAND, cmd); >>> + >>> + /* USB Controller 1 */ >>> + pci_write_config32(usb1, PCI_BASE_ADDRESS_0, >>> + PCH_EHCI1_TEMP_BAR0); >>> + cmd = pci_read_config32(usb1, PCI_COMMAND); >>> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >>> + pci_write_config32(usb1, PCI_COMMAND, cmd); >>> + >>> + /* USB3 Controller */ >>> + pci_write_config32(usb3, PCI_BASE_ADDRESS_0, >>> + PCH_XHCI_TEMP_BAR0); >>> + cmd = pci_read_config32(usb3, PCI_COMMAND); >>> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >>> + pci_write_config32(usb3, PCI_COMMAND, cmd); >>>
Re: [U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices
Hi Bin, On 11 November 2014 07:52, Bin Meng wrote: > Hi Simon, > > On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass wrote: >> Many PCH devices are hard-coded to a particular PCI address. Set these >> up early in case they are needed. >> >> Signed-off-by: Simon Glass >> --- >> >> arch/x86/cpu/ivybridge/Makefile | 1 + >> arch/x86/cpu/ivybridge/cpu.c | 142 >> + >> arch/x86/cpu/ivybridge/early_init.c | 145 >> ++ >> arch/x86/include/asm/arch-ivybridge/pch.h | 121 +- >> arch/x86/include/asm/arch-ivybridge/sandybridge.h | 107 >> arch/x86/include/asm/global_data.h| 8 ++ >> arch/x86/include/asm/post.h | 2 + >> 7 files changed, 525 insertions(+), 1 deletion(-) >> create mode 100644 arch/x86/cpu/ivybridge/early_init.c >> create mode 100644 arch/x86/include/asm/arch-ivybridge/sandybridge.h >> >> diff --git a/arch/x86/cpu/ivybridge/Makefile >> b/arch/x86/cpu/ivybridge/Makefile >> index a3ea566..4bfb03a 100644 >> --- a/arch/x86/cpu/ivybridge/Makefile >> +++ b/arch/x86/cpu/ivybridge/Makefile >> @@ -6,6 +6,7 @@ >> >> obj-y += car.o >> obj-y += cpu.o >> +obj-y += early_init.o >> obj-y += lpc.o >> obj-y += microcode_intel.o >> obj-y += sdram.o >> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c >> index bd2660f..a435520 100644 >> --- a/arch/x86/cpu/ivybridge/cpu.c >> +++ b/arch/x86/cpu/ivybridge/cpu.c >> @@ -4,6 +4,7 @@ >> * Graeme Russ, graeme.r...@gmail.com. >> * >> * Some portions from coreboot src/mainboard/google/link/romstage.c >> + * and src/cpu/intel/model_206ax/bootblock.c >> * Copyright (C) 2007-2010 coresystems GmbH >> * Copyright (C) 2011 Google Inc. >> * >> @@ -16,11 +17,13 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> #include >> #include >> +#include >> >> DECLARE_GLOBAL_DATA_PTR; >> >> @@ -178,6 +181,83 @@ int arch_cpu_init(void) >> return 0; >> } >> >> +static int enable_smbus(void) >> +{ >> + pci_dev_t dev; >> + uint16_t value; >> + >> + /* Set the SMBus device statically. */ >> + dev = PCI_BDF(0x0, 0x1f, 0x3); >> + >> + /* Check to make sure we've got the right device. */ >> + value = pci_read_config16(dev, 0x0); >> + if (value != 0x8086) { >> + printf("SMBus controller not found\n"); >> + return -ENOSYS; >> + } >> + >> + /* 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); >> + debug("SMBus controller enabled\n"); >> + >> + return 0; >> +} >> + >> +#define PCH_EHCI0_TEMP_BAR0 0xe800 >> +#define PCH_EHCI1_TEMP_BAR0 0xe8000400 >> +#define PCH_XHCI_TEMP_BAR0 0xe8001000 >> + >> +/* >> + * Setup USB controller MMIO BAR to prevent the reference code from >> + * resetting the controller. >> + * >> + * The BAR will be re-assigned during device enumeration so these are only >> + * temporary. >> + * >> + * This is used to speed up the resume path. >> + */ >> +static void enable_usb_bar(void) >> +{ >> + pci_dev_t usb0 = PCH_EHCI1_DEV; >> + pci_dev_t usb1 = PCH_EHCI2_DEV; >> + pci_dev_t usb3 = PCH_XHCI_DEV; >> + u32 cmd; >> + >> + /* USB Controller 1 */ >> + pci_write_config32(usb0, PCI_BASE_ADDRESS_0, >> + PCH_EHCI0_TEMP_BAR0); >> + cmd = pci_read_config32(usb0, PCI_COMMAND); >> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >> + pci_write_config32(usb0, PCI_COMMAND, cmd); >> + >> + /* USB Controller 1 */ >> + pci_write_config32(usb1, PCI_BASE_ADDRESS_0, >> + PCH_EHCI1_TEMP_BAR0); >> + cmd = pci_read_config32(usb1, PCI_COMMAND); >> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >> + pci_write_config32(usb1, PCI_COMMAND, cmd); >> + >> + /* USB3 Controller */ >> + pci_write_config32(usb3, PCI_BASE_ADDRESS_0, >> + PCH_XHCI_TEMP_BAR0); >> + cmd = pci_read_config32(usb3, PCI_COMMAND); >> + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; >> + pci_write_config32(usb3, PCI_COMMAND, cmd); >> +} >> + >> static int report_bist_failure(void) >> { >> if (gd->arch.bist != 0) { >> @@ -190,8 +270,11 @@ static int report_bist_failure(void) >> >> int print_cpuinfo(void) >> { >> + enum pei_b
Re: [U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices
Hi Simon, On Fri, Nov 7, 2014 at 4:20 AM, Simon Glass wrote: > Many PCH devices are hard-coded to a particular PCI address. Set these > up early in case they are needed. > > Signed-off-by: Simon Glass > --- > > arch/x86/cpu/ivybridge/Makefile | 1 + > arch/x86/cpu/ivybridge/cpu.c | 142 + > arch/x86/cpu/ivybridge/early_init.c | 145 > ++ > arch/x86/include/asm/arch-ivybridge/pch.h | 121 +- > arch/x86/include/asm/arch-ivybridge/sandybridge.h | 107 > arch/x86/include/asm/global_data.h| 8 ++ > arch/x86/include/asm/post.h | 2 + > 7 files changed, 525 insertions(+), 1 deletion(-) > create mode 100644 arch/x86/cpu/ivybridge/early_init.c > create mode 100644 arch/x86/include/asm/arch-ivybridge/sandybridge.h > > diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile > index a3ea566..4bfb03a 100644 > --- a/arch/x86/cpu/ivybridge/Makefile > +++ b/arch/x86/cpu/ivybridge/Makefile > @@ -6,6 +6,7 @@ > > obj-y += car.o > obj-y += cpu.o > +obj-y += early_init.o > obj-y += lpc.o > obj-y += microcode_intel.o > obj-y += sdram.o > diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c > index bd2660f..a435520 100644 > --- a/arch/x86/cpu/ivybridge/cpu.c > +++ b/arch/x86/cpu/ivybridge/cpu.c > @@ -4,6 +4,7 @@ > * Graeme Russ, graeme.r...@gmail.com. > * > * Some portions from coreboot src/mainboard/google/link/romstage.c > + * and src/cpu/intel/model_206ax/bootblock.c > * Copyright (C) 2007-2010 coresystems GmbH > * Copyright (C) 2011 Google Inc. > * > @@ -16,11 +17,13 @@ > #include > #include > #include > +#include > #include > #include > #include > #include > #include > +#include > > DECLARE_GLOBAL_DATA_PTR; > > @@ -178,6 +181,83 @@ int arch_cpu_init(void) > return 0; > } > > +static int enable_smbus(void) > +{ > + pci_dev_t dev; > + uint16_t value; > + > + /* Set the SMBus device statically. */ > + dev = PCI_BDF(0x0, 0x1f, 0x3); > + > + /* Check to make sure we've got the right device. */ > + value = pci_read_config16(dev, 0x0); > + if (value != 0x8086) { > + printf("SMBus controller not found\n"); > + return -ENOSYS; > + } > + > + /* 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); > + debug("SMBus controller enabled\n"); > + > + return 0; > +} > + > +#define PCH_EHCI0_TEMP_BAR0 0xe800 > +#define PCH_EHCI1_TEMP_BAR0 0xe8000400 > +#define PCH_XHCI_TEMP_BAR0 0xe8001000 > + > +/* > + * Setup USB controller MMIO BAR to prevent the reference code from > + * resetting the controller. > + * > + * The BAR will be re-assigned during device enumeration so these are only > + * temporary. > + * > + * This is used to speed up the resume path. > + */ > +static void enable_usb_bar(void) > +{ > + pci_dev_t usb0 = PCH_EHCI1_DEV; > + pci_dev_t usb1 = PCH_EHCI2_DEV; > + pci_dev_t usb3 = PCH_XHCI_DEV; > + u32 cmd; > + > + /* USB Controller 1 */ > + pci_write_config32(usb0, PCI_BASE_ADDRESS_0, > + PCH_EHCI0_TEMP_BAR0); > + cmd = pci_read_config32(usb0, PCI_COMMAND); > + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; > + pci_write_config32(usb0, PCI_COMMAND, cmd); > + > + /* USB Controller 1 */ > + pci_write_config32(usb1, PCI_BASE_ADDRESS_0, > + PCH_EHCI1_TEMP_BAR0); > + cmd = pci_read_config32(usb1, PCI_COMMAND); > + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; > + pci_write_config32(usb1, PCI_COMMAND, cmd); > + > + /* USB3 Controller */ > + pci_write_config32(usb3, PCI_BASE_ADDRESS_0, > + PCH_XHCI_TEMP_BAR0); > + cmd = pci_read_config32(usb3, PCI_COMMAND); > + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; > + pci_write_config32(usb3, PCI_COMMAND, cmd); > +} > + > static int report_bist_failure(void) > { > if (gd->arch.bist != 0) { > @@ -190,8 +270,11 @@ static int report_bist_failure(void) > > int print_cpuinfo(void) > { > + enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE; > char processor_name[CPU_MAX_NAME_LEN]; > const char *name; > + uint32_t pm1_cnt; > + uint16_t pm1_sts; > int ret; > > /* Halt i
[U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices
Many PCH devices are hard-coded to a particular PCI address. Set these up early in case they are needed. Signed-off-by: Simon Glass --- arch/x86/cpu/ivybridge/Makefile | 1 + arch/x86/cpu/ivybridge/cpu.c | 142 + arch/x86/cpu/ivybridge/early_init.c | 145 ++ arch/x86/include/asm/arch-ivybridge/pch.h | 121 +- arch/x86/include/asm/arch-ivybridge/sandybridge.h | 107 arch/x86/include/asm/global_data.h| 8 ++ arch/x86/include/asm/post.h | 2 + 7 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/ivybridge/early_init.c create mode 100644 arch/x86/include/asm/arch-ivybridge/sandybridge.h diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index a3ea566..4bfb03a 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -6,6 +6,7 @@ obj-y += car.o obj-y += cpu.o +obj-y += early_init.o obj-y += lpc.o obj-y += microcode_intel.o obj-y += sdram.o diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c index bd2660f..a435520 100644 --- a/arch/x86/cpu/ivybridge/cpu.c +++ b/arch/x86/cpu/ivybridge/cpu.c @@ -4,6 +4,7 @@ * Graeme Russ, graeme.r...@gmail.com. * * Some portions from coreboot src/mainboard/google/link/romstage.c + * and src/cpu/intel/model_206ax/bootblock.c * Copyright (C) 2007-2010 coresystems GmbH * Copyright (C) 2011 Google Inc. * @@ -16,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -178,6 +181,83 @@ int arch_cpu_init(void) return 0; } +static int enable_smbus(void) +{ + pci_dev_t dev; + uint16_t value; + + /* Set the SMBus device statically. */ + dev = PCI_BDF(0x0, 0x1f, 0x3); + + /* Check to make sure we've got the right device. */ + value = pci_read_config16(dev, 0x0); + if (value != 0x8086) { + printf("SMBus controller not found\n"); + return -ENOSYS; + } + + /* 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); + debug("SMBus controller enabled\n"); + + return 0; +} + +#define PCH_EHCI0_TEMP_BAR0 0xe800 +#define PCH_EHCI1_TEMP_BAR0 0xe8000400 +#define PCH_XHCI_TEMP_BAR0 0xe8001000 + +/* + * Setup USB controller MMIO BAR to prevent the reference code from + * resetting the controller. + * + * The BAR will be re-assigned during device enumeration so these are only + * temporary. + * + * This is used to speed up the resume path. + */ +static void enable_usb_bar(void) +{ + pci_dev_t usb0 = PCH_EHCI1_DEV; + pci_dev_t usb1 = PCH_EHCI2_DEV; + pci_dev_t usb3 = PCH_XHCI_DEV; + u32 cmd; + + /* USB Controller 1 */ + pci_write_config32(usb0, PCI_BASE_ADDRESS_0, + PCH_EHCI0_TEMP_BAR0); + cmd = pci_read_config32(usb0, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config32(usb0, PCI_COMMAND, cmd); + + /* USB Controller 1 */ + pci_write_config32(usb1, PCI_BASE_ADDRESS_0, + PCH_EHCI1_TEMP_BAR0); + cmd = pci_read_config32(usb1, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config32(usb1, PCI_COMMAND, cmd); + + /* USB3 Controller */ + pci_write_config32(usb3, PCI_BASE_ADDRESS_0, + PCH_XHCI_TEMP_BAR0); + cmd = pci_read_config32(usb3, PCI_COMMAND); + cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_write_config32(usb3, PCI_COMMAND, cmd); +} + static int report_bist_failure(void) { if (gd->arch.bist != 0) { @@ -190,8 +270,11 @@ static int report_bist_failure(void) int print_cpuinfo(void) { + enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE; char processor_name[CPU_MAX_NAME_LEN]; const char *name; + uint32_t pm1_cnt; + uint16_t pm1_sts; int ret; /* Halt if there was a built in self test failure */ @@ -203,9 +286,68 @@ int print_cpuinfo(void) if (ret && ret != -ENOENT && ret != -EEXIST) return ret; + /* Enable upper 128bytes of CMOS */ + writel(1 << 2, RCB_REG(RC)); + + /* TODO: cmos_post_init() */ + if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) { +