blob: d6e8f53ee48e48bd1828bd4ecb069f01ba1b6e48 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Barnali Sarkar89331cd2017-02-16 17:22:37 +05302
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -08003#include <arch/romstage.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02004#include <device/mmio.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05305#include <assert.h>
6#include <device/pci_def.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +02007#include <device/pci_ops.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05308#include <commonlib/helpers.h>
Aaron Durbin5391e552017-06-02 12:16:04 -05009#include <cpu/x86/mtrr.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053010#include <fast_spi_def.h>
Srinidhi N Kaushik60949082020-11-25 01:58:34 -080011#include <intelblocks/dmi.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053012#include <intelblocks/fast_spi.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050013#include <lib.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053014#include <soc/pci_devs.h>
15#include <spi_flash.h>
16#include <spi-generic.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053017
18/*
19 * Get the FAST_SPIBAR.
20 */
21void *fast_spi_get_bar(void)
22{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020023#if defined(__SIMPLE_DEVICE__)
24 pci_devfn_t dev = PCH_DEV_SPI;
25#else
26 struct device *dev = PCH_DEV_SPI;
27#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053028 uintptr_t bar;
29
30 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
31 assert(bar != 0);
32 /*
33 * Bits 31-12 are the base address as per EDS for SPI,
34 * Don't care about 0-11 bit
35 */
36 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
37}
38
39/*
40 * Disable the BIOS write protect and Enable Prefetching and Caching.
41 */
42void fast_spi_init(void)
43{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020044#if defined(__SIMPLE_DEVICE__)
45 pci_devfn_t dev = PCH_DEV_SPI;
46#else
47 struct device *dev = PCH_DEV_SPI;
48#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053049 uint8_t bios_cntl;
50
51 bios_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
52
53 /* Disable the BIOS write protect so write commands are allowed. */
54 bios_cntl &= ~SPIBAR_BIOS_CONTROL_EISS;
55 bios_cntl |= SPIBAR_BIOS_CONTROL_WPD;
56 /* Enable Prefetching and caching. */
57 bios_cntl |= SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE;
58 bios_cntl &= ~SPIBAR_BIOS_CONTROL_CACHE_DISABLE;
59
60 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bios_cntl);
61}
62
63/*
Subrata Banik8e390092017-07-21 10:06:17 +053064 * Set FAST_SPIBAR BIOS Control register based on input bit field.
Barnali Sarkar89331cd2017-02-16 17:22:37 +053065 */
66static void fast_spi_set_bios_control_reg(uint8_t bios_cntl_bit)
67{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020068#if defined(__SIMPLE_DEVICE__)
69 pci_devfn_t dev = PCH_DEV_SPI;
70#else
71 struct device *dev = PCH_DEV_SPI;
72#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053073 uint8_t bc_cntl;
74
75 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
76 bc_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
77 bc_cntl |= bios_cntl_bit;
78 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bc_cntl);
79}
80
81/*
Subrata Banik8e390092017-07-21 10:06:17 +053082 * Ensure an additional read back after performing lock down
83 */
84static void fast_spi_read_post_write(uint8_t reg)
85{
86 pci_read_config8(PCH_DEV_SPI, reg);
87}
88
89/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +053090 * Set FAST_SPIBAR BIOS Control BILD bit.
91 */
92void fast_spi_set_bios_interface_lock_down(void)
93{
94 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_BILD);
Subrata Banik8e390092017-07-21 10:06:17 +053095
96 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053097}
98
99/*
100 * Set FAST_SPIBAR BIOS Control LE bit.
101 */
102void fast_spi_set_lock_enable(void)
103{
104 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_LOCK_ENABLE);
Subrata Banik8e390092017-07-21 10:06:17 +0530105
Subrata Banik8e390092017-07-21 10:06:17 +0530106 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530107}
108
109/*
110 * Set FAST_SPIBAR BIOS Control EISS bit.
111 */
112void fast_spi_set_eiss(void)
113{
114 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_EISS);
Subrata Banik8e390092017-07-21 10:06:17 +0530115
116 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530117}
118
119/*
120 * Set FAST_SPI opcode menu.
121 */
122void fast_spi_set_opcode_menu(void)
123{
124 void *spibar = fast_spi_get_bar();
125
126 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
127 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
128 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
129 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
130}
131
132/*
133 * Lock FAST_SPIBAR.
Barnali Sarkar8e513192017-07-19 16:09:56 +0530134 * Use 16bit write to avoid touching two upper bytes what may cause the write
135 * cycle to fail in case a prior transaction has not completed.
136 * While WRSDIS is lockable with FLOCKDN, writing both in the same
137 * cycle is guaranteed to work by design.
138 *
139 * Avoid read->modify->write not to clear RW1C bits unintentionally.
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530140 */
141void fast_spi_lock_bar(void)
142{
143 void *spibar = fast_spi_get_bar();
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700144 uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN;
145
Julius Wernercd49cce2019-03-05 16:53:33 -0800146 if (CONFIG(FAST_SPI_DISABLE_WRITE_STATUS))
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700147 hsfs |= SPIBAR_HSFSTS_WRSDIS;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530148
Barnali Sarkar8e513192017-07-19 16:09:56 +0530149 write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530150}
151
152/*
Barnali Sarkar4f6e3412017-08-17 11:49:27 +0530153 * Set FAST_SPIBAR + DLOCK (0x0C) register bits to discrete lock the
154 * FAST_SPI Protected Range (PR) registers.
155 */
156void fast_spi_pr_dlock(void)
157{
158 void *spibar = fast_spi_get_bar();
159 uint32_t dlock;
160
161 dlock = read32(spibar + SPIBAR_DLOCK);
162 dlock |= (SPIBAR_DLOCK_PR0LOCKDN | SPIBAR_DLOCK_PR1LOCKDN
163 | SPIBAR_DLOCK_PR2LOCKDN | SPIBAR_DLOCK_PR3LOCKDN
164 | SPIBAR_DLOCK_PR4LOCKDN);
165
166 write32(spibar + SPIBAR_DLOCK, dlock);
167}
168
169/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530170 * Set FAST_SPIBAR Soft Reset Data Register value.
171 */
172void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
173{
174 void *spibar = fast_spi_get_bar();
175 uint32_t ssl, ssms;
176
177 /* Set Strap Lock Disable */
178 ssl = read32(spibar + SPIBAR_RESET_LOCK);
179 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
180 write32(spibar + SPIBAR_RESET_LOCK, ssl);
181
182 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
183 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
184
185 /* Set Strap Mux Select set to '1' */
186 ssms = read32(spibar + SPIBAR_RESET_CTRL);
187 ssms |= SPIBAR_RESET_CTRL_SSMC;
188 write32(spibar + SPIBAR_RESET_CTRL, ssms);
189
190 /* Set Strap Lock Enable */
191 ssl = read32(spibar + SPIBAR_RESET_LOCK);
192 ssl |= SPIBAR_RESET_LOCK_ENABLE;
193 write32(spibar + SPIBAR_RESET_LOCK, ssl);
194}
195
196/*
197 * Returns bios_start and fills in size of the BIOS region.
198 */
199size_t fast_spi_get_bios_region(size_t *bios_size)
200{
201 size_t bios_start, bios_end;
202 /*
203 * BIOS_BFPREG provides info about BIOS Flash Primary Region
204 * Base and Limit.
205 * Base and Limit fields are in units of 4KiB.
206 */
207 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
208
209 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
210 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
211 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
212 *bios_size = bios_end - bios_start;
213 return bios_start;
214}
215
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800216static bool fast_spi_ext_bios_cache_range(uintptr_t *base, size_t *size)
217{
218 uint32_t alignment;
219 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
220 return false;
221
222 fast_spi_get_ext_bios_window(base, size);
223
224 /* Enable extended bios only if Size of Bios region is greater than 16MiB */
225 if (*size == 0 || *base == 0)
226 return false;
227
228 /* Round to power of two */
229 alignment = 1UL << (log2_ceil(*size));
230 *size = ALIGN_UP(*size, alignment);
231 *base = ALIGN_DOWN(*base, *size);
232
233 return true;
234}
235
236static void fast_spi_cache_ext_bios_window(void)
237{
238 size_t ext_bios_size;
239 uintptr_t ext_bios_base;
240 const int type = MTRR_TYPE_WRPROT;
241
242 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
243 return;
244
245 int mtrr = get_free_var_mtrr();
246 if (mtrr == -1)
247 return;
248 set_var_mtrr(mtrr, ext_bios_base, ext_bios_size, type);
249}
250
251void fast_spi_cache_ext_bios_postcar(struct postcar_frame *pcf)
252{
253 size_t ext_bios_size;
254 uintptr_t ext_bios_base;
255 const int type = MTRR_TYPE_WRPROT;
256
257 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
258 return;
259
260 postcar_frame_add_mtrr(pcf, ext_bios_base, ext_bios_size, type);
261}
262
Aaron Durbin5391e552017-06-02 12:16:04 -0500263void fast_spi_cache_bios_region(void)
264{
Aaron Durbin5391e552017-06-02 12:16:04 -0500265 size_t bios_size;
266 uint32_t alignment;
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500267 const int type = MTRR_TYPE_WRPROT;
268 uintptr_t base;
Aaron Durbin5391e552017-06-02 12:16:04 -0500269
270 /* Only the IFD BIOS region is memory mapped (at top of 4G) */
271 fast_spi_get_bios_region(&bios_size);
272
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800273 /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will
274 * cause memory type conflict when setting memory type to write
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +0100275 * protection, so limit the cached BIOS region to be no more than 16MB.
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800276 * */
277 bios_size = MIN(bios_size, 16 * MiB);
John Zhao1ceac4e2019-07-09 14:27:28 -0700278 if (bios_size <= 0)
John Zhao2bb432e2019-05-21 19:32:51 -0700279 return;
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800280
Aaron Durbin5391e552017-06-02 12:16:04 -0500281 /* Round to power of two */
Paul Menzel64e83402017-10-27 11:05:14 +0200282 alignment = 1UL << (log2_ceil(bios_size));
Aaron Durbin5391e552017-06-02 12:16:04 -0500283 bios_size = ALIGN_UP(bios_size, alignment);
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500284 base = 4ULL*GiB - bios_size;
285
Subrata Banik42c44c22019-05-15 20:27:04 +0530286 if (ENV_PAYLOAD_LOADER) {
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500287 mtrr_use_temp_range(base, bios_size, type);
288 } else {
289 int mtrr = get_free_var_mtrr();
290
291 if (mtrr == -1)
292 return;
293
294 set_var_mtrr(mtrr, base, bios_size, type);
295 }
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800296
297 /* Check if caching is needed for extended bios region if supported */
298 fast_spi_cache_ext_bios_window();
Aaron Durbin5391e552017-06-02 12:16:04 -0500299}
300
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530301/*
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800302 * Enable extended BIOS support
303 * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS
304 * region support.
305 */
306static void fast_spi_enable_ext_bios(void)
307{
308#if defined(__SIMPLE_DEVICE__)
309 pci_devfn_t dev = PCH_DEV_SPI;
310#else
311 struct device *dev = PCH_DEV_SPI;
312#endif
313 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
314 return;
315
316#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)
317 /*
318 * Ensure that the base for the extended window in host space is a multiple of 32 MiB
319 * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed
320 * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS
321 * region happens at the top of the extended window in this case.
322 */
323 _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE,
324 "Extended BIOS window base must be a multiple of 32 * MiB!");
325 _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB),
326 "Only 32MiB windows are supported for extended BIOS!");
327#endif
328
329 /* Confgiure DMI Source decode for Extended BIOS Region */
330 if (dmi_enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE,
331 soc_get_spi_dmi_destination_id()) == CB_ERR)
332 return;
333
334 /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */
335 pci_write_config32(dev, SPI_CFG_BAR1,
336 CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
337
338 /*
339 * Since the top 16MiB of the BIOS region is always decoded by the standard window
340 * below the 4G boundary, we need to map the rest of the BIOS region that lies
341 * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to
342 * 16MiB. This determines the maximum address in the SPI flash space that is mapped
343 * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is
344 * basically the offset from the end of the BIOS region that will be mapped to the top
345 * of the extended window.
346 * This enables the decoding as follows:
347 -Standard decode window: (bios_region_top - 16MiB) to bios_region_top
348 -Extended decode window:
349 (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB))
350 to (bios_region_top - 16MiB).
351 */
352 pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB));
353
354 /* Program EXT_BIOS EN */
355 pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_ENABLE);
356}
357
358/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530359 * Program temporary BAR for SPI in case any of the stages before ramstage need
360 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
361 * enumeration.
362 */
363void fast_spi_early_init(uintptr_t spi_base_address)
364{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200365#if defined(__SIMPLE_DEVICE__)
366 pci_devfn_t dev = PCH_DEV_SPI;
367#else
368 struct device *dev = PCH_DEV_SPI;
369#endif
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200370 uint16_t pcireg;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530371
372 /* Assign Resources to SPI Controller */
373 /* Clear BIT 1-2 SPI Command Register */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200374 pcireg = pci_read_config16(dev, PCI_COMMAND);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530375 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200376 pci_write_config16(dev, PCI_COMMAND, pcireg);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530377
378 /* Program Temporary BAR for SPI */
379 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
380 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
381
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800382 /*
383 * Enable extended bios support. Since it configures memory BAR, this is done before
384 * enabling MMIO space.
385 */
386 fast_spi_enable_ext_bios();
387
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530388 /* Enable Bus Master and MMIO Space */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200389 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530390
391 /* Initialize SPI to allow BIOS to write/erase on flash. */
392 fast_spi_init();
393}
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700394
395/* Read SPI Write Protect disable status. */
396bool fast_spi_wpd_status(void)
397{
398 return pci_read_config16(PCH_DEV_SPI, SPIBAR_BIOS_CONTROL) &
399 SPIBAR_BIOS_CONTROL_WPD;
400}
401
402/* Enable SPI Write Protect. */
403void fast_spi_enable_wp(void)
404{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200405#if defined(__SIMPLE_DEVICE__)
406 pci_devfn_t dev = PCH_DEV_SPI;
407#else
408 struct device *dev = PCH_DEV_SPI;
409#endif
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700410 uint8_t bios_cntl;
411
412 bios_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
413 bios_cntl &= ~SPIBAR_BIOS_CONTROL_WPD;
414 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bios_cntl);
415}