summaryrefslogtreecommitdiff
path: root/src/soc/intel/quark/spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/quark/spi.c')
-rw-r--r--src/soc/intel/quark/spi.c290
1 files changed, 0 insertions, 290 deletions
diff --git a/src/soc/intel/quark/spi.c b/src/soc/intel/quark/spi.c
deleted file mode 100644
index cc284f33a7..0000000000
--- a/src/soc/intel/quark/spi.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include <device/mmio.h>
-#include <device/pci_ops.h>
-#include <bootstate.h>
-#include <console/console.h>
-#include <device/pci_ids.h>
-#include <device/pci_def.h>
-#include <delay.h>
-#include <soc/pci_devs.h>
-#include <soc/QuarkNcSocId.h>
-#include <soc/spi.h>
-#include <string.h>
-
-struct spi_context spi_driver_context = {
- NULL,
- 0,
- 0
-};
-
-void spi_bios_base(uint32_t bios_base_address)
-{
- uint32_t address;
- volatile struct flash_ctrlr *ctrlr = spi_driver_context.ctrlr;
-
- /* Prevent all SPI operations below this address */
- address = 0xff000000 | bios_base_address;
- ctrlr->bbar = address;
-}
-
-void spi_controller_lock(void)
-{
- volatile struct flash_ctrlr *ctrlr = spi_driver_context.ctrlr;
-
- /* Prevent BIOS and system from changing the SPI controller setup */
- ctrlr->status |= SPISTS_CLD;
-}
-
-int spi_protection(uint32_t address, uint32_t length)
-{
- uint32_t base;
- volatile struct flash_ctrlr *ctrlr = spi_driver_context.ctrlr;
- int index;
- uint32_t limit;
- uint32_t protect;
- uint32_t value;
-
- /* Determine the protection range */
- base = address;
- limit = address + length - 1;
- protect = SPIPBR_WPE | (limit & SPIPBR_PRL)
- | ((base >> SPIPBR_PRB_SHIFT) & SPIPBR_PRB);
-
- /* Walk the list of protected areas */
- for (index = 0; index < ARRAY_SIZE(ctrlr->pbr); index++) {
- value = read32(&ctrlr->pbr[index]);
-
- /* Don't duplicate if the range is already protected */
- if (value == protect)
- return 0;
-
- /* Use the first free register to protect this range */
- if ((value & SPIPBR_WPE) == 0) {
- write32(&ctrlr->pbr[index], protect);
- return 0;
- }
- }
-
- /* No free protection range registers */
- printk(BIOS_ERR,
- "Failed to set protection: 0x%08x - 0x%08x, PRRs full!\n",
- address, address + length - 1);
- return -1;
-}
-
-static int xfer(const struct spi_slave *slave, const void *dout,
- size_t bytesout, void *din, size_t bytesin)
-{
- struct spi_context *context;
- uint16_t control;
- volatile struct flash_ctrlr *ctrlr;
- uint8_t *data;
- int index;
- uint8_t opcode;
- uint32_t status;
- int type;
-
- /* Locate the context structure */
- context = &spi_driver_context;
- ctrlr = context->ctrlr;
-
- /* Validate the buffer sizes */
- if (bytesin > sizeof(ctrlr->data)) {
- printk(BIOS_ERR, "bytesin > %zu\n", sizeof(ctrlr->data));
- goto error;
- }
-
- if (bytesin && (din == NULL)) {
- printk(BIOS_ERR, "din is NULL\n");
- goto error;
- }
-
- if (bytesout == 0) {
- /* Check for a read operation */
- if (bytesin == 0) {
- printk(BIOS_ERR, "bytesout and bytesin == 0\n");
- goto error;
- }
-
- /* Issue the read operation */
- control = context->control;
- control |= SPICTL_DC | ((bytesin - 1) << SPICTL_DBCNT_SHIFT);
- goto start_cycle;
- }
-
- /* Locate the opcode in the opcode table */
- data = (uint8_t *)dout;
- opcode = *data++;
- bytesout -= 1;
- for (index = 0; index < sizeof(ctrlr->opmenu); index++)
- if (opcode == ctrlr->opmenu[index])
- break;
-
- /* Check for a prefix byte */
- if (index == sizeof(ctrlr->opmenu)) {
- for (index = 0; index < sizeof(ctrlr->prefix); index++)
- if (opcode == ctrlr->prefix[index])
- break;
-
- /* Handle the unknown opcode error */
- if (index == sizeof(ctrlr->prefix)) {
- printk(BIOS_ERR, "Unknown SPI flash opcode\n");
- goto error;
- }
-
- /* Save the index for the next operation */
- context->prefix = index;
- return 0;
- }
-
- /* Get the opcode type */
- type = (ctrlr->type >> (index * 2))
- & (SPITYPE_ADDRESS | SPITYPE_PREFIX);
-
- /* Determine if the opcode has an address */
- if (type & SPITYPE_ADDRESS) {
- if (bytesout < 3) {
- printk(BIOS_ERR, "Missing address bytes\n");
- goto error;
- }
-
- /* Use chip select 0 */
- ctrlr->address = (data[0] << 16)
- | (data[1] << 8)
- | data[2];
-
- /* read in order to flush the write buffer */
- status = ctrlr->address;
-
- data += 3;
- bytesout -= 3;
- }
-
- /* Build the control value */
- control = (index << SPICTL_COPTR_SHIFT)
- | (context->prefix << SPICTL_SOPTR_SHIFT)
- | SPICTL_CG | SPICTL_AR;
- if (bytesout) {
- memcpy((void *)&ctrlr->data[0], data, bytesout);
- control |= SPICTL_DC | ((bytesout - 1) << SPICTL_DBCNT_SHIFT);
- }
-
- /* Save the control value for the read operation request */
- if (!(type & SPITYPE_PREFIX)) {
- context->control = control;
- return 0;
- }
-
- /* Write operations require a prefix */
- control |= SPICTL_ACS;
-
-start_cycle:
- /* Start the SPI cycle */
- ctrlr->control = control;
- status = ctrlr->control;
- context->prefix = 0;
-
- /* Wait for the access to complete */
- while ((status = ctrlr->status) & SPISTS_CIP)
- udelay(1);
-
- /* Clear any errors */
- ctrlr->status = status;
-
- /* Handle the blocked access error */
- if (status & SPISTS_BA) {
- printk(BIOS_ERR, "SPI access blocked!\n");
- return -1;
- }
-
- /* Check for done */
- if (status & SPISTS_CD) {
- /* Return any receive data */
- if (bytesin)
- memcpy(din, (void *)&ctrlr->data[0], bytesin);
- return 0;
- }
-
- /* Handle the timeout error */
- printk(BIOS_ERR, "SPI transaction timeout!\n");
-
-error:
- context->prefix = 0;
- return -1;
-}
-
-void spi_init(void)
-{
- uint32_t bios_control;
- struct spi_context *context;
- volatile struct flash_ctrlr *ctrlr;
- struct device *dev;
- uint32_t rcba;
-
- /* Determine the base address of the SPI flash controller */
- context = &spi_driver_context;
- dev = dev_find_device(PCI_VID_INTEL, LPC_DEVID, NULL);
- rcba = pci_read_config32(dev, R_QNC_LPC_RCBA);
- if (!(rcba & B_QNC_LPC_RCBA_EN)) {
- printk(BIOS_ERR, "RBCA not enabled\n");
- return;
- }
- rcba &= B_QNC_LPC_RCBA_MASK;
- ctrlr = (volatile struct flash_ctrlr *)rcba;
-
- /* Enable writes to the SPI flash */
- bios_control = pci_read_config32(dev, R_QNC_LPC_BIOS_CNTL);
- bios_control |= B_QNC_LPC_BIOS_CNTL_BIOSWE;
- pci_write_config32(dev, R_QNC_LPC_BIOS_CNTL, bios_control);
-
- /* Setup the SPI flash controller */
- context->ctrlr = ctrlr;
- ctrlr->opmenu[0] = 0x03; /* Read */
- ctrlr->opmenu[1] = 0x0b; /* Read fast */
- ctrlr->opmenu[2] = 0x05; /* Read status */
- ctrlr->opmenu[3] = 0x9f; /* Read ID */
- ctrlr->opmenu[4] = 0x02; /* Page program */
- ctrlr->opmenu[5] = 0x20; /* Erase 4 KiB */
- ctrlr->opmenu[6] = 0xd8; /* Erase 64 KiB */
- ctrlr->opmenu[7] = 0x01; /* Write status */
- ctrlr->prefix[0] = 0x50; /* Write status enable */
- ctrlr->prefix[1] = 0x06; /* Write enable */
- ctrlr->type = SPITYPE_ADDRESS /* Read */
- | (SPITYPE_ADDRESS << 2) /* Read fast */
- | (0 << 4) /* Read status */
- | (0 << 6) /* Read ID */
- | ((SPITYPE_ADDRESS | SPITYPE_PREFIX) << 8) /* Page program */
- | ((SPITYPE_ADDRESS | SPITYPE_PREFIX) << 10) /* Erase 4 KiB */
- | ((SPITYPE_ADDRESS | SPITYPE_PREFIX) << 12) /* Erase 64 KiB */
- | (SPITYPE_PREFIX << 14); /* Write status */
-}
-
-static void spi_init_cb(void *unused)
-{
- struct spi_flash flash;
-
- spi_init();
- if (spi_flash_probe(0, 0, &flash)) {
- printk(BIOS_DEBUG, "SPI flash failed initialization!\n");
- return;
- }
- printk(BIOS_DEBUG, "SPI flash successfully initialized\n");
-}
-
-BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL);
-
-const struct spi_ctrlr spi_driver = {
- .xfer = xfer,
- .max_xfer_size = 64,
-};
-
-const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
- {
- .ctrlr = &spi_driver,
- .bus_start = 0,
- .bus_end = 0,
- },
-};
-
-const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);