diff options
Diffstat (limited to 'src/soc/intel')
-rw-r--r-- | src/soc/intel/baytrail/acpi.c | 7 | ||||
-rw-r--r-- | src/soc/intel/baytrail/acpi/dptf/charger.asl | 43 | ||||
-rw-r--r-- | src/soc/intel/baytrail/acpi/dptf/cpu.asl | 5 | ||||
-rw-r--r-- | src/soc/intel/baytrail/acpi/dptf/dptf.asl | 5 | ||||
-rw-r--r-- | src/soc/intel/baytrail/acpi/lpe.asl | 2 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/gpio.h | 6 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/lpc.h | 4 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/mrc_wrapper.h | 3 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/msr.h | 7 | ||||
-rw-r--r-- | src/soc/intel/baytrail/baytrail/spi.h | 37 | ||||
-rw-r--r-- | src/soc/intel/baytrail/cpu.c | 30 | ||||
-rw-r--r-- | src/soc/intel/baytrail/mrc_cache.c | 13 | ||||
-rw-r--r-- | src/soc/intel/baytrail/nvm.c | 6 | ||||
-rw-r--r-- | src/soc/intel/baytrail/romstage/romstage.c | 37 | ||||
-rw-r--r-- | src/soc/intel/baytrail/southcluster.c | 52 | ||||
-rw-r--r-- | src/soc/intel/baytrail/spi.c | 2 |
16 files changed, 214 insertions, 45 deletions
diff --git a/src/soc/intel/baytrail/acpi.c b/src/soc/intel/baytrail/acpi.c index 1ab1eb3748..67e8c0ca89 100644 --- a/src/soc/intel/baytrail/acpi.c +++ b/src/soc/intel/baytrail/acpi.c @@ -73,7 +73,7 @@ static acpi_cstate_t cstate_map[] = { /* C6FS with full L2 shrink */ .ctype = 3, /* ACPI C3 */ .latency = 1500, /* 1.5ms worst case */ - .power = 10, + .power = 1, .resource = MWAIT_RES(5, 2), } }; @@ -353,8 +353,9 @@ static int generate_P_state_entries(int core, int cores_per_package) vid_max = pattrs->iacore_vids[IACORE_MAX]; vid_min = pattrs->iacore_vids[IACORE_LFM]; - /* Hardware coordination of P-states */ - coord_type = HW_ALL; + /* Set P-states coordination type based on MSR disable bit */ + msr = rdmsr(MSR_PMG_CST_CONFIG_CONTROL); + coord_type = (msr.lo & SINGLE_PCTL) ? SW_ALL : HW_ALL; /* Max Non-Turbo Frequency */ clock_max = (ratio_max * pattrs->bclk_khz) / 1000; diff --git a/src/soc/intel/baytrail/acpi/dptf/charger.asl b/src/soc/intel/baytrail/acpi/dptf/charger.asl index 7560f139be..7c7f62fb57 100644 --- a/src/soc/intel/baytrail/acpi/dptf/charger.asl +++ b/src/soc/intel/baytrail/acpi/dptf/charger.asl @@ -14,23 +14,46 @@ Device (TCHG) } } - Name (PPSS, Package () + /* Return charger performance states defined by mainboard */ + Method (PPSS) { - Package () { 0, 0, 0, 0, 0, 0x880, "mA", 0 }, /* 2.1A */ - Package () { 0, 0, 0, 0, 1, 0x800, "mA", 0 }, /* 2.0A */ - Package () { 0, 0, 0, 0, 2, 0x600, "mA", 0 }, /* 1.5A */ - Package () { 0, 0, 0, 0, 3, 0x400, "mA", 0 }, /* 1.0A */ - Package () { 0, 0, 0, 0, 4, 0x200, "mA", 0 }, /* 0.5A */ - Package () { 0, 0, 0, 0, 5, 0x000, "mA", 0 }, /* 0.0A */ - }) + Return (\_SB.CHPS) + } + /* Return maximum charger current limit */ Method (PPPC) { + /* Convert size of PPSS table to index */ + Store (SizeOf (\_SB.CHPS), Local0) + Decrement (Local0) + + /* Check if charging is disabled (AC removed) */ + If (LEqual (\PWRS, Zero)) { + /* Return last power state */ + Return (Local0) + } Else { + /* Return highest power state */ + Return (0) + } + Return (0) } - Method (SPPC, 1, Serialized) + /* Set charger current limit */ + Method (SPPC, 1) + { + /* Retrieve Control (index 4) for specified PPSS level */ + Store (DeRefOf (Index (DeRefOf (Index + (\_SB.CHPS, ToInteger (Arg0))), 4)), Local0) + + /* Pass Control value to EC to limit charging */ + \_SB.PCI0.LPCB.EC0.CHGS (Local0) + } + + /* Initialize charger participant */ + Method (INIT) { - /* TODO: Tell EC to limit battery charging */ + /* Disable charge limit */ + \_SB.PCI0.LPCB.EC0.CHGD () } } diff --git a/src/soc/intel/baytrail/acpi/dptf/cpu.asl b/src/soc/intel/baytrail/acpi/dptf/cpu.asl index 93d434b8b4..89f9b8b02a 100644 --- a/src/soc/intel/baytrail/acpi/dptf/cpu.asl +++ b/src/soc/intel/baytrail/acpi/dptf/cpu.asl @@ -115,7 +115,10 @@ Device (TCPU) Method (_PDL) { - If (CondRefOf (\_PR.CPU0._PSS)) { + /* Check for mainboard specific _PDL override */ + If (CondRefOf (\_SB.MPDL)) { + Return (\_SB.MPDL) + } ElseIf (CondRefOf (\_PR.CPU0._PSS)) { Store (SizeOf (\_PR.CPU0._PSS ()), Local0) Decrement (Local0) Return (Local0) diff --git a/src/soc/intel/baytrail/acpi/dptf/dptf.asl b/src/soc/intel/baytrail/acpi/dptf/dptf.asl index a54478cd05..9ebfb8c9ce 100644 --- a/src/soc/intel/baytrail/acpi/dptf/dptf.asl +++ b/src/soc/intel/baytrail/acpi/dptf/dptf.asl @@ -36,6 +36,11 @@ Device (DPTF) If (LEqual (DeRefOf (Index (IDSP, 0)), Arg0)) { /* Initialize Thermal Devices */ ^TINI () + +#ifdef DPTF_ENABLE_CHARGER + /* Initialize Charger Device */ + ^TCHG.INIT () +#endif } Return (Arg3) diff --git a/src/soc/intel/baytrail/acpi/lpe.asl b/src/soc/intel/baytrail/acpi/lpe.asl index 71a2746533..dfa555c834 100644 --- a/src/soc/intel/baytrail/acpi/lpe.asl +++ b/src/soc/intel/baytrail/acpi/lpe.asl @@ -74,7 +74,7 @@ Device (LPEA) /* Append any Mainboard defined GPIOs */ If (CondRefOf (^GBUF, Local0)) { - ConcatenateResTemplate (^RBUF, Local0, Local1) + ConcatenateResTemplate (^RBUF, ^GBUF, Local1) Return (Local1) } diff --git a/src/soc/intel/baytrail/baytrail/gpio.h b/src/soc/intel/baytrail/baytrail/gpio.h index 05fcf7dae1..a5ba6a3d24 100644 --- a/src/soc/intel/baytrail/baytrail/gpio.h +++ b/src/soc/intel/baytrail/baytrail/gpio.h @@ -378,4 +378,10 @@ static inline int ssus_get_gpio(int pad) return read32(val_addr) & PAD_VAL_HIGH; } +static inline void ssus_disable_internal_pull(int pad) +{ + const uint32_t pull_mask = ~(0xf << 7); + write32(ssus_pconf0(pad), read32(ssus_pconf0(pad)) & pull_mask); +} + #endif /* _BAYTRAIL_GPIO_H_ */ diff --git a/src/soc/intel/baytrail/baytrail/lpc.h b/src/soc/intel/baytrail/baytrail/lpc.h index 31de3105e2..2f6256cc41 100644 --- a/src/soc/intel/baytrail/baytrail/lpc.h +++ b/src/soc/intel/baytrail/baytrail/lpc.h @@ -47,4 +47,8 @@ enum baytrail_stepping { STEP_C0, }; +/* Registers behind the RCBA_BASE_ADDRESS bar. */ +#define GCS 0x00 +# define BILD (1 << 0) + #endif /* _BAYTRAIL_LPC_H_ */ diff --git a/src/soc/intel/baytrail/baytrail/mrc_wrapper.h b/src/soc/intel/baytrail/baytrail/mrc_wrapper.h index 893debc34f..fc18f0c823 100644 --- a/src/soc/intel/baytrail/baytrail/mrc_wrapper.h +++ b/src/soc/intel/baytrail/baytrail/mrc_wrapper.h @@ -28,7 +28,7 @@ #ifndef _MRC_WRAPPER_H_ #define _MRC_WRAPPER_H_ -#define MRC_PARAMS_VER 3 +#define MRC_PARAMS_VER 4 #define NUM_CHANNELS 2 @@ -60,6 +60,7 @@ enum mrc_wrapper_error { struct mrc_mainboard_params { int dram_type; int dram_info_location; /* DRAM_INFO_* */ + int weaker_odt_settings; /* Apply weaker on-die-termination settings. */ int spd_addrs[NUM_CHANNELS]; void *dram_data[NUM_CHANNELS]; /* SPD or Timing specific data. */ } __attribute__((packed)); diff --git a/src/soc/intel/baytrail/baytrail/msr.h b/src/soc/intel/baytrail/baytrail/msr.h index dd03af0d17..656d26aae7 100644 --- a/src/soc/intel/baytrail/baytrail/msr.h +++ b/src/soc/intel/baytrail/baytrail/msr.h @@ -24,12 +24,16 @@ #define MSR_BSEL_CR_OVERCLOCK_CONTROL 0xcd #define MSR_PLATFORM_INFO 0xce #define MSR_PMG_CST_CONFIG_CONTROL 0xe2 +#define SINGLE_PCTL (1 << 11) #define MSR_POWER_MISC 0x120 +#define ENABLE_ULFM_AUTOCM_MASK (1 << 2) +#define ENABLE_INDP_AUTOCM_MASK (1 << 3) #define MSR_IA32_PERF_CTL 0x199 #define MSR_IA32_MISC_ENABLES 0x1a0 #define MSR_POWER_CTL 0x1fc #define MSR_PKG_POWER_SKU_UNIT 0x606 #define MSR_PKG_POWER_LIMIT 0x610 +#define MSR_PP1_POWER_LIMIT 0x638 #define MSR_IACORE_RATIOS 0x66a #define MSR_IACORE_TURBO_RATIOS 0x66c #define MSR_IACORE_VIDS 0x66b @@ -37,6 +41,9 @@ #define MSR_PKG_TURBO_CFG1 0x670 #define MSR_CPU_TURBO_WKLD_CFG1 0x671 #define MSR_CPU_TURBO_WKLD_CFG2 0x672 +#define MSR_CPU_THERM_CFG1 0x673 +#define MSR_CPU_THERM_CFG2 0x674 +#define MSR_CPU_THERM_SENS_CFG 0x675 /* Read BCLK from MSR */ unsigned bus_freq_khz(void); diff --git a/src/soc/intel/baytrail/baytrail/spi.h b/src/soc/intel/baytrail/baytrail/spi.h index 2b7e26ef4d..9c0c29d53b 100644 --- a/src/soc/intel/baytrail/baytrail/spi.h +++ b/src/soc/intel/baytrail/baytrail/spi.h @@ -20,11 +20,48 @@ #ifndef _BAYTRAIL_SPI_H_ #define _BAYTRAIL_SPI_H_ +#include <stdint.h> + /* These registers live behind SPI_BASE_ADDRESS. */ +#define HSFSTS 0x04 +# define FLOCKDN (0x1 << 15) +#define PREOP 0x94 +#define OPTYPE 0x96 +#define OPMENU0 0x98 +#define OPMENU1 0x9c +#define LVSCC 0xc4 +# define VCL (0x1 << 23) +# define EO(x) (((x) & 0xff) << 8) +# define WG_1_BYTE (0x0 << 2) +# define WG_64_BYTE (0x1 << 2) +# define BES_256_BYTE (0x0 << 0) +# define BES_4_KB (0x1 << 0) +# define BES_8_KB (0x2 << 0) +# define BES_64_KB (0x3 << 0) +#define UVSCC 0xc8 +#define SCS 0xf8 +# define SMIWPEN (0x1 << 7) #define BCR 0xfc +# define EISS (0x1 << 5) # define SRC_MASK (0x3 << 2) # define SRC_CACHE_NO_PREFETCH (0x0 << 2) # define SRC_NO_CACHE_NO_PREFETCH (0x1 << 2) # define SRC_CACHE_PREFETCH (0x2 << 2) +# define BCR_LE (0x1 << 1) +# define BCR_WPD (0x1 << 0) + +/* + * SPI lockdown configuration. + */ +struct spi_config { + uint16_t preop; + uint16_t optype; + uint32_t opmenu[2]; + uint32_t lvscc; + uint32_t uvscc; +}; + +/* Return 0 on success < 0 on failure. */ +int mainboard_get_spi_config(struct spi_config *cfg); #endif /* _BAYTRAIL_SPI_H_ */ diff --git a/src/soc/intel/baytrail/cpu.c b/src/soc/intel/baytrail/cpu.c index 15efab9e62..1bbcb087dd 100644 --- a/src/soc/intel/baytrail/cpu.c +++ b/src/soc/intel/baytrail/cpu.c @@ -55,9 +55,13 @@ static int adjust_apic_id(int index, int apic_id) const struct reg_script package_msr_script[] = { /* Set Package TDP to ~7W */ REG_MSR_WRITE(MSR_PKG_POWER_LIMIT, 0x3880fa), + REG_MSR_RMW(MSR_PP1_POWER_LIMIT, ~(0x7f << 17), 0), REG_MSR_WRITE(MSR_PKG_TURBO_CFG1, 0x702), REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG1, 0x200b), REG_MSR_WRITE(MSR_CPU_TURBO_WKLD_CFG2, 0), + REG_MSR_WRITE(MSR_CPU_THERM_CFG1, 0x00000305), + REG_MSR_WRITE(MSR_CPU_THERM_CFG2, 0x0405500d), + REG_MSR_WRITE(MSR_CPU_THERM_SENS_CFG, 0x27), REG_SCRIPT_END }; @@ -71,6 +75,29 @@ const struct reg_script core_msr_script[] = { REG_SCRIPT_END }; +/* Enable hardware coordination for 2-core, disable for 4-core */ +static void baytrail_set_pstate_coord(void) +{ + const struct pattrs *pattrs = pattrs_get(); + msr_t pmg_cst = rdmsr(MSR_PMG_CST_CONFIG_CONTROL); + msr_t power_misc = rdmsr(MSR_POWER_MISC); + + if (pattrs->num_cpus > 2) { + /* Disable hardware coordination */ + pmg_cst.lo |= SINGLE_PCTL; + power_misc.lo &= ~(ENABLE_ULFM_AUTOCM_MASK | + ENABLE_INDP_AUTOCM_MASK); + } else { + /* Enable hardware coordination */ + pmg_cst.lo &= ~SINGLE_PCTL; + power_misc.lo |= (ENABLE_ULFM_AUTOCM_MASK | + ENABLE_INDP_AUTOCM_MASK); + } + + wrmsr(MSR_PMG_CST_CONFIG_CONTROL, pmg_cst); + wrmsr(MSR_POWER_MISC, power_misc); +} + void baytrail_init_cpus(device_t dev) { struct bus *cpu_bus = dev->link_list; @@ -114,6 +141,9 @@ static void baytrail_core_init(device_t cpu) /* Set core MSRs */ reg_script_run(core_msr_script); + /* Set P-State coordination */ + baytrail_set_pstate_coord(); + /* Set this core to max frequency ratio */ set_max_freq(); } diff --git a/src/soc/intel/baytrail/mrc_cache.c b/src/soc/intel/baytrail/mrc_cache.c index ae0afe7f7f..f12f3ef0ea 100644 --- a/src/soc/intel/baytrail/mrc_cache.c +++ b/src/soc/intel/baytrail/mrc_cache.c @@ -174,8 +174,8 @@ int mrc_cache_stash_data(void *data, size_t size) return -1; } - /* Clear alignment padding bytes. */ - memset(&cache->data[size], 0, cbmem_size - size); + /* Clear alignment padding bytes at end of data. */ + memset(&cache->data[size], 0, cbmem_size - size - sizeof(*cache)); printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%zu bytes)\n", data, cache, size); @@ -206,7 +206,7 @@ static int mrc_slot_valid(const struct mrc_data_region *region, size = to_save->size + sizeof(*to_save); slot_end = slot_begin + size; - if (slot_begin < region_begin || slot_begin > region_end) + if (slot_begin < region_begin || slot_begin >= region_end) return 0; if (size > region->size) @@ -285,8 +285,11 @@ static void update_mrc_cache(void *unused) next_slot = region.base; } - nvm_write((void *)next_slot, current_boot, - current_boot->size + sizeof(*current_boot)); + if (nvm_write((void *)next_slot, current_boot, + current_boot->size + sizeof(*current_boot))) { + printk(BIOS_DEBUG, "Failure writing MRC cache to %p.\n", + next_slot); + } } BOOT_STATE_INIT_ENTRIES(mrc_cache_update) = { diff --git a/src/soc/intel/baytrail/nvm.c b/src/soc/intel/baytrail/nvm.c index 0cc64f59f3..0cd42ccd52 100644 --- a/src/soc/intel/baytrail/nvm.c +++ b/src/soc/intel/baytrail/nvm.c @@ -70,8 +70,7 @@ int nvm_erase(void *start, size_t size) { if (nvm_init() < 0) return -1; - flash->erase(flash, to_flash_offset(start), size); - return 0; + return flash->erase(flash, to_flash_offset(start), size); } /* Write data to NVM. Returns 0 on success < 0 on error. */ @@ -79,6 +78,5 @@ int nvm_write(void *start, const void *data, size_t size) { if (nvm_init() < 0) return -1; - flash->write(flash, to_flash_offset(start), size, data); - return 0; + return flash->write(flash, to_flash_offset(start), size, data); } diff --git a/src/soc/intel/baytrail/romstage/romstage.c b/src/soc/intel/baytrail/romstage/romstage.c index 3a1d65d8ab..1c08f339fd 100644 --- a/src/soc/intel/baytrail/romstage/romstage.c +++ b/src/soc/intel/baytrail/romstage/romstage.c @@ -98,9 +98,19 @@ static void program_base_addresses(void) static void spi_init(void) { + const unsigned long scs = SPI_BASE_ADDRESS + SCS; const unsigned long bcr = SPI_BASE_ADDRESS + BCR; - /* Enable caching and prefetching in the SPI controller. */ - write32(bcr, (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH); + uint32_t reg; + + /* Disable generating SMI when setting WPD bit. */ + write32(scs, read32(scs) & ~SMIWPEN); + /* + * Enable caching and prefetching in the SPI controller. Disable + * the SMM-only BIOS write and set WPD bit. + */ + reg = (read32(bcr) & ~SRC_MASK) | SRC_CACHE_PREFETCH | BCR_WPD; + reg &= ~EISS; + write32(bcr, reg); } static inline void mark_ts(struct romstage_params *rp, uint64_t ts) @@ -239,15 +249,17 @@ void romstage_common(struct romstage_params *params) mark_ts(params, timestamp_get()); -#if CONFIG_ELOG_BOOT_COUNT - boot_count_increment(); -#endif - ps = fill_power_state(); prev_sleep_state = chipset_prev_sleep_state(ps); printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state); +#if CONFIG_ELOG_BOOT_COUNT + if (prev_sleep_state != 3) + boot_count_increment(); +#endif + + /* Initialize RAM */ raminit(params->mrc_params, prev_sleep_state); @@ -268,21 +280,8 @@ void romstage_common(struct romstage_params *params) timestamp_add(TS_AFTER_INITRAM, ts64_to_tsc(params->ts.times[3])); } -static void open_up_spi(void) -{ - const uintptr_t sbase = SPI_BASE_ADDRESS; - - /* Disable generating SMI when setting WPD bit. */ - write32(sbase + 0xf8, read32(sbase + 0xf8) & ~(1 << 7)); - /* Disable the SMM-only BIOS write and set WPD bit. */ - write32(sbase + 0xfc, 1 | (read32(sbase + 0xfc) & ~(1 << 5))); -} - void asmlinkage romstage_after_car(void) { - /* Allow BIOS to program SPI part. */ - open_up_spi(); - timestamp_add_now(TS_END_ROMSTAGE); /* Load the ramstage. */ diff --git a/src/soc/intel/baytrail/southcluster.c b/src/soc/intel/baytrail/southcluster.c index bcce792659..49e4c91a13 100644 --- a/src/soc/intel/baytrail/southcluster.c +++ b/src/soc/intel/baytrail/southcluster.c @@ -20,8 +20,10 @@ #include <stdint.h> #include <arch/io.h> +#include <bootstate.h> #include <cbmem.h> #include <console/console.h> +#include <cpu/x86/smm.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> @@ -35,6 +37,7 @@ #include <baytrail/pci_devs.h> #include <baytrail/pmc.h> #include <baytrail/ramstage.h> +#include <baytrail/spi.h> #include "chip.h" static inline void @@ -482,3 +485,52 @@ static const struct pci_driver southcluster __pci_driver = { .vendor = PCI_VENDOR_ID_INTEL, .device = LPC_DEVID, }; + +int __attribute__((weak)) mainboard_get_spi_config(struct spi_config *cfg) +{ + return -1; +} + +static void finalize_chipset(void *unused) +{ + const unsigned long bcr = SPI_BASE_ADDRESS + BCR; + const unsigned long gcs = RCBA_BASE_ADDRESS + GCS; + const unsigned long gen_pmcon2 = PMC_BASE_ADDRESS + GEN_PMCON2; + const unsigned long etr = PMC_BASE_ADDRESS + ETR; + const unsigned long spi = SPI_BASE_ADDRESS; + struct spi_config cfg; + + /* Set the lock enable on the BIOS control register. */ + write32(bcr, read32(bcr) | BCR_LE); + + /* Set BIOS lock down bit controlling boot block size and swapping. */ + write32(gcs, read32(gcs) | BILD); + + /* Lock sleep stretching policy and set SMI lock. */ + write32(gen_pmcon2, read32(gen_pmcon2) | SLPSX_STR_POL_LOCK | SMI_LOCK); + + /* Set the CF9 lock. */ + write32(etr, read32(etr) | CF9LOCK); + + if (mainboard_get_spi_config(&cfg) < 0) { + printk(BIOS_DEBUG, "No SPI lockdown configuration.\n"); + } else { + write16(spi + PREOP, cfg.preop); + write16(spi + OPTYPE, cfg.optype); + write32(spi + OPMENU0, cfg.opmenu[0]); + write32(spi + OPMENU1, cfg.opmenu[1]); + write16(spi + HSFSTS, read16(spi + HSFSTS) | FLOCKDN); + write32(spi + UVSCC, cfg.uvscc); + write32(spi + LVSCC, cfg.lvscc | VCL); + } + + printk(BIOS_DEBUG, "Finalizing SMM.\n"); + outb(APM_CNT_FINALIZE, APM_CNT); +} + +BOOT_STATE_INIT_ENTRIES(finalize_bscb) = { + BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, + finalize_chipset, NULL), + BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, + finalize_chipset, NULL), +}; diff --git a/src/soc/intel/baytrail/spi.c b/src/soc/intel/baytrail/spi.c index 0dc980f8af..8677b61057 100644 --- a/src/soc/intel/baytrail/spi.c +++ b/src/soc/intel/baytrail/spi.c @@ -481,7 +481,7 @@ static int spi_setup_offset(spi_transaction *trans) */ static int ich_status_poll(u16 bitmask, int wait_til_set) { - int timeout = 6000; /* This will result in 60 ms */ + int timeout = 40000; /* This will result in 400 ms */ u16 status = 0; while (timeout--) { |