blob: 843071e2a8140d3d135524267ec13ded7b69bb3f [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
Angel Pons52072432021-02-15 13:09:36 +01003#define __SIMPLE_DEVICE__
4
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -08005#include <arch/romstage.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02006#include <device/mmio.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05307#include <assert.h>
8#include <device/pci_def.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +02009#include <device/pci_ops.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053010#include <commonlib/helpers.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050011#include <cpu/x86/mtrr.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053012#include <fast_spi_def.h>
Srinidhi N Kaushik60949082020-11-25 01:58:34 -080013#include <intelblocks/dmi.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053014#include <intelblocks/fast_spi.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050015#include <lib.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053016#include <soc/pci_devs.h>
17#include <spi_flash.h>
18#include <spi-generic.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053019
20/*
21 * Get the FAST_SPIBAR.
22 */
23void *fast_spi_get_bar(void)
24{
Angel Pons52072432021-02-15 13:09:36 +010025 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053026 uintptr_t bar;
27
28 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
29 assert(bar != 0);
30 /*
31 * Bits 31-12 are the base address as per EDS for SPI,
32 * Don't care about 0-11 bit
33 */
34 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
35}
36
37/*
38 * Disable the BIOS write protect and Enable Prefetching and Caching.
39 */
40void fast_spi_init(void)
41{
Angel Pons52072432021-02-15 13:09:36 +010042 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053043 uint8_t bios_cntl;
44
Angel Pons122cc8c2021-02-15 17:18:55 +010045 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053046
47 /* Disable the BIOS write protect so write commands are allowed. */
Angel Pons122cc8c2021-02-15 17:18:55 +010048 bios_cntl &= ~SPI_BIOS_CONTROL_EISS;
49 bios_cntl |= SPI_BIOS_CONTROL_WPD;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053050 /* Enable Prefetching and caching. */
Angel Pons122cc8c2021-02-15 17:18:55 +010051 bios_cntl |= SPI_BIOS_CONTROL_PREFETCH_ENABLE;
52 bios_cntl &= ~SPI_BIOS_CONTROL_CACHE_DISABLE;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053053
Angel Pons122cc8c2021-02-15 17:18:55 +010054 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053055}
56
57/*
Subrata Banik8e390092017-07-21 10:06:17 +053058 * Set FAST_SPIBAR BIOS Control register based on input bit field.
Barnali Sarkar89331cd2017-02-16 17:22:37 +053059 */
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080060static void fast_spi_set_bios_control_reg(uint32_t bios_cntl_bit)
Barnali Sarkar89331cd2017-02-16 17:22:37 +053061{
Angel Pons52072432021-02-15 13:09:36 +010062 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080063 uint32_t bc_cntl;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053064
65 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
Angel Pons122cc8c2021-02-15 17:18:55 +010066 bc_cntl = pci_read_config32(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053067 bc_cntl |= bios_cntl_bit;
Angel Pons122cc8c2021-02-15 17:18:55 +010068 pci_write_config32(dev, SPI_BIOS_CONTROL, bc_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053069}
70
71/*
Subrata Banik8e390092017-07-21 10:06:17 +053072 * Ensure an additional read back after performing lock down
73 */
74static void fast_spi_read_post_write(uint8_t reg)
75{
76 pci_read_config8(PCH_DEV_SPI, reg);
77}
78
79/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +053080 * Set FAST_SPIBAR BIOS Control BILD bit.
81 */
82void fast_spi_set_bios_interface_lock_down(void)
83{
Angel Pons122cc8c2021-02-15 17:18:55 +010084 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_BILD);
Subrata Banik8e390092017-07-21 10:06:17 +053085
Angel Pons122cc8c2021-02-15 17:18:55 +010086 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053087}
88
89/*
90 * Set FAST_SPIBAR BIOS Control LE bit.
91 */
92void fast_spi_set_lock_enable(void)
93{
Angel Pons122cc8c2021-02-15 17:18:55 +010094 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_LOCK_ENABLE);
Subrata Banik8e390092017-07-21 10:06:17 +053095
Angel Pons122cc8c2021-02-15 17:18:55 +010096 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053097}
98
99/*
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800100 * Set FAST_SPIBAR BIOS Control EXT BIOS LE bit.
101 */
102void fast_spi_set_ext_bios_lock_enable(void)
103{
104 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
105 return;
106
Angel Pons122cc8c2021-02-15 17:18:55 +0100107 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EXT_BIOS_LOCK_ENABLE);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800108
Angel Pons122cc8c2021-02-15 17:18:55 +0100109 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800110}
111
112/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530113 * Set FAST_SPIBAR BIOS Control EISS bit.
114 */
115void fast_spi_set_eiss(void)
116{
Angel Pons122cc8c2021-02-15 17:18:55 +0100117 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EISS);
Subrata Banik8e390092017-07-21 10:06:17 +0530118
Angel Pons122cc8c2021-02-15 17:18:55 +0100119 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530120}
121
122/*
123 * Set FAST_SPI opcode menu.
124 */
125void fast_spi_set_opcode_menu(void)
126{
127 void *spibar = fast_spi_get_bar();
128
129 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
130 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
131 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
132 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
133}
134
135/*
136 * Lock FAST_SPIBAR.
Barnali Sarkar8e513192017-07-19 16:09:56 +0530137 * Use 16bit write to avoid touching two upper bytes what may cause the write
138 * cycle to fail in case a prior transaction has not completed.
139 * While WRSDIS is lockable with FLOCKDN, writing both in the same
140 * cycle is guaranteed to work by design.
141 *
142 * Avoid read->modify->write not to clear RW1C bits unintentionally.
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530143 */
144void fast_spi_lock_bar(void)
145{
146 void *spibar = fast_spi_get_bar();
Marc Jones051bf5d2021-03-30 12:16:09 -0600147 uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN | SPIBAR_HSFSTS_PRR34_LOCKDN;
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700148
Julius Wernercd49cce2019-03-05 16:53:33 -0800149 if (CONFIG(FAST_SPI_DISABLE_WRITE_STATUS))
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700150 hsfs |= SPIBAR_HSFSTS_WRSDIS;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530151
Barnali Sarkar8e513192017-07-19 16:09:56 +0530152 write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530153}
154
155/*
Barnali Sarkar4f6e3412017-08-17 11:49:27 +0530156 * Set FAST_SPIBAR + DLOCK (0x0C) register bits to discrete lock the
157 * FAST_SPI Protected Range (PR) registers.
158 */
159void fast_spi_pr_dlock(void)
160{
161 void *spibar = fast_spi_get_bar();
162 uint32_t dlock;
163
164 dlock = read32(spibar + SPIBAR_DLOCK);
165 dlock |= (SPIBAR_DLOCK_PR0LOCKDN | SPIBAR_DLOCK_PR1LOCKDN
166 | SPIBAR_DLOCK_PR2LOCKDN | SPIBAR_DLOCK_PR3LOCKDN
167 | SPIBAR_DLOCK_PR4LOCKDN);
168
169 write32(spibar + SPIBAR_DLOCK, dlock);
170}
171
172/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530173 * Set FAST_SPIBAR Soft Reset Data Register value.
174 */
175void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
176{
177 void *spibar = fast_spi_get_bar();
178 uint32_t ssl, ssms;
179
180 /* Set Strap Lock Disable */
181 ssl = read32(spibar + SPIBAR_RESET_LOCK);
182 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
183 write32(spibar + SPIBAR_RESET_LOCK, ssl);
184
185 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
186 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
187
188 /* Set Strap Mux Select set to '1' */
189 ssms = read32(spibar + SPIBAR_RESET_CTRL);
190 ssms |= SPIBAR_RESET_CTRL_SSMC;
191 write32(spibar + SPIBAR_RESET_CTRL, ssms);
192
193 /* Set Strap Lock Enable */
194 ssl = read32(spibar + SPIBAR_RESET_LOCK);
195 ssl |= SPIBAR_RESET_LOCK_ENABLE;
196 write32(spibar + SPIBAR_RESET_LOCK, ssl);
197}
198
199/*
200 * Returns bios_start and fills in size of the BIOS region.
201 */
202size_t fast_spi_get_bios_region(size_t *bios_size)
203{
204 size_t bios_start, bios_end;
205 /*
206 * BIOS_BFPREG provides info about BIOS Flash Primary Region
207 * Base and Limit.
208 * Base and Limit fields are in units of 4KiB.
209 */
210 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
211
212 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
213 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
214 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
215 *bios_size = bios_end - bios_start;
216 return bios_start;
217}
218
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800219static bool fast_spi_ext_bios_cache_range(uintptr_t *base, size_t *size)
220{
221 uint32_t alignment;
222 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
223 return false;
224
225 fast_spi_get_ext_bios_window(base, size);
226
227 /* Enable extended bios only if Size of Bios region is greater than 16MiB */
228 if (*size == 0 || *base == 0)
229 return false;
230
231 /* Round to power of two */
232 alignment = 1UL << (log2_ceil(*size));
233 *size = ALIGN_UP(*size, alignment);
234 *base = ALIGN_DOWN(*base, *size);
235
236 return true;
237}
238
239static void fast_spi_cache_ext_bios_window(void)
240{
241 size_t ext_bios_size;
242 uintptr_t ext_bios_base;
243 const int type = MTRR_TYPE_WRPROT;
244
245 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
246 return;
247
248 int mtrr = get_free_var_mtrr();
249 if (mtrr == -1)
250 return;
251 set_var_mtrr(mtrr, ext_bios_base, ext_bios_size, type);
252}
253
254void fast_spi_cache_ext_bios_postcar(struct postcar_frame *pcf)
255{
256 size_t ext_bios_size;
257 uintptr_t ext_bios_base;
258 const int type = MTRR_TYPE_WRPROT;
259
260 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
261 return;
262
263 postcar_frame_add_mtrr(pcf, ext_bios_base, ext_bios_size, type);
264}
265
Aaron Durbin5391e552017-06-02 12:16:04 -0500266void fast_spi_cache_bios_region(void)
267{
Aaron Durbin5391e552017-06-02 12:16:04 -0500268 size_t bios_size;
269 uint32_t alignment;
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500270 const int type = MTRR_TYPE_WRPROT;
271 uintptr_t base;
Aaron Durbin5391e552017-06-02 12:16:04 -0500272
273 /* Only the IFD BIOS region is memory mapped (at top of 4G) */
274 fast_spi_get_bios_region(&bios_size);
275
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800276 /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will
277 * cause memory type conflict when setting memory type to write
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +0100278 * protection, so limit the cached BIOS region to be no more than 16MB.
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800279 * */
280 bios_size = MIN(bios_size, 16 * MiB);
John Zhao1ceac4e2019-07-09 14:27:28 -0700281 if (bios_size <= 0)
John Zhao2bb432e2019-05-21 19:32:51 -0700282 return;
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800283
Aaron Durbin5391e552017-06-02 12:16:04 -0500284 /* Round to power of two */
Paul Menzel64e83402017-10-27 11:05:14 +0200285 alignment = 1UL << (log2_ceil(bios_size));
Aaron Durbin5391e552017-06-02 12:16:04 -0500286 bios_size = ALIGN_UP(bios_size, alignment);
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500287 base = 4ULL*GiB - bios_size;
288
Subrata Banik42c44c22019-05-15 20:27:04 +0530289 if (ENV_PAYLOAD_LOADER) {
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500290 mtrr_use_temp_range(base, bios_size, type);
291 } else {
292 int mtrr = get_free_var_mtrr();
293
294 if (mtrr == -1)
295 return;
296
297 set_var_mtrr(mtrr, base, bios_size, type);
298 }
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800299
300 /* Check if caching is needed for extended bios region if supported */
301 fast_spi_cache_ext_bios_window();
Aaron Durbin5391e552017-06-02 12:16:04 -0500302}
303
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530304/*
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800305 * Enable extended BIOS support
306 * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS
307 * region support.
308 */
309static void fast_spi_enable_ext_bios(void)
310{
Angel Pons52072432021-02-15 13:09:36 +0100311 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800312 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
313 return;
314
315#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)
316 /*
317 * Ensure that the base for the extended window in host space is a multiple of 32 MiB
318 * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed
319 * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS
320 * region happens at the top of the extended window in this case.
321 */
322 _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE,
323 "Extended BIOS window base must be a multiple of 32 * MiB!");
324 _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB),
325 "Only 32MiB windows are supported for extended BIOS!");
326#endif
327
328 /* Confgiure DMI Source decode for Extended BIOS Region */
329 if (dmi_enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE,
330 soc_get_spi_dmi_destination_id()) == CB_ERR)
331 return;
332
333 /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */
334 pci_write_config32(dev, SPI_CFG_BAR1,
335 CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
336
337 /*
338 * Since the top 16MiB of the BIOS region is always decoded by the standard window
339 * below the 4G boundary, we need to map the rest of the BIOS region that lies
340 * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to
341 * 16MiB. This determines the maximum address in the SPI flash space that is mapped
342 * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is
343 * basically the offset from the end of the BIOS region that will be mapped to the top
344 * of the extended window.
345 * This enables the decoding as follows:
346 -Standard decode window: (bios_region_top - 16MiB) to bios_region_top
347 -Extended decode window:
348 (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB))
349 to (bios_region_top - 16MiB).
350 */
Angel Pons122cc8c2021-02-15 17:18:55 +0100351 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB));
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800352
353 /* Program EXT_BIOS EN */
Angel Pons122cc8c2021-02-15 17:18:55 +0100354 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_ENABLE);
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800355}
356
357/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530358 * Program temporary BAR for SPI in case any of the stages before ramstage need
359 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
360 * enumeration.
361 */
362void fast_spi_early_init(uintptr_t spi_base_address)
363{
Angel Pons52072432021-02-15 13:09:36 +0100364 const pci_devfn_t dev = PCH_DEV_SPI;
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200365 uint16_t pcireg;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530366
367 /* Assign Resources to SPI Controller */
368 /* Clear BIT 1-2 SPI Command Register */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200369 pcireg = pci_read_config16(dev, PCI_COMMAND);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530370 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200371 pci_write_config16(dev, PCI_COMMAND, pcireg);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530372
373 /* Program Temporary BAR for SPI */
374 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
375 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
376
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800377 /*
378 * Enable extended bios support. Since it configures memory BAR, this is done before
379 * enabling MMIO space.
380 */
381 fast_spi_enable_ext_bios();
382
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530383 /* Enable Bus Master and MMIO Space */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200384 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530385
386 /* Initialize SPI to allow BIOS to write/erase on flash. */
387 fast_spi_init();
388}
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700389
Angel Pons967753f2021-02-15 17:44:09 +0100390/* Clear SPI Synchronous SMI status bit and return its value. */
391bool fast_spi_clear_sync_smi_status(void)
392{
393 const uint32_t bios_cntl = pci_read_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL);
394 const bool smi_asserted = bios_cntl & SPI_BIOS_CONTROL_SYNC_SS;
395 /*
396 * Do not unconditionally write 1 to clear SYNC_SS. Hardware could set
397 * SYNC_SS here (after we read but before we write SPI_BIOS_CONTROL),
398 * and the event would be lost when unconditionally clearing SYNC_SS.
399 */
400 pci_write_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL, bios_cntl);
401 return smi_asserted;
402}
403
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700404/* Read SPI Write Protect disable status. */
405bool fast_spi_wpd_status(void)
406{
Angel Pons122cc8c2021-02-15 17:18:55 +0100407 return pci_read_config16(PCH_DEV_SPI, SPI_BIOS_CONTROL) &
408 SPI_BIOS_CONTROL_WPD;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700409}
410
411/* Enable SPI Write Protect. */
412void fast_spi_enable_wp(void)
413{
Angel Pons52072432021-02-15 13:09:36 +0100414 const pci_devfn_t dev = PCH_DEV_SPI;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700415 uint8_t bios_cntl;
416
Angel Pons122cc8c2021-02-15 17:18:55 +0100417 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
418 bios_cntl &= ~SPI_BIOS_CONTROL_WPD;
419 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700420}
Angel Ponsd21b4632021-02-10 17:12:05 +0100421
422/* Disable SPI Write Protect. */
423void fast_spi_disable_wp(void)
424{
425 const pci_devfn_t dev = PCH_DEV_SPI;
426 uint8_t bios_cntl;
427
428 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
429 bios_cntl |= SPI_BIOS_CONTROL_WPD;
430 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
431}