diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-04-20 15:20:28 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-06-25 21:50:48 +0200 |
commit | 32471729d9ebbabe809711ec55568925c6ce2070 (patch) | |
tree | b9f6db4e4969ee5edd6c2571e4f7612121070a9f /src/soc/intel/braswell/spi.c | |
parent | 5fe62efb77a2ecfeecdcc526404712b816e74693 (diff) | |
download | coreboot-32471729d9ebbabe809711ec55568925c6ce2070.tar.xz |
Braswell: Add Braswell SOC support
Add the files to support the Braswell SOC.
BRANCH=none
BUG=None
TEST=Build for a Braswell platform
Change-Id: I968da68733e57647d0a08e4040ff0378b4d59004
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10051
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/braswell/spi.c')
-rw-r--r-- | src/soc/intel/braswell/spi.c | 129 |
1 files changed, 57 insertions, 72 deletions
diff --git a/src/soc/intel/braswell/spi.c b/src/soc/intel/braswell/spi.c index b1fc692c24..16fb465037 100644 --- a/src/soc/intel/braswell/spi.c +++ b/src/soc/intel/braswell/spi.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. * * See file CREDITS for list of people who contributed to this * project. @@ -20,18 +21,17 @@ */ /* This file is derived from the flashrom project. */ -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <bootstate.h> -#include <delay.h> #include <arch/io.h> +#include <bootstate.h> #include <console/console.h> +#include <delay.h> #include <device/pci_ids.h> -#include <spi_flash.h> - #include <soc/lpc.h> #include <soc/pci_devs.h> +#include <spi_flash.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> #ifdef __SMM__ #define pci_read_config_byte(dev, reg, targ)\ @@ -84,20 +84,6 @@ typedef struct ich9_spi_regs { uint16_t preop; uint16_t optype; uint8_t opmenu[8]; - uint32_t bbar; - uint8_t _reserved3[12]; - uint32_t fdoc; - uint32_t fdod; - uint8_t _reserved4[8]; - uint32_t afc; - uint32_t lvscc; - uint32_t uvscc; - uint8_t _reserved5[4]; - uint32_t fpb; - uint8_t _reserved6[28]; - uint32_t srdl; - uint32_t srdc; - uint32_t srd; } __attribute__((packed)) ich9_spi_regs; typedef struct ich_spi_controller { @@ -112,7 +98,6 @@ typedef struct ich_spi_controller { unsigned databytes; uint8_t *status; uint16_t *control; - uint32_t *bbar; } ich_spi_controller; static ich_spi_controller cntlr; @@ -167,51 +152,45 @@ enum { SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 }; -#if CONFIG_DEBUG_SPI_FLASH +#if IS_ENABLED(CONFIG_DEBUG_SPI_FLASH) -static u8 readb_(const void *addr) +static u8 readb_(void *addr) { - u8 v = read8((unsigned long)addr); - printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); + u8 v = read8(addr); + printk(BIOS_DEBUG, "0x%p --> 0x%2.2x\n", addr, v); return v; } -static u16 readw_(const void *addr) +static u16 readw_(void *addr) { - u16 v = read16((unsigned long)addr); - printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); + u16 v = read16(addr); + printk(BIOS_DEBUG, "0x%p --> 0x%4.4x\n", addr, v); return v; } -static u32 readl_(const void *addr) +static u32 readl_(void *addr) { - u32 v = read32((unsigned long)addr); - printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", - v, ((unsigned) addr & 0xffff) - 0xf020); + u32 v = read32(addr); + printk(BIOS_DEBUG, "0x%p --> 0x%8.8x\n", addr, v); return v; } -static void writeb_(u8 b, const void *addr) +static void writeb_(u8 b, void *addr) { + printk(BIOS_DEBUG, "0x%p <-- 0x%2.2x\n", addr, b); write8(addr, b); - printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); } -static void writew_(u16 b, const void *addr) +static void writew_(u16 b, void *addr) { + printk(BIOS_DEBUG, "0x%p <-- 0x%4.4x\n", addr, b); write16(addr, b); - printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); } -static void writel_(u32 b, const void *addr) +static void writel_(u32 b, void *addr) { + printk(BIOS_DEBUG, "0x%p <-- 0x%8.8x\n", addr, b); write32(addr, b); - printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", - b, ((unsigned) addr & 0xffff) - 0xf020); } #else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ @@ -240,9 +219,9 @@ static void write_reg(const void *value, void *dest, uint32_t size) } } -static void read_reg(const void *src, void *value, uint32_t size) +static void read_reg(void *src, void *value, uint32_t size) { - const uint8_t *bsrc = src; + uint8_t *bsrc = src; uint8_t *bvalue = value; while (size >= 4) { @@ -255,23 +234,12 @@ static void read_reg(const void *src, void *value, uint32_t size) } } -static void ich_set_bbar(uint32_t minaddr) -{ - const uint32_t bbar_mask = 0x00ffff00; - uint32_t ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs) { ich_spi_slave *slave = malloc(sizeof(*slave)); if (!slave) { - printk(BIOS_DEBUG, "ICH SPI: Bad allocation\n"); + printk(BIOS_ERR, "ICH SPI: Bad allocation\n"); return NULL; } @@ -292,6 +260,11 @@ static ich9_spi_regs *spi_regs(void) #else dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC)); #endif + if (!dev) { + printk(BIOS_ERR, "%s: PCI device not found", __func__); + return NULL; + } + pci_read_config_dword(dev, SBASE, &sbase); sbase &= ~0x1ff; @@ -300,7 +273,14 @@ static ich9_spi_regs *spi_regs(void) void spi_init(void) { - ich9_spi_regs *ich9_spi = spi_regs(); + ich9_spi_regs *ich9_spi; + + ich9_spi = spi_regs(); + if (!ich9_spi) { + printk(BIOS_ERR, "Not initialising spi as %s returned NULL\n", + __func__); + return; + } ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN; cntlr.opmenu = ich9_spi->opmenu; @@ -311,19 +291,19 @@ void spi_init(void) cntlr.databytes = sizeof(ich9_spi->fdata); cntlr.status = &ich9_spi->ssfs; cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; cntlr.preop = &ich9_spi->preop; - ich_set_bbar(0); } -#ifndef __SMM__ +#if ENV_RAMSTAGE + static void spi_init_cb(void *unused) { spi_init(); } BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); -#endif + +#endif /* ENV_RAMSTAGE */ int spi_claim_bus(struct spi_slave *slave) { @@ -460,13 +440,14 @@ static int spi_setup_offset(spi_transaction *trans) spi_use_out(trans, 3); return 1; default: - printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); + printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", + trans->type); return -1; } } /* - * Wait for up to 60ms til status register bit(s) turn 1 (in case wait_til_set + * Wait for up to 400ms til status register bit(s) turn 1 (in case wait_til_set * below is True) or 0. In case the wait was for the bit(s) to set - write * those bits back, which would cause resetting them. * @@ -477,6 +458,7 @@ static int ich_status_poll(u16 bitmask, int wait_til_set) int timeout = 40000; /* This will result in 400 ms */ u16 status = 0; + wait_til_set &= 1; while (timeout--) { status = readw_(cntlr.status); if (wait_til_set ^ ((status & bitmask) == 0)) { @@ -487,7 +469,7 @@ static int ich_status_poll(u16 bitmask, int wait_til_set) udelay(10); } - printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, expected %x\n", + printk(BIOS_ERR, "ICH SPI: SCIP timeout, read %x, expected %x\n", status, bitmask); return -1; } @@ -528,9 +510,11 @@ int spi_xfer(struct spi_slave *slave, const void *dout, writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) + opcode_index = spi_setup_opcode(&trans); + if (opcode_index < 0) return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) + with_address = spi_setup_offset(&trans); + if (with_address < 0) return -1; if (trans.opcode == SPI_OPCODE_WREN) { @@ -570,7 +554,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return -1; if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); + printk(BIOS_ERR, "ICH SPI: Command transaction error\n"); return -1; } @@ -585,8 +569,9 @@ int spi_xfer(struct spi_slave *slave, const void *dout, * by the SPI chip driver. */ if (trans.bytesout > cntlr.databytes) { - printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" - " spi_crop_chunk()?\n"); + printk(BIOS_DEBUG, + "ICH SPI: Too much to write. Does your SPI chip driver use" + " CONTROLLER_PAGE_LIMIT?\n"); return -1; } @@ -627,7 +612,7 @@ int spi_xfer(struct spi_slave *slave, const void *dout, return -1; if (status & SPIS_FCERR) { - printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); + printk(BIOS_ERR, "ICH SPI: Data transaction error\n"); return -1; } |