blob: 8dc173cf05c49567c36f1a815b4022a74dffa9aa [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
Werner Zeh53553e82022-05-05 11:55:30 +02005#include <acpi/acpi.h>
6#include <acpi/acpigen.h>
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -08007#include <arch/romstage.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02008#include <device/mmio.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +05309#include <assert.h>
Werner Zehbae84982022-05-05 11:04:04 +020010#include <device/pci.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053011#include <device/pci_def.h>
Werner Zehbae84982022-05-05 11:04:04 +020012#include <device/pci_ids.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +020013#include <device/pci_ops.h>
Subrata Banikdef18c42022-03-31 00:16:00 +053014#include <console/console.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053015#include <commonlib/helpers.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050016#include <cpu/x86/mtrr.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053017#include <fast_spi_def.h>
18#include <intelblocks/fast_spi.h>
Subrata Banik211be9c2022-04-13 12:13:09 +053019#include <intelblocks/gpmr.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050020#include <lib.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053021#include <soc/pci_devs.h>
22#include <spi_flash.h>
23#include <spi-generic.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053024
Werner Zeh0c78f4c2022-05-05 14:56:07 +020025#define FLASH_MMIO_SIZE (16 * MiB)
26#define FLASH_BASE_ADDR ((0xffffffff - FLASH_MMIO_SIZE) + 1)
27
Barnali Sarkar89331cd2017-02-16 17:22:37 +053028/*
29 * Get the FAST_SPIBAR.
30 */
31void *fast_spi_get_bar(void)
32{
Angel Pons52072432021-02-15 13:09:36 +010033 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053034 uintptr_t bar;
35
36 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
37 assert(bar != 0);
38 /*
39 * Bits 31-12 are the base address as per EDS for SPI,
40 * Don't care about 0-11 bit
41 */
42 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
43}
44
45/*
46 * Disable the BIOS write protect and Enable Prefetching and Caching.
47 */
48void fast_spi_init(void)
49{
Angel Pons52072432021-02-15 13:09:36 +010050 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053051 uint8_t bios_cntl;
52
Angel Pons122cc8c2021-02-15 17:18:55 +010053 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053054
55 /* Disable the BIOS write protect so write commands are allowed. */
Angel Pons122cc8c2021-02-15 17:18:55 +010056 bios_cntl &= ~SPI_BIOS_CONTROL_EISS;
57 bios_cntl |= SPI_BIOS_CONTROL_WPD;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053058 /* Enable Prefetching and caching. */
Angel Pons122cc8c2021-02-15 17:18:55 +010059 bios_cntl |= SPI_BIOS_CONTROL_PREFETCH_ENABLE;
60 bios_cntl &= ~SPI_BIOS_CONTROL_CACHE_DISABLE;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053061
Angel Pons122cc8c2021-02-15 17:18:55 +010062 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053063}
64
65/*
Subrata Banik8e390092017-07-21 10:06:17 +053066 * Set FAST_SPIBAR BIOS Control register based on input bit field.
Barnali Sarkar89331cd2017-02-16 17:22:37 +053067 */
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080068static void fast_spi_set_bios_control_reg(uint32_t bios_cntl_bit)
Barnali Sarkar89331cd2017-02-16 17:22:37 +053069{
Angel Pons52072432021-02-15 13:09:36 +010070 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080071 uint32_t bc_cntl;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053072
73 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
Angel Pons122cc8c2021-02-15 17:18:55 +010074 bc_cntl = pci_read_config32(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053075 bc_cntl |= bios_cntl_bit;
Angel Pons122cc8c2021-02-15 17:18:55 +010076 pci_write_config32(dev, SPI_BIOS_CONTROL, bc_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053077}
78
79/*
Subrata Banik8e390092017-07-21 10:06:17 +053080 * Ensure an additional read back after performing lock down
81 */
82static void fast_spi_read_post_write(uint8_t reg)
83{
84 pci_read_config8(PCH_DEV_SPI, reg);
85}
86
87/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +053088 * Set FAST_SPIBAR BIOS Control BILD bit.
89 */
90void fast_spi_set_bios_interface_lock_down(void)
91{
Angel Pons122cc8c2021-02-15 17:18:55 +010092 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_BILD);
Subrata Banik8e390092017-07-21 10:06:17 +053093
Angel Pons122cc8c2021-02-15 17:18:55 +010094 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053095}
96
97/*
98 * Set FAST_SPIBAR BIOS Control LE bit.
99 */
100void fast_spi_set_lock_enable(void)
101{
Angel Pons122cc8c2021-02-15 17:18:55 +0100102 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_LOCK_ENABLE);
Subrata Banik8e390092017-07-21 10:06:17 +0530103
Angel Pons122cc8c2021-02-15 17:18:55 +0100104 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530105}
106
107/*
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800108 * Set FAST_SPIBAR BIOS Control EXT BIOS LE bit.
109 */
110void fast_spi_set_ext_bios_lock_enable(void)
111{
112 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
113 return;
114
Angel Pons122cc8c2021-02-15 17:18:55 +0100115 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EXT_BIOS_LOCK_ENABLE);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800116
Angel Pons122cc8c2021-02-15 17:18:55 +0100117 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800118}
119
120/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530121 * Set FAST_SPIBAR BIOS Control EISS bit.
122 */
123void fast_spi_set_eiss(void)
124{
Angel Pons122cc8c2021-02-15 17:18:55 +0100125 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EISS);
Subrata Banik8e390092017-07-21 10:06:17 +0530126
Angel Pons122cc8c2021-02-15 17:18:55 +0100127 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530128}
129
130/*
131 * Set FAST_SPI opcode menu.
132 */
133void fast_spi_set_opcode_menu(void)
134{
135 void *spibar = fast_spi_get_bar();
136
137 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
138 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
139 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
140 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
141}
142
143/*
144 * Lock FAST_SPIBAR.
Barnali Sarkar8e513192017-07-19 16:09:56 +0530145 * Use 16bit write to avoid touching two upper bytes what may cause the write
146 * cycle to fail in case a prior transaction has not completed.
147 * While WRSDIS is lockable with FLOCKDN, writing both in the same
148 * cycle is guaranteed to work by design.
149 *
150 * Avoid read->modify->write not to clear RW1C bits unintentionally.
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530151 */
152void fast_spi_lock_bar(void)
153{
154 void *spibar = fast_spi_get_bar();
Marc Jones051bf5d2021-03-30 12:16:09 -0600155 uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN | SPIBAR_HSFSTS_PRR34_LOCKDN;
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700156
Julius Wernercd49cce2019-03-05 16:53:33 -0800157 if (CONFIG(FAST_SPI_DISABLE_WRITE_STATUS))
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700158 hsfs |= SPIBAR_HSFSTS_WRSDIS;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530159
Barnali Sarkar8e513192017-07-19 16:09:56 +0530160 write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530161}
162
163/*
Barnali Sarkar4f6e3412017-08-17 11:49:27 +0530164 * Set FAST_SPIBAR + DLOCK (0x0C) register bits to discrete lock the
165 * FAST_SPI Protected Range (PR) registers.
166 */
167void fast_spi_pr_dlock(void)
168{
169 void *spibar = fast_spi_get_bar();
170 uint32_t dlock;
171
172 dlock = read32(spibar + SPIBAR_DLOCK);
173 dlock |= (SPIBAR_DLOCK_PR0LOCKDN | SPIBAR_DLOCK_PR1LOCKDN
174 | SPIBAR_DLOCK_PR2LOCKDN | SPIBAR_DLOCK_PR3LOCKDN
175 | SPIBAR_DLOCK_PR4LOCKDN);
176
177 write32(spibar + SPIBAR_DLOCK, dlock);
178}
179
180/*
Subrata Banikd6431652022-04-13 20:30:53 +0530181 * Set FAST_SPIBAR + VSCC0 (0xC4) register VCL (bit 30).
182 */
183void fast_spi_vscc0_lock(void)
184{
185 void *spibar = fast_spi_get_bar();
186
187 /*
188 * SPI Flash Programming Guide Section 5.5.2 describes Vendor Component Lock (VCL).
189 * It is recommended to set the VCL bit. VCL applies to both VSCC0 and VSCC1.
190 * Without this bit being set, it is possible to modify Host/GbE VSCC register(s),
191 * which might results in undesired host and integrated GbE Serial Flash
192 * functionality.
193 */
194 setbits32(spibar + SPIBAR_SFDP0_VSCC0, SPIBAR_VSCC0_VCL);
195}
196
197/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530198 * Set FAST_SPIBAR Soft Reset Data Register value.
199 */
200void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
201{
202 void *spibar = fast_spi_get_bar();
203 uint32_t ssl, ssms;
204
205 /* Set Strap Lock Disable */
206 ssl = read32(spibar + SPIBAR_RESET_LOCK);
207 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
208 write32(spibar + SPIBAR_RESET_LOCK, ssl);
209
210 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
211 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
212
213 /* Set Strap Mux Select set to '1' */
214 ssms = read32(spibar + SPIBAR_RESET_CTRL);
215 ssms |= SPIBAR_RESET_CTRL_SSMC;
216 write32(spibar + SPIBAR_RESET_CTRL, ssms);
217
218 /* Set Strap Lock Enable */
219 ssl = read32(spibar + SPIBAR_RESET_LOCK);
220 ssl |= SPIBAR_RESET_LOCK_ENABLE;
221 write32(spibar + SPIBAR_RESET_LOCK, ssl);
222}
223
Subrata Banikdef18c42022-03-31 00:16:00 +0530224static void fast_spi_enable_cache_range(unsigned int base, unsigned int size)
225{
Arthur Heymans481599f2022-04-11 14:28:14 +0200226 if (ENV_RAMSTAGE) {
227 mtrr_use_temp_range(base, size, MTRR_TYPE_WRPROT);
228 return;
229 }
230
Subrata Banikdef18c42022-03-31 00:16:00 +0530231 const int type = MTRR_TYPE_WRPROT;
232 int mtrr = get_free_var_mtrr();
233 if (mtrr == -1) {
234 printk(BIOS_WARNING, "ROM caching failed due to no free MTRR available!\n");
235 return;
236 }
237
238 set_var_mtrr(mtrr, base, size, type);
239}
240
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530241/*
242 * Returns bios_start and fills in size of the BIOS region.
243 */
244size_t fast_spi_get_bios_region(size_t *bios_size)
245{
246 size_t bios_start, bios_end;
247 /*
248 * BIOS_BFPREG provides info about BIOS Flash Primary Region
249 * Base and Limit.
250 * Base and Limit fields are in units of 4KiB.
251 */
252 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
253
254 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
255 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
256 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
257 *bios_size = bios_end - bios_start;
258 return bios_start;
259}
260
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800261static bool fast_spi_ext_bios_cache_range(uintptr_t *base, size_t *size)
262{
263 uint32_t alignment;
264 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
265 return false;
266
267 fast_spi_get_ext_bios_window(base, size);
268
269 /* Enable extended bios only if Size of Bios region is greater than 16MiB */
270 if (*size == 0 || *base == 0)
271 return false;
272
273 /* Round to power of two */
274 alignment = 1UL << (log2_ceil(*size));
275 *size = ALIGN_UP(*size, alignment);
276 *base = ALIGN_DOWN(*base, *size);
277
278 return true;
279}
280
281static void fast_spi_cache_ext_bios_window(void)
282{
283 size_t ext_bios_size;
284 uintptr_t ext_bios_base;
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800285
286 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
287 return;
288
Subrata Banikdef18c42022-03-31 00:16:00 +0530289 fast_spi_enable_cache_range(ext_bios_base, ext_bios_size);
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800290}
291
292void fast_spi_cache_ext_bios_postcar(struct postcar_frame *pcf)
293{
294 size_t ext_bios_size;
295 uintptr_t ext_bios_base;
296 const int type = MTRR_TYPE_WRPROT;
297
298 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
299 return;
300
301 postcar_frame_add_mtrr(pcf, ext_bios_base, ext_bios_size, type);
302}
303
Aaron Durbin5391e552017-06-02 12:16:04 -0500304void fast_spi_cache_bios_region(void)
305{
Aaron Durbin5391e552017-06-02 12:16:04 -0500306 size_t bios_size;
307 uint32_t alignment;
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500308 uintptr_t base;
Aaron Durbin5391e552017-06-02 12:16:04 -0500309
310 /* Only the IFD BIOS region is memory mapped (at top of 4G) */
311 fast_spi_get_bios_region(&bios_size);
312
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800313 /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will
314 * cause memory type conflict when setting memory type to write
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +0100315 * protection, so limit the cached BIOS region to be no more than 16MB.
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800316 * */
317 bios_size = MIN(bios_size, 16 * MiB);
John Zhao1ceac4e2019-07-09 14:27:28 -0700318 if (bios_size <= 0)
John Zhao2bb432e2019-05-21 19:32:51 -0700319 return;
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800320
Aaron Durbin5391e552017-06-02 12:16:04 -0500321 /* Round to power of two */
Paul Menzel64e83402017-10-27 11:05:14 +0200322 alignment = 1UL << (log2_ceil(bios_size));
Aaron Durbin5391e552017-06-02 12:16:04 -0500323 bios_size = ALIGN_UP(bios_size, alignment);
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500324 base = 4ULL*GiB - bios_size;
325
Subrata Banikdef18c42022-03-31 00:16:00 +0530326 fast_spi_enable_cache_range(base, bios_size);
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800327
328 /* Check if caching is needed for extended bios region if supported */
329 fast_spi_cache_ext_bios_window();
Aaron Durbin5391e552017-06-02 12:16:04 -0500330}
331
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530332/*
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800333 * Enable extended BIOS support
334 * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS
335 * region support.
336 */
337static void fast_spi_enable_ext_bios(void)
338{
Angel Pons52072432021-02-15 13:09:36 +0100339 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800340 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
341 return;
342
343#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)
344 /*
345 * Ensure that the base for the extended window in host space is a multiple of 32 MiB
346 * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed
347 * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS
348 * region happens at the top of the extended window in this case.
349 */
350 _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE,
351 "Extended BIOS window base must be a multiple of 32 * MiB!");
352 _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB),
353 "Only 32MiB windows are supported for extended BIOS!");
354#endif
355
Wonkyu Kimaaec8092021-09-15 15:52:51 -0700356 /* Configure Source decode for Extended BIOS Region */
Subrata Banik211be9c2022-04-13 12:13:09 +0530357 if (enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE,
Wonkyu Kimaaec8092021-09-15 15:52:51 -0700358 soc_get_spi_psf_destination_id()) == CB_ERR)
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800359 return;
360
361 /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */
362 pci_write_config32(dev, SPI_CFG_BAR1,
363 CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
364
365 /*
366 * Since the top 16MiB of the BIOS region is always decoded by the standard window
367 * below the 4G boundary, we need to map the rest of the BIOS region that lies
368 * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to
369 * 16MiB. This determines the maximum address in the SPI flash space that is mapped
370 * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is
371 * basically the offset from the end of the BIOS region that will be mapped to the top
372 * of the extended window.
373 * This enables the decoding as follows:
374 -Standard decode window: (bios_region_top - 16MiB) to bios_region_top
375 -Extended decode window:
376 (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB))
377 to (bios_region_top - 16MiB).
378 */
Angel Pons122cc8c2021-02-15 17:18:55 +0100379 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB));
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800380
381 /* Program EXT_BIOS EN */
Angel Pons122cc8c2021-02-15 17:18:55 +0100382 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_ENABLE);
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800383}
384
385/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530386 * Program temporary BAR for SPI in case any of the stages before ramstage need
387 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
388 * enumeration.
389 */
390void fast_spi_early_init(uintptr_t spi_base_address)
391{
Angel Pons52072432021-02-15 13:09:36 +0100392 const pci_devfn_t dev = PCH_DEV_SPI;
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200393 uint16_t pcireg;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530394
395 /* Assign Resources to SPI Controller */
396 /* Clear BIT 1-2 SPI Command Register */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200397 pcireg = pci_read_config16(dev, PCI_COMMAND);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530398 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200399 pci_write_config16(dev, PCI_COMMAND, pcireg);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530400
401 /* Program Temporary BAR for SPI */
402 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
403 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
404
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800405 /*
406 * Enable extended bios support. Since it configures memory BAR, this is done before
407 * enabling MMIO space.
408 */
409 fast_spi_enable_ext_bios();
410
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530411 /* Enable Bus Master and MMIO Space */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200412 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530413
414 /* Initialize SPI to allow BIOS to write/erase on flash. */
415 fast_spi_init();
416}
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700417
Angel Pons967753f2021-02-15 17:44:09 +0100418/* Clear SPI Synchronous SMI status bit and return its value. */
419bool fast_spi_clear_sync_smi_status(void)
420{
421 const uint32_t bios_cntl = pci_read_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL);
422 const bool smi_asserted = bios_cntl & SPI_BIOS_CONTROL_SYNC_SS;
423 /*
424 * Do not unconditionally write 1 to clear SYNC_SS. Hardware could set
425 * SYNC_SS here (after we read but before we write SPI_BIOS_CONTROL),
426 * and the event would be lost when unconditionally clearing SYNC_SS.
427 */
428 pci_write_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL, bios_cntl);
429 return smi_asserted;
430}
431
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700432/* Read SPI Write Protect disable status. */
433bool fast_spi_wpd_status(void)
434{
Angel Pons122cc8c2021-02-15 17:18:55 +0100435 return pci_read_config16(PCH_DEV_SPI, SPI_BIOS_CONTROL) &
436 SPI_BIOS_CONTROL_WPD;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700437}
438
439/* Enable SPI Write Protect. */
440void fast_spi_enable_wp(void)
441{
Angel Pons52072432021-02-15 13:09:36 +0100442 const pci_devfn_t dev = PCH_DEV_SPI;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700443 uint8_t bios_cntl;
444
Angel Pons122cc8c2021-02-15 17:18:55 +0100445 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
446 bios_cntl &= ~SPI_BIOS_CONTROL_WPD;
447 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700448}
Angel Ponsd21b4632021-02-10 17:12:05 +0100449
450/* Disable SPI Write Protect. */
451void fast_spi_disable_wp(void)
452{
453 const pci_devfn_t dev = PCH_DEV_SPI;
454 uint8_t bios_cntl;
455
456 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
457 bios_cntl |= SPI_BIOS_CONTROL_WPD;
458 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
459}
Subrata Banikd5e7c632022-04-14 00:08:05 +0530460
461void fast_spi_clear_outstanding_status(void)
462{
463 void *spibar = fast_spi_get_bar();
464
465 /* Make sure all W1C status bits get cleared. */
466 write32(spibar + SPIBAR_HSFSTS_CTL, SPIBAR_HSFSTS_W1C_BITS);
467}
Werner Zehbae84982022-05-05 11:04:04 +0200468
Werner Zeh53553e82022-05-05 11:55:30 +0200469
470/* As there is no official ACPI ID for this controller use the generic PNP ID for now. */
471static const char *fast_spi_acpi_hid(const struct device *dev)
472{
473 return "PNP0C02";
474}
475
476static const char *fast_spi_acpi_name(const struct device *dev)
477{
478 return "FSPI";
479}
480
481/*
482 * Generate an ACPI entry for the SPI controller. This way the allocated resources
483 * for the SPI controller can be communicated to the OS even if the device is
484 * not visible on PCI (because it is hidden) and therefore can not be probed by the OS.
485 */
486static void fast_spi_fill_ssdt(const struct device *dev)
487{
488 const char *scope = acpi_device_scope(dev);
489 const char *hid = fast_spi_acpi_hid(dev);
490 struct resource *res;
491
492 /* Do not add SSDT if the fast SPI device is hidden. */
493 if (dev->hidden || !CONFIG(FAST_SPI_GENERATE_SSDT))
494 return;
495 if (!scope || !hid)
496 return;
497
498 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
499 if (!res)
500 return;
501
502 /* Scope */
503 acpigen_write_scope(scope);
504
505 /* Device */
506 acpigen_write_device(acpi_device_name(dev));
507 acpigen_write_name_string("_HID", hid);
508 acpi_device_write_uid(dev);
509 acpigen_write_name_string("_DDN", "ACPI Fast SPI");
510 acpigen_write_STA(acpi_device_status(dev));
511
512 /* Resources */
513 acpigen_write_name("_CRS");
514 acpigen_write_resourcetemplate_header();
515
516 /* Add BAR0 resource. */
517 acpigen_write_mem32fixed(1, res->base, res->size);
518
519 acpigen_write_resourcetemplate_footer();
520
521 acpigen_pop_len(); /* Device */
522 acpigen_pop_len(); /* Scope */
523}
524
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200525
526static void fast_spi_read_resources(struct device *dev)
527{
528 /* Read standard PCI resources. */
529 pci_dev_read_resources(dev);
530
531 /* Add SPI flash MMIO window as a reserved resource. */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300532 mmio_resource_kb(dev, 0, FLASH_BASE_ADDR / KiB, FLASH_MMIO_SIZE / KiB);
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200533}
534
Werner Zehbae84982022-05-05 11:04:04 +0200535static struct device_operations fast_spi_dev_ops = {
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200536 .read_resources = fast_spi_read_resources,
Werner Zehbae84982022-05-05 11:04:04 +0200537 .set_resources = pci_dev_set_resources,
538 .enable_resources = pci_dev_enable_resources,
Werner Zeh53553e82022-05-05 11:55:30 +0200539 .acpi_fill_ssdt = fast_spi_fill_ssdt,
540 .acpi_name = fast_spi_acpi_name,
Werner Zehbae84982022-05-05 11:04:04 +0200541};
542
543static const unsigned short pci_device_ids[] = {
544 PCI_DID_INTEL_APL_HWSEQ_SPI,
545 0
546};
547
548static const struct pci_driver fast_spi __pci_driver = {
549 .ops = &fast_spi_dev_ops,
550 .vendor = PCI_VID_INTEL,
551 .devices = pci_device_ids,
552};