cpu.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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/cpu_x86.h>
  13. #include <asm/lapic.h>
  14. #include <asm/msr.h>
  15. #include <asm/turbo.h>
  16. static void set_max_freq(void)
  17. {
  18. msr_t perf_ctl;
  19. msr_t msr;
  20. /* Enable speed step */
  21. msr = msr_read(MSR_IA32_MISC_ENABLES);
  22. msr.lo |= (1 << 16);
  23. msr_write(MSR_IA32_MISC_ENABLES, msr);
  24. /*
  25. * Set guaranteed ratio [21:16] from IACORE_RATIOS to bits [15:8] of
  26. * the PERF_CTL
  27. */
  28. msr = msr_read(MSR_IACORE_RATIOS);
  29. perf_ctl.lo = (msr.lo & 0x3f0000) >> 8;
  30. /*
  31. * Set guaranteed vid [21:16] from IACORE_VIDS to bits [7:0] of
  32. * the PERF_CTL
  33. */
  34. msr = msr_read(MSR_IACORE_VIDS);
  35. perf_ctl.lo |= (msr.lo & 0x7f0000) >> 16;
  36. perf_ctl.hi = 0;
  37. msr_write(MSR_IA32_PERF_CTL, perf_ctl);
  38. }
  39. static int cpu_x86_baytrail_probe(struct udevice *dev)
  40. {
  41. if (!ll_boot_init())
  42. return 0;
  43. debug("Init BayTrail core\n");
  44. /*
  45. * On BayTrail the turbo disable bit is actually scoped at the
  46. * building-block level, not package. For non-BSP cores that are
  47. * within a building block, enable turbo. The cores within the BSP's
  48. * building block will just see it already enabled and move on.
  49. */
  50. if (lapicid())
  51. turbo_enable();
  52. /* Dynamic L2 shrink enable and threshold */
  53. msr_clrsetbits_64(MSR_PMG_CST_CONFIG_CONTROL, 0x3f000f, 0xe0008),
  54. /* Disable C1E */
  55. msr_clrsetbits_64(MSR_POWER_CTL, 2, 0);
  56. msr_setbits_64(MSR_POWER_MISC, 0x44);
  57. /* Set this core to max frequency ratio */
  58. set_max_freq();
  59. return 0;
  60. }
  61. static unsigned bus_freq(void)
  62. {
  63. msr_t clk_info = msr_read(MSR_BSEL_CR_OVERCLOCK_CONTROL);
  64. switch (clk_info.lo & 0x3) {
  65. case 0:
  66. return 83333333;
  67. case 1:
  68. return 100000000;
  69. case 2:
  70. return 133333333;
  71. case 3:
  72. return 116666666;
  73. default:
  74. return 0;
  75. }
  76. }
  77. static unsigned long tsc_freq(void)
  78. {
  79. msr_t platform_info;
  80. ulong bclk = bus_freq();
  81. if (!bclk)
  82. return 0;
  83. platform_info = msr_read(MSR_PLATFORM_INFO);
  84. return bclk * ((platform_info.lo >> 8) & 0xff);
  85. }
  86. static int baytrail_get_info(struct udevice *dev, struct cpu_info *info)
  87. {
  88. info->cpu_freq = tsc_freq();
  89. info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU;
  90. return 0;
  91. }
  92. static int baytrail_get_count(struct udevice *dev)
  93. {
  94. int ecx = 0;
  95. /*
  96. * Use the algorithm described in Intel 64 and IA-32 Architectures
  97. * Software Developer's Manual Volume 3 (3A, 3B & 3C): System
  98. * Programming Guide, Jan-2015. Section 8.9.2: Hierarchical Mapping
  99. * of CPUID Extended Topology Leaf.
  100. */
  101. while (1) {
  102. struct cpuid_result leaf_b;
  103. leaf_b = cpuid_ext(0xb, ecx);
  104. /*
  105. * Bay Trail doesn't have hyperthreading so just determine the
  106. * number of cores by from level type (ecx[15:8] == * 2)
  107. */
  108. if ((leaf_b.ecx & 0xff00) == 0x0200)
  109. return leaf_b.ebx & 0xffff;
  110. ecx++;
  111. }
  112. return 0;
  113. }
  114. static const struct cpu_ops cpu_x86_baytrail_ops = {
  115. .get_desc = cpu_x86_get_desc,
  116. .get_info = baytrail_get_info,
  117. .get_count = baytrail_get_count,
  118. };
  119. static const struct udevice_id cpu_x86_baytrail_ids[] = {
  120. { .compatible = "intel,baytrail-cpu" },
  121. { }
  122. };
  123. U_BOOT_DRIVER(cpu_x86_baytrail_drv) = {
  124. .name = "cpu_x86_baytrail",
  125. .id = UCLASS_CPU,
  126. .of_match = cpu_x86_baytrail_ids,
  127. .bind = cpu_x86_bind,
  128. .probe = cpu_x86_baytrail_probe,
  129. .ops = &cpu_x86_baytrail_ops,
  130. };