blob: ed2e8f2b3988aaf694b10e67852e3421f88bf08c [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>
Werner Zehbae84982022-05-05 11:04:04 +020011#include <device/pci_ids.h>
Patrick Rudolphe56189c2018-04-18 10:11:59 +020012#include <device/pci_ops.h>
Subrata Banikdef18c42022-03-31 00:16:00 +053013#include <console/console.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053014#include <commonlib/helpers.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050015#include <cpu/x86/mtrr.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053016#include <fast_spi_def.h>
17#include <intelblocks/fast_spi.h>
Subrata Banik211be9c2022-04-13 12:13:09 +053018#include <intelblocks/gpmr.h>
Aaron Durbin5391e552017-06-02 12:16:04 -050019#include <lib.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053020#include <soc/pci_devs.h>
21#include <spi_flash.h>
22#include <spi-generic.h>
Barnali Sarkar89331cd2017-02-16 17:22:37 +053023
Werner Zeh0c78f4c2022-05-05 14:56:07 +020024#define FLASH_MMIO_SIZE (16 * MiB)
25#define FLASH_BASE_ADDR ((0xffffffff - FLASH_MMIO_SIZE) + 1)
26
Barnali Sarkar89331cd2017-02-16 17:22:37 +053027/*
28 * Get the FAST_SPIBAR.
29 */
30void *fast_spi_get_bar(void)
31{
Angel Pons52072432021-02-15 13:09:36 +010032 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053033 uintptr_t bar;
34
35 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
36 assert(bar != 0);
37 /*
38 * Bits 31-12 are the base address as per EDS for SPI,
39 * Don't care about 0-11 bit
40 */
41 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
42}
43
44/*
45 * Disable the BIOS write protect and Enable Prefetching and Caching.
46 */
47void fast_spi_init(void)
48{
Angel Pons52072432021-02-15 13:09:36 +010049 const pci_devfn_t dev = PCH_DEV_SPI;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053050 uint8_t bios_cntl;
51
Angel Pons122cc8c2021-02-15 17:18:55 +010052 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053053
54 /* Disable the BIOS write protect so write commands are allowed. */
Angel Pons122cc8c2021-02-15 17:18:55 +010055 bios_cntl &= ~SPI_BIOS_CONTROL_EISS;
56 bios_cntl |= SPI_BIOS_CONTROL_WPD;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053057 /* Enable Prefetching and caching. */
Angel Pons122cc8c2021-02-15 17:18:55 +010058 bios_cntl |= SPI_BIOS_CONTROL_PREFETCH_ENABLE;
59 bios_cntl &= ~SPI_BIOS_CONTROL_CACHE_DISABLE;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053060
Angel Pons122cc8c2021-02-15 17:18:55 +010061 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053062}
63
64/*
Subrata Banik8e390092017-07-21 10:06:17 +053065 * Set FAST_SPIBAR BIOS Control register based on input bit field.
Barnali Sarkar89331cd2017-02-16 17:22:37 +053066 */
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080067static void fast_spi_set_bios_control_reg(uint32_t bios_cntl_bit)
Barnali Sarkar89331cd2017-02-16 17:22:37 +053068{
Angel Pons52072432021-02-15 13:09:36 +010069 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -080070 uint32_t bc_cntl;
Barnali Sarkar89331cd2017-02-16 17:22:37 +053071
72 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
Angel Pons122cc8c2021-02-15 17:18:55 +010073 bc_cntl = pci_read_config32(dev, SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053074 bc_cntl |= bios_cntl_bit;
Angel Pons122cc8c2021-02-15 17:18:55 +010075 pci_write_config32(dev, SPI_BIOS_CONTROL, bc_cntl);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053076}
77
78/*
Subrata Banik8e390092017-07-21 10:06:17 +053079 * Ensure an additional read back after performing lock down
80 */
81static void fast_spi_read_post_write(uint8_t reg)
82{
83 pci_read_config8(PCH_DEV_SPI, reg);
84}
85
86/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +053087 * Set FAST_SPIBAR BIOS Control BILD bit.
88 */
89void fast_spi_set_bios_interface_lock_down(void)
90{
Angel Pons122cc8c2021-02-15 17:18:55 +010091 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_BILD);
Subrata Banik8e390092017-07-21 10:06:17 +053092
Angel Pons122cc8c2021-02-15 17:18:55 +010093 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +053094}
95
96/*
97 * Set FAST_SPIBAR BIOS Control LE bit.
98 */
99void fast_spi_set_lock_enable(void)
100{
Angel Pons122cc8c2021-02-15 17:18:55 +0100101 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_LOCK_ENABLE);
Subrata Banik8e390092017-07-21 10:06:17 +0530102
Angel Pons122cc8c2021-02-15 17:18:55 +0100103 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530104}
105
106/*
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800107 * Set FAST_SPIBAR BIOS Control EXT BIOS LE bit.
108 */
109void fast_spi_set_ext_bios_lock_enable(void)
110{
111 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
112 return;
113
Angel Pons122cc8c2021-02-15 17:18:55 +0100114 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EXT_BIOS_LOCK_ENABLE);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800115
Angel Pons122cc8c2021-02-15 17:18:55 +0100116 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Srinidhi N Kaushik28e1d0e2020-11-25 21:57:37 -0800117}
118
119/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530120 * Set FAST_SPIBAR BIOS Control EISS bit.
121 */
122void fast_spi_set_eiss(void)
123{
Angel Pons122cc8c2021-02-15 17:18:55 +0100124 fast_spi_set_bios_control_reg(SPI_BIOS_CONTROL_EISS);
Subrata Banik8e390092017-07-21 10:06:17 +0530125
Angel Pons122cc8c2021-02-15 17:18:55 +0100126 fast_spi_read_post_write(SPI_BIOS_CONTROL);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530127}
128
129/*
130 * Set FAST_SPI opcode menu.
131 */
132void fast_spi_set_opcode_menu(void)
133{
134 void *spibar = fast_spi_get_bar();
135
136 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
137 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
138 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
139 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
140}
141
142/*
143 * Lock FAST_SPIBAR.
Barnali Sarkar8e513192017-07-19 16:09:56 +0530144 * Use 16bit write to avoid touching two upper bytes what may cause the write
145 * cycle to fail in case a prior transaction has not completed.
146 * While WRSDIS is lockable with FLOCKDN, writing both in the same
147 * cycle is guaranteed to work by design.
148 *
149 * Avoid read->modify->write not to clear RW1C bits unintentionally.
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530150 */
151void fast_spi_lock_bar(void)
152{
153 void *spibar = fast_spi_get_bar();
Marc Jones051bf5d2021-03-30 12:16:09 -0600154 uint16_t hsfs = SPIBAR_HSFSTS_FLOCKDN | SPIBAR_HSFSTS_PRR34_LOCKDN;
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700155
Julius Wernercd49cce2019-03-05 16:53:33 -0800156 if (CONFIG(FAST_SPI_DISABLE_WRITE_STATUS))
Duncan Lauriedc1e6bc2017-08-15 13:32:26 -0700157 hsfs |= SPIBAR_HSFSTS_WRSDIS;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530158
Barnali Sarkar8e513192017-07-19 16:09:56 +0530159 write16(spibar + SPIBAR_HSFSTS_CTL, hsfs);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530160}
161
162/*
Barnali Sarkar4f6e3412017-08-17 11:49:27 +0530163 * Set FAST_SPIBAR + DLOCK (0x0C) register bits to discrete lock the
164 * FAST_SPI Protected Range (PR) registers.
165 */
166void fast_spi_pr_dlock(void)
167{
168 void *spibar = fast_spi_get_bar();
169 uint32_t dlock;
170
171 dlock = read32(spibar + SPIBAR_DLOCK);
172 dlock |= (SPIBAR_DLOCK_PR0LOCKDN | SPIBAR_DLOCK_PR1LOCKDN
173 | SPIBAR_DLOCK_PR2LOCKDN | SPIBAR_DLOCK_PR3LOCKDN
174 | SPIBAR_DLOCK_PR4LOCKDN);
175
176 write32(spibar + SPIBAR_DLOCK, dlock);
177}
178
179/*
Subrata Banikd6431652022-04-13 20:30:53 +0530180 * Set FAST_SPIBAR + VSCC0 (0xC4) register VCL (bit 30).
181 */
182void fast_spi_vscc0_lock(void)
183{
184 void *spibar = fast_spi_get_bar();
185
186 /*
187 * SPI Flash Programming Guide Section 5.5.2 describes Vendor Component Lock (VCL).
188 * It is recommended to set the VCL bit. VCL applies to both VSCC0 and VSCC1.
189 * Without this bit being set, it is possible to modify Host/GbE VSCC register(s),
190 * which might results in undesired host and integrated GbE Serial Flash
191 * functionality.
192 */
193 setbits32(spibar + SPIBAR_SFDP0_VSCC0, SPIBAR_VSCC0_VCL);
194}
195
196/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530197 * Set FAST_SPIBAR Soft Reset Data Register value.
198 */
199void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
200{
201 void *spibar = fast_spi_get_bar();
202 uint32_t ssl, ssms;
203
204 /* Set Strap Lock Disable */
205 ssl = read32(spibar + SPIBAR_RESET_LOCK);
206 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
207 write32(spibar + SPIBAR_RESET_LOCK, ssl);
208
209 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
210 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
211
Angel Pons12459162022-11-02 19:07:58 +0100212 /* Set Strap Mux Select set to '1' */
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530213 ssms = read32(spibar + SPIBAR_RESET_CTRL);
214 ssms |= SPIBAR_RESET_CTRL_SSMC;
215 write32(spibar + SPIBAR_RESET_CTRL, ssms);
216
217 /* Set Strap Lock Enable */
218 ssl = read32(spibar + SPIBAR_RESET_LOCK);
219 ssl |= SPIBAR_RESET_LOCK_ENABLE;
220 write32(spibar + SPIBAR_RESET_LOCK, ssl);
221}
222
Subrata Banikdef18c42022-03-31 00:16:00 +0530223static void fast_spi_enable_cache_range(unsigned int base, unsigned int size)
224{
Arthur Heymans481599f2022-04-11 14:28:14 +0200225 if (ENV_RAMSTAGE) {
226 mtrr_use_temp_range(base, size, MTRR_TYPE_WRPROT);
227 return;
228 }
229
Subrata Banikdef18c42022-03-31 00:16:00 +0530230 const int type = MTRR_TYPE_WRPROT;
231 int mtrr = get_free_var_mtrr();
232 if (mtrr == -1) {
233 printk(BIOS_WARNING, "ROM caching failed due to no free MTRR available!\n");
234 return;
235 }
236
237 set_var_mtrr(mtrr, base, size, type);
238}
239
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530240/*
241 * Returns bios_start and fills in size of the BIOS region.
242 */
243size_t fast_spi_get_bios_region(size_t *bios_size)
244{
245 size_t bios_start, bios_end;
246 /*
247 * BIOS_BFPREG provides info about BIOS Flash Primary Region
248 * Base and Limit.
249 * Base and Limit fields are in units of 4KiB.
250 */
251 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
252
253 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
254 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
255 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
256 *bios_size = bios_end - bios_start;
257 return bios_start;
258}
259
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800260static bool fast_spi_ext_bios_cache_range(uintptr_t *base, size_t *size)
261{
262 uint32_t alignment;
263 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
264 return false;
265
266 fast_spi_get_ext_bios_window(base, size);
267
268 /* Enable extended bios only if Size of Bios region is greater than 16MiB */
269 if (*size == 0 || *base == 0)
270 return false;
271
272 /* Round to power of two */
273 alignment = 1UL << (log2_ceil(*size));
274 *size = ALIGN_UP(*size, alignment);
275 *base = ALIGN_DOWN(*base, *size);
276
277 return true;
278}
279
280static void fast_spi_cache_ext_bios_window(void)
281{
282 size_t ext_bios_size;
283 uintptr_t ext_bios_base;
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800284
285 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
286 return;
287
Subrata Banikdef18c42022-03-31 00:16:00 +0530288 fast_spi_enable_cache_range(ext_bios_base, ext_bios_size);
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800289}
290
291void fast_spi_cache_ext_bios_postcar(struct postcar_frame *pcf)
292{
293 size_t ext_bios_size;
294 uintptr_t ext_bios_base;
295 const int type = MTRR_TYPE_WRPROT;
296
297 if (!fast_spi_ext_bios_cache_range(&ext_bios_base, &ext_bios_size))
298 return;
299
300 postcar_frame_add_mtrr(pcf, ext_bios_base, ext_bios_size, type);
301}
302
Aaron Durbin5391e552017-06-02 12:16:04 -0500303void fast_spi_cache_bios_region(void)
304{
Aaron Durbin5391e552017-06-02 12:16:04 -0500305 size_t bios_size;
306 uint32_t alignment;
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500307 uintptr_t base;
Aaron Durbin5391e552017-06-02 12:16:04 -0500308
309 /* Only the IFD BIOS region is memory mapped (at top of 4G) */
310 fast_spi_get_bios_region(&bios_size);
311
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800312 /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will
313 * cause memory type conflict when setting memory type to write
Elyes HAOUAS6dc9d032020-02-16 16:22:52 +0100314 * protection, so limit the cached BIOS region to be no more than 16MB.
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800315 * */
316 bios_size = MIN(bios_size, 16 * MiB);
John Zhao1ceac4e2019-07-09 14:27:28 -0700317 if (bios_size <= 0)
John Zhao2bb432e2019-05-21 19:32:51 -0700318 return;
Lijian Zhaoad1e49a2018-11-29 16:24:24 -0800319
Aaron Durbin5391e552017-06-02 12:16:04 -0500320 /* Round to power of two */
Paul Menzel64e83402017-10-27 11:05:14 +0200321 alignment = 1UL << (log2_ceil(bios_size));
Aaron Durbin5391e552017-06-02 12:16:04 -0500322 bios_size = ALIGN_UP(bios_size, alignment);
Aaron Durbin0b34fc62017-06-08 10:52:58 -0500323 base = 4ULL*GiB - bios_size;
324
Subrata Banikdef18c42022-03-31 00:16:00 +0530325 fast_spi_enable_cache_range(base, bios_size);
Srinidhi N Kaushik4eb489f2020-11-25 02:21:57 -0800326
327 /* Check if caching is needed for extended bios region if supported */
328 fast_spi_cache_ext_bios_window();
Aaron Durbin5391e552017-06-02 12:16:04 -0500329}
330
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530331/*
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800332 * Enable extended BIOS support
333 * Checks BIOS region in the flashmap, if its more than 16Mib, enables extended BIOS
334 * region support.
335 */
336static void fast_spi_enable_ext_bios(void)
337{
Angel Pons52072432021-02-15 13:09:36 +0100338 const pci_devfn_t dev = PCH_DEV_SPI;
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800339 if (!CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW))
340 return;
341
342#if CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)
343 /*
344 * Ensure that the base for the extended window in host space is a multiple of 32 MiB
345 * and size is fixed at 32 MiB. Controller assumes that the extended window has a fixed
346 * size of 32 MiB even if the actual BIOS region is smaller. The mapping of the BIOS
347 * region happens at the top of the extended window in this case.
348 */
349 _Static_assert(ALIGN_UP(CONFIG_EXT_BIOS_WIN_BASE, 32 * MiB) == CONFIG_EXT_BIOS_WIN_BASE,
350 "Extended BIOS window base must be a multiple of 32 * MiB!");
351 _Static_assert(CONFIG_EXT_BIOS_WIN_SIZE == (32 * MiB),
352 "Only 32MiB windows are supported for extended BIOS!");
353#endif
354
Wonkyu Kimaaec8092021-09-15 15:52:51 -0700355 /* Configure Source decode for Extended BIOS Region */
Subrata Banik211be9c2022-04-13 12:13:09 +0530356 if (enable_gpmr(CONFIG_EXT_BIOS_WIN_BASE, CONFIG_EXT_BIOS_WIN_SIZE,
Wonkyu Kimaaec8092021-09-15 15:52:51 -0700357 soc_get_spi_psf_destination_id()) == CB_ERR)
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800358 return;
359
360 /* Program EXT_BIOS_BAR1 with obtained ext_bios_base */
361 pci_write_config32(dev, SPI_CFG_BAR1,
362 CONFIG_EXT_BIOS_WIN_BASE | PCI_BASE_ADDRESS_SPACE_MEMORY);
363
364 /*
365 * Since the top 16MiB of the BIOS region is always decoded by the standard window
366 * below the 4G boundary, we need to map the rest of the BIOS region that lies
367 * below the top 16MiB in the extended window. Thus, EXT_BIOS_LIMIT will be set to
368 * 16MiB. This determines the maximum address in the SPI flash space that is mapped
369 * to the top of the extended window in the host address space. EXT_BIOS_LIMIT is
370 * basically the offset from the end of the BIOS region that will be mapped to the top
371 * of the extended window.
372 * This enables the decoding as follows:
373 -Standard decode window: (bios_region_top - 16MiB) to bios_region_top
374 -Extended decode window:
375 (bios_region_top - 16MiB - MIN(extended_window_size, bios_size - 16MiB))
376 to (bios_region_top - 16MiB).
377 */
Angel Pons122cc8c2021-02-15 17:18:55 +0100378 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_LIMIT(16 * MiB));
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800379
380 /* Program EXT_BIOS EN */
Angel Pons122cc8c2021-02-15 17:18:55 +0100381 pci_or_config32(dev, SPI_BIOS_CONTROL, SPI_BIOS_CONTROL_EXT_BIOS_ENABLE);
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800382}
383
384/*
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530385 * Program temporary BAR for SPI in case any of the stages before ramstage need
386 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
387 * enumeration.
388 */
389void fast_spi_early_init(uintptr_t spi_base_address)
390{
Angel Pons52072432021-02-15 13:09:36 +0100391 const pci_devfn_t dev = PCH_DEV_SPI;
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200392 uint16_t pcireg;
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530393
394 /* Assign Resources to SPI Controller */
395 /* Clear BIT 1-2 SPI Command Register */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200396 pcireg = pci_read_config16(dev, PCI_COMMAND);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530397 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200398 pci_write_config16(dev, PCI_COMMAND, pcireg);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530399
400 /* Program Temporary BAR for SPI */
401 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
402 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
403
Srinidhi N Kaushik60949082020-11-25 01:58:34 -0800404 /*
405 * Enable extended bios support. Since it configures memory BAR, this is done before
406 * enabling MMIO space.
407 */
408 fast_spi_enable_ext_bios();
409
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530410 /* Enable Bus Master and MMIO Space */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +0200411 pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
Barnali Sarkar89331cd2017-02-16 17:22:37 +0530412
413 /* Initialize SPI to allow BIOS to write/erase on flash. */
414 fast_spi_init();
415}
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700416
Angel Pons967753f2021-02-15 17:44:09 +0100417/* Clear SPI Synchronous SMI status bit and return its value. */
418bool fast_spi_clear_sync_smi_status(void)
419{
420 const uint32_t bios_cntl = pci_read_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL);
421 const bool smi_asserted = bios_cntl & SPI_BIOS_CONTROL_SYNC_SS;
422 /*
423 * Do not unconditionally write 1 to clear SYNC_SS. Hardware could set
424 * SYNC_SS here (after we read but before we write SPI_BIOS_CONTROL),
425 * and the event would be lost when unconditionally clearing SYNC_SS.
426 */
427 pci_write_config32(PCH_DEV_SPI, SPI_BIOS_CONTROL, bios_cntl);
428 return smi_asserted;
429}
430
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700431/* Read SPI Write Protect disable status. */
432bool fast_spi_wpd_status(void)
433{
Angel Pons122cc8c2021-02-15 17:18:55 +0100434 return pci_read_config16(PCH_DEV_SPI, SPI_BIOS_CONTROL) &
435 SPI_BIOS_CONTROL_WPD;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700436}
437
438/* Enable SPI Write Protect. */
439void fast_spi_enable_wp(void)
440{
Angel Pons52072432021-02-15 13:09:36 +0100441 const pci_devfn_t dev = PCH_DEV_SPI;
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700442 uint8_t bios_cntl;
443
Angel Pons122cc8c2021-02-15 17:18:55 +0100444 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
445 bios_cntl &= ~SPI_BIOS_CONTROL_WPD;
446 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
Ravi Sarawadib051a9f52017-09-07 12:15:45 -0700447}
Angel Ponsd21b4632021-02-10 17:12:05 +0100448
449/* Disable SPI Write Protect. */
450void fast_spi_disable_wp(void)
451{
452 const pci_devfn_t dev = PCH_DEV_SPI;
453 uint8_t bios_cntl;
454
455 bios_cntl = pci_read_config8(dev, SPI_BIOS_CONTROL);
456 bios_cntl |= SPI_BIOS_CONTROL_WPD;
457 pci_write_config8(dev, SPI_BIOS_CONTROL, bios_cntl);
458}
Subrata Banikd5e7c632022-04-14 00:08:05 +0530459
460void fast_spi_clear_outstanding_status(void)
461{
462 void *spibar = fast_spi_get_bar();
463
464 /* Make sure all W1C status bits get cleared. */
465 write32(spibar + SPIBAR_HSFSTS_CTL, SPIBAR_HSFSTS_W1C_BITS);
466}
Werner Zehbae84982022-05-05 11:04:04 +0200467
Werner Zeh53553e82022-05-05 11:55:30 +0200468
469/* As there is no official ACPI ID for this controller use the generic PNP ID for now. */
470static const char *fast_spi_acpi_hid(const struct device *dev)
471{
472 return "PNP0C02";
473}
474
475static const char *fast_spi_acpi_name(const struct device *dev)
476{
477 return "FSPI";
478}
479
480/*
481 * Generate an ACPI entry for the SPI controller. This way the allocated resources
482 * for the SPI controller can be communicated to the OS even if the device is
483 * not visible on PCI (because it is hidden) and therefore can not be probed by the OS.
484 */
485static void fast_spi_fill_ssdt(const struct device *dev)
486{
487 const char *scope = acpi_device_scope(dev);
488 const char *hid = fast_spi_acpi_hid(dev);
489 struct resource *res;
490
491 /* Do not add SSDT if the fast SPI device is hidden. */
492 if (dev->hidden || !CONFIG(FAST_SPI_GENERATE_SSDT))
493 return;
494 if (!scope || !hid)
495 return;
496
497 res = probe_resource(dev, PCI_BASE_ADDRESS_0);
498 if (!res)
499 return;
500
501 /* Scope */
502 acpigen_write_scope(scope);
503
504 /* Device */
505 acpigen_write_device(acpi_device_name(dev));
506 acpigen_write_name_string("_HID", hid);
507 acpi_device_write_uid(dev);
508 acpigen_write_name_string("_DDN", "ACPI Fast SPI");
509 acpigen_write_STA(acpi_device_status(dev));
510
511 /* Resources */
512 acpigen_write_name("_CRS");
513 acpigen_write_resourcetemplate_header();
514
515 /* Add BAR0 resource. */
516 acpigen_write_mem32fixed(1, res->base, res->size);
517
518 acpigen_write_resourcetemplate_footer();
519
520 acpigen_pop_len(); /* Device */
521 acpigen_pop_len(); /* Scope */
522}
523
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200524static void fast_spi_read_resources(struct device *dev)
525{
526 /* Read standard PCI resources. */
527 pci_dev_read_resources(dev);
528
529 /* Add SPI flash MMIO window as a reserved resource. */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300530 mmio_resource_kb(dev, 0, FLASH_BASE_ADDR / KiB, FLASH_MMIO_SIZE / KiB);
Werner Zeh826b45b2022-09-12 06:34:04 +0200531 /* Add extended SPI flash MMIO window as reserved resource if enabled. */
532 if (CONFIG(FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW)) {
533 mmio_resource_kb(dev, 1, CONFIG_EXT_BIOS_WIN_BASE / KiB,
534 CONFIG_EXT_BIOS_WIN_SIZE / KiB);
535 }
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200536}
537
Werner Zehbae84982022-05-05 11:04:04 +0200538static struct device_operations fast_spi_dev_ops = {
Werner Zeh0c78f4c2022-05-05 14:56:07 +0200539 .read_resources = fast_spi_read_resources,
Werner Zehbae84982022-05-05 11:04:04 +0200540 .set_resources = pci_dev_set_resources,
541 .enable_resources = pci_dev_enable_resources,
Werner Zeh53553e82022-05-05 11:55:30 +0200542 .acpi_fill_ssdt = fast_spi_fill_ssdt,
543 .acpi_name = fast_spi_acpi_name,
Kapil Porwala2a9e8e2022-12-27 19:26:48 +0530544 .ops_pci = &pci_dev_ops_pci,
Werner Zehbae84982022-05-05 11:04:04 +0200545};
546
547static const unsigned short pci_device_ids[] = {
Werner Zeh77709902022-08-29 12:44:02 +0200548 PCI_DID_INTEL_ADP_M_N_HWSEQ_SPI,
549 PCI_DID_INTEL_ADP_P_HWSEQ_SPI,
550 PCI_DID_INTEL_ADP_S_HWSEQ_SPI,
Werner Zehbae84982022-05-05 11:04:04 +0200551 PCI_DID_INTEL_APL_HWSEQ_SPI,
Sean Rhodese7bdc1b2022-09-07 13:13:42 +0100552 PCI_DID_INTEL_GLK_HWSEQ_SPI,
Werner Zeh77709902022-08-29 12:44:02 +0200553 PCI_DID_INTEL_CMP_HWSEQ_SPI,
554 PCI_DID_INTEL_CMP_H_HWSEQ_SPI,
555 PCI_DID_INTEL_CNL_HWSEQ_SPI,
556 PCI_DID_INTEL_CNP_H_HWSEQ_SPI,
557 PCI_DID_INTEL_ICP_HWSEQ_SPI,
558 PCI_DID_INTEL_JSP_HWSEQ_SPI,
559 PCI_DID_INTEL_LWB_SPI,
560 PCI_DID_INTEL_LWB_SPI_SUPER,
561 PCI_DID_INTEL_MCC_SPI0,
562 PCI_DID_INTEL_MTL_HWSEQ_SPI,
563 PCI_DID_INTEL_SPR_HWSEQ_SPI,
564 PCI_DID_INTEL_TGP_SPI0,
Werner Zehbae84982022-05-05 11:04:04 +0200565 0
566};
567
568static const struct pci_driver fast_spi __pci_driver = {
569 .ops = &fast_spi_dev_ops,
570 .vendor = PCI_VID_INTEL,
571 .devices = pci_device_ids,
572};