northbridge.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. /*
  2. * From Coreboot northbridge/intel/sandybridge/northbridge.c
  3. *
  4. * Copyright (C) 2007-2009 coresystems GmbH
  5. * Copyright (C) 2011 The Chromium Authors
  6. *
  7. * SPDX-License-Identifier: GPL-2.0
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <asm/msr.h>
  12. #include <asm/cpu.h>
  13. #include <asm/intel_regs.h>
  14. #include <asm/io.h>
  15. #include <asm/pci.h>
  16. #include <asm/processor.h>
  17. #include <asm/arch/pch.h>
  18. #include <asm/arch/model_206ax.h>
  19. #include <asm/arch/sandybridge.h>
  20. int bridge_silicon_revision(struct udevice *dev)
  21. {
  22. struct cpuid_result result;
  23. u16 bridge_id;
  24. u8 stepping;
  25. result = cpuid(1);
  26. stepping = result.eax & 0xf;
  27. dm_pci_read_config16(dev, PCI_DEVICE_ID, &bridge_id);
  28. bridge_id &= 0xf0;
  29. return bridge_id | stepping;
  30. }
  31. /*
  32. * Reserve everything between A segment and 1MB:
  33. *
  34. * 0xa0000 - 0xbffff: legacy VGA
  35. * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel)
  36. * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI
  37. */
  38. static const int legacy_hole_base_k = 0xa0000 / 1024;
  39. static const int legacy_hole_size_k = 384;
  40. static int get_pcie_bar(struct udevice *dev, u32 *base, u32 *len)
  41. {
  42. u32 pciexbar_reg;
  43. *base = 0;
  44. *len = 0;
  45. dm_pci_read_config32(dev, PCIEXBAR, &pciexbar_reg);
  46. if (!(pciexbar_reg & (1 << 0)))
  47. return 0;
  48. switch ((pciexbar_reg >> 1) & 3) {
  49. case 0: /* 256MB */
  50. *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
  51. (1 << 28));
  52. *len = 256 * 1024 * 1024;
  53. return 1;
  54. case 1: /* 128M */
  55. *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
  56. (1 << 28) | (1 << 27));
  57. *len = 128 * 1024 * 1024;
  58. return 1;
  59. case 2: /* 64M */
  60. *base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
  61. (1 << 28) | (1 << 27) | (1 << 26));
  62. *len = 64 * 1024 * 1024;
  63. return 1;
  64. }
  65. return 0;
  66. }
  67. static void add_fixed_resources(struct udevice *dev, int index)
  68. {
  69. u32 pcie_config_base, pcie_config_size;
  70. if (get_pcie_bar(dev, &pcie_config_base, &pcie_config_size)) {
  71. debug("Adding PCIe config bar base=0x%08x size=0x%x\n",
  72. pcie_config_base, pcie_config_size);
  73. }
  74. }
  75. static void northbridge_dmi_init(struct udevice *dev, int rev)
  76. {
  77. /* Clear error status bits */
  78. writel(0xffffffff, DMIBAR_REG(0x1c4));
  79. writel(0xffffffff, DMIBAR_REG(0x1d0));
  80. /* Steps prior to DMI ASPM */
  81. if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
  82. clrsetbits_le32(DMIBAR_REG(0x250), (1 << 22) | (1 << 20),
  83. 1 << 21);
  84. }
  85. setbits_le32(DMIBAR_REG(0x238), 1 << 29);
  86. if (rev >= SNB_STEP_D0) {
  87. setbits_le32(DMIBAR_REG(0x1f8), 1 << 16);
  88. } else if (rev >= SNB_STEP_D1) {
  89. clrsetbits_le32(DMIBAR_REG(0x1f8), 1 << 26, 1 << 16);
  90. setbits_le32(DMIBAR_REG(0x1fc), (1 << 12) | (1 << 23));
  91. }
  92. /* Enable ASPM on SNB link, should happen before PCH link */
  93. if ((rev & BASE_REV_MASK) == BASE_REV_SNB)
  94. setbits_le32(DMIBAR_REG(0xd04), 1 << 4);
  95. setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0));
  96. }
  97. static void northbridge_init(struct udevice *dev, int rev)
  98. {
  99. u32 bridge_type;
  100. add_fixed_resources(dev, 6);
  101. northbridge_dmi_init(dev, rev);
  102. bridge_type = readl(MCHBAR_REG(0x5f10));
  103. bridge_type &= ~0xff;
  104. if ((rev & BASE_REV_MASK) == BASE_REV_IVB) {
  105. /* Enable Power Aware Interrupt Routing - fixed priority */
  106. clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4);
  107. /* 30h for IvyBridge */
  108. bridge_type |= 0x30;
  109. } else {
  110. /* 20h for Sandybridge */
  111. bridge_type |= 0x20;
  112. }
  113. writel(bridge_type, MCHBAR_REG(0x5f10));
  114. /*
  115. * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU
  116. * that BIOS has initialized memory and power management
  117. */
  118. setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 1);
  119. debug("Set BIOS_RESET_CPL\n");
  120. /* Configure turbo power limits 1ms after reset complete bit */
  121. mdelay(1);
  122. set_power_limits(28);
  123. /*
  124. * CPUs with configurable TDP also need power limits set
  125. * in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT.
  126. */
  127. if (cpu_config_tdp_levels()) {
  128. msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);
  129. writel(msr.lo, MCHBAR_REG(0x59A0));
  130. writel(msr.hi, MCHBAR_REG(0x59A4));
  131. }
  132. /* Set here before graphics PM init */
  133. writel(0x00100001, MCHBAR_REG(0x5500));
  134. }
  135. static void sandybridge_setup_northbridge_bars(struct udevice *dev)
  136. {
  137. /* Set up all hardcoded northbridge BARs */
  138. debug("Setting up static registers\n");
  139. dm_pci_write_config32(dev, EPBAR, DEFAULT_EPBAR | 1);
  140. dm_pci_write_config32(dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
  141. dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1);
  142. dm_pci_write_config32(dev, MCHBAR + 4, (0LL + MCH_BASE_ADDRESS) >> 32);
  143. /* 64MB - busses 0-63 */
  144. dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
  145. dm_pci_write_config32(dev, PCIEXBAR + 4,
  146. (0LL + DEFAULT_PCIEXBAR) >> 32);
  147. dm_pci_write_config32(dev, DMIBAR, DEFAULT_DMIBAR | 1);
  148. dm_pci_write_config32(dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32);
  149. /* Set C0000-FFFFF to access RAM on both reads and writes */
  150. dm_pci_write_config8(dev, PAM0, 0x30);
  151. dm_pci_write_config8(dev, PAM1, 0x33);
  152. dm_pci_write_config8(dev, PAM2, 0x33);
  153. dm_pci_write_config8(dev, PAM3, 0x33);
  154. dm_pci_write_config8(dev, PAM4, 0x33);
  155. dm_pci_write_config8(dev, PAM5, 0x33);
  156. dm_pci_write_config8(dev, PAM6, 0x33);
  157. }
  158. static int bd82x6x_northbridge_early_init(struct udevice *dev)
  159. {
  160. const int chipset_type = SANDYBRIDGE_MOBILE;
  161. u32 capid0_a;
  162. u8 reg8;
  163. /* Device ID Override Enable should be done very early */
  164. dm_pci_read_config32(dev, 0xe4, &capid0_a);
  165. if (capid0_a & (1 << 10)) {
  166. dm_pci_read_config8(dev, 0xf3, &reg8);
  167. reg8 &= ~7; /* Clear 2:0 */
  168. if (chipset_type == SANDYBRIDGE_MOBILE)
  169. reg8 |= 1; /* Set bit 0 */
  170. dm_pci_write_config8(dev, 0xf3, reg8);
  171. }
  172. sandybridge_setup_northbridge_bars(dev);
  173. /* Device Enable */
  174. dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
  175. return 0;
  176. }
  177. static int bd82x6x_northbridge_probe(struct udevice *dev)
  178. {
  179. int rev;
  180. if (!(gd->flags & GD_FLG_RELOC))
  181. return bd82x6x_northbridge_early_init(dev);
  182. rev = bridge_silicon_revision(dev);
  183. northbridge_init(dev, rev);
  184. return 0;
  185. }
  186. static const struct udevice_id bd82x6x_northbridge_ids[] = {
  187. { .compatible = "intel,bd82x6x-northbridge" },
  188. { }
  189. };
  190. U_BOOT_DRIVER(bd82x6x_northbridge_drv) = {
  191. .name = "bd82x6x_northbridge",
  192. .id = UCLASS_NORTHBRIDGE,
  193. .of_match = bd82x6x_northbridge_ids,
  194. .probe = bd82x6x_northbridge_probe,
  195. };