Angel Pons | f23ae0b | 2020-04-02 23:48:12 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 2 | |
| 3 | #include <stdint.h> |
Kyösti Mälkki | de64078 | 2019-12-03 07:30:26 +0200 | [diff] [blame] | 4 | #include <arch/bootblock.h> |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 5 | #include <cpu/x86/msr.h> |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 6 | #include <arch/io.h> |
Angel Pons | 9dd1eb6 | 2020-10-29 11:18:04 +0100 | [diff] [blame] | 7 | #include <delay.h> |
Patrick Georgi | 546953c | 2014-11-29 10:38:17 +0100 | [diff] [blame] | 8 | #include <halt.h> |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 9 | |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 10 | #include "haswell.h" |
| 11 | |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 12 | #include <southbridge/intel/lynxpoint/pch.h> |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 13 | |
| 14 | static void set_flex_ratio_to_tdp_nominal(void) |
| 15 | { |
| 16 | msr_t flex_ratio, msr; |
| 17 | u32 soft_reset; |
| 18 | u8 nominal_ratio; |
| 19 | |
| 20 | /* Check for Flex Ratio support */ |
| 21 | flex_ratio = rdmsr(MSR_FLEX_RATIO); |
| 22 | if (!(flex_ratio.lo & FLEX_RATIO_EN)) |
| 23 | return; |
| 24 | |
| 25 | /* Check for >0 configurable TDPs */ |
| 26 | msr = rdmsr(MSR_PLATFORM_INFO); |
| 27 | if (((msr.hi >> 1) & 3) == 0) |
| 28 | return; |
| 29 | |
| 30 | /* Use nominal TDP ratio for flex ratio */ |
| 31 | msr = rdmsr(MSR_CONFIG_TDP_NOMINAL); |
| 32 | nominal_ratio = msr.lo & 0xff; |
| 33 | |
| 34 | /* See if flex ratio is already set to nominal TDP ratio */ |
| 35 | if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio) |
| 36 | return; |
| 37 | |
| 38 | /* Set flex ratio to nominal TDP ratio */ |
| 39 | flex_ratio.lo &= ~0xff00; |
| 40 | flex_ratio.lo |= nominal_ratio << 8; |
| 41 | flex_ratio.lo |= FLEX_RATIO_LOCK; |
| 42 | wrmsr(MSR_FLEX_RATIO, flex_ratio); |
| 43 | |
| 44 | /* Set flex ratio in soft reset data register bits 11:6. |
| 45 | * RCBA region is enabled in southbridge bootblock */ |
| 46 | soft_reset = RCBA32(SOFT_RESET_DATA); |
| 47 | soft_reset &= ~(0x3f << 6); |
| 48 | soft_reset |= (nominal_ratio & 0x3f) << 6; |
| 49 | RCBA32(SOFT_RESET_DATA) = soft_reset; |
| 50 | |
| 51 | /* Set soft reset control to use register value */ |
| 52 | RCBA32_OR(SOFT_RESET_CTRL, 1); |
| 53 | |
Angel Pons | 9dd1eb6 | 2020-10-29 11:18:04 +0100 | [diff] [blame] | 54 | /* Delay before reset to avoid potential TPM lockout */ |
Kyösti Mälkki | d2b2a18 | 2021-04-29 15:33:07 +0300 | [diff] [blame] | 55 | if (CONFIG(TPM)) |
Angel Pons | 9dd1eb6 | 2020-10-29 11:18:04 +0100 | [diff] [blame] | 56 | mdelay(30); |
| 57 | |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 58 | /* Issue warm reset, will be "CPU only" due to soft reset data */ |
| 59 | outb(0x0, 0xcf9); |
| 60 | outb(0x6, 0xcf9); |
Patrick Georgi | 546953c | 2014-11-29 10:38:17 +0100 | [diff] [blame] | 61 | halt(); |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 62 | } |
| 63 | |
Arthur Heymans | 8e646e7 | 2018-06-05 11:19:22 +0200 | [diff] [blame] | 64 | void bootblock_early_cpu_init(void) |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 65 | { |
| 66 | /* Set flex ratio and reset if needed */ |
| 67 | set_flex_ratio_to_tdp_nominal(); |
Aaron Durbin | 76c3700 | 2012-10-30 09:03:43 -0500 | [diff] [blame] | 68 | } |