/* This file is part of the coreboot project. */ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* GSPI Memory Mapped Registers */ #define SSCR0 0x0 /* SSP Control Register 0 */ #define SSCR0_EDSS_0 (0 << 20) #define SSCR0_EDSS_1 (1 << 20) #define SSCR0_SCR_SHIFT (8) #define SSCR0_SCR_MASK (0xFFF) #define SSCR0_SSE_DISABLE (0 << 7) #define SSCR0_SSE_ENABLE (1 << 7) #define SSCR0_ECS_ON_CHIP (0 << 6) #define SSCR0_FRF_MOTOROLA (0 << 4) #define SSCR0_DSS_SHIFT (0) #define SSCR0_DSS_MASK (0xF) #define SSCR1 0x4 /* SSP Control Register 1 */ #define SSCR1_IFS_LOW (0 << 16) #define SSCR1_IFS_HIGH (1 << 16) #define SSCR1_SPH_FIRST (0 << 4) #define SSCR1_SPH_SECOND (1 << 4) #define SSCR1_SPO_LOW (0 << 3) #define SSCR1_SPO_HIGH (1 << 3) #define SSSR 0x8 /* SSP Status Register */ #define SSSR_TUR (1 << 21) /* Tx FIFO underrun */ #define SSSR_TINT (1 << 19) /* Rx Time-out interrupt */ #define SSSR_PINT (1 << 18) /* Peripheral trailing byte interrupt */ #define SSSR_ROR (1 << 7) /* Rx FIFO Overrun */ #define SSSR_BSY (1 << 4) /* SSP Busy */ #define SSSR_RNE (1 << 3) /* Receive FIFO not empty */ #define SSSR_TNF (1 << 2) /* Transmit FIFO not full */ #define SSDR 0x10 /* SSP Data Register */ #define SSTO 0x28 /* SSP Time out */ #define SITF 0x44 /* SPI Transmit FIFO */ #define SITF_LEVEL_SHIFT (16) #define SITF_LEVEL_MASK (0x3f) #define SITF_LWM_SHIFT (8) #define SITF_LWM_MASK (0x3f) #define SITF_LWM(x) ((((x) - 1) & SITF_LWM_MASK) << SITF_LWM_SHIFT) #define SITF_HWM_SHIFT (0) #define SITF_HWM_MASK (0x3f) #define SITF_HWM(x) ((((x) - 1) & SITF_HWM_MASK) << SITF_HWM_SHIFT) #define SIRF 0x48 /* SPI Receive FIFO */ #define SIRF_LEVEL_SHIFT (8) #define SIRF_LEVEL_MASK (0x3f) #define SIRF_WM_SHIFT (0) #define SIRF_WM_MASK (0x3f) #define SIRF_WM(x) ((((x) - 1) & SIRF_WM_MASK) << SIRF_WM_SHIFT) /* GSPI Additional Registers */ #define CLOCKS 0x200 /* Clocks */ #define CLOCKS_UPDATE (1 << 31) #define CLOCKS_N_SHIFT (16) #define CLOCKS_N_MASK (0x7fff) #define CLOCKS_M_SHIFT (1) #define CLOCKS_M_MASK (0x7fff) #define CLOCKS_DISABLE (0 << 0) #define CLOCKS_ENABLE (1 << 0) #define RESETS 0x204 /* Resets */ #define DMA_RESET (0 << 2) #define DMA_ACTIVE (1 << 2) #define CTRLR_RESET (0 << 0) #define CTRLR_ACTIVE (3 << 0) #define ACTIVELTR_VALUE 0x210 /* Active LTR */ #define IDLELTR_VALUE 0x214 /* Idle LTR Value */ #define TX_BIT_COUNT 0x218 /* Tx Bit Count */ #define RX_BIT_COUNT 0x21c /* Rx Bit Count */ #define SSP_REG 0x220 /* SSP Reg */ #define DMA_FINISH_DISABLE (1 << 0) #define SPI_CS_CONTROL 0x224 /* SPI CS Control */ #define CS_0_POL_SHIFT (12) #define CS_0_POL_MASK (1 << CS_0_POL_SHIFT) #define CS_POL_LOW (0) #define CS_POL_HIGH (1) #define CS_0 (0 << 8) #define CS_STATE_SHIFT (1) #define CS_STATE_MASK (1 << CS_STATE_SHIFT) #define CS_V1_STATE_LOW (0) #define CS_V1_STATE_HIGH (1) #define CS_MODE_HW (0 << 0) #define CS_MODE_SW (1 << 0) #define GSPI_DATA_BIT_LENGTH (8) #define GSPI_BUS_BASE(bar, bus) ((bar) + (bus) * 4 * KiB) /* Get base address for early init of GSPI controllers. */ static uintptr_t gspi_get_early_base(void) { return EARLY_GSPI_BASE_ADDRESS; } /* Get gspi_config array from devicetree. Returns NULL in case of error. */ static const struct gspi_cfg *gspi_get_cfg(void) { const struct soc_intel_common_config *common_config; common_config = chip_get_common_soc_structure(); return &common_config->gspi[0]; } #if defined(__SIMPLE_DEVICE__) static uintptr_t gspi_get_base_addr(int devfn, DEVTREE_CONST struct device *dev) { pci_devfn_t pci_dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); return ALIGN_DOWN(pci_read_config32(pci_dev, PCI_BASE_ADDRESS_0), 16); } static void gspi_set_base_addr(int devfn, DEVTREE_CONST struct device *dev, uintptr_t base) { pci_devfn_t pci_dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); pci_write_config32(pci_dev, PCI_BASE_ADDRESS_0, base); pci_write_config32(pci_dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); } void gspi_early_bar_init(void) { unsigned int gspi_bus; const unsigned int gspi_max = CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; const struct gspi_cfg *cfg = gspi_get_cfg(); int devfn; uintptr_t gspi_base_addr; assert(gspi_max != 0); if (!cfg) { printk(BIOS_ERR, "%s: No GSPI config provided by SoC!\n", __func__); return; } gspi_base_addr = gspi_get_early_base(); if (!gspi_base_addr) { printk(BIOS_ERR, "%s: GSPI base address provided is NULL!\n", __func__); return; } for (gspi_bus = 0; gspi_bus < gspi_max; gspi_bus++) { if (!cfg[gspi_bus].early_init) continue; devfn = gspi_soc_bus_to_devfn(gspi_bus); gspi_set_base_addr(devfn, NULL, GSPI_BUS_BASE(gspi_base_addr, gspi_bus)); } } #else static uintptr_t gspi_get_base_addr(int devfn, struct device *dev) { return ALIGN_DOWN(pci_read_config32(dev, PCI_BASE_ADDRESS_0), 16); } static void gspi_set_base_addr(int devfn, struct device *dev, uintptr_t base) { pci_write_config32(dev, PCI_BASE_ADDRESS_0, base); pci_write_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); } #endif static int gspi_read_bus_range(unsigned int *start, unsigned int *end) { size_t i; const struct spi_ctrlr_buses *desc; for (i = 0; i < spi_ctrlr_bus_map_count; i++) { desc = &spi_ctrlr_bus_map[i]; if (desc->ctrlr != &gspi_ctrlr) continue; *start = desc->bus_start; *end = desc->bus_end; return 0; } return -1; } static int gspi_spi_to_gspi_bus(unsigned int spi_bus, unsigned int *gspi_bus) { unsigned int start; unsigned int end; int ret; ret = gspi_read_bus_range(&start, &end); if (ret != 0 || (spi_bus < start) || (spi_bus > end)) return -1; *gspi_bus = spi_bus - start; return 0; } static uintptr_t gspi_calc_base_addr(unsigned int gspi_bus) { uintptr_t bus_base, gspi_base_addr; DEVTREE_CONST struct device *dev; int devfn = gspi_soc_bus_to_devfn(gspi_bus); if (devfn < 0) return 0; dev = pcidev_path_on_root(devfn); if (!dev || !dev->enabled) return 0; bus_base = gspi_get_base_addr(devfn, dev); if (bus_base) return bus_base; gspi_base_addr = gspi_get_early_base(); if (!gspi_base_addr) return 0; bus_base = GSPI_BUS_BASE(gspi_base_addr, gspi_bus); gspi_set_base_addr(devfn, dev, bus_base); return bus_base; } static uint32_t gspi_get_bus_clk_mhz(unsigned int gspi_bus) { const struct gspi_cfg *cfg = gspi_get_cfg(); if (!cfg) return 0; return cfg[gspi_bus].speed_mhz; } static uintptr_t gspi_base[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX]; static uintptr_t gspi_get_bus_base_addr(unsigned int gspi_bus) { if (!gspi_base[gspi_bus]) gspi_base[gspi_bus] = gspi_calc_base_addr(gspi_bus); return gspi_base[gspi_bus]; } /* Parameters for GSPI controller operation. */ struct gspi_ctrlr_params { uintptr_t mmio_base; unsigned int gspi_bus; uint8_t *in; size_t bytesin; const uint8_t *out; size_t bytesout; }; static uint32_t gspi_read_mmio_reg(const struct gspi_ctrlr_params *p, uint32_t offset) { assert(p->mmio_base != 0); return read32((void *)(p->mmio_base + offset)); } static void gspi_write_mmio_reg(const struct gspi_ctrlr_params *p, uint32_t offset, uint32_t value) { assert(p->mmio_base != 0); write32((void *)(p->mmio_base + offset), value); } static int gspi_ctrlr_params_init(struct gspi_ctrlr_params *p, unsigned int spi_bus) { memset(p, 0, sizeof(*p)); if (gspi_spi_to_gspi_bus(spi_bus, &p->gspi_bus)) { printk(BIOS_ERR, "%s: No GSPI bus available for SPI bus %u.\n", __func__, spi_bus); return -1; } p->mmio_base = gspi_get_bus_base_addr(p->gspi_bus); if (!p->mmio_base) { printk(BIOS_ERR, "%s: Base addr is 0 for GSPI bus=%u.\n", __func__, p->gspi_bus); return -1; } return 0; } enum cs_assert { CS_ASSERT, CS_DEASSERT, }; /* * SPI_CS_CONTROL bit definitions based on GSPI_VERSION_x: * * VERSION_2 (CNL GSPI controller): * Polarity: Indicates inactive polarity of chip-select * State : Indicates assert/de-assert of chip-select * * Default (SKL/KBL GSPI controller): * Polarity: Indicates active polarity of chip-select * State : Indicates low/high output state of chip-select */ static uint32_t gspi_csctrl_state_v2(uint32_t pol, enum cs_assert cs_assert) { return cs_assert; } static uint32_t gspi_csctrl_state_v1(uint32_t pol, enum cs_assert cs_assert) { uint32_t state; if (pol == CS_POL_HIGH) state = (cs_assert == CS_ASSERT) ? CS_V1_STATE_HIGH : CS_V1_STATE_LOW; else state = (cs_assert == CS_ASSERT) ? CS_V1_STATE_LOW : CS_V1_STATE_HIGH; return state; } static uint32_t gspi_csctrl_state(uint32_t pol, enum cs_assert cs_assert) { if (CONFIG(SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2)) return gspi_csctrl_state_v2(pol, cs_assert); return gspi_csctrl_state_v1(pol, cs_assert); } static uint32_t gspi_csctrl_polarity_v2(enum spi_polarity active_pol) { /* Polarity field indicates cs inactive polarity */ if (active_pol == SPI_POLARITY_LOW) return CS_POL_HIGH; return CS_POL_LOW; } static uint32_t gspi_csctrl_polarity_v1(enum spi_polarity active_pol) { /* Polarity field indicates cs active polarity */ if (active_pol == SPI_POLARITY_LOW) return CS_POL_LOW; return CS_POL_HIGH; } static uint32_t gspi_csctrl_polarity(enum spi_polarity active_pol) { if (CONFIG(SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2)) return gspi_csctrl_polarity_v2(active_pol); return gspi_csctrl_polarity_v1(active_pol); } static void __gspi_cs_change(const struct gspi_ctrlr_params *p, enum cs_assert cs_assert) { uint32_t cs_ctrl, pol; cs_ctrl = gspi_read_mmio_reg(p, SPI_CS_CONTROL); cs_ctrl &= ~CS_STATE_MASK; pol = !!(cs_ctrl & CS_0_POL_MASK); cs_ctrl |= gspi_csctrl_state(pol, cs_assert) << CS_STATE_SHIFT; gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl); } static int gspi_cs_change(const struct spi_slave *dev, enum cs_assert cs_assert) { struct gspi_ctrlr_params params, *p = ¶ms; if (gspi_ctrlr_params_init(p, dev->bus)) return -1; __gspi_cs_change(p, cs_assert); return 0; } int __weak gspi_get_soc_spi_cfg(unsigned int gspi_bus, struct spi_cfg *cfg) { cfg->clk_phase = SPI_CLOCK_PHASE_FIRST; cfg->clk_polarity = SPI_POLARITY_LOW; cfg->cs_polarity = SPI_POLARITY_LOW; cfg->wire_mode = SPI_4_WIRE_MODE; cfg->data_bit_length = GSPI_DATA_BIT_LENGTH; return 0; } static int gspi_cs_assert(const struct spi_slave *dev) { return gspi_cs_change(dev, CS_ASSERT); } static void gspi_cs_deassert(const struct spi_slave *dev) { gspi_cs_change(dev, CS_DEASSERT); } static uint32_t gspi_get_clk_div(unsigned int gspi_bus) { const uint32_t ref_clk_mhz = CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ; uint32_t gspi_clk_mhz = gspi_get_bus_clk_mhz(gspi_bus); if (!gspi_clk_mhz) gspi_clk_mhz = 1; assert(ref_clk_mhz != 0); return (DIV_ROUND_UP(ref_clk_mhz, gspi_clk_mhz) - 1) & SSCR0_SCR_MASK; } static int gspi_ctrlr_setup(const struct spi_slave *dev) { struct spi_cfg cfg; int devfn; uint32_t cs_ctrl, sscr0, sscr1, clocks, sitf, sirf, pol; struct gspi_ctrlr_params params, *p = ¶ms; const struct device *device; /* Only chip select 0 is supported. */ if (dev->cs != 0) { printk(BIOS_ERR, "%s: Invalid CS value: cs=%u.\n", __func__, dev->cs); return -1; } if (gspi_ctrlr_params_init(p, dev->bus)) return -1; /* Obtain SPI bus configuration for the device. */ if (gspi_get_soc_spi_cfg(p->gspi_bus, &cfg)) { printk(BIOS_ERR, "%s: Failed to get config for bus=%u.\n", __func__, p->gspi_bus); return -1; } devfn = gspi_soc_bus_to_devfn(p->gspi_bus); /* * devfn is already validated as part of gspi_ctrlr_params_init. * No need to revalidate it again. */ device = pcidev_path_on_root(devfn); /* Ensure controller is in D0 state */ lpss_set_power_state(device, STATE_D0); /* Take controller out of reset, keeping DMA in reset. */ gspi_write_mmio_reg(p, RESETS, CTRLR_ACTIVE | DMA_RESET); /* * CS control: * - Set SW mode. * - Set chip select to 0. * - Set polarity based on device configuration. * - Do not assert CS. */ cs_ctrl = CS_MODE_SW | CS_0; pol = gspi_csctrl_polarity(cfg.cs_polarity); cs_ctrl |= pol << CS_0_POL_SHIFT; cs_ctrl |= gspi_csctrl_state(pol, CS_DEASSERT) << CS_STATE_SHIFT; gspi_write_mmio_reg(p, SPI_CS_CONTROL, cs_ctrl); /* Disable SPI controller. */ gspi_write_mmio_reg(p, SSCR0, SSCR0_SSE_DISABLE); /* * SSCR0 configuration: * clk_div - Based on reference clock and expected clock frequency. * data bit length - assumed to be 8, hence EDSS = 0. * ECS - Use on-chip clock * FRF - Frame format set to Motorola SPI */ sscr0 = gspi_get_clk_div(p->gspi_bus) << SSCR0_SCR_SHIFT; assert(GSPI_DATA_BIT_LENGTH == 8); sscr0 |= ((GSPI_DATA_BIT_LENGTH - 1) << SSCR0_DSS_SHIFT) | SSCR0_EDSS_0; sscr0 |= SSCR0_ECS_ON_CHIP | SSCR0_FRF_MOTOROLA; gspi_write_mmio_reg(p, SSCR0, sscr0); /* * SSCR1 configuration: * - Chip select polarity * - Clock phase setting * - Clock polarity */ sscr1 = (cfg.cs_polarity == SPI_POLARITY_LOW) ? SSCR1_IFS_LOW : SSCR1_IFS_HIGH; sscr1 |= (cfg.clk_phase == SPI_CLOCK_PHASE_FIRST) ? SSCR1_SPH_FIRST : SSCR1_SPH_SECOND; sscr1 |= (cfg.clk_polarity == SPI_POLARITY_LOW) ? SSCR1_SPO_LOW : SSCR1_SPO_HIGH; gspi_write_mmio_reg(p, SSCR1, sscr1); /* * Program m/n divider. * Set m and n to 1, so that this divider acts as a pass-through. */ clocks = (1 << CLOCKS_N_SHIFT) | (1 << CLOCKS_M_SHIFT) | CLOCKS_ENABLE | CLOCKS_UPDATE; gspi_write_mmio_reg(p, CLOCKS, clocks); udelay(10); /* * Tx FIFO Threshold. * Low watermark threshold = 1 * High watermark threshold = 1 */ sitf = SITF_LWM(1) | SITF_HWM(1); gspi_write_mmio_reg(p, SITF, sitf); /* Rx FIFO Threshold (set to 1). */ sirf = SIRF_WM(1); gspi_write_mmio_reg(p, SIRF, sirf); /* Enable GSPI controller. */ sscr0 |= SSCR0_SSE_ENABLE; gspi_write_mmio_reg(p, SSCR0, sscr0); return 0; } static uint32_t gspi_read_status(const struct gspi_ctrlr_params *p) { return gspi_read_mmio_reg(p, SSSR); } static void gspi_clear_status(const struct gspi_ctrlr_params *p) { const uint32_t sssr = SSSR_TUR | SSSR_TINT | SSSR_PINT | SSSR_ROR; gspi_write_mmio_reg(p, SSSR, sssr); } static bool gspi_rx_fifo_empty(const struct gspi_ctrlr_params *p) { return !(gspi_read_status(p) & SSSR_RNE); } static bool gspi_tx_fifo_full(const struct gspi_ctrlr_params *p) { return !(gspi_read_status(p) & SSSR_TNF); } static bool gspi_rx_fifo_overrun(const struct gspi_ctrlr_params *p) { if (gspi_read_status(p) & SSSR_ROR) { printk(BIOS_ERR, "%s:GSPI receive FIFO overrun!" " (bus=%u).\n", __func__, p->gspi_bus); return true; } return false; } /* Read SSDR and return lowest byte. */ static uint8_t gspi_read_byte(const struct gspi_ctrlr_params *p) { return gspi_read_mmio_reg(p, SSDR) & 0xFF; } /* Write 32-bit word with "data" in lowest byte to SSDR. */ static void gspi_write_byte(const struct gspi_ctrlr_params *p, uint8_t data) { return gspi_write_mmio_reg(p, SSDR, data); } static void gspi_read_data(struct gspi_ctrlr_params *p) { *(p->in) = gspi_read_byte(p); p->in++; p->bytesin--; } static void gspi_write_data(struct gspi_ctrlr_params *p) { gspi_write_byte(p, *(p->out)); p->out++; p->bytesout--; } static void gspi_read_dummy(struct gspi_ctrlr_params *p) { gspi_read_byte(p); p->bytesin--; } static void gspi_write_dummy(struct gspi_ctrlr_params *p) { gspi_write_byte(p, 0); p->bytesout--; } static int gspi_ctrlr_flush(const struct gspi_ctrlr_params *p) { const uint32_t timeout_ms = 500; struct stopwatch sw; /* Wait 500ms to allow Rx FIFO to be empty. */ stopwatch_init_msecs_expire(&sw, timeout_ms); while (!gspi_rx_fifo_empty(p)) { if (stopwatch_expired(&sw)) { printk(BIOS_ERR, "%s: Rx FIFO not empty after 500ms! " "(bus=%u)\n", __func__, p->gspi_bus); return -1; } gspi_read_byte(p); } return 0; } static int __gspi_xfer(struct gspi_ctrlr_params *p) { /* * If bytesin is non-zero, then use gspi_read_data to perform * byte-by-byte read of data from SSDR and save it to "in" buffer. Else * discard the read data using gspi_read_dummy. */ void (*fn_read)(struct gspi_ctrlr_params *p) = gspi_read_data; /* * If bytesout is non-zero, then use gspi_write_data to perform * byte-by-byte write of data from "out" buffer to SSDR. Else, use * gspi_write_dummy to write dummy "0" data to SSDR in order to trigger * read from slave. */ void (*fn_write)(struct gspi_ctrlr_params *p) = gspi_write_data; if (!p->bytesin) { p->bytesin = p->bytesout; fn_read = gspi_read_dummy; } if (!p->bytesout) { p->bytesout = p->bytesin; fn_write = gspi_write_dummy; } while (p->bytesout || p->bytesin) { if (p->bytesout && !gspi_tx_fifo_full(p)) fn_write(p); if (p->bytesin && !gspi_rx_fifo_empty(p)) { if (gspi_rx_fifo_overrun(p)) return -1; fn_read(p); } } return 0; } static int gspi_ctrlr_xfer(const struct spi_slave *dev, const void *dout, size_t bytesout, void *din, size_t bytesin) { struct gspi_ctrlr_params params; struct gspi_ctrlr_params *p = ¶ms; /* * Assumptions about in and out transfers: * 1. Both bytesin and bytesout cannot be 0. * 2. If both bytesin and bytesout are non-zero, then they should be * equal i.e. if both in and out transfers are to be done in same * transaction, then they should be equal in length. * 3. Buffer corresponding to non-zero bytes (bytesin/bytesout) cannot * be NULL. */ if (!bytesin && !bytesout) { printk(BIOS_ERR, "%s: Both in and out bytes cannot be zero!\n", __func__); return -1; } else if (bytesin && bytesout && (bytesin != bytesout)) { printk(BIOS_ERR, "%s: bytesin(%zd) != bytesout(%zd)\n", __func__, bytesin, bytesout); return -1; } if ((bytesin && !din) || (bytesout && !dout)) { printk(BIOS_ERR, "%s: in/out buffer is NULL!\n", __func__); return -1; } if (gspi_ctrlr_params_init(p, dev->bus)) return -1; /* Flush out any stale data in Rx FIFO. */ if (gspi_ctrlr_flush(p)) return -1; /* Clear status bits. */ gspi_clear_status(p); p->in = din; p->bytesin = bytesin; p->out = dout; p->bytesout = bytesout; return __gspi_xfer(p); } const struct spi_ctrlr gspi_ctrlr = { .claim_bus = gspi_cs_assert, .release_bus = gspi_cs_deassert, .setup = gspi_ctrlr_setup, .xfer = gspi_ctrlr_xfer, .max_xfer_size = SPI_CTRLR_DEFAULT_MAX_XFER_SIZE, };