1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #include <arch/bootblock.h> 4 #include <arch/io.h> 5 #include <cpu/cpu.h> 6 #include <cpu/x86/msr.h> 7 #include <halt.h> 8 #include <stdint.h> 9 10 #include "model_206ax.h" 11 12 #if CONFIG(SOUTHBRIDGE_INTEL_BD82X6X) || \ 13 CONFIG(SOUTHBRIDGE_INTEL_C216) 14 /* Needed for RCBA access to set Soft Reset Data register */ 15 #include <southbridge/intel/bd82x6x/pch.h> 16 #else 17 #error "CPU must be paired with Intel BD82X6X or C216 southbridge" 18 #endif 19 set_flex_ratio_to_tdp_nominal(void)20static void set_flex_ratio_to_tdp_nominal(void) 21 { 22 msr_t flex_ratio, msr; 23 u32 soft_reset; 24 u8 nominal_ratio; 25 26 /* Minimum CPU revision for configurable TDP support */ 27 if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID) 28 return; 29 30 /* Check for Flex Ratio support */ 31 flex_ratio = rdmsr(MSR_FLEX_RATIO); 32 if (!(flex_ratio.lo & FLEX_RATIO_EN)) 33 return; 34 35 /* Check for >0 configurable TDPs */ 36 msr = rdmsr(MSR_PLATFORM_INFO); 37 if (((msr.hi >> 1) & 3) == 0) 38 return; 39 40 /* Use nominal TDP ratio for flex ratio */ 41 msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); 42 nominal_ratio = msr.lo & 0xff; 43 44 /* See if flex ratio is already set to nominal TDP ratio */ 45 if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio) 46 return; 47 48 /* Set flex ratio to nominal TDP ratio */ 49 flex_ratio.lo &= ~0xff00; 50 flex_ratio.lo |= nominal_ratio << 8; 51 flex_ratio.lo |= FLEX_RATIO_LOCK; 52 wrmsr(MSR_FLEX_RATIO, flex_ratio); 53 54 /* Set flex ratio in soft reset data register bits 11:6. 55 * RCBA region is enabled in southbridge bootblock */ 56 soft_reset = RCBA32(SOFT_RESET_DATA); 57 soft_reset &= ~(0x3f << 6); 58 soft_reset |= (nominal_ratio & 0x3f) << 6; 59 RCBA32(SOFT_RESET_DATA) = soft_reset; 60 61 /* Set soft reset control to use register value */ 62 RCBA32_OR(SOFT_RESET_CTRL, 1); 63 64 /* Issue warm reset, will be "CPU only" due to soft reset data */ 65 outb(0x0, 0xcf9); 66 outb(0x6, 0xcf9); 67 halt(); 68 } 69 bootblock_early_cpu_init(void)70void bootblock_early_cpu_init(void) 71 { 72 /* Set flex ratio and reset if needed */ 73 set_flex_ratio_to_tdp_nominal(); 74 } 75