drivers/spi/spi_flash: Clean up SPI flash probe
1. Rename __spi_flash_probe to spi_flash_generic_probe and export it so that drivers can use it outside spi_flash.c. 2. Make southbridge intel spi driver use spi_flash_generic_probe if spi_is_multichip returns 0. 3. Add spi_flash_probe to spi_ctrlr structure to allow platforms to provide specialized probe functions. With this change, the specialized spi flash probe functions are now associated with a particular spi ctrlr structure and no longer disconnected from the spi controller. BUG=b:38330715 Change-Id: I35f3bd8ddc5e71515df3ef0c1c4b1a68ee56bf4b Signed-off-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: https://review.coreboot.org/19708 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
bd9e32efdd
commit
a1491574ef
|
@ -281,16 +281,7 @@ static struct {
|
|||
};
|
||||
#define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
|
||||
|
||||
int
|
||||
__attribute__((weak)) spi_flash_programmer_probe(const struct spi_slave *spi,
|
||||
int force,
|
||||
struct spi_flash *flash)
|
||||
{
|
||||
/* Default weak implementation. Do nothing. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __spi_flash_probe(const struct spi_slave *spi,
|
||||
int spi_flash_generic_probe(const struct spi_slave *spi,
|
||||
struct spi_flash *flash)
|
||||
{
|
||||
int ret, i, shift;
|
||||
|
@ -330,32 +321,29 @@ static int __spi_flash_probe(const struct spi_slave *spi,
|
|||
int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash)
|
||||
{
|
||||
struct spi_slave spi;
|
||||
int ret = -1;
|
||||
|
||||
if (spi_setup_slave(bus, cs, &spi)) {
|
||||
printk(BIOS_WARNING, "SF: Failed to set up slave\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Try special programmer probe if any (without force). */
|
||||
if (spi_flash_programmer_probe(&spi, 0, flash) == 0)
|
||||
goto flash_found;
|
||||
/* Try special programmer probe if any. */
|
||||
if (spi.ctrlr->flash_probe)
|
||||
ret = spi.ctrlr->flash_probe(&spi, flash);
|
||||
|
||||
/* If flash is not found, try generic spi flash probe. */
|
||||
if (__spi_flash_probe(&spi, flash) == 0)
|
||||
goto flash_found;
|
||||
|
||||
/* If flash is not yet found, force special programmer probe if any. */
|
||||
if (spi_flash_programmer_probe(&spi, 1, flash) == 0)
|
||||
goto flash_found;
|
||||
if (ret)
|
||||
ret = spi_flash_generic_probe(&spi, flash);
|
||||
|
||||
/* Give up -- nothing more to try if flash is not found. */
|
||||
printk(BIOS_WARNING, "SF: Unsupported manufacturer!\n");
|
||||
return -1;
|
||||
if (ret) {
|
||||
printk(BIOS_WARNING, "SF: Unsupported manufacturer!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
flash_found:
|
||||
printk(BIOS_INFO, "SF: Detected %s with sector size 0x%x, total 0x%x\n",
|
||||
flash->name, flash->sector_size, flash->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ struct spi_cfg {
|
|||
*/
|
||||
#define SPI_CTRLR_DEFAULT_MAX_XFER_SIZE (UINT32_MAX)
|
||||
|
||||
struct spi_flash;
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
* Representation of a SPI controller.
|
||||
*
|
||||
|
@ -108,6 +110,11 @@ struct spi_cfg {
|
|||
* deduct_cmd_len: Whether cmd_len should be deducted from max_xfer_size
|
||||
* when calculating max_data_size
|
||||
*
|
||||
* Following member is provided by specialized SPI controllers that are
|
||||
* actually SPI flash controllers.
|
||||
*
|
||||
* flash_probe: Specialized probe function provided by SPI flash
|
||||
* controllers.
|
||||
*/
|
||||
struct spi_ctrlr {
|
||||
int (*claim_bus)(const struct spi_slave *slave);
|
||||
|
@ -119,6 +126,8 @@ struct spi_ctrlr {
|
|||
struct spi_op vectors[], size_t count);
|
||||
uint32_t max_xfer_size;
|
||||
bool deduct_cmd_len;
|
||||
int (*flash_probe)(const struct spi_slave *slave,
|
||||
struct spi_flash *flash);
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------------------------
|
||||
|
|
|
@ -65,20 +65,19 @@ void lb_spi_flash(struct lb_header *header);
|
|||
* non-zero = error
|
||||
*/
|
||||
int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash);
|
||||
|
||||
/*
|
||||
* Specialized probing performed by platform. This is a weak function which can
|
||||
* be overriden by platform driver.
|
||||
* Generic probing for SPI flash chip based on the different flashes provided.
|
||||
*
|
||||
* Params:
|
||||
* spi = Pointer to spi_slave structure.
|
||||
* force = Indicates if the platform driver can skip specialized probing.
|
||||
* spi = Pointer to spi_slave structure
|
||||
* flash = Pointer to spi_flash structure that needs to be filled.
|
||||
*
|
||||
* Return value:
|
||||
* 0 = success
|
||||
* 0 = success
|
||||
* non-zero = error
|
||||
*/
|
||||
int spi_flash_programmer_probe(const struct spi_slave *spi, int force,
|
||||
int spi_flash_generic_probe(const struct spi_slave *slave,
|
||||
struct spi_flash *flash);
|
||||
|
||||
/* All the following functions return 0 on success and non-zero on error. */
|
||||
|
|
|
@ -280,8 +280,8 @@ static int fast_spi_flash_status(const struct spi_flash *flash,
|
|||
* The size of the flash component is always taken from density field in the
|
||||
* SFDP table. FLCOMP.C0DEN is no longer used by the Flash Controller.
|
||||
*/
|
||||
int spi_flash_programmer_probe(const struct spi_slave *dev,
|
||||
int force, struct spi_flash *flash)
|
||||
static int fast_spi_flash_probe(const struct spi_slave *dev,
|
||||
struct spi_flash *flash)
|
||||
{
|
||||
BOILERPLATE_CREATE_CTX(ctx);
|
||||
uint32_t flash_bits;
|
||||
|
@ -362,4 +362,5 @@ static int fast_spi_flash_ctrlr_setup(const struct spi_slave *dev)
|
|||
const struct spi_ctrlr fast_spi_flash_ctrlr = {
|
||||
.setup = fast_spi_flash_ctrlr_setup,
|
||||
.max_xfer_size = SPI_CTRLR_DEFAULT_MAX_XFER_SIZE,
|
||||
.flash_probe = fast_spi_flash_probe,
|
||||
};
|
||||
|
|
|
@ -228,14 +228,8 @@ static int nor_erase(const struct spi_flash *flash, u32 offset, size_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_programmer_probe(const struct spi_slave *spi,
|
||||
int force, struct spi_flash *flash)
|
||||
int mtk_spi_flash_probe(const struct spi_slave *spi, struct spi_flash *flash)
|
||||
{
|
||||
static int done;
|
||||
|
||||
if (done)
|
||||
return 0;
|
||||
|
||||
write32(&mt8173_nor->wrprot, SFLASH_COMMAND_ENABLE);
|
||||
memcpy(&flash->spi, spi, sizeof(*spi));
|
||||
flash->name = "mt8173 flash controller";
|
||||
|
@ -246,6 +240,6 @@ int spi_flash_programmer_probe(const struct spi_slave *spi,
|
|||
flash->sector_size = 0x1000;
|
||||
flash->erase_cmd = SECTOR_ERASE_CMD;
|
||||
flash->size = CONFIG_ROM_SIZE;
|
||||
done = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -87,4 +87,6 @@ struct mt8173_nor_regs {
|
|||
check_member(mt8173_nor_regs, fdma_end_dadr, 0x724);
|
||||
static struct mt8173_nor_regs * const mt8173_nor = (void *)SFLASH_REG_BASE;
|
||||
|
||||
int mtk_spi_flash_probe(const struct spi_slave *spi, struct spi_flash *flash);
|
||||
|
||||
#endif /* __SOC_MEDIATEK_MT8173_FLASH_CONTROLLER_H__ */
|
||||
|
|
|
@ -295,6 +295,7 @@ static const struct spi_ctrlr spi_ctrlr = {
|
|||
.xfer = spi_ctrlr_xfer,
|
||||
.xfer_vector = spi_xfer_two_vectors,
|
||||
.max_xfer_size = 65535,
|
||||
.flash_probe = mtk_spi_flash_probe,
|
||||
};
|
||||
|
||||
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
|
||||
|
|
|
@ -653,20 +653,6 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_ctrlr spi_ctrlr = {
|
||||
.xfer = spi_ctrlr_xfer,
|
||||
.xfer_vector = spi_xfer_two_vectors,
|
||||
.max_xfer_size = member_size(ich9_spi_regs, fdata),
|
||||
};
|
||||
|
||||
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
|
||||
{
|
||||
slave->bus = bus;
|
||||
slave->cs = cs;
|
||||
slave->ctrlr = &spi_ctrlr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */
|
||||
static void ich_hwseq_set_addr(uint32_t addr)
|
||||
{
|
||||
|
@ -899,18 +885,14 @@ static int ich_hwseq_write(const struct spi_flash *flash, u32 addr, size_t len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int spi_flash_programmer_probe(const struct spi_slave *spi,
|
||||
int force, struct spi_flash *flash)
|
||||
static int spi_flash_programmer_probe(const struct spi_slave *spi,
|
||||
struct spi_flash *flash)
|
||||
{
|
||||
uint32_t flcomp;
|
||||
|
||||
/*
|
||||
* Perform SPI flash probing only if:
|
||||
* 1. spi_is_multichip returns 1 or
|
||||
* 2. Specialized probing is forced by SPI flash driver.
|
||||
*/
|
||||
if (!spi_is_multichip() && !force)
|
||||
return -1;
|
||||
/* Try generic probing first if spi_is_multichip returns 0. */
|
||||
if (!spi_is_multichip() && !spi_flash_generic_probe(spi, flash))
|
||||
return 0;
|
||||
|
||||
memcpy(&flash->spi, spi, sizeof(*spi));
|
||||
flash->name = "Opaque HW-sequencing";
|
||||
|
@ -946,3 +928,18 @@ int spi_flash_programmer_probe(const struct spi_slave *spi,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct spi_ctrlr spi_ctrlr = {
|
||||
.xfer = spi_ctrlr_xfer,
|
||||
.xfer_vector = spi_xfer_two_vectors,
|
||||
.max_xfer_size = member_size(ich9_spi_regs, fdata),
|
||||
.flash_probe = spi_flash_programmer_probe,
|
||||
};
|
||||
|
||||
int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave)
|
||||
{
|
||||
slave->bus = bus;
|
||||
slave->cs = cs;
|
||||
slave->ctrlr = &spi_ctrlr;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue