blob: 24c667b845d844d992c7bd06a576d6d34efea6a6 [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
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05304#include <assert.h>
5#include <device/pci_def.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +02006#include <device/pci_ops.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05307#include <commonlib/helpers.h>
Aaron Durbin5391e552017-06-02 12:16:04 -05008#include <cpu/x86/mtrr.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05309#include <fast_spi_def.h>
Srinidhi N Kaushik60949082020-11-25 01:58:34 -080010#include <intelblocks/dmi.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053011#include <intelblocks/fast_spi.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050012#include <lib.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053013#include <soc/pci_devs.h>
14#include <spi_flash.h>
15#include <spi-generic.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053016
17/*
18 * Get the FAST_SPIBAR.
19 */
20void *fast_spi_get_bar(void)
21{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020022#if defined(__SIMPLE_DEVICE__)
23 pci_devfn_t dev = PCH_DEV_SPI;
24#else
25 struct device *dev = PCH_DEV_SPI;
26#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053027 uintptr_t bar;
28
29 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
30 assert(bar != 0);
31 /*
32 * Bits 31-12 are the base address as per EDS for SPI,
33 * Don't care about 0-11 bit
34 */
35 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
36}
37
38/*
39 * Disable the BIOS write protect and Enable Prefetching and Caching.
40 */
41void fast_spi_init(void)
42{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020043#if defined(__SIMPLE_DEVICE__)
44 pci_devfn_t dev = PCH_DEV_SPI;
45#else
46 struct device *dev = PCH_DEV_SPI;
47#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053048 uint8_t bios_cntl;
49
50 bios_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
51
52 /* Disable the BIOS write protect so write commands are allowed. */
53 bios_cntl &= ~SPIBAR_BIOS_CONTROL_EISS;
54 bios_cntl |= SPIBAR_BIOS_CONTROL_WPD;
55 /* Enable Prefetching and caching. */
56 bios_cntl |= SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE;
57 bios_cntl &= ~SPIBAR_BIOS_CONTROL_CACHE_DISABLE;
58
59 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bios_cntl);
60}
61
62/*
Subrata Banik8e390092017-07-21 10:06:17 +053063 * Set FAST_SPIBAR BIOS Control register based on input bit field.
Barnali Sarkar89331cd2017-02-16 17:22:37 +053064 */
65static void fast_spi_set_bios_control_reg(uint8_t bios_cntl_bit)
66{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020067#if defined(__SIMPLE_DEVICE__)
68 pci_devfn_t dev = PCH_DEV_SPI;
69#else
70 struct device *dev = PCH_DEV_SPI;
71#endif
Barnali Sarkar89331cd2017-02-16 17:22:37 +053072 uint8_t bc_cntl;
73
74 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
75 bc_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
76 bc_cntl |= bios_cntl_bit;
77 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bc_cntl);
78}
79
80/*
Subrata Banik8e390092017-07-21 10:06:17 +053081 * Ensure an additional read back after performing lock down
82 */
83static void fast_spi_read_post_write(uint8_t reg)
84{
85 pci_read_config8(PCH_DEV_SPI, reg);
86}
87
88/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +053089 * Set FAST_SPIBAR BIOS Control BILD bit.
90 */
91void fast_spi_set_bios_interface_lock_down(void)
92{
93 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_BILD);
Subrata Banik8e390092017-07-21 10:06:17 +053094
95 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053096}
97
98/*
99 * Set FAST_SPIBAR BIOS Control LE bit.
100 */
101void fast_spi_set_lock_enable(void)
102{
103 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_LOCK_ENABLE);
Subrata Banik8e390092017-07-21 10:06:17 +0530104
Subrata Banik8e390092017-07-21 10:06:17 +0530105 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530106}
107
108/*
109 * Set FAST_SPIBAR BIOS Control EISS bit.
110 */
111void fast_spi_set_eiss(void)
112{
113 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_EISS);
Subrata Banik8e390092017-07-21 10:06:17 +0530114
115 fast_spi_read_post_write(SPIBAR_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530116}
117
118/*
119 * Set FAST_SPI opcode menu.
120 */
121void fast_spi_set_opcode_menu(void)
122{
123 void *spibar = fast_spi_get_bar();
124
125 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
126 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
127 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
128 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
129}
130
131/*
132 * Lock FAST_SPIBAR.
Barnali Sarkar8e513192017-07-19 16:09:56 +0530133 * Use 16bit write to avoid touching two upper bytes what may cause the write
134 * cycle to fail in case a prior transaction has not completed.
135 * While WRSDIS is lockable with FLOCKDN, writing both in the same
136 * cycle is guaranteed to work by design.
137 *
138 * Avoid read->modify->write not to clear RW1C bits unintentionally.
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530139 */
140void fast_spi_lock_bar(void)
141{
142 void *spibar = fast_spi_get_bar();
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700143 uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN;
144
Julius Wernercd49cce2019-03-05 16:53:33 -0800145 if (CONFIG(FAST_SPI_DISABLE_WRITE_STATUS))
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700146 hsfs |= SPIBAR_HSFSTS_WRSDIS;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530147
Barnali Sarkar8e513192017-07-19 16:09:56 +0530148 write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530149}
150
151/*
Barnali Sarkar4f6e3412017-08-17 11:49:27 +0530152 * Set FAST_SPIBAR + DLOCK (0x0C) register bits to discrete lock the
153 * FAST_SPI Protected Range (PR) registers.
154 */
155void fast_spi_pr_dlock(void)
156{
157 void *spibar = fast_spi_get_bar();
158 uint32_t dlock;
159
160 dlock = read32(spibar + SPIBAR_DLOCK);
161 dlock |= (SPIBAR_DLOCK_PR0LOCKDN | SPIBAR_DLOCK_PR1LOCKDN
162 | SPIBAR_DLOCK_PR2LOCKDN | SPIBAR_DLOCK_PR3LOCKDN
163 | SPIBAR_DLOCK_PR4LOCKDN);
164
165 write32(spibar + SPIBAR_DLOCK, dlock);
166}
167
168/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530169 * Set FAST_SPIBAR Soft Reset Data Register value.
170 */
171void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
172{
173 void *spibar = fast_spi_get_bar();
174 uint32_t ssl, ssms;
175
176 /* Set Strap Lock Disable */
177 ssl = read32(spibar + SPIBAR_RESET_LOCK);
178 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
179 write32(spibar + SPIBAR_RESET_LOCK, ssl);
180
181 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
182 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
183
184 /* Set Strap Mux Select set to '1' */
185 ssms = read32(spibar + SPIBAR_RESET_CTRL);
186 ssms |= SPIBAR_RESET_CTRL_SSMC;
187 write32(spibar + SPIBAR_RESET_CTRL, ssms);
188
189 /* Set Strap Lock Enable */
190 ssl = read32(spibar + SPIBAR_RESET_LOCK);
191 ssl |= SPIBAR_RESET_LOCK_ENABLE;
192 write32(spibar + SPIBAR_RESET_LOCK, ssl);
193}
194
195/*
196 * Returns bios_start and fills in size of the BIOS region.
197 */
198size_t fast_spi_get_bios_region(size_t *bios_size)
199{
200 size_t bios_start, bios_end;
201 /*
202 * BIOS_BFPREG provides info about BIOS Flash Primary Region
203 * Base and Limit.
204 * Base and Limit fields are in units of 4KiB.
205 */
206 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
207
208 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
209 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
210 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
211 *bios_size = bios_end - bios_start;
212 return bios_start;
213}
214
Aaron Durbin5391e552017-06-02 12:16:04 -0500215void fast_spi_cache_bios_region(void)
216{
Aaron Durbin5391e552017-06-02 12:16:04 -0500217 size_t bios_size;
218 uint32_t alignment;
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500219 const int type = MTRR_TYPE_WRPROT;
220 uintptr_t base;
Aaron Durbin5391e552017-06-02 12:16:04 -0500221
222 /* Only the IFD BIOS region is memory mapped (at top of 4G) */
223 fast_spi_get_bios_region(&bios_size);
224
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800225 /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will
226 * cause memory type conflict when setting memory type to write
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +0100227 * protection, so limit the cached BIOS region to be no more than 16MB.
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800228 * */
229 bios_size = MIN(bios_size, 16 * MiB);
John Zhao1ceac4e2019-07-09 14:27:28 -0700230 if (bios_size <= 0)
John Zhao2bb432e2019-05-21 19:32:51 -0700231 return;
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800232
Aaron Durbin5391e552017-06-02 12:16:04 -0500233 /* Round to power of two */
Paul Menzel64e83402017-10-27 11:05:14 +0200234 alignment = 1UL << (log2_ceil(bios_size));
Aaron Durbin5391e552017-06-02 12:16:04 -0500235 bios_size = ALIGN_UP(bios_size, alignment);
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500236 base = 4ULL*GiB - bios_size;
237
Subrata Banik42c44c22019-05-15 20:27:04 +0530238 if (ENV_PAYLOAD_LOADER) {
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500239 mtrr_use_temp_range(base, bios_size, type);
240 } else {
241 int mtrr = get_free_var_mtrr();
242
243 if (mtrr == -1)
244 return;
245
246 set_var_mtrr(mtrr, base, bios_size, type);
247 }
Aaron Durbin5391e552017-06-02 12:16:04 -0500248}
249
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530250/*
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800251 * Enable extended BIOS support
252 * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS
253 * region support.
254 */
255static void fast_spi_enable_ext_bios(void)
256{
257#if defined(__SIMPLE_DEVICE__)
258 pci_devfn_t dev = PCH_DEV_SPI;
259#else
260 struct device *dev = PCH_DEV_SPI;
261#endif
262 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
263 return;
264
265#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)
266 /*
267 * Ensure that the base for the extended window in host space is a multiple of 32 MiB
268 * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed
269 * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS
270 * region happens at the top of the extended window in this case.
271 */
272 _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE,
273 "Extended BIOS window base must be a multiple of 32 * MiB!");
274 _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB),
275 "Only 32MiB windows are supported for extended BIOS!");
276#endif
277
278 /* Confgiure DMI Source decode for Extended BIOS Region */
279 if (dmi_enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE,
280 soc_get_spi_dmi_destination_id()) == CB_ERR)
281 return;
282
283 /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */
284 pci_write_config32(dev, SPI_CFG_BAR1,
285 CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
286
287 /*
288 * Since the top 16MiB of the BIOS region is always decoded by the standard window
289 * below the 4G boundary, we need to map the rest of the BIOS region that lies
290 * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to
291 * 16MiB. This determines the maximum address in the SPI flash space that is mapped
292 * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is
293 * basically the offset from the end of the BIOS region that will be mapped to the top
294 * of the extended window.
295 * This enables the decoding as follows:
296 -Standard decode window: (bios_region_top - 16MiB) to bios_region_top
297 -Extended decode window:
298 (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB))
299 to (bios_region_top - 16MiB).
300 */
301 pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB));
302
303 /* Program EXT_BIOS EN */
304 pci_or_config32(dev, SPIBAR_BIOS_CONTROL, SPIBAR_BIOS_CONTROL_EXT_BIOS_ENABLE);
305}
306
307/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530308 * Program temporary BAR for SPI in case any of the stages before ramstage need
309 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
310 * enumeration.
311 */
312void fast_spi_early_init(uintptr_t spi_base_address)
313{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200314#if defined(__SIMPLE_DEVICE__)
315 pci_devfn_t dev = PCH_DEV_SPI;
316#else
317 struct device *dev = PCH_DEV_SPI;
318#endif
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200319 uint16_t pcireg;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530320
321 /* Assign Resources to SPI Controller */
322 /* Clear BIT 1-2 SPI Command Register */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200323 pcireg = pci_read_config16(dev, PCI_COMMAND);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530324 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200325 pci_write_config16(dev, PCI_COMMAND, pcireg);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530326
327 /* Program Temporary BAR for SPI */
328 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
329 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
330
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800331 /*
332 * Enable extended bios support. Since it configures memory BAR, this is done before
333 * enabling MMIO space.
334 */
335 fast_spi_enable_ext_bios();
336
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530337 /* Enable Bus Master and MMIO Space */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200338 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530339
340 /* Initialize SPI to allow BIOS to write/erase on flash. */
341 fast_spi_init();
342}
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700343
344/* Read SPI Write Protect disable status. */
345bool fast_spi_wpd_status(void)
346{
347 return pci_read_config16(PCH_DEV_SPI, SPIBAR_BIOS_CONTROL) &
348 SPIBAR_BIOS_CONTROL_WPD;
349}
350
351/* Enable SPI Write Protect. */
352void fast_spi_enable_wp(void)
353{
Elyes HAOUAS68c851b2018-06-12 22:06:09 +0200354#if defined(__SIMPLE_DEVICE__)
355 pci_devfn_t dev = PCH_DEV_SPI;
356#else
357 struct device *dev = PCH_DEV_SPI;
358#endif
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700359 uint8_t bios_cntl;
360
361 bios_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
362 bios_cntl &= ~SPIBAR_BIOS_CONTROL_WPD;
363 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bios_cntl);
364}