2 * Copyright (c) 2016 Google, Inc
4 * SPDX-License-Identifier: GPL-2.0
6 * Based on code from coreboot src/soc/intel/broadwell/cpu.c
13 #include <asm/cpu_x86.h>
14 #include <asm/cpu_common.h>
15 #include <asm/intel_regs.h>
18 #include <asm/turbo.h>
19 #include <asm/arch/cpu.h>
20 #include <asm/arch/pch.h>
21 #include <asm/arch/rcb.h>
23 struct cpu_broadwell_priv
{
27 /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
28 static const u8 power_limit_time_sec_to_msr
[] = {
56 /* Convert POWER_LIMIT_1_TIME MSR value to seconds */
57 static const u8 power_limit_time_msr_to_sec
[] = {
85 int arch_cpu_init_dm(void)
90 /* Start up the LPC so we have serial */
91 ret
= uclass_first_device(UCLASS_LPC
, &dev
);
96 ret
= cpu_set_flex_ratio_to_tdp_nominal();
103 void set_max_freq(void)
105 msr_t msr
, perf_ctl
, platform_info
;
107 /* Check for configurable TDP option */
108 platform_info
= msr_read(MSR_PLATFORM_INFO
);
110 if ((platform_info
.hi
>> 1) & 3) {
111 /* Set to nominal TDP ratio */
112 msr
= msr_read(MSR_CONFIG_TDP_NOMINAL
);
113 perf_ctl
.lo
= (msr
.lo
& 0xff) << 8;
115 /* Platform Info bits 15:8 give max ratio */
116 msr
= msr_read(MSR_PLATFORM_INFO
);
117 perf_ctl
.lo
= msr
.lo
& 0xff00;
121 msr_write(IA32_PERF_CTL
, perf_ctl
);
123 debug("CPU: frequency set to %d MHz\n",
124 ((perf_ctl
.lo
>> 8) & 0xff) * CPU_BCLK
);
127 int arch_cpu_init(void)
129 post_code(POST_CPU_INIT
);
131 return x86_cpu_init_f();
134 int print_cpuinfo(void)
136 char processor_name
[CPU_MAX_NAME_LEN
];
142 ret
= cpu_common_init();
145 gd
->arch
.pei_boot_mode
= PEI_BOOT_NONE
;
147 /* Print processor name */
148 name
= cpu_get_name(processor_name
);
149 printf("CPU: %s\n", name
);
155 * The core 100MHz BLCK is disabled in deeper c-states. One needs to calibrate
156 * the 100MHz BCLCK against the 24MHz BLCK to restore the clocks properly
157 * when a core is woken up
159 static int pcode_ready(void)
162 const int delay_step
= 10;
166 if (!(readl(MCHBAR_REG(BIOS_MAILBOX_INTERFACE
)) &
169 wait_count
+= delay_step
;
171 } while (wait_count
< 1000);
176 static u32
pcode_mailbox_read(u32 command
)
182 debug("PCODE: mailbox timeout on wait ready\n");
186 /* Send command and start transaction */
187 writel(command
| MAILBOX_RUN_BUSY
, MCHBAR_REG(BIOS_MAILBOX_INTERFACE
));
191 debug("PCODE: mailbox timeout on completion\n");
196 return readl(MCHBAR_REG(BIOS_MAILBOX_DATA
));
199 static int pcode_mailbox_write(u32 command
, u32 data
)
205 debug("PCODE: mailbox timeout on wait ready\n");
209 writel(data
, MCHBAR_REG(BIOS_MAILBOX_DATA
));
211 /* Send command and start transaction */
212 writel(command
| MAILBOX_RUN_BUSY
, MCHBAR_REG(BIOS_MAILBOX_INTERFACE
));
216 debug("PCODE: mailbox timeout on completion\n");
223 /* @dev is the CPU device */
224 static void initialize_vr_config(struct udevice
*dev
)
229 debug("Initializing VR config\n");
231 /* Configure VR_CURRENT_CONFIG */
232 msr
= msr_read(MSR_VR_CURRENT_CONFIG
);
234 * Preserve bits 63 and 62. Bit 62 is PSI4 enable, but it is only valid
237 msr
.hi
&= 0xc0000000;
238 msr
.hi
|= (0x01 << (52 - 32)); /* PSI3 threshold - 1A */
239 msr
.hi
|= (0x05 << (42 - 32)); /* PSI2 threshold - 5A */
240 msr
.hi
|= (0x14 << (32 - 32)); /* PSI1 threshold - 20A */
241 msr
.hi
|= (1 << (62 - 32)); /* Enable PSI4 */
242 /* Leave the max instantaneous current limit (12:0) to default */
243 msr_write(MSR_VR_CURRENT_CONFIG
, msr
);
245 /* Configure VR_MISC_CONFIG MSR */
246 msr
= msr_read(MSR_VR_MISC_CONFIG
);
247 /* Set the IOUT_SLOPE scalar applied to dIout in U10.1.9 format */
248 msr
.hi
&= ~(0x3ff << (40 - 32));
249 msr
.hi
|= (0x200 << (40 - 32)); /* 1.0 */
250 /* Set IOUT_OFFSET to 0 */
252 /* Set entry ramp rate to slow */
253 msr
.hi
&= ~(1 << (51 - 32));
254 /* Enable decay mode on C-state entry */
255 msr
.hi
|= (1 << (52 - 32));
256 /* Set the slow ramp rate */
257 msr
.hi
&= ~(0x3 << (53 - 32));
258 /* Configure the C-state exit ramp rate */
259 ramp
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
, "intel,slow-ramp",
262 /* Configured slow ramp rate */
263 msr
.hi
|= ((ramp
& 0x3) << (53 - 32));
264 /* Set exit ramp rate to slow */
265 msr
.hi
&= ~(1 << (50 - 32));
267 /* Fast ramp rate / 4 */
268 msr
.hi
|= (0x01 << (53 - 32));
269 /* Set exit ramp rate to fast */
270 msr
.hi
|= (1 << (50 - 32));
272 /* Set MIN_VID (31:24) to allow CPU to have full control */
273 msr
.lo
&= ~0xff000000;
274 min_vid
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
, "intel,min-vid",
276 msr
.lo
|= (min_vid
& 0xff) << 24;
277 msr_write(MSR_VR_MISC_CONFIG
, msr
);
279 /* Configure VR_MISC_CONFIG2 MSR */
280 msr
= msr_read(MSR_VR_MISC_CONFIG2
);
283 * Allow CPU to control minimum voltage completely (15:8) and
284 * set the fast ramp voltage in 10mV steps
286 if (cpu_get_family_model() == BROADWELL_FAMILY_ULT
)
287 msr
.lo
|= 0x006a; /* 1.56V */
289 msr
.lo
|= 0x006f; /* 1.60V */
290 msr_write(MSR_VR_MISC_CONFIG2
, msr
);
292 /* Set C9/C10 VCC Min */
293 pcode_mailbox_write(MAILBOX_BIOS_CMD_WRITE_C9C10_VOLTAGE
, 0x1f1f);
296 static int calibrate_24mhz_bclk(void)
305 /* A non-zero value initiates the PCODE calibration */
306 writel(~0, MCHBAR_REG(BIOS_MAILBOX_DATA
));
307 writel(MAILBOX_RUN_BUSY
| MAILBOX_BIOS_CMD_FSM_MEASURE_INTVL
,
308 MCHBAR_REG(BIOS_MAILBOX_INTERFACE
));
314 err_code
= readl(MCHBAR_REG(BIOS_MAILBOX_INTERFACE
)) & 0xff;
316 debug("PCODE: 24MHz BLCK calibration response: %d\n", err_code
);
318 /* Read the calibrated value */
319 writel(MAILBOX_RUN_BUSY
| MAILBOX_BIOS_CMD_READ_CALIBRATION
,
320 MCHBAR_REG(BIOS_MAILBOX_INTERFACE
));
326 debug("PCODE: 24MHz BLCK calibration value: 0x%08x\n",
327 readl(MCHBAR_REG(BIOS_MAILBOX_DATA
)));
332 static void configure_pch_power_sharing(void)
334 u32 pch_power
, pch_power_ext
, pmsync
, pmsync2
;
337 /* Read PCH Power levels from PCODE */
338 pch_power
= pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER
);
339 pch_power_ext
= pcode_mailbox_read(MAILBOX_BIOS_CMD_READ_PCH_POWER_EXT
);
341 debug("PCH Power: PCODE Levels 0x%08x 0x%08x\n", pch_power
,
344 pmsync
= readl(RCB_REG(PMSYNC_CONFIG
));
345 pmsync2
= readl(RCB_REG(PMSYNC_CONFIG2
));
348 * Program PMSYNC_TPR_CONFIG PCH power limit values
349 * pmsync[0:4] = mailbox[0:5]
350 * pmsync[8:12] = mailbox[6:11]
351 * pmsync[16:20] = mailbox[12:17]
353 for (i
= 0; i
< 3; i
++) {
354 u32 level
= pch_power
& 0x3f;
356 pmsync
&= ~(0x1f << (i
* 8));
357 pmsync
|= (level
& 0x1f) << (i
* 8);
359 writel(pmsync
, RCB_REG(PMSYNC_CONFIG
));
362 * Program PMSYNC_TPR_CONFIG2 Extended PCH power limit values
363 * pmsync2[0:4] = mailbox[23:18]
364 * pmsync2[8:12] = mailbox_ext[6:11]
365 * pmsync2[16:20] = mailbox_ext[12:17]
366 * pmsync2[24:28] = mailbox_ext[18:22]
369 pmsync2
|= pch_power
& 0x1f;
371 for (i
= 1; i
< 4; i
++) {
372 u32 level
= pch_power_ext
& 0x3f;
374 pmsync2
&= ~(0x1f << (i
* 8));
375 pmsync2
|= (level
& 0x1f) << (i
* 8);
377 writel(pmsync2
, RCB_REG(PMSYNC_CONFIG2
));
380 static int bsp_init_before_ap_bringup(struct udevice
*dev
)
384 initialize_vr_config(dev
);
385 ret
= calibrate_24mhz_bclk();
388 configure_pch_power_sharing();
393 int cpu_config_tdp_levels(void)
397 /* Bits 34:33 indicate how many levels supported */
398 platform_info
= msr_read(MSR_PLATFORM_INFO
);
399 return (platform_info
.hi
>> 1) & 3;
402 static void set_max_ratio(void)
408 /* Check for configurable TDP option */
409 if (turbo_get_state() == TURBO_ENABLED
) {
410 msr
= msr_read(MSR_NHM_TURBO_RATIO_LIMIT
);
411 perf_ctl
.lo
= (msr
.lo
& 0xff) << 8;
412 } else if (cpu_config_tdp_levels()) {
413 /* Set to nominal TDP ratio */
414 msr
= msr_read(MSR_CONFIG_TDP_NOMINAL
);
415 perf_ctl
.lo
= (msr
.lo
& 0xff) << 8;
417 /* Platform Info bits 15:8 give max ratio */
418 msr
= msr_read(MSR_PLATFORM_INFO
);
419 perf_ctl
.lo
= msr
.lo
& 0xff00;
421 msr_write(IA32_PERF_CTL
, perf_ctl
);
423 debug("cpu: frequency set to %d\n",
424 ((perf_ctl
.lo
>> 8) & 0xff) * CPU_BCLK
);
427 int broadwell_init(struct udevice
*dev
)
429 struct cpu_broadwell_priv
*priv
= dev_get_priv(dev
);
435 msr
= msr_read(CORE_THREAD_COUNT_MSR
);
436 num_threads
= (msr
.lo
>> 0) & 0xffff;
437 num_cores
= (msr
.lo
>> 16) & 0xffff;
438 debug("CPU has %u cores, %u threads enabled\n", num_cores
,
441 priv
->ht_disabled
= num_threads
== num_cores
;
443 ret
= bsp_init_before_ap_bringup(dev
);
452 static void configure_mca(void)
455 const unsigned int mcg_cap_msr
= 0x179;
459 msr
= msr_read(mcg_cap_msr
);
460 num_banks
= msr
.lo
& 0xff;
464 * TODO(adurbin): This should only be done on a cold boot. Also, some
465 * of these banks are core vs package scope. For now every CPU clears
468 for (i
= 0; i
< num_banks
; i
++)
469 msr_write(MSR_IA32_MC0_STATUS
+ (i
* 4), msr
);
472 static void enable_lapic_tpr(void)
476 msr
= msr_read(MSR_PIC_MSG_CONTROL
);
477 msr
.lo
&= ~(1 << 10); /* Enable APIC TPR updates */
478 msr_write(MSR_PIC_MSG_CONTROL
, msr
);
482 static void configure_c_states(void)
486 msr
= msr_read(MSR_PMG_CST_CONFIG_CONTROL
);
487 msr
.lo
|= (1 << 31); /* Timed MWAIT Enable */
488 msr
.lo
|= (1 << 30); /* Package c-state Undemotion Enable */
489 msr
.lo
|= (1 << 29); /* Package c-state Demotion Enable */
490 msr
.lo
|= (1 << 28); /* C1 Auto Undemotion Enable */
491 msr
.lo
|= (1 << 27); /* C3 Auto Undemotion Enable */
492 msr
.lo
|= (1 << 26); /* C1 Auto Demotion Enable */
493 msr
.lo
|= (1 << 25); /* C3 Auto Demotion Enable */
494 msr
.lo
&= ~(1 << 10); /* Disable IO MWAIT redirection */
495 /* The deepest package c-state defaults to factory-configured value */
496 msr_write(MSR_PMG_CST_CONFIG_CONTROL
, msr
);
498 msr
= msr_read(MSR_MISC_PWR_MGMT
);
499 msr
.lo
&= ~(1 << 0); /* Enable P-state HW_ALL coordination */
500 msr_write(MSR_MISC_PWR_MGMT
, msr
);
502 msr
= msr_read(MSR_POWER_CTL
);
503 msr
.lo
|= (1 << 18); /* Enable Energy Perf Bias MSR 0x1b0 */
504 msr
.lo
|= (1 << 1); /* C1E Enable */
505 msr
.lo
|= (1 << 0); /* Bi-directional PROCHOT# */
506 msr_write(MSR_POWER_CTL
, msr
);
508 /* C-state Interrupt Response Latency Control 0 - package C3 latency */
510 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_0_LIMIT
;
511 msr_write(MSR_C_STATE_LATENCY_CONTROL_0
, msr
);
513 /* C-state Interrupt Response Latency Control 1 */
515 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_1_LIMIT
;
516 msr_write(MSR_C_STATE_LATENCY_CONTROL_1
, msr
);
518 /* C-state Interrupt Response Latency Control 2 - package C6/C7 short */
520 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_2_LIMIT
;
521 msr_write(MSR_C_STATE_LATENCY_CONTROL_2
, msr
);
523 /* C-state Interrupt Response Latency Control 3 - package C8 */
525 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_3_LIMIT
;
526 msr_write(MSR_C_STATE_LATENCY_CONTROL_3
, msr
);
528 /* C-state Interrupt Response Latency Control 4 - package C9 */
530 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_4_LIMIT
;
531 msr_write(MSR_C_STATE_LATENCY_CONTROL_4
, msr
);
533 /* C-state Interrupt Response Latency Control 5 - package C10 */
535 msr
.lo
= IRTL_VALID
| IRTL_1024_NS
| C_STATE_LATENCY_CONTROL_5_LIMIT
;
536 msr_write(MSR_C_STATE_LATENCY_CONTROL_5
, msr
);
539 static void configure_misc(void)
543 msr
= msr_read(MSR_IA32_MISC_ENABLE
);
544 msr
.lo
|= (1 << 0); /* Fast String enable */
545 msr
.lo
|= (1 << 3); /* TM1/TM2/EMTTM enable */
546 msr
.lo
|= (1 << 16); /* Enhanced SpeedStep Enable */
547 msr_write(MSR_IA32_MISC_ENABLE
, msr
);
549 /* Disable thermal interrupts */
552 msr_write(MSR_IA32_THERM_INTERRUPT
, msr
);
554 /* Enable package critical interrupt only */
557 msr_write(MSR_IA32_PACKAGE_THERM_INTERRUPT
, msr
);
560 static void configure_thermal_target(struct udevice
*dev
)
565 tcc_offset
= fdtdec_get_int(gd
->fdt_blob
, dev
->of_offset
,
566 "intel,tcc-offset", 0);
568 /* Set TCC activaiton offset if supported */
569 msr
= msr_read(MSR_PLATFORM_INFO
);
570 if ((msr
.lo
& (1 << 30)) && tcc_offset
) {
571 msr
= msr_read(MSR_TEMPERATURE_TARGET
);
572 msr
.lo
&= ~(0xf << 24); /* Bits 27:24 */
573 msr
.lo
|= (tcc_offset
& 0xf) << 24;
574 msr_write(MSR_TEMPERATURE_TARGET
, msr
);
578 static void configure_dca_cap(void)
580 struct cpuid_result cpuid_regs
;
583 /* Check feature flag in CPUID.(EAX=1):ECX[18]==1 */
584 cpuid_regs
= cpuid(1);
585 if (cpuid_regs
.ecx
& (1 << 18)) {
586 msr
= msr_read(MSR_IA32_PLATFORM_DCA_CAP
);
588 msr_write(MSR_IA32_PLATFORM_DCA_CAP
, msr
);
592 static void set_energy_perf_bias(u8 policy
)
597 /* Determine if energy efficient policy is supported */
598 ecx
= cpuid_ecx(0x6);
599 if (!(ecx
& (1 << 3)))
602 /* Energy Policy is bits 3:0 */
603 msr
= msr_read(MSR_IA32_ENERGY_PERFORMANCE_BIAS
);
605 msr
.lo
|= policy
& 0xf;
606 msr_write(MSR_IA32_ENERGY_PERFORMANCE_BIAS
, msr
);
608 debug("cpu: energy policy set to %u\n", policy
);
611 /* All CPUs including BSP will run the following function */
612 static void cpu_core_init(struct udevice
*dev
)
614 /* Clear out pending MCEs */
617 /* Enable the local cpu apics */
620 /* Configure C States */
621 configure_c_states();
623 /* Configure Enhanced SpeedStep and Thermal Sensors */
626 /* Thermal throttle activation offset */
627 configure_thermal_target(dev
);
629 /* Enable Direct Cache Access */
632 /* Set energy policy */
633 set_energy_perf_bias(ENERGY_POLICY_NORMAL
);
640 * Configure processor power limits if possible
641 * This must be done AFTER set of BIOS_RESET_CPL
643 void cpu_set_power_limits(int power_limit_1_time
)
648 unsigned tdp
, min_power
, max_power
, max_time
;
649 u8 power_limit_1_val
;
651 msr
= msr_read(MSR_PLATFORM_INFO
);
652 if (power_limit_1_time
> ARRAY_SIZE(power_limit_time_sec_to_msr
))
653 power_limit_1_time
= 28;
655 if (!(msr
.lo
& PLATFORM_INFO_SET_TDP
))
659 msr
= msr_read(MSR_PKG_POWER_SKU_UNIT
);
660 power_unit
= 2 << ((msr
.lo
& 0xf) - 1);
662 /* Get power defaults for this SKU */
663 msr
= msr_read(MSR_PKG_POWER_SKU
);
664 tdp
= msr
.lo
& 0x7fff;
665 min_power
= (msr
.lo
>> 16) & 0x7fff;
666 max_power
= msr
.hi
& 0x7fff;
667 max_time
= (msr
.hi
>> 16) & 0x7f;
669 debug("CPU TDP: %u Watts\n", tdp
/ power_unit
);
671 if (power_limit_time_msr_to_sec
[max_time
] > power_limit_1_time
)
672 power_limit_1_time
= power_limit_time_msr_to_sec
[max_time
];
674 if (min_power
> 0 && tdp
< min_power
)
677 if (max_power
> 0 && tdp
> max_power
)
680 power_limit_1_val
= power_limit_time_sec_to_msr
[power_limit_1_time
];
682 /* Set long term power limit to TDP */
684 limit
.lo
|= tdp
& PKG_POWER_LIMIT_MASK
;
685 limit
.lo
|= PKG_POWER_LIMIT_EN
;
686 limit
.lo
|= (power_limit_1_val
& PKG_POWER_LIMIT_TIME_MASK
) <<
687 PKG_POWER_LIMIT_TIME_SHIFT
;
689 /* Set short term power limit to 1.25 * TDP */
691 limit
.hi
|= ((tdp
* 125) / 100) & PKG_POWER_LIMIT_MASK
;
692 limit
.hi
|= PKG_POWER_LIMIT_EN
;
693 /* Power limit 2 time is only programmable on server SKU */
695 msr_write(MSR_PKG_POWER_LIMIT
, limit
);
697 /* Set power limit values in MCHBAR as well */
698 writel(limit
.lo
, MCHBAR_REG(MCH_PKG_POWER_LIMIT_LO
));
699 writel(limit
.hi
, MCHBAR_REG(MCH_PKG_POWER_LIMIT_HI
));
701 /* Set DDR RAPL power limit by copying from MMIO to MSR */
702 msr
.lo
= readl(MCHBAR_REG(MCH_DDR_POWER_LIMIT_LO
));
703 msr
.hi
= readl(MCHBAR_REG(MCH_DDR_POWER_LIMIT_HI
));
704 msr_write(MSR_DDR_RAPL_LIMIT
, msr
);
706 /* Use nominal TDP values for CPUs with configurable TDP */
707 if (cpu_config_tdp_levels()) {
708 msr
= msr_read(MSR_CONFIG_TDP_NOMINAL
);
710 limit
.lo
= msr
.lo
& 0xff;
711 msr_write(MSR_TURBO_ACTIVATION_RATIO
, limit
);
715 static int broadwell_get_info(struct udevice
*dev
, struct cpu_info
*info
)
719 msr
= msr_read(IA32_PERF_CTL
);
720 info
->cpu_freq
= ((msr
.lo
>> 8) & 0xff) * BROADWELL_BCLK
* 1000000;
721 info
->features
= 1 << CPU_FEAT_L1_CACHE
| 1 << CPU_FEAT_MMU
|
722 1 << CPU_FEAT_UCODE
| 1 << CPU_FEAT_DEVICE_ID
;
727 static int broadwell_get_count(struct udevice
*dev
)
732 static int cpu_x86_broadwell_probe(struct udevice
*dev
)
736 return broadwell_init(dev
);
742 static const struct cpu_ops cpu_x86_broadwell_ops
= {
743 .get_desc
= cpu_x86_get_desc
,
744 .get_info
= broadwell_get_info
,
745 .get_count
= broadwell_get_count
,
748 static const struct udevice_id cpu_x86_broadwell_ids
[] = {
749 { .compatible
= "intel,core-i3-gen5" },
753 U_BOOT_DRIVER(cpu_x86_broadwell_drv
) = {
754 .name
= "cpu_x86_broadwell",
756 .of_match
= cpu_x86_broadwell_ids
,
757 .bind
= cpu_x86_bind
,
758 .probe
= cpu_x86_broadwell_probe
,
759 .ops
= &cpu_x86_broadwell_ops
,
760 .priv_auto_alloc_size
= sizeof(struct cpu_broadwell_priv
),