Angel Pons | 6e5aabd | 2020-03-23 23:44:42 +0100 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 2 | |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 3 | #include <arch/cpu.h> |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 4 | #include <console/console.h> |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 5 | #include <cpu/intel/model_206ax/model_206ax.h> |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 6 | #include <northbridge/intel/sandybridge/sandybridge.h> |
| 7 | #include <southbridge/intel/bd82x6x/pch.h> |
| 8 | |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 9 | static void dmi_recipe(void) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 10 | { |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 11 | const u32 cpuid = cpu_get_cpuid(); |
| 12 | |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 13 | int i; |
| 14 | |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 15 | /* The DMI recipe is only needed on Ivy Bridge */ |
| 16 | if (!IS_IVY_CPU(cpuid)) |
| 17 | return; |
| 18 | |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 19 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 20 | dmibar_setbits32(0x0914 + (i << 5), 1 << 31); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 21 | } |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 22 | |
| 23 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 24 | dmibar_clrbits32(0x0a00 + (i << 4), 3 << 26); |
| 25 | dmibar_setbits32(0x0a04 + (i << 4), 1 << 11); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 26 | } |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 27 | dmibar_clrsetbits32(0x0c30, 0xf << 28, 1 << 30); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 28 | |
| 29 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 30 | dmibar_clrbits32(0x0904 + (i << 5), 7 << 22); |
| 31 | dmibar_clrbits32(0x090c + (i << 5), 7 << 17); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 32 | } |
| 33 | |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 34 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 35 | dmibar_clrbits32(0x090c + (i << 5), 0xf << 21); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 39 | dmibar_read32(0x0904 + (i << 5)); // !!! = 0x7a1842ec |
| 40 | dmibar_write32(0x0904 + (i << 5), 0x7a1842ec); |
| 41 | dmibar_read32(0x090c + (i << 5)); // !!! = 0x00000208 |
| 42 | dmibar_write32(0x090c + (i << 5), 0x00000128); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 46 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x46139008 |
| 47 | dmibar_write32(0x0700 + (i << 5), 0x46139008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 48 | } |
| 49 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 50 | dmibar_read32(0x0c04); // !!! = 0x2e680008 |
| 51 | dmibar_write32(0x0c04, 0x2e680008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 52 | |
| 53 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 54 | dmibar_read32(0x0904 + (i << 5)); // !!! = 0x7a1842ec |
| 55 | dmibar_write32(0x0904 + (i << 5), 0x3a1842ec); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 59 | dmibar_read32(0x0910 + (i << 5)); // !!! = 0x00006300 |
| 60 | dmibar_write32(0x0910 + (i << 5), 0x00004300); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 64 | dmibar_read32(0x0a00 + (i << 4)); // !!! = 0x03042010 |
| 65 | dmibar_write32(0x0a00 + (i << 4), 0x03042018); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 66 | } |
| 67 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 68 | dmibar_read32(0x0c00); // !!! = 0x29700c08 |
| 69 | dmibar_write32(0x0c00, 0x29700c08); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 70 | |
| 71 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 72 | dmibar_read32(0x0a04 + (i << 4)); // !!! = 0x0c0708f0 |
| 73 | dmibar_write32(0x0a04 + (i << 4), 0x0c0718f0); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 74 | } |
| 75 | |
| 76 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 77 | dmibar_read32(0x0900 + (i << 5)); // !!! = 0x50000000 |
| 78 | dmibar_write32(0x0900 + (i << 5), 0x50000000); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 79 | } |
| 80 | |
| 81 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 82 | dmibar_read32(0x0908 + (i << 5)); // !!! = 0x51ffffff |
| 83 | dmibar_write32(0x0908 + (i << 5), 0x51ffffff); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 87 | dmibar_read32(0x0a00 + (i << 4)); // !!! = 0x03042018 |
| 88 | dmibar_write32(0x0a00 + (i << 4), 0x03042018); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 89 | } |
| 90 | |
| 91 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 92 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x46139008 |
| 93 | dmibar_write32(0x0700 + (i << 5), 0x46139008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 97 | dmibar_read32(0x0904 + (i << 5)); // !!! = 0x3a1842ec |
| 98 | dmibar_write32(0x0904 + (i << 5), 0x3a1846ec); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 102 | dmibar_read32(0x0a00 + (i << 4)); // !!! = 0x03042018 |
| 103 | dmibar_write32(0x0a00 + (i << 4), 0x03042018); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 104 | } |
| 105 | |
| 106 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 107 | dmibar_read32(0x0908 + (i << 5)); // !!! = 0x51ffffff |
| 108 | dmibar_write32(0x0908 + (i << 5), 0x51ffffff); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 109 | } |
| 110 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 111 | dmibar_read32(0x0c00); // !!! = 0x29700c08 |
| 112 | dmibar_write32(0x0c00, 0x29700c08); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 113 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 114 | dmibar_read32(0x0c0c); // !!! = 0x16063400 |
| 115 | dmibar_write32(0x0c0c, 0x00063400); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 116 | |
| 117 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 118 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x46139008 |
| 119 | dmibar_write32(0x0700 + (i << 5), 0x46339008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 123 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x46339008 |
| 124 | dmibar_write32(0x0700 + (i << 5), 0x45339008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 128 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x45339008 |
| 129 | dmibar_write32(0x0700 + (i << 5), 0x453b9008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 133 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x453b9008 |
| 134 | dmibar_write32(0x0700 + (i << 5), 0x45bb9008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 138 | dmibar_read32(0x0700 + (i << 5)); // !!! = 0x45bb9008 |
| 139 | dmibar_write32(0x0700 + (i << 5), 0x45fb9008); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 143 | dmibar_read32(0x0914 + (i << 5)); // !!! = 0x9021a080 |
| 144 | dmibar_write32(0x0914 + (i << 5), 0x9021a280); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 145 | } |
| 146 | |
| 147 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 148 | dmibar_read32(0x0914 + (i << 5)); // !!! = 0x9021a080 |
| 149 | dmibar_write32(0x0914 + (i << 5), 0x9821a280); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 150 | } |
| 151 | |
| 152 | for (i = 0; i < 4; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 153 | dmibar_read32(0x0a00 + (i << 4)); // !!! = 0x03042018 |
| 154 | dmibar_write32(0x0a00 + (i << 4), 0x03242018); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 155 | } |
| 156 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 157 | dmibar_read32(0x0258); // !!! = 0x40000600 |
| 158 | dmibar_write32(0x0258, 0x60000600); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 159 | |
| 160 | for (i = 0; i < 2; i++) { |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 161 | dmibar_read32(0x0904 + (i << 5)); // !!! = 0x3a1846ec |
| 162 | dmibar_write32(0x0904 + (i << 5), 0x2a1846ec); |
| 163 | dmibar_read32(0x0914 + (i << 5)); // !!! = 0x9821a280 |
| 164 | dmibar_write32(0x0914 + (i << 5), 0x98200280); |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 165 | } |
| 166 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 167 | dmibar_read32(DMIL0SLAT); // !!! = 0x00c26460 |
| 168 | dmibar_write32(DMIL0SLAT, 0x00c2403c); |
Angel Pons | 64b8862 | 2020-12-07 15:25:36 +0100 | [diff] [blame] | 169 | } |
| 170 | |
| 171 | void early_init_dmi(void) |
| 172 | { |
| 173 | dmi_recipe(); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 174 | |
| 175 | early_pch_init_native_dmi_pre(); |
| 176 | |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 177 | /* Write once settings */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 178 | dmibar_clrsetbits32(DMILCAP, 0x3f00f, |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 179 | (2 << 0) | // 5GT/s |
| 180 | (2 << 12) | // L0s 128 ns to less than 256 ns |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 181 | (2 << 15)); // L1 2 us to less than 4 us |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 182 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 183 | dmibar_setbits8(DMILCTL, 1 << 5); // Retrain link |
| 184 | while (dmibar_read16(DMILSTS) & TXTRN) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 185 | ; |
| 186 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 187 | dmibar_setbits8(DMILCTL, 1 << 5); // Retrain link |
| 188 | while (dmibar_read16(DMILSTS) & TXTRN) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 189 | ; |
| 190 | |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 191 | const u8 w = (dmibar_read16(DMILSTS) >> 4) & 0x1f; |
| 192 | const u16 t = (dmibar_read16(DMILSTS) & 0x0f) * 2500; |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 193 | |
| 194 | printk(BIOS_DEBUG, "DMI: Running at X%x @ %dMT/s\n", w, t); |
| 195 | /* |
| 196 | * Virtual Channel resources must match settings in RCBA! |
| 197 | * |
Angel Pons | e82b02c | 2020-03-18 13:09:39 +0100 | [diff] [blame] | 198 | * Channel Vp and Vm are documented in: |
| 199 | * "Desktop 4th Generation Intel Core Processor Family, Desktop Intel Pentium |
| 200 | * Processor Family, and Desktop Intel Celeron Processor Family Vol. 2" |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 201 | */ |
| 202 | |
| 203 | /* Channel 0: Enable, Set ID to 0, map TC0 and TC3 and TC4 to VC0. */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 204 | dmibar_write32(DMIVC0RCTL, 1 << 31 | 0 << 24 | 0x0c << 1 | 1); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 205 | /* Channel 1: Enable, Set ID to 1, map TC1 and TC5 to VC1. */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 206 | dmibar_write32(DMIVC1RCTL, 1 << 31 | 1 << 24 | 0x11 << 1); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 207 | /* Channel p: Enable, Set ID to 2, map TC2 and TC6 to VCp */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 208 | dmibar_write32(DMIVCPRCTL, 1 << 31 | 2 << 24 | 0x22 << 1); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 209 | /* Channel m: Enable, Set ID to 0, map TC7 to VCm */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 210 | dmibar_write32(DMIVCMRCTL, 1 << 31 | 7 << 24 | 0x40 << 1); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 211 | |
| 212 | /* Set Extended VC Count (EVCC) to 1 as Channel 1 is active. */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 213 | dmibar_setbits8(DMIPVCCAP1, 1 << 0); |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 214 | |
| 215 | early_pch_init_native_dmi_post(); |
| 216 | |
| 217 | /* |
| 218 | * BIOS Requirement: Check if DMI VC Negotiation was successful. |
| 219 | * Wait for virtual channels negotiation pending. |
| 220 | */ |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 221 | while (dmibar_read16(DMIVC0RSTS) & VC0NP) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 222 | ; |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 223 | while (dmibar_read16(DMIVC1RSTS) & VC1NP) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 224 | ; |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 225 | while (dmibar_read16(DMIVCPRSTS) & VCPNP) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 226 | ; |
Angel Pons | 66780a0 | 2021-03-26 13:33:22 +0100 | [diff] [blame] | 227 | while (dmibar_read16(DMIVCMRSTS) & VCMNP) |
Patrick Rudolph | 6aca7e6 | 2019-03-26 18:22:36 +0100 | [diff] [blame] | 228 | ; |
| 229 | } |