hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (c) 2016 Google, Inc
 *
 * SPDX-License-Identifier:    GPL-2.0
 */
 
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <asm/cpu_common.h>
#include <asm/intel_regs.h>
#include <asm/lapic.h>
#include <asm/lpc_common.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
#include <asm/post.h>
#include <asm/microcode.h>
 
DECLARE_GLOBAL_DATA_PTR;
 
static int report_bist_failure(void)
{
   if (gd->arch.bist != 0) {
       post_code(POST_BIST_FAILURE);
       printf("BIST failed: %08x\n", gd->arch.bist);
       return -EFAULT;
   }
 
   return 0;
}
 
int cpu_common_init(void)
{
   struct udevice *dev, *lpc;
   int ret;
 
   /* Halt if there was a built in self test failure */
   ret = report_bist_failure();
   if (ret)
       return ret;
 
   enable_lapic();
 
   ret = microcode_update_intel();
   if (ret && ret != -EEXIST) {
       debug("%s: Microcode update failure (err=%d)\n", __func__, ret);
       return ret;
   }
 
   /* Enable upper 128bytes of CMOS */
   writel(1 << 2, RCB_REG(RC));
 
   /* Early chipset init required before RAM init can work */
   uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
 
   ret = uclass_first_device(UCLASS_LPC, &lpc);
   if (ret)
       return ret;
   if (!lpc)
       return -ENODEV;
 
   /* Cause the SATA device to do its early init */
   uclass_first_device(UCLASS_AHCI, &dev);
 
   return 0;
}
 
int cpu_set_flex_ratio_to_tdp_nominal(void)
{
   msr_t flex_ratio, msr;
   u8 nominal_ratio;
 
   /* Check for Flex Ratio support */
   flex_ratio = msr_read(MSR_FLEX_RATIO);
   if (!(flex_ratio.lo & FLEX_RATIO_EN))
       return -EINVAL;
 
   /* Check for >0 configurable TDPs */
   msr = msr_read(MSR_PLATFORM_INFO);
   if (((msr.hi >> 1) & 3) == 0)
       return -EINVAL;
 
   /* Use nominal TDP ratio for flex ratio */
   msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
   nominal_ratio = msr.lo & 0xff;
 
   /* See if flex ratio is already set to nominal TDP ratio */
   if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
       return 0;
 
   /* Set flex ratio to nominal TDP ratio */
   flex_ratio.lo &= ~0xff00;
   flex_ratio.lo |= nominal_ratio << 8;
   flex_ratio.lo |= FLEX_RATIO_LOCK;
   msr_write(MSR_FLEX_RATIO, flex_ratio);
 
   /* Set flex ratio in soft reset data register bits 11:6 */
   clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
           (nominal_ratio & 0x3f) << 6);
 
   debug("CPU: Soft reset to set up flex ratio\n");
 
   /* Set soft reset control to use register value */
   setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
 
   /* Issue warm reset, will be "CPU only" due to soft reset data */
   outb(0x0, IO_PORT_RESET);
   outb(SYS_RST | RST_CPU, IO_PORT_RESET);
   cpu_hlt();
 
   /* Not reached */
   return -EINVAL;
}