[U-Boot] [PATCH 09/13] x86: Add Intel Braswell SoC support

Bin Meng bmeng.cn at gmail.com
Sat Aug 26 13:55:04 UTC 2017


Hi Simon,

On Sat, Aug 26, 2017 at 9:39 PM, Simon Glass <sjg at chromium.org> wrote:
> On 15 August 2017 at 23:41, Bin Meng <bmeng.cn at gmail.com> wrote:
>> This adds initial Intel Braswell SoC support. It uses Intel FSP
>> to initialize the chipset.
>>
>> Similar to its predecessor BayTrail, there are some work to do to
>> enable the legacy UART integrated in the Braswell SoC.
>>
>> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
>> ---
>>
>>  arch/x86/Kconfig                           |   1 +
>>  arch/x86/cpu/Makefile                      |   1 +
>>  arch/x86/cpu/braswell/Kconfig              |  38 +++++++
>>  arch/x86/cpu/braswell/Makefile             |   7 ++
>>  arch/x86/cpu/braswell/braswell.c           |  36 ++++++
>>  arch/x86/cpu/braswell/cpu.c                | 170 +++++++++++++++++++++++++++++
>>  arch/x86/cpu/braswell/early_uart.c         |  86 +++++++++++++++
>>  arch/x86/include/asm/arch-braswell/iomap.h |  50 +++++++++
>>  8 files changed, 389 insertions(+)
>>  create mode 100644 arch/x86/cpu/braswell/Kconfig
>>  create mode 100644 arch/x86/cpu/braswell/Makefile
>>  create mode 100644 arch/x86/cpu/braswell/braswell.c
>>  create mode 100644 arch/x86/cpu/braswell/cpu.c
>>  create mode 100644 arch/x86/cpu/braswell/early_uart.c
>>  create mode 100644 arch/x86/include/asm/arch-braswell/iomap.h
>
> Reviewed-by: Simon Glass <sjg at chromium.org>
>
> A few nits / suggestions below.
>
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index f72d307..9620764 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -108,6 +108,7 @@ source "board/intel/Kconfig"
>>
>>  # platform-specific options below
>>  source "arch/x86/cpu/baytrail/Kconfig"
>> +source "arch/x86/cpu/braswell/Kconfig"
>>  source "arch/x86/cpu/broadwell/Kconfig"
>>  source "arch/x86/cpu/coreboot/Kconfig"
>>  source "arch/x86/cpu/ivybridge/Kconfig"
>> diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile
>> index 999429e..94cdff1 100644
>> --- a/arch/x86/cpu/Makefile
>> +++ b/arch/x86/cpu/Makefile
>> @@ -27,6 +27,7 @@ endif
>>
>>  obj-y += intel_common/
>>  obj-$(CONFIG_INTEL_BAYTRAIL) += baytrail/
>> +obj-$(CONFIG_INTEL_BRASWELL) += braswell/
>>  obj-$(CONFIG_INTEL_BROADWELL) += broadwell/
>>  obj-$(CONFIG_SYS_COREBOOT) += coreboot/
>>  obj-$(CONFIG_EFI_APP) += efi/
>> diff --git a/arch/x86/cpu/braswell/Kconfig b/arch/x86/cpu/braswell/Kconfig
>> new file mode 100644
>> index 0000000..c993889
>> --- /dev/null
>> +++ b/arch/x86/cpu/braswell/Kconfig
>> @@ -0,0 +1,38 @@
>> +#
>> +# Copyright (C) 2017, Bin Meng <bmeng.cn at gmail.com>
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +config INTEL_BRASWELL
>> +       bool
>> +       select HAVE_FSP
>> +       select ARCH_MISC_INIT
>> +       imply HAVE_INTEL_ME
>> +       imply HAVE_VBT
>> +       imply ENABLE_MRC_CACHE
>> +       imply ENV_IS_IN_SPI_FLASH
>> +       imply AHCI_PCI
>> +       imply ICH_SPI
>> +       imply MMC
>> +       imply MMC_PCI
>> +       imply MMC_SDHCI
>> +       imply MMC_SDHCI_SDMA
>> +       imply SCSI
>> +       imply SPI_FLASH
>> +       imply SYS_NS16550
>> +       imply USB
>> +       imply USB_XHCI_HCD
>> +       imply VIDEO_FSP
>> +
>> +if INTEL_BRASWELL
>> +
>> +config FSP_ADDR
>> +       hex
>> +       default 0xfff20000
>> +
>> +config FSP_LOCKDOWN_SPI
>> +       bool
>> +       default y
>> +
>> +endif
>> diff --git a/arch/x86/cpu/braswell/Makefile b/arch/x86/cpu/braswell/Makefile
>> new file mode 100644
>> index 0000000..19bcee6
>> --- /dev/null
>> +++ b/arch/x86/cpu/braswell/Makefile
>> @@ -0,0 +1,7 @@
>> +#
>> +# Copyright (C) 2017, Bin Meng <bmeng.cn at gmail.com>
>> +#
>> +# SPDX-License-Identifier:     GPL-2.0+
>> +#
>> +
>> +obj-y += braswell.o cpu.o early_uart.o
>> diff --git a/arch/x86/cpu/braswell/braswell.c b/arch/x86/cpu/braswell/braswell.c
>> new file mode 100644
>> index 0000000..37099aa
>> --- /dev/null
>> +++ b/arch/x86/cpu/braswell/braswell.c
>> @@ -0,0 +1,36 @@
>> +/*
>> + * Copyright (C) 2017, Bin Meng <bmeng.cn at gmail.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/mrccache.h>
>> +#include <asm/post.h>
>> +
>> +int arch_cpu_init(void)
>> +{
>> +       post_code(POST_CPU_INIT);
>> +
>> +       return x86_cpu_init_f();
>> +}
>> +
>> +int arch_misc_init(void)
>> +{
>> +#ifdef CONFIG_ENABLE_MRC_CACHE
>> +       /*
>> +        * We intend not to check any return value here, as even MRC cache
>> +        * is not saved successfully, it is not a severe error that will
>> +        * prevent system from continuing to boot.
>> +        */
>> +       mrccache_save();
>> +#endif
>> +
>> +       return 0;
>> +}
>> +
>> +void reset_cpu(ulong addr)
>> +{
>> +       /* cold reset */
>> +       x86_full_reset();
>> +}
>> diff --git a/arch/x86/cpu/braswell/cpu.c b/arch/x86/cpu/braswell/cpu.c
>> new file mode 100644
>> index 0000000..6ff9036
>> --- /dev/null
>> +++ b/arch/x86/cpu/braswell/cpu.c
>> @@ -0,0 +1,170 @@
>> +/*
>> + * Copyright (C) 2017, Bin Meng <bmeng.cn at gmail.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + *
>> + * Derived from arch/x86/cpu/baytrail/cpu.c
>> + */
>> +
>> +#include <common.h>
>> +#include <cpu.h>
>> +#include <dm.h>
>> +#include <asm/cpu.h>
>> +#include <asm/cpu_x86.h>
>> +#include <asm/io.h>
>> +#include <asm/lapic.h>
>> +#include <asm/msr.h>
>> +#include <asm/turbo.h>
>> +
>> +static const unsigned int braswell_bus_freq_table[] = {
>> +       83333333,
>> +       100000000,
>> +       133333333,
>> +       116666666,
>> +       80000000,
>> +       93333333,
>> +       90000000,
>> +       88900000,
>> +       87500000
>> +};
>> +
>> +static unsigned int braswell_bus_freq(void)
>> +{
>> +       msr_t clk_info = msr_read(MSR_BSEL_CR_OVERCLOCK_CONTROL);
>> +
>> +       if ((clk_info.lo & 0xf) < (ARRAY_SIZE(braswell_bus_freq_table)))
>> +               return braswell_bus_freq_table[clk_info.lo & 0xf];
>> +
>> +       return 0;
>> +}
>> +
>> +static unsigned long braswell_tsc_freq(void)
>> +{
>> +       msr_t platform_info;
>> +       ulong bclk = braswell_bus_freq();
>> +
>> +       if (!bclk)
>> +               return 0;
>> +
>> +       platform_info = msr_read(MSR_PLATFORM_INFO);
>> +
>> +       return bclk * ((platform_info.lo >> 8) & 0xff);
>> +}
>> +
>> +static int braswell_get_info(struct udevice *dev, struct cpu_info *info)
>> +{
>> +       info->cpu_freq = braswell_tsc_freq();
>> +       info->features = (1 << CPU_FEAT_L1_CACHE) | (1 << CPU_FEAT_MMU);
>> +
>> +       return 0;
>> +}
>> +
>> +static int braswell_get_count(struct udevice *dev)
>> +{
>> +       int ecx = 0;
>> +
>> +       /*
>> +        * Use the algorithm described in Intel 64 and IA-32 Architectures
>> +        * Software Developer's Manual Volume 3 (3A, 3B & 3C): System
>> +        * Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping
>> +        * of CPUID Extended Topology Leaf.
>> +        */
>> +       while (1) {
>> +               struct cpuid_result leaf_b;
>> +
>> +               leaf_b = cpuid_ext(0xb, ecx);
>> +
>> +               /*
>> +                * Braswell doesn't have hyperthreading so just determine the
>> +                * number of cores by from level type (ecx[15:8] == * 2)
>> +                */
>> +               if ((leaf_b.ecx & 0xff00) == 0x0200)
>> +                       return leaf_b.ebx & 0xffff;
>> +
>> +               ecx++;
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>> +static void braswell_set_max_freq(void)
>> +{
>> +       msr_t perf_ctl;
>> +       msr_t msr;
>> +
>> +       /* Enable speed step */
>> +       msr = msr_read(MSR_IA32_MISC_ENABLES);
>> +       msr.lo |= (1 << 16);
>> +       msr_write(MSR_IA32_MISC_ENABLES, msr);
>> +
>> +       /* Enable Burst Mode */
>> +       msr = msr_read(MSR_IA32_MISC_ENABLES);
>> +       msr.hi = 0;
>> +       msr_write(MSR_IA32_MISC_ENABLES, msr);
>> +
>> +       /*
>> +        * Set guaranteed ratio [21:16] from IACORE_TURBO_RATIOS to
>> +        * bits [15:8] of the PERF_CTL
>> +        */
>> +       msr = msr_read(MSR_IACORE_TURBO_RATIOS);
>> +       perf_ctl.lo = (msr.lo & 0x3f0000) >> 8;
>> +
>> +       /*
>> +        * Set guaranteed vid [22:16] from IACORE_TURBO_VIDS to
>> +        * bits [7:0] of the PERF_CTL
>> +        */
>> +       msr = msr_read(MSR_IACORE_TURBO_VIDS);
>> +       perf_ctl.lo |= (msr.lo & 0x7f0000) >> 16;
>> +
>> +       perf_ctl.hi = 0;
>> +       msr_write(MSR_IA32_PERF_CTL, perf_ctl);
>> +}
>> +
>> +static int braswell_probe(struct udevice *dev)
>> +{
>> +       debug("Init Braswell core\n");
>> +
>> +       /*
>> +        * On Braswell the turbo disable bit is actually scoped at the
>> +        * building-block level, not package. For non-BSP cores that are
>> +        * within a building block, enable turbo. The cores within the BSP's
>> +        * building block will just see it already enabled and move on.
>> +        */
>> +       if (lapicid())
>> +               turbo_enable();
>> +
>> +       /* Dynamic L2 shrink enable and threshold, clear SINGLE_PCTL bit 11 */
>> +       msr_clrsetbits_64(MSR_PMG_CST_CONFIG_CONTROL, 0x3f080f, 0xe0008),
>> +       msr_clrsetbits_64(MSR_POWER_MISC,
>> +                         ENABLE_ULFM_AUTOCM_MASK | ENABLE_INDP_AUTOCM_MASK, 0);
>> +
>> +       /* Disable C1E */
>> +       msr_clrsetbits_64(MSR_POWER_CTL, 2, 0);
>> +       msr_setbits_64(MSR_POWER_MISC, 0x44);
>> +
>> +       /* Set this core to max frequency ratio */
>> +       braswell_set_max_freq();
>> +
>> +       return 0;
>> +}
>> +
>> +static const struct udevice_id braswell_ids[] = {
>> +       { .compatible = "intel,braswell-cpu" },
>> +       { }
>> +};
>> +
>> +static const struct cpu_ops braswell_ops = {
>> +       .get_desc       = cpu_x86_get_desc,
>> +       .get_info       = braswell_get_info,
>> +       .get_count      = braswell_get_count,
>> +       .get_vendor     = cpu_x86_get_vendor,
>> +};
>> +
>> +U_BOOT_DRIVER(cpu_x86_braswell_drv) = {
>> +       .name           = "cpu_x86_braswell",
>> +       .id             = UCLASS_CPU,
>> +       .of_match       = braswell_ids,
>> +       .bind           = cpu_x86_bind,
>> +       .probe          = braswell_probe,
>> +       .ops            = &braswell_ops,
>> +};
>> diff --git a/arch/x86/cpu/braswell/early_uart.c b/arch/x86/cpu/braswell/early_uart.c
>> new file mode 100644
>> index 0000000..0300e13
>> --- /dev/null
>> +++ b/arch/x86/cpu/braswell/early_uart.c
>> @@ -0,0 +1,86 @@
>> +/*
>> + * Copyright (C) 2017, Bin Meng <bmeng.cn at gmail.com>
>> + *
>> + * SPDX-License-Identifier:    GPL-2.0+
>> + */
>> +
>> +#include <common.h>
>> +#include <asm/io.h>
>> +
>> +#define PCI_DEV_CONFIG(segbus, dev, fn) ( \
>> +               (((segbus) & 0xfff) << 20) | \
>> +               (((dev) & 0x1f) << 15) | \
>> +               (((fn)  & 0x07) << 12))
>
> This seems to be shared by baytrail? Do you think it should go in a header file?
>

Yes, I think so.

>> +
>> +/* Platform Controller Unit */
>> +#define LPC_DEV                        0x1f
>> +#define LPC_FUNC               0
>> +
>> +/* Enable UART */
>> +#define UART_CONT              0x80
>> +
>> +/* UART PAD definitions */
>> +#define UART_RXD_COMMUITY      1
>> +#define UART_TXD_COMMUITY      1
>> +#define UART_RXD_FAMILY                4
>> +#define UART_TXD_FAMILY                4
>> +#define UART_RXD_PAD           2
>> +#define UART_TXD_PAD           7
>> +#define UART_RXD_FUNC          3
>> +#define UART_TXD_FUNC          3
>> +
>> +/* IO Memory */
>> +#define IO_BASE_ADDRESS                0xfed80000
>> +
>> +static inline uint32_t gpio_pconf0(int community, int family, int pad)
>> +{
>> +       return IO_BASE_ADDRESS + community * 0x8000 + 0x4400 +
>> +               family * 0x400 + pad * 8;
>> +}
>> +
>> +static void gpio_select_func(int community, int family, int pad, int func)
>> +{
>> +       uint32_t reg;
>> +       uint32_t pconf0_addr = gpio_pconf0(community, family, pad);
>> +
>> +       reg = readl(pconf0_addr);
>> +       reg &= ~(0xf << 16);
>> +       reg |= (func << 16);
>> +       writel(reg, pconf0_addr);
>
> Can we use setclrbits_le32()?

Will do in v2.

>
>> +}
>> +
>> +static void x86_pci_write_config32(int dev, unsigned int where, u32 value)
>> +{
>> +       unsigned long addr;
>> +
>> +       addr = CONFIG_PCIE_ECAM_BASE | dev | (where & ~3);
>> +       writel(value, addr);
>> +}
>> +

Regards,
Bin


More information about the U-Boot mailing list