cpu.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright (C) 2015 Google, Inc
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. *
  6. * Based on code from coreboot
  7. */
  8. #include <common.h>
  9. #include <cpu.h>
  10. #include <dm.h>
  11. #include <asm/cpu.h>
  12. #include <asm/lapic.h>
  13. #include <asm/mp.h>
  14. #include <asm/msr.h>
  15. #include <asm/turbo.h>
  16. #ifdef CONFIG_SMP
  17. static int enable_smis(struct udevice *cpu, void *unused)
  18. {
  19. return 0;
  20. }
  21. static struct mp_flight_record mp_steps[] = {
  22. MP_FR_BLOCK_APS(mp_init_cpu, NULL, mp_init_cpu, NULL),
  23. /* Wait for APs to finish initialization before proceeding. */
  24. MP_FR_BLOCK_APS(NULL, NULL, enable_smis, NULL),
  25. };
  26. static int detect_num_cpus(void)
  27. {
  28. int ecx = 0;
  29. /*
  30. * Use the algorithm described in Intel 64 and IA-32 Architectures
  31. * Software Developer's Manual Volume 3 (3A, 3B & 3C): System
  32. * Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping
  33. * of CPUID Extended Topology Leaf.
  34. */
  35. while (1) {
  36. struct cpuid_result leaf_b;
  37. leaf_b = cpuid_ext(0xb, ecx);
  38. /*
  39. * Bay Trail doesn't have hyperthreading so just determine the
  40. * number of cores by from level type (ecx[15:8] == * 2)
  41. */
  42. if ((leaf_b.ecx & 0xff00) == 0x0200)
  43. return leaf_b.ebx & 0xffff;
  44. ecx++;
  45. }
  46. }
  47. static int baytrail_init_cpus(void)
  48. {
  49. struct mp_params mp_params;
  50. lapic_setup();
  51. mp_params.num_cpus = detect_num_cpus();
  52. mp_params.parallel_microcode_load = 0,
  53. mp_params.flight_plan = &mp_steps[0];
  54. mp_params.num_records = ARRAY_SIZE(mp_steps);
  55. mp_params.microcode_pointer = 0;
  56. if (mp_init(&mp_params)) {
  57. printf("Warning: MP init failure\n");
  58. return -EIO;
  59. }
  60. return 0;
  61. }
  62. #endif
  63. int x86_init_cpus(void)
  64. {
  65. #ifdef CONFIG_SMP
  66. debug("Init additional CPUs\n");
  67. baytrail_init_cpus();
  68. #endif
  69. return 0;
  70. }
  71. static void set_max_freq(void)
  72. {
  73. msr_t perf_ctl;
  74. msr_t msr;
  75. /* Enable speed step */
  76. msr = msr_read(MSR_IA32_MISC_ENABLES);
  77. msr.lo |= (1 << 16);
  78. msr_write(MSR_IA32_MISC_ENABLES, msr);
  79. /*
  80. * Set guaranteed ratio [21:16] from IACORE_RATIOS to bits [15:8] of
  81. * the PERF_CTL
  82. */
  83. msr = msr_read(MSR_IACORE_RATIOS);
  84. perf_ctl.lo = (msr.lo & 0x3f0000) >> 8;
  85. /*
  86. * Set guaranteed vid [21:16] from IACORE_VIDS to bits [7:0] of
  87. * the PERF_CTL
  88. */
  89. msr = msr_read(MSR_IACORE_VIDS);
  90. perf_ctl.lo |= (msr.lo & 0x7f0000) >> 16;
  91. perf_ctl.hi = 0;
  92. msr_write(MSR_IA32_PERF_CTL, perf_ctl);
  93. }
  94. static int cpu_x86_baytrail_probe(struct udevice *dev)
  95. {
  96. debug("Init BayTrail core\n");
  97. /*
  98. * On BayTrail the turbo disable bit is actually scoped at the
  99. * building-block level, not package. For non-BSP cores that are
  100. * within a building block, enable turbo. The cores within the BSP's
  101. * building block will just see it already enabled and move on.
  102. */
  103. if (lapicid())
  104. turbo_enable();
  105. /* Dynamic L2 shrink enable and threshold */
  106. msr_clrsetbits_64(MSR_PMG_CST_CONFIG_CONTROL, 0x3f000f, 0xe0008),
  107. /* Disable C1E */
  108. msr_clrsetbits_64(MSR_POWER_CTL, 2, 0);
  109. msr_setbits_64(MSR_POWER_MISC, 0x44);
  110. /* Set this core to max frequency ratio */
  111. set_max_freq();
  112. return 0;
  113. }
  114. static unsigned bus_freq(void)
  115. {
  116. msr_t clk_info = msr_read(MSR_BSEL_CR_OVERCLOCK_CONTROL);
  117. switch (clk_info.lo & 0x3) {
  118. case 0:
  119. return 83333333;
  120. case 1:
  121. return 100000000;
  122. case 2:
  123. return 133333333;
  124. case 3:
  125. return 116666666;
  126. default:
  127. return 0;
  128. }
  129. }
  130. static unsigned long tsc_freq(void)
  131. {
  132. msr_t platform_info;
  133. ulong bclk = bus_freq();
  134. if (!bclk)
  135. return 0;
  136. platform_info = msr_read(MSR_PLATFORM_INFO);
  137. return bclk * ((platform_info.lo >> 8) & 0xff);
  138. }
  139. static int baytrail_get_info(struct udevice *dev, struct cpu_info *info)
  140. {
  141. info->cpu_freq = tsc_freq();
  142. info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU;
  143. return 0;
  144. }
  145. static int cpu_x86_baytrail_bind(struct udevice *dev)
  146. {
  147. struct cpu_platdata *plat = dev_get_parent_platdata(dev);
  148. plat->cpu_id = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
  149. "intel,apic-id", -1);
  150. return 0;
  151. }
  152. static const struct cpu_ops cpu_x86_baytrail_ops = {
  153. .get_desc = x86_cpu_get_desc,
  154. .get_info = baytrail_get_info,
  155. };
  156. static const struct udevice_id cpu_x86_baytrail_ids[] = {
  157. { .compatible = "intel,baytrail-cpu" },
  158. { }
  159. };
  160. U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
  161. .name = "cpu_x86_baytrail",
  162. .id = UCLASS_CPU,
  163. .of_match = cpu_x86_baytrail_ids,
  164. .bind = cpu_x86_baytrail_bind,
  165. .probe = cpu_x86_baytrail_probe,
  166. .ops = &cpu_x86_baytrail_ops,
  167. };