diff --git a/src/soc/amd/common/block/include/amdblocks/spi.h b/src/soc/amd/common/block/include/amdblocks/spi.h index 83d09e90d7..70de548bf7 100644 --- a/src/soc/amd/common/block/include/amdblocks/spi.h +++ b/src/soc/amd/common/block/include/amdblocks/spi.h @@ -70,6 +70,14 @@ enum spi100_speed { #define SPI100_HOST_PREF_CONFIG 0x2c #define SPI_RD4DW_EN_HOST BIT(15) +#define SPI_STATUS 0x4c +#define SPI_DONE_BYTE_COUNT_SHIFT 0 +#define SPI_DONE_BYTE_COUNT_MASK 0xff +#define SPI_FIFO_WR_PTR_SHIFT 8 +#define SPI_FIFO_WR_PTR_MASK 0x7f +#define SPI_FIFO_RD_PTR_SHIFT 16 +#define SPI_FIFO_RD_PTR_MASK 0x7f + #define SPI_ROM_PAGE 0x5c #define SPI_ROM_PAGE_SEL (BIT(0) | BIT(1)) diff --git a/src/soc/amd/common/block/psp/psp_smi_flash.c b/src/soc/amd/common/block/psp/psp_smi_flash.c index 9f9f31d94c..7e0328330c 100644 --- a/src/soc/amd/common/block/psp/psp_smi_flash.c +++ b/src/soc/amd/common/block/psp/psp_smi_flash.c @@ -96,14 +96,42 @@ static bool spi_controller_busy(void) { bool busy = false; - if (CONFIG(SOC_AMD_PICASSO)) { + /* + * When ring0 is operating on the SPI flash and the controller is + * busy, don't interrupt ongoing transfer. + */ + if (spi_read32(SPI_STATUS) & SPI_BUSY) + busy = true; + + /* + * Even when the SPI controller is not busy, the SPI flash + * might be busy. When that's the case reading from the + * memory mapped SPI flash doesn't work and returns all 0xffs. + * Thus check if the SPI flash is busy. + */ + if (CONFIG(SPI_FLASH) && !busy) { + const struct spi_flash *spi_flash_dev; + uint8_t sr1 = 0; + + spi_flash_dev = boot_device_spi_flash(); + assert(spi_flash_dev); + if (spi_flash_dev) { + /* Read Status Register 1 */ + if (spi_flash_status(spi_flash_dev, &sr1) < 0) + busy = true; + else if (sr1 & BIT(0)) + busy = true; + } + } + + if (CONFIG(SOC_AMD_PICASSO) && !busy) { // Only implemented on Picasso and Raven Ridge busy = (spi_read8(SPI_MISC_CNTRL) & SPI_SEMAPHORE_DRIVER_LOCKED); - - if (busy) - printk(BIOS_NOTICE, "PSP: SPI controller busy\n"); } + if (busy) + printk(BIOS_NOTICE, "PSP: SPI controller or SPI flash busy\n"); + return busy; } diff --git a/src/soc/amd/common/block/spi/fch_spi_ctrl.c b/src/soc/amd/common/block/spi/fch_spi_ctrl.c index aa07542a54..95b68ff050 100644 --- a/src/soc/amd/common/block/spi/fch_spi_ctrl.c +++ b/src/soc/amd/common/block/spi/fch_spi_ctrl.c @@ -22,13 +22,6 @@ #define SPI_CMD_TRIGGER_EXECUTE BIT(7) #define SPI_TX_BYTE_COUNT 0x48 #define SPI_RX_BYTE_COUNT 0x4b -#define SPI_STATUS 0x4c -#define SPI_DONE_BYTE_COUNT_SHIFT 0 -#define SPI_DONE_BYTE_COUNT_MASK 0xff -#define SPI_FIFO_WR_PTR_SHIFT 8 -#define SPI_FIFO_WR_PTR_MASK 0x7f -#define SPI_FIFO_RD_PTR_SHIFT 16 -#define SPI_FIFO_RD_PTR_MASK 0x7f enum spi_dump_state_phase { SPI_DUMP_STATE_BEFORE_CMD,