Re: [U-Boot] [PATCH 34/39] x86: ivybridge: Add early init for PCH devices

2014-11-11 Thread Simon Glass
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

2014-11-11 Thread Bin Meng
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

2014-11-11 Thread Simon Glass
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

2014-11-11 Thread Bin Meng
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

2014-11-06 Thread Simon Glass
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) {
+