diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-04-20 15:20:28 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-06-25 21:50:48 +0200 |
commit | 32471729d9ebbabe809711ec55568925c6ce2070 (patch) | |
tree | b9f6db4e4969ee5edd6c2571e4f7612121070a9f /src/soc/intel/braswell/acpi.c | |
parent | 5fe62efb77a2ecfeecdcc526404712b816e74693 (diff) |
Braswell: Add Braswell SOC support
Add the files to support the Braswell SOC.
BRANCH=none
BUG=None
TEST=Build for a Braswell platform
Change-Id: I968da68733e57647d0a08e4040ff0378b4d59004
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10051
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/braswell/acpi.c')
-rw-r--r-- | src/soc/intel/braswell/acpi.c | 204 |
1 files changed, 136 insertions, 68 deletions
diff --git a/src/soc/intel/braswell/acpi.c b/src/soc/intel/braswell/acpi.c index 8357705ee4..e008f07513 100644 --- a/src/soc/intel/braswell/acpi.c +++ b/src/soc/intel/braswell/acpi.c @@ -3,6 +3,7 @@ * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. * * 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 @@ -20,27 +21,30 @@ #include <arch/acpi.h> #include <arch/acpigen.h> +#include <arch/cpu.h> #include <arch/io.h> #include <arch/smp/mpspec.h> +#include <cbfs.h> #include <cbmem.h> #include <console/console.h> -#include <cpu/x86/smm.h> -#include <console/console.h> -#include <types.h> -#include <string.h> -#include <arch/cpu.h> +#include <cpu/intel/turbo.h> #include <cpu/x86/msr.h> +#include <cpu/x86/smm.h> #include <cpu/x86/tsc.h> -#include <cpu/intel/turbo.h> - +#include <device/pci.h> +#include <device/pci_ids.h> +#include <ec/google/chromeec/ec.h> +#include <fsp_gop.h> #include <soc/acpi.h> +#include <soc/gfx.h> #include <soc/iomap.h> #include <soc/irq.h> #include <soc/msr.h> #include <soc/pattrs.h> -#include <soc/pmc.h> - -#include <ec/google/chromeec/ec.h> +#include <soc/pci_devs.h> +#include <soc/pm.h> +#include <string.h> +#include <types.h> #include <vendorcode/google/chromeos/gnvs.h> #define MWAIT_RES(state, sub_state) \ @@ -89,15 +93,15 @@ void acpi_init_gnvs(global_nvs_t *gnvs) /* Top of Low Memory (start of resource allocation) */ gnvs->tolm = nc_read_top_of_low_memory(); -#if CONFIG_CONSOLE_CBMEM +#if IS_ENABLED(CONFIG_CONSOLE_CBMEM) /* Update the mem console pointer. */ gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE); #endif -#if CONFIG_CHROMEOS +#if IS_ENABLED(CONFIG_CHROMEOS) /* Initialize Verified Boot data */ chromeos_init_vboot(&(gnvs->chromeos)); -#if CONFIG_EC_GOOGLE_CHROMEEC +#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) gnvs->chromeos.vbt2 = google_ec_running_ro() ? ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; #endif @@ -137,7 +141,7 @@ static int acpi_sci_irq(void) return sci_irq; } -void acpi_create_intel_hpet(acpi_hpet_t * hpet) +void acpi_create_intel_hpet(acpi_hpet_t *hpet) { acpi_header_t *header = &(hpet->header); acpi_addr_t *addr = &(hpet->addr); @@ -284,7 +288,7 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } -static acpi_tstate_t baytrail_tss_table[] = { +static acpi_tstate_t soc_tss_table[] = { { 100, 1000, 0, 0x00, 0 }, { 88, 875, 0, 0x1e, 0 }, { 75, 750, 0, 0x1c, 0 }, @@ -295,24 +299,20 @@ static acpi_tstate_t baytrail_tss_table[] = { { 13, 125, 0, 0x12, 0 }, }; -static int generate_T_state_entries(int core, int cores_per_package) +static void generate_T_state_entries(int core, int cores_per_package) { - int len; - /* Indicate SW_ALL coordination for T-states */ - len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL); + acpigen_write_TSD_package(core, cores_per_package, SW_ALL); /* Indicate FFixedHW so OS will use MSR */ - len += acpigen_write_empty_PTC(); + acpigen_write_empty_PTC(); /* Set NVS controlled T-state limit */ - len += acpigen_write_TPC("\\TLVL"); + acpigen_write_TPC("\\TLVL"); /* Write TSS table for MSR access */ - len += acpigen_write_TSS_package( - ARRAY_SIZE(baytrail_tss_table), baytrail_tss_table); - - return len; + acpigen_write_TSS_package( + ARRAY_SIZE(soc_tss_table), soc_tss_table); } static int calculate_power(int tdp, int p1_ratio, int ratio) @@ -336,9 +336,8 @@ static int calculate_power(int tdp, int p1_ratio, int ratio) return (int)power; } -static int generate_P_state_entries(int core, int cores_per_package) +static void generate_P_state_entries(int core, int cores_per_package) { - int len, len_pss; int ratio_min, ratio_max, ratio_turbo, ratio_step, ratio_range_2; int coord_type, power_max, power_unit, num_entries; int ratio, power, clock, clock_max; @@ -366,16 +365,16 @@ static int generate_P_state_entries(int core, int cores_per_package) power_max = ((msr.lo & 0x7fff) / power_unit) * 1000; /* Write _PCT indicating use of FFixedHW */ - len = acpigen_write_empty_PCT(); + acpigen_write_empty_PCT(); /* Write _PPC with NVS specified limit on supported P-state */ - len += acpigen_write_PPC_NVS(); + acpigen_write_PPC_NVS(); /* Write PSD indicating configured coordination type */ - len += acpigen_write_PSD_package(core, 1, coord_type); + acpigen_write_PSD_package(core, 1, coord_type); /* Add P-state entries in _PSS table */ - len += acpigen_write_name("_PSS"); + acpigen_write_name("_PSS"); /* Determine ratio points */ ratio_step = 1; @@ -388,36 +387,36 @@ static int generate_P_state_entries(int core, int cores_per_package) /* P[T] is Turbo state if enabled */ if (get_turbo_state() == TURBO_ENABLED) { /* _PSS package count including Turbo */ - len_pss = acpigen_write_package(num_entries + 2); + acpigen_write_package(num_entries + 2); ratio_turbo = pattrs->iacore_ratios[IACORE_TURBO]; vid_turbo = pattrs->iacore_vids[IACORE_TURBO]; control_status = (ratio_turbo << 8) | vid_turbo; /* Add entry for Turbo ratio */ - len_pss += acpigen_write_PSS_package( - clock_max + 1, /*MHz*/ - power_max, /*mW*/ - 10, /*lat1*/ - 10, /*lat2*/ - control_status, /*control*/ - control_status); /*status*/ + acpigen_write_PSS_package( + clock_max + 1, /* MHz */ + power_max, /* mW */ + 10, /* lat1 */ + 10, /* lat2 */ + control_status, /* control */ + control_status); /* status */ } else { /* _PSS package count without Turbo */ - len_pss = acpigen_write_package(num_entries + 1); + acpigen_write_package(num_entries + 1); ratio_turbo = ratio_max; vid_turbo = vid_max; } /* First regular entry is max non-turbo ratio */ control_status = (ratio_max << 8) | vid_max; - len_pss += acpigen_write_PSS_package( - clock_max, /*MHz*/ - power_max, /*mW*/ - 10, /*lat1*/ - 10, /*lat2*/ - control_status, /*control */ - control_status); /*status*/ + acpigen_write_PSS_package( + clock_max, /* MHz */ + power_max, /* mW */ + 10, /* lat1 */ + 10, /* lat2 */ + control_status, /* control */ + control_status); /* status */ /* Set up ratio and vid ranges for VID calculation */ ratio_range_2 = (ratio_turbo - ratio_min) * 2; @@ -439,52 +438,48 @@ static int generate_P_state_entries(int core, int cores_per_package) clock = (ratio * pattrs->bclk_khz) / 1000; control_status = (ratio << 8) | (vid & 0xff); - len_pss += acpigen_write_PSS_package( - clock, /*MHz*/ - power, /*mW*/ - 10, /*lat1*/ - 10, /*lat2*/ - control_status, /*control*/ - control_status); /*status*/ + acpigen_write_PSS_package( + clock, /* MHz */ + power, /* mW */ + 10, /* lat1 */ + 10, /* lat2 */ + control_status, /* control */ + control_status); /* status */ } /* Fix package length */ - len_pss--; - acpigen_patch_len(len_pss); - - return len + len_pss; + acpigen_pop_len(); } -void generate_cpu_entries(void) +void generate_cpu_entries(device_t device) { - int len_pr, core; + int core; int pcontrol_blk = get_pmbase(), plen = 6; const struct pattrs *pattrs = pattrs_get(); - for (core=0; core<pattrs->num_cpus; core++) { + for (core = 0; core < pattrs->num_cpus; core++) { if (core > 0) { pcontrol_blk = 0; plen = 0; } /* Generate processor \_PR.CPUx */ - len_pr = acpigen_write_processor( + acpigen_write_processor( core, pcontrol_blk, plen); /* Generate P-state tables */ - len_pr += generate_P_state_entries( + generate_P_state_entries( core, pattrs->num_cpus); /* Generate C-state tables */ - len_pr += acpigen_write_CST_package( + acpigen_write_CST_package( cstate_map, ARRAY_SIZE(cstate_map)); /* Generate T-state tables */ - len_pr += generate_T_state_entries( + generate_T_state_entries( core, pattrs->num_cpus); - len_pr--; - acpigen_patch_len(len_pr); + acpigen_pop_len(); } } @@ -505,7 +500,80 @@ unsigned long acpi_madt_irq_overrides(unsigned long current) irqovr = (void *)current; current += acpi_create_madt_irqoverride(irqovr, 0, sci_irq, sci_irq, - sci_flags); + sci_flags); return current; } + +#if CONFIG_GOP_SUPPORT +/* Reading VBT table from flash */ +static void get_fsp_vbt(igd_opregion_t *opregion) +{ + const optionrom_vbt_t *vbt; + uint32_t vbt_len; + + vbt = fsp_get_vbt(&vbt_len); + if (!vbt) + die("vbt data not found"); + memcpy(opregion->header.vbios_version, vbt->coreblock_biosbuild, 4); + memcpy(opregion->vbt.gvd1, vbt, vbt->hdr_vbt_size < + sizeof(opregion->vbt.gvd1) ? vbt->hdr_vbt_size : + sizeof(opregion->vbt.gvd1)); +} + +/* Initialize IGD OpRegion, called from ACPI code */ +int init_igd_opregion(igd_opregion_t *opregion) +{ + device_t igd; + u16 reg16; + + memset(opregion, 0, sizeof(igd_opregion_t)); + + /* FIXME if IGD is disabled, we should exit here. */ + + memcpy(&opregion->header.signature, IGD_OPREGION_SIGNATURE, + sizeof(IGD_OPREGION_SIGNATURE)); + + /* 8kb */ + opregion->header.size = sizeof(igd_opregion_t) / 1024; + opregion->header.version = IGD_OPREGION_VERSION; + + /* FIXME We just assume we're mobile for now */ + opregion->header.mailboxes = MAILBOXES_MOBILE; + + /* TODO Initialize Mailbox 1 */ + + /* TODO Initialize Mailbox 3 */ + opregion->mailbox3.bclp = IGD_BACKLIGHT_BRIGHTNESS; + opregion->mailbox3.pfit = IGD_FIELD_VALID | IGD_PFIT_STRETCH; + opregion->mailbox3.pcft = 0; /* should be (IMON << 1) & 0x3e */ + opregion->mailbox3.cblv = IGD_FIELD_VALID | IGD_INITIAL_BRIGHTNESS; + opregion->mailbox3.bclm[0] = IGD_WORD_FIELD_VALID + 0x0000; + opregion->mailbox3.bclm[1] = IGD_WORD_FIELD_VALID + 0x0a19; + opregion->mailbox3.bclm[2] = IGD_WORD_FIELD_VALID + 0x1433; + opregion->mailbox3.bclm[3] = IGD_WORD_FIELD_VALID + 0x1e4c; + opregion->mailbox3.bclm[4] = IGD_WORD_FIELD_VALID + 0x2866; + opregion->mailbox3.bclm[5] = IGD_WORD_FIELD_VALID + 0x327f; + opregion->mailbox3.bclm[6] = IGD_WORD_FIELD_VALID + 0x3c99; + opregion->mailbox3.bclm[7] = IGD_WORD_FIELD_VALID + 0x46b2; + opregion->mailbox3.bclm[8] = IGD_WORD_FIELD_VALID + 0x50cc; + opregion->mailbox3.bclm[9] = IGD_WORD_FIELD_VALID + 0x5ae5; + opregion->mailbox3.bclm[10] = IGD_WORD_FIELD_VALID + 0x64ff; + + get_fsp_vbt(opregion); + + /* + * TODO This needs to happen in S3 resume, too. + * Maybe it should move to the finalize handler + */ + igd = dev_find_slot(0, PCI_DEVFN(GFX_DEV, GFX_FUNC)); + + pci_write_config32(igd, ASLS, (u32)opregion); + reg16 = pci_read_config16(igd, SWSCI); + reg16 &= ~(1 << 0); + reg16 |= (1 << 15); + pci_write_config16(igd, SWSCI, reg16); + + return 0; +} +#endif |