Oskar Enoksson (enok@lysator.liu.se) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/5186
-gerrit
commit 079d3b80b9e943c408ea186ccbe2f2864c327fd4 Author: Oskar Enoksson enok@lysator.liu.se Date: Sat Feb 8 00:25:32 2014 +0100
hp/dl145_g1: Adding FID/VID and Powernow ACPI
Add cool-n-quiet functionality which allows the OS to dynamic alter CPU voltage and frequency change in order to save power e.g. when the CPU load is low.
Change-Id: I4c895a56bcf571d4276af192aeef87d120143063 Signed-off-by: Oskar Enoksson enok@lysator.liu.se --- src/mainboard/hp/dl145_g1/Kconfig | 2 + src/mainboard/hp/dl145_g1/acpi_tables.c | 5 +++ src/mainboard/hp/dl145_g1/romstage.c | 77 ++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 25 deletions(-)
diff --git a/src/mainboard/hp/dl145_g1/Kconfig b/src/mainboard/hp/dl145_g1/Kconfig index 94189ce..2768007 100644 --- a/src/mainboard/hp/dl145_g1/Kconfig +++ b/src/mainboard/hp/dl145_g1/Kconfig @@ -12,6 +12,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy select HAVE_PIRQ_TABLE select HAVE_MP_TABLE select BOARD_ROMSIZE_KB_512 + select SET_FIDVID + select SET_FIDVID_DEBUG select RAMINIT_SYSINFO # select SB_HT_CHAIN_UNITID_OFFSET_ONLY select QRANK_DIMM_SUPPORT diff --git a/src/mainboard/hp/dl145_g1/acpi_tables.c b/src/mainboard/hp/dl145_g1/acpi_tables.c index dd96318..33310f8 100644 --- a/src/mainboard/hp/dl145_g1/acpi_tables.c +++ b/src/mainboard/hp/dl145_g1/acpi_tables.c @@ -21,6 +21,7 @@ #include <cpu/amd/amdk8_sysconf.h> #include "northbridge/amd/amdk8/acpi.h" #include "mb_sysconf.h" +#include <cpu/amd/model_fxx_powernow.h>
#define DUMP_ACPI_TABLES 0
@@ -163,6 +164,10 @@ unsigned long acpi_fill_madt(unsigned long current)
unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id) { k8acpi_write_vars(); +#if CONFIG_SET_FIDVID + amd_model_fxx_generate_powernow(pm_base+0x10, 6, 1); + acpigen_write_mainboard_resources("\_SB.PCI0.MBRS", "_CRS"); +#endif return (unsigned long) (acpigen_get_current()); }
diff --git a/src/mainboard/hp/dl145_g1/romstage.c b/src/mainboard/hp/dl145_g1/romstage.c index 67ce9c1..63da831 100644 --- a/src/mainboard/hp/dl145_g1/romstage.c +++ b/src/mainboard/hp/dl145_g1/romstage.c @@ -44,18 +44,6 @@ static void memreset(int controllers, const struct mem_controller *ctrl)
#define SMBUS_HUB 0x18
-static inline void activate_spd_rom(const struct mem_controller *ctrl) -{ - int ret,i; - unsigned device=(ctrl->channel0[0])>>8; - /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/ - i=2; - do { - ret = smbus_write_byte(SMBUS_HUB, 0x01, device); - } while ((ret!=0) && (i-->0)); - smbus_write_byte(SMBUS_HUB, 0x03, 0); -} - static inline void change_i2c_mux(unsigned device) { int ret, i; @@ -69,6 +57,11 @@ static inline void change_i2c_mux(unsigned device) print_debug("change_i2c_mux 2 ret="); print_debug_hex32(ret); print_debug("\n"); }
+static inline void activate_spd_rom(const struct mem_controller *ctrl) +{ + change_i2c_mux(ctrl->channel0[0]>>8); +} + static inline int spd_read_byte(unsigned device, unsigned address) { return smbus_read_byte(device, address); @@ -82,22 +75,12 @@ static inline int spd_read_byte(unsigned device, unsigned address) #include "cpu/amd/dualcore/dualcore.c" #include <spd.h> #include "cpu/amd/model_fxx/init_cpus.c" - -#define RC0 ((1<<1)<<8) -#define RC1 ((1<<2)<<8) +#if CONFIG_SET_FIDVID +#include "cpu/amd/model_fxx/fidvid.c" +#endif
void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) { - static const uint16_t spd_addr [] = { - //first node - RC0|DIMM0, RC0|DIMM2, 0, 0, - RC0|DIMM1, RC0|DIMM3, 0, 0, -#if CONFIG_MAX_PHYSICAL_CPUS > 1 - //second node - RC1|DIMM0, RC1|DIMM2, 0, 0, - RC1|DIMM1, RC1|DIMM3, 0, 0, -#endif - }; struct sys_info *sysinfo = &sysinfo_car;
int needs_reset = 0; @@ -126,6 +109,33 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) #endif
ht_setup_chains_x(sysinfo); +#if CONFIG_SET_FIDVID + /* Check to see if processor is capable of changing FIDVID */ + /* otherwise it will throw a GP# when reading FIDVID_STATUS */ + struct cpuid_result cpuid1 = cpuid(0x80000007); + if ((cpuid1.edx & 0x6) == 0x6) { + { + /* Read FIDVID_STATUS */ + msr_t msr; + msr=rdmsr(0xc0010042); + print_debug("begin msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\n"); + } + + enable_fid_change(); + enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn); + init_fidvid_bsp(bsp_apicid); + + // show final fid and vid + { + msr_t msr; + msr=rdmsr(0xc0010042); + print_debug("end msr fid, vid "); print_debug_hex32( msr.hi ); print_debug_hex32(msr.lo); print_debug("\n"); + } + + } else { + print_debug("Changing FIDVID not supported\n"); + } +#endif
needs_reset |= optimize_link_coherent_ht(); needs_reset |= optimize_link_incoherent_ht(sysinfo); @@ -138,6 +148,10 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) enable_smbus();
int i; + +#define RC0 ((1 << 1) << 8) +#define RC1 ((1 << 2) << 8) + for(i=0;i<2;i++) { activate_spd_rom(&sysinfo->ctrl[i]); } @@ -152,9 +166,22 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx) allow_all_aps_stop(bsp_apicid);
//It's the time to set ctrl now; + static const uint16_t spd_addr [] = { + //first node + RC0|DIMM0, RC0|DIMM2, 0, 0, + RC0|DIMM1, RC0|DIMM3, 0, 0, +#if CONFIG_MAX_PHYSICAL_CPUS > 1 + //second node + RC1|DIMM0, RC1|DIMM2, 0, 0, + RC1|DIMM1, RC1|DIMM3, 0, 0, +#endif + }; fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
memreset_setup(); +#if CONFIG_SET_FIDVID + init_timer(); // Need to use TMICT to synchronize FID/VID +#endif sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
//dump_pci_devices();