Browse Source

x86: fsp: Configure SPI opcode registers before SPI is locked down

Some Intel FSP (like Braswell) does SPI lock-down during the call
to fsp_notify(INIT_PHASE_BOOT). But before SPI lock-down is done,
it's bootloader's responsibility to configure the SPI controller's
opcode registers properly otherwise SPI controller driver doesn't
know how to communicate with the SPI flash device.

This introduces a Kconfig option CONFIG_FSP_LOCKDOWN_SPI for such
FSPs. When it is on, U-Boot will configure the SPI opcode registers
before the lock-down.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Reviewed-by: Stefan Roese <sr@denx.de>
Bin Meng 7 years ago
parent
commit
1e6ebee667
2 changed files with 33 additions and 0 deletions
  1. 9 0
      arch/x86/Kconfig
  2. 24 0
      arch/x86/lib/fsp/fsp_common.c

+ 9 - 0
arch/x86/Kconfig

@@ -401,6 +401,15 @@ config FSP_BROKEN_HOB
 	  do not overwrite the important boot service data which is used by
 	  do not overwrite the important boot service data which is used by
 	  FSP, otherwise the subsequent call to fsp_notify() will fail.
 	  FSP, otherwise the subsequent call to fsp_notify() will fail.
 
 
+config FSP_LOCKDOWN_SPI
+	bool
+	depends on HAVE_FSP
+	help
+	  Some Intel FSP (like Braswell) does SPI lock-down during the call
+	  to fsp_notify(INIT_PHASE_BOOT). This option should be turned on
+	  for such FSP and U-Boot will configure the SPI opcode registers
+	  before the lock-down.
+
 config ENABLE_MRC_CACHE
 config ENABLE_MRC_CACHE
 	bool "Enable MRC cache"
 	bool "Enable MRC cache"
 	depends on !EFI && !SYS_COREBOOT
 	depends on !EFI && !SYS_COREBOOT

+ 24 - 0
arch/x86/lib/fsp/fsp_common.c

@@ -19,6 +19,8 @@
 
 
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
+extern void ich_spi_config_opcode(struct udevice *dev);
+
 int checkcpu(void)
 int checkcpu(void)
 {
 {
 	return 0;
 	return 0;
@@ -49,6 +51,28 @@ void board_final_cleanup(void)
 {
 {
 	u32 status;
 	u32 status;
 
 
+#ifdef CONFIG_FSP_LOCKDOWN_SPI
+	struct udevice *dev;
+
+	/*
+	 * Some Intel FSP (like Braswell) does SPI lock-down during the call
+	 * to fsp_notify(INIT_PHASE_BOOT). But before SPI lock-down is done,
+	 * it's bootloader's responsibility to configure the SPI controller's
+	 * opcode registers properly otherwise SPI controller driver doesn't
+	 * know how to communicate with the SPI flash device.
+	 *
+	 * Note we cannot do such configuration elsewhere (eg: during the SPI
+	 * controller driver's probe() routine), because:
+	 *
+	 * 1). U-Boot SPI controller driver does not set the lock-down bit
+	 * 2). Any SPI transfer will corrupt the contents of these registers
+	 *
+	 * Hence we have to do it right here before SPI lock-down bit is set.
+	 */
+	if (!uclass_first_device_err(UCLASS_SPI, &dev))
+		ich_spi_config_opcode(dev);
+#endif
+
 	/* call into FspNotify */
 	/* call into FspNotify */
 	debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
 	debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
 	status = fsp_notify(NULL, INIT_PHASE_BOOT);
 	status = fsp_notify(NULL, INIT_PHASE_BOOT);