1e23e5a05SMika Westerberg // SPDX-License-Identifier: GPL-2.0-only 2e23e5a05SMika Westerberg /* 3e23e5a05SMika Westerberg * Intel PCH/PCU SPI flash driver. 4e23e5a05SMika Westerberg * 5e23e5a05SMika Westerberg * Copyright (C) 2016 - 2022, Intel Corporation 6e23e5a05SMika Westerberg * Author: Mika Westerberg <mika.westerberg@linux.intel.com> 7e23e5a05SMika Westerberg */ 8e23e5a05SMika Westerberg 9e23e5a05SMika Westerberg #include <linux/iopoll.h> 10e23e5a05SMika Westerberg #include <linux/module.h> 11e23e5a05SMika Westerberg 12e23e5a05SMika Westerberg #include <linux/mtd/partitions.h> 13e23e5a05SMika Westerberg #include <linux/mtd/spi-nor.h> 14e23e5a05SMika Westerberg 15e23e5a05SMika Westerberg #include <linux/spi/flash.h> 16e23e5a05SMika Westerberg #include <linux/spi/spi.h> 17e23e5a05SMika Westerberg #include <linux/spi/spi-mem.h> 18e23e5a05SMika Westerberg 19e23e5a05SMika Westerberg #include "spi-intel.h" 20e23e5a05SMika Westerberg 21e23e5a05SMika Westerberg /* Offsets are from @ispi->base */ 22e23e5a05SMika Westerberg #define BFPREG 0x00 23e23e5a05SMika Westerberg 24e23e5a05SMika Westerberg #define HSFSTS_CTL 0x04 25e23e5a05SMika Westerberg #define HSFSTS_CTL_FSMIE BIT(31) 26e23e5a05SMika Westerberg #define HSFSTS_CTL_FDBC_SHIFT 24 27e23e5a05SMika Westerberg #define HSFSTS_CTL_FDBC_MASK (0x3f << HSFSTS_CTL_FDBC_SHIFT) 28e23e5a05SMika Westerberg 29e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_SHIFT 17 30e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_MASK (0x0f << HSFSTS_CTL_FCYCLE_SHIFT) 31e23e5a05SMika Westerberg /* HW sequencer opcodes */ 32e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_READ (0x00 << HSFSTS_CTL_FCYCLE_SHIFT) 33e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_WRITE (0x02 << HSFSTS_CTL_FCYCLE_SHIFT) 34e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_ERASE (0x03 << HSFSTS_CTL_FCYCLE_SHIFT) 35e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_ERASE_64K (0x04 << HSFSTS_CTL_FCYCLE_SHIFT) 36e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_RDID (0x06 << HSFSTS_CTL_FCYCLE_SHIFT) 37e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_WRSR (0x07 << HSFSTS_CTL_FCYCLE_SHIFT) 38e23e5a05SMika Westerberg #define HSFSTS_CTL_FCYCLE_RDSR (0x08 << HSFSTS_CTL_FCYCLE_SHIFT) 39e23e5a05SMika Westerberg 40e23e5a05SMika Westerberg #define HSFSTS_CTL_FGO BIT(16) 41e23e5a05SMika Westerberg #define HSFSTS_CTL_FLOCKDN BIT(15) 42e23e5a05SMika Westerberg #define HSFSTS_CTL_FDV BIT(14) 43e23e5a05SMika Westerberg #define HSFSTS_CTL_SCIP BIT(5) 44e23e5a05SMika Westerberg #define HSFSTS_CTL_AEL BIT(2) 45e23e5a05SMika Westerberg #define HSFSTS_CTL_FCERR BIT(1) 46e23e5a05SMika Westerberg #define HSFSTS_CTL_FDONE BIT(0) 47e23e5a05SMika Westerberg 48e23e5a05SMika Westerberg #define FADDR 0x08 49e23e5a05SMika Westerberg #define DLOCK 0x0c 50e23e5a05SMika Westerberg #define FDATA(n) (0x10 + ((n) * 4)) 51e23e5a05SMika Westerberg 52e23e5a05SMika Westerberg #define FRACC 0x50 53e23e5a05SMika Westerberg 54e23e5a05SMika Westerberg #define FREG(n) (0x54 + ((n) * 4)) 55e23e5a05SMika Westerberg #define FREG_BASE_MASK 0x3fff 56e23e5a05SMika Westerberg #define FREG_LIMIT_SHIFT 16 57e23e5a05SMika Westerberg #define FREG_LIMIT_MASK (0x03fff << FREG_LIMIT_SHIFT) 58e23e5a05SMika Westerberg 59e23e5a05SMika Westerberg /* Offset is from @ispi->pregs */ 60e23e5a05SMika Westerberg #define PR(n) ((n) * 4) 61e23e5a05SMika Westerberg #define PR_WPE BIT(31) 62e23e5a05SMika Westerberg #define PR_LIMIT_SHIFT 16 63e23e5a05SMika Westerberg #define PR_LIMIT_MASK (0x3fff << PR_LIMIT_SHIFT) 64e23e5a05SMika Westerberg #define PR_RPE BIT(15) 65e23e5a05SMika Westerberg #define PR_BASE_MASK 0x3fff 66e23e5a05SMika Westerberg 67e23e5a05SMika Westerberg /* Offsets are from @ispi->sregs */ 68e23e5a05SMika Westerberg #define SSFSTS_CTL 0x00 69e23e5a05SMika Westerberg #define SSFSTS_CTL_FSMIE BIT(23) 70e23e5a05SMika Westerberg #define SSFSTS_CTL_DS BIT(22) 71e23e5a05SMika Westerberg #define SSFSTS_CTL_DBC_SHIFT 16 72e23e5a05SMika Westerberg #define SSFSTS_CTL_SPOP BIT(11) 73e23e5a05SMika Westerberg #define SSFSTS_CTL_ACS BIT(10) 74e23e5a05SMika Westerberg #define SSFSTS_CTL_SCGO BIT(9) 75e23e5a05SMika Westerberg #define SSFSTS_CTL_COP_SHIFT 12 76e23e5a05SMika Westerberg #define SSFSTS_CTL_FRS BIT(7) 77e23e5a05SMika Westerberg #define SSFSTS_CTL_DOFRS BIT(6) 78e23e5a05SMika Westerberg #define SSFSTS_CTL_AEL BIT(4) 79e23e5a05SMika Westerberg #define SSFSTS_CTL_FCERR BIT(3) 80e23e5a05SMika Westerberg #define SSFSTS_CTL_FDONE BIT(2) 81e23e5a05SMika Westerberg #define SSFSTS_CTL_SCIP BIT(0) 82e23e5a05SMika Westerberg 83e23e5a05SMika Westerberg #define PREOP_OPTYPE 0x04 84e23e5a05SMika Westerberg #define OPMENU0 0x08 85e23e5a05SMika Westerberg #define OPMENU1 0x0c 86e23e5a05SMika Westerberg 87e23e5a05SMika Westerberg #define OPTYPE_READ_NO_ADDR 0 88e23e5a05SMika Westerberg #define OPTYPE_WRITE_NO_ADDR 1 89e23e5a05SMika Westerberg #define OPTYPE_READ_WITH_ADDR 2 90e23e5a05SMika Westerberg #define OPTYPE_WRITE_WITH_ADDR 3 91e23e5a05SMika Westerberg 92e23e5a05SMika Westerberg /* CPU specifics */ 93e23e5a05SMika Westerberg #define BYT_PR 0x74 94e23e5a05SMika Westerberg #define BYT_SSFSTS_CTL 0x90 95e23e5a05SMika Westerberg #define BYT_FREG_NUM 5 96e23e5a05SMika Westerberg #define BYT_PR_NUM 5 97e23e5a05SMika Westerberg 98e23e5a05SMika Westerberg #define LPT_PR 0x74 99e23e5a05SMika Westerberg #define LPT_SSFSTS_CTL 0x90 100e23e5a05SMika Westerberg #define LPT_FREG_NUM 5 101e23e5a05SMika Westerberg #define LPT_PR_NUM 5 102e23e5a05SMika Westerberg 103e23e5a05SMika Westerberg #define BXT_PR 0x84 104e23e5a05SMika Westerberg #define BXT_SSFSTS_CTL 0xa0 105e23e5a05SMika Westerberg #define BXT_FREG_NUM 12 106e23e5a05SMika Westerberg #define BXT_PR_NUM 6 107e23e5a05SMika Westerberg 108e23e5a05SMika Westerberg #define CNL_PR 0x84 109e23e5a05SMika Westerberg #define CNL_FREG_NUM 6 110e23e5a05SMika Westerberg #define CNL_PR_NUM 5 111e23e5a05SMika Westerberg 112e23e5a05SMika Westerberg #define LVSCC 0xc4 113e23e5a05SMika Westerberg #define UVSCC 0xc8 114e23e5a05SMika Westerberg #define ERASE_OPCODE_SHIFT 8 115e23e5a05SMika Westerberg #define ERASE_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) 116e23e5a05SMika Westerberg #define ERASE_64K_OPCODE_SHIFT 16 117e23e5a05SMika Westerberg #define ERASE_64K_OPCODE_MASK (0xff << ERASE_OPCODE_SHIFT) 118e23e5a05SMika Westerberg 119e23e5a05SMika Westerberg #define INTEL_SPI_TIMEOUT 5000 /* ms */ 120e23e5a05SMika Westerberg #define INTEL_SPI_FIFO_SZ 64 121e23e5a05SMika Westerberg 122e23e5a05SMika Westerberg /** 123e23e5a05SMika Westerberg * struct intel_spi - Driver private data 124e23e5a05SMika Westerberg * @dev: Device pointer 125e23e5a05SMika Westerberg * @info: Pointer to board specific info 126e23e5a05SMika Westerberg * @base: Beginning of MMIO space 127e23e5a05SMika Westerberg * @pregs: Start of protection registers 128e23e5a05SMika Westerberg * @sregs: Start of software sequencer registers 129e23e5a05SMika Westerberg * @master: Pointer to the SPI controller structure 130e23e5a05SMika Westerberg * @nregions: Maximum number of regions 131e23e5a05SMika Westerberg * @pr_num: Maximum number of protected range registers 132e23e5a05SMika Westerberg * @locked: Is SPI setting locked 133e23e5a05SMika Westerberg * @swseq_reg: Use SW sequencer in register reads/writes 134e23e5a05SMika Westerberg * @swseq_erase: Use SW sequencer in erase operation 135e23e5a05SMika Westerberg * @atomic_preopcode: Holds preopcode when atomic sequence is requested 136e23e5a05SMika Westerberg * @opcodes: Opcodes which are supported. This are programmed by BIOS 137e23e5a05SMika Westerberg * before it locks down the controller. 138e23e5a05SMika Westerberg * @mem_ops: Pointer to SPI MEM ops supported by the controller 139e23e5a05SMika Westerberg */ 140e23e5a05SMika Westerberg struct intel_spi { 141e23e5a05SMika Westerberg struct device *dev; 142e23e5a05SMika Westerberg const struct intel_spi_boardinfo *info; 143e23e5a05SMika Westerberg void __iomem *base; 144e23e5a05SMika Westerberg void __iomem *pregs; 145e23e5a05SMika Westerberg void __iomem *sregs; 146e23e5a05SMika Westerberg struct spi_controller *master; 147e23e5a05SMika Westerberg size_t nregions; 148e23e5a05SMika Westerberg size_t pr_num; 149e23e5a05SMika Westerberg bool locked; 150e23e5a05SMika Westerberg bool swseq_reg; 151e23e5a05SMika Westerberg bool swseq_erase; 152e23e5a05SMika Westerberg u8 atomic_preopcode; 153e23e5a05SMika Westerberg u8 opcodes[8]; 154e23e5a05SMika Westerberg const struct intel_spi_mem_op *mem_ops; 155e23e5a05SMika Westerberg }; 156e23e5a05SMika Westerberg 157e23e5a05SMika Westerberg struct intel_spi_mem_op { 158e23e5a05SMika Westerberg struct spi_mem_op mem_op; 159e23e5a05SMika Westerberg u32 replacement_op; 160e23e5a05SMika Westerberg int (*exec_op)(struct intel_spi *ispi, 161e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 162e23e5a05SMika Westerberg const struct spi_mem_op *op); 163e23e5a05SMika Westerberg }; 164e23e5a05SMika Westerberg 165e23e5a05SMika Westerberg static bool writeable; 166e23e5a05SMika Westerberg module_param(writeable, bool, 0); 167e23e5a05SMika Westerberg MODULE_PARM_DESC(writeable, "Enable write access to SPI flash chip (default=0)"); 168e23e5a05SMika Westerberg 169e23e5a05SMika Westerberg static void intel_spi_dump_regs(struct intel_spi *ispi) 170e23e5a05SMika Westerberg { 171e23e5a05SMika Westerberg u32 value; 172e23e5a05SMika Westerberg int i; 173e23e5a05SMika Westerberg 174e23e5a05SMika Westerberg dev_dbg(ispi->dev, "BFPREG=0x%08x\n", readl(ispi->base + BFPREG)); 175e23e5a05SMika Westerberg 176e23e5a05SMika Westerberg value = readl(ispi->base + HSFSTS_CTL); 177e23e5a05SMika Westerberg dev_dbg(ispi->dev, "HSFSTS_CTL=0x%08x\n", value); 178e23e5a05SMika Westerberg if (value & HSFSTS_CTL_FLOCKDN) 179e23e5a05SMika Westerberg dev_dbg(ispi->dev, "-> Locked\n"); 180e23e5a05SMika Westerberg 181e23e5a05SMika Westerberg dev_dbg(ispi->dev, "FADDR=0x%08x\n", readl(ispi->base + FADDR)); 182e23e5a05SMika Westerberg dev_dbg(ispi->dev, "DLOCK=0x%08x\n", readl(ispi->base + DLOCK)); 183e23e5a05SMika Westerberg 184e23e5a05SMika Westerberg for (i = 0; i < 16; i++) 185e23e5a05SMika Westerberg dev_dbg(ispi->dev, "FDATA(%d)=0x%08x\n", 186e23e5a05SMika Westerberg i, readl(ispi->base + FDATA(i))); 187e23e5a05SMika Westerberg 188e23e5a05SMika Westerberg dev_dbg(ispi->dev, "FRACC=0x%08x\n", readl(ispi->base + FRACC)); 189e23e5a05SMika Westerberg 190e23e5a05SMika Westerberg for (i = 0; i < ispi->nregions; i++) 191e23e5a05SMika Westerberg dev_dbg(ispi->dev, "FREG(%d)=0x%08x\n", i, 192e23e5a05SMika Westerberg readl(ispi->base + FREG(i))); 193e23e5a05SMika Westerberg for (i = 0; i < ispi->pr_num; i++) 194e23e5a05SMika Westerberg dev_dbg(ispi->dev, "PR(%d)=0x%08x\n", i, 195e23e5a05SMika Westerberg readl(ispi->pregs + PR(i))); 196e23e5a05SMika Westerberg 197e23e5a05SMika Westerberg if (ispi->sregs) { 198e23e5a05SMika Westerberg value = readl(ispi->sregs + SSFSTS_CTL); 199e23e5a05SMika Westerberg dev_dbg(ispi->dev, "SSFSTS_CTL=0x%08x\n", value); 200e23e5a05SMika Westerberg dev_dbg(ispi->dev, "PREOP_OPTYPE=0x%08x\n", 201e23e5a05SMika Westerberg readl(ispi->sregs + PREOP_OPTYPE)); 202e23e5a05SMika Westerberg dev_dbg(ispi->dev, "OPMENU0=0x%08x\n", 203e23e5a05SMika Westerberg readl(ispi->sregs + OPMENU0)); 204e23e5a05SMika Westerberg dev_dbg(ispi->dev, "OPMENU1=0x%08x\n", 205e23e5a05SMika Westerberg readl(ispi->sregs + OPMENU1)); 206e23e5a05SMika Westerberg } 207e23e5a05SMika Westerberg 208e23e5a05SMika Westerberg dev_dbg(ispi->dev, "LVSCC=0x%08x\n", readl(ispi->base + LVSCC)); 209e23e5a05SMika Westerberg dev_dbg(ispi->dev, "UVSCC=0x%08x\n", readl(ispi->base + UVSCC)); 210e23e5a05SMika Westerberg 211e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Protected regions:\n"); 212e23e5a05SMika Westerberg for (i = 0; i < ispi->pr_num; i++) { 213e23e5a05SMika Westerberg u32 base, limit; 214e23e5a05SMika Westerberg 215e23e5a05SMika Westerberg value = readl(ispi->pregs + PR(i)); 216e23e5a05SMika Westerberg if (!(value & (PR_WPE | PR_RPE))) 217e23e5a05SMika Westerberg continue; 218e23e5a05SMika Westerberg 219e23e5a05SMika Westerberg limit = (value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; 220e23e5a05SMika Westerberg base = value & PR_BASE_MASK; 221e23e5a05SMika Westerberg 222e23e5a05SMika Westerberg dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x [%c%c]\n", 223e23e5a05SMika Westerberg i, base << 12, (limit << 12) | 0xfff, 224e23e5a05SMika Westerberg value & PR_WPE ? 'W' : '.', value & PR_RPE ? 'R' : '.'); 225e23e5a05SMika Westerberg } 226e23e5a05SMika Westerberg 227e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Flash regions:\n"); 228e23e5a05SMika Westerberg for (i = 0; i < ispi->nregions; i++) { 229e23e5a05SMika Westerberg u32 region, base, limit; 230e23e5a05SMika Westerberg 231e23e5a05SMika Westerberg region = readl(ispi->base + FREG(i)); 232e23e5a05SMika Westerberg base = region & FREG_BASE_MASK; 233e23e5a05SMika Westerberg limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; 234e23e5a05SMika Westerberg 235e23e5a05SMika Westerberg if (base >= limit || (i > 0 && limit == 0)) 236e23e5a05SMika Westerberg dev_dbg(ispi->dev, " %02d disabled\n", i); 237e23e5a05SMika Westerberg else 238e23e5a05SMika Westerberg dev_dbg(ispi->dev, " %02d base: 0x%08x limit: 0x%08x\n", 239e23e5a05SMika Westerberg i, base << 12, (limit << 12) | 0xfff); 240e23e5a05SMika Westerberg } 241e23e5a05SMika Westerberg 242e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Using %cW sequencer for register access\n", 243e23e5a05SMika Westerberg ispi->swseq_reg ? 'S' : 'H'); 244e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Using %cW sequencer for erase operation\n", 245e23e5a05SMika Westerberg ispi->swseq_erase ? 'S' : 'H'); 246e23e5a05SMika Westerberg } 247e23e5a05SMika Westerberg 248e23e5a05SMika Westerberg /* Reads max INTEL_SPI_FIFO_SZ bytes from the device fifo */ 249e23e5a05SMika Westerberg static int intel_spi_read_block(struct intel_spi *ispi, void *buf, size_t size) 250e23e5a05SMika Westerberg { 251e23e5a05SMika Westerberg size_t bytes; 252e23e5a05SMika Westerberg int i = 0; 253e23e5a05SMika Westerberg 254e23e5a05SMika Westerberg if (size > INTEL_SPI_FIFO_SZ) 255e23e5a05SMika Westerberg return -EINVAL; 256e23e5a05SMika Westerberg 257e23e5a05SMika Westerberg while (size > 0) { 258e23e5a05SMika Westerberg bytes = min_t(size_t, size, 4); 259e23e5a05SMika Westerberg memcpy_fromio(buf, ispi->base + FDATA(i), bytes); 260e23e5a05SMika Westerberg size -= bytes; 261e23e5a05SMika Westerberg buf += bytes; 262e23e5a05SMika Westerberg i++; 263e23e5a05SMika Westerberg } 264e23e5a05SMika Westerberg 265e23e5a05SMika Westerberg return 0; 266e23e5a05SMika Westerberg } 267e23e5a05SMika Westerberg 268e23e5a05SMika Westerberg /* Writes max INTEL_SPI_FIFO_SZ bytes to the device fifo */ 269e23e5a05SMika Westerberg static int intel_spi_write_block(struct intel_spi *ispi, const void *buf, 270e23e5a05SMika Westerberg size_t size) 271e23e5a05SMika Westerberg { 272e23e5a05SMika Westerberg size_t bytes; 273e23e5a05SMika Westerberg int i = 0; 274e23e5a05SMika Westerberg 275e23e5a05SMika Westerberg if (size > INTEL_SPI_FIFO_SZ) 276e23e5a05SMika Westerberg return -EINVAL; 277e23e5a05SMika Westerberg 278e23e5a05SMika Westerberg while (size > 0) { 279e23e5a05SMika Westerberg bytes = min_t(size_t, size, 4); 280e23e5a05SMika Westerberg memcpy_toio(ispi->base + FDATA(i), buf, bytes); 281e23e5a05SMika Westerberg size -= bytes; 282e23e5a05SMika Westerberg buf += bytes; 283e23e5a05SMika Westerberg i++; 284e23e5a05SMika Westerberg } 285e23e5a05SMika Westerberg 286e23e5a05SMika Westerberg return 0; 287e23e5a05SMika Westerberg } 288e23e5a05SMika Westerberg 289e23e5a05SMika Westerberg static int intel_spi_wait_hw_busy(struct intel_spi *ispi) 290e23e5a05SMika Westerberg { 291e23e5a05SMika Westerberg u32 val; 292e23e5a05SMika Westerberg 293e23e5a05SMika Westerberg return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, 294e23e5a05SMika Westerberg !(val & HSFSTS_CTL_SCIP), 0, 295e23e5a05SMika Westerberg INTEL_SPI_TIMEOUT * 1000); 296e23e5a05SMika Westerberg } 297e23e5a05SMika Westerberg 298e23e5a05SMika Westerberg static int intel_spi_wait_sw_busy(struct intel_spi *ispi) 299e23e5a05SMika Westerberg { 300e23e5a05SMika Westerberg u32 val; 301e23e5a05SMika Westerberg 302e23e5a05SMika Westerberg return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, 303e23e5a05SMika Westerberg !(val & SSFSTS_CTL_SCIP), 0, 304e23e5a05SMika Westerberg INTEL_SPI_TIMEOUT * 1000); 305e23e5a05SMika Westerberg } 306e23e5a05SMika Westerberg 307e23e5a05SMika Westerberg static bool intel_spi_set_writeable(struct intel_spi *ispi) 308e23e5a05SMika Westerberg { 309e23e5a05SMika Westerberg if (!ispi->info->set_writeable) 310e23e5a05SMika Westerberg return false; 311e23e5a05SMika Westerberg 312e23e5a05SMika Westerberg return ispi->info->set_writeable(ispi->base, ispi->info->data); 313e23e5a05SMika Westerberg } 314e23e5a05SMika Westerberg 315e23e5a05SMika Westerberg static int intel_spi_opcode_index(struct intel_spi *ispi, u8 opcode, int optype) 316e23e5a05SMika Westerberg { 317e23e5a05SMika Westerberg int i; 318e23e5a05SMika Westerberg int preop; 319e23e5a05SMika Westerberg 320e23e5a05SMika Westerberg if (ispi->locked) { 321e23e5a05SMika Westerberg for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) 322e23e5a05SMika Westerberg if (ispi->opcodes[i] == opcode) 323e23e5a05SMika Westerberg return i; 324e23e5a05SMika Westerberg 325e23e5a05SMika Westerberg return -EINVAL; 326e23e5a05SMika Westerberg } 327e23e5a05SMika Westerberg 328e23e5a05SMika Westerberg /* The lock is off, so just use index 0 */ 329e23e5a05SMika Westerberg writel(opcode, ispi->sregs + OPMENU0); 330e23e5a05SMika Westerberg preop = readw(ispi->sregs + PREOP_OPTYPE); 331e23e5a05SMika Westerberg writel(optype << 16 | preop, ispi->sregs + PREOP_OPTYPE); 332e23e5a05SMika Westerberg 333e23e5a05SMika Westerberg return 0; 334e23e5a05SMika Westerberg } 335e23e5a05SMika Westerberg 336e23e5a05SMika Westerberg static int intel_spi_hw_cycle(struct intel_spi *ispi, u8 opcode, size_t len) 337e23e5a05SMika Westerberg { 338e23e5a05SMika Westerberg u32 val, status; 339e23e5a05SMika Westerberg int ret; 340e23e5a05SMika Westerberg 341e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 342e23e5a05SMika Westerberg val &= ~(HSFSTS_CTL_FCYCLE_MASK | HSFSTS_CTL_FDBC_MASK); 343e23e5a05SMika Westerberg 344e23e5a05SMika Westerberg switch (opcode) { 345e23e5a05SMika Westerberg case SPINOR_OP_RDID: 346e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCYCLE_RDID; 347e23e5a05SMika Westerberg break; 348e23e5a05SMika Westerberg case SPINOR_OP_WRSR: 349e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCYCLE_WRSR; 350e23e5a05SMika Westerberg break; 351e23e5a05SMika Westerberg case SPINOR_OP_RDSR: 352e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCYCLE_RDSR; 353e23e5a05SMika Westerberg break; 354e23e5a05SMika Westerberg default: 355e23e5a05SMika Westerberg return -EINVAL; 356e23e5a05SMika Westerberg } 357e23e5a05SMika Westerberg 358e23e5a05SMika Westerberg if (len > INTEL_SPI_FIFO_SZ) 359e23e5a05SMika Westerberg return -EINVAL; 360e23e5a05SMika Westerberg 361e23e5a05SMika Westerberg val |= (len - 1) << HSFSTS_CTL_FDBC_SHIFT; 362e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; 363e23e5a05SMika Westerberg val |= HSFSTS_CTL_FGO; 364e23e5a05SMika Westerberg writel(val, ispi->base + HSFSTS_CTL); 365e23e5a05SMika Westerberg 366e23e5a05SMika Westerberg ret = intel_spi_wait_hw_busy(ispi); 367e23e5a05SMika Westerberg if (ret) 368e23e5a05SMika Westerberg return ret; 369e23e5a05SMika Westerberg 370e23e5a05SMika Westerberg status = readl(ispi->base + HSFSTS_CTL); 371e23e5a05SMika Westerberg if (status & HSFSTS_CTL_FCERR) 372e23e5a05SMika Westerberg return -EIO; 373e23e5a05SMika Westerberg else if (status & HSFSTS_CTL_AEL) 374e23e5a05SMika Westerberg return -EACCES; 375e23e5a05SMika Westerberg 376e23e5a05SMika Westerberg return 0; 377e23e5a05SMika Westerberg } 378e23e5a05SMika Westerberg 379e23e5a05SMika Westerberg static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, size_t len, 380e23e5a05SMika Westerberg int optype) 381e23e5a05SMika Westerberg { 382e23e5a05SMika Westerberg u32 val = 0, status; 383e23e5a05SMika Westerberg u8 atomic_preopcode; 384e23e5a05SMika Westerberg int ret; 385e23e5a05SMika Westerberg 386e23e5a05SMika Westerberg ret = intel_spi_opcode_index(ispi, opcode, optype); 387e23e5a05SMika Westerberg if (ret < 0) 388e23e5a05SMika Westerberg return ret; 389e23e5a05SMika Westerberg 390e23e5a05SMika Westerberg if (len > INTEL_SPI_FIFO_SZ) 391e23e5a05SMika Westerberg return -EINVAL; 392e23e5a05SMika Westerberg 393e23e5a05SMika Westerberg /* 394e23e5a05SMika Westerberg * Always clear it after each SW sequencer operation regardless 395e23e5a05SMika Westerberg * of whether it is successful or not. 396e23e5a05SMika Westerberg */ 397e23e5a05SMika Westerberg atomic_preopcode = ispi->atomic_preopcode; 398e23e5a05SMika Westerberg ispi->atomic_preopcode = 0; 399e23e5a05SMika Westerberg 400e23e5a05SMika Westerberg /* Only mark 'Data Cycle' bit when there is data to be transferred */ 401e23e5a05SMika Westerberg if (len > 0) 402e23e5a05SMika Westerberg val = ((len - 1) << SSFSTS_CTL_DBC_SHIFT) | SSFSTS_CTL_DS; 403e23e5a05SMika Westerberg val |= ret << SSFSTS_CTL_COP_SHIFT; 404e23e5a05SMika Westerberg val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE; 405e23e5a05SMika Westerberg val |= SSFSTS_CTL_SCGO; 406e23e5a05SMika Westerberg if (atomic_preopcode) { 407e23e5a05SMika Westerberg u16 preop; 408e23e5a05SMika Westerberg 409e23e5a05SMika Westerberg switch (optype) { 410e23e5a05SMika Westerberg case OPTYPE_WRITE_NO_ADDR: 411e23e5a05SMika Westerberg case OPTYPE_WRITE_WITH_ADDR: 412e23e5a05SMika Westerberg /* Pick matching preopcode for the atomic sequence */ 413e23e5a05SMika Westerberg preop = readw(ispi->sregs + PREOP_OPTYPE); 414e23e5a05SMika Westerberg if ((preop & 0xff) == atomic_preopcode) 415e23e5a05SMika Westerberg ; /* Do nothing */ 416e23e5a05SMika Westerberg else if ((preop >> 8) == atomic_preopcode) 417e23e5a05SMika Westerberg val |= SSFSTS_CTL_SPOP; 418e23e5a05SMika Westerberg else 419e23e5a05SMika Westerberg return -EINVAL; 420e23e5a05SMika Westerberg 421e23e5a05SMika Westerberg /* Enable atomic sequence */ 422e23e5a05SMika Westerberg val |= SSFSTS_CTL_ACS; 423e23e5a05SMika Westerberg break; 424e23e5a05SMika Westerberg 425e23e5a05SMika Westerberg default: 426e23e5a05SMika Westerberg return -EINVAL; 427e23e5a05SMika Westerberg } 428e23e5a05SMika Westerberg } 429e23e5a05SMika Westerberg writel(val, ispi->sregs + SSFSTS_CTL); 430e23e5a05SMika Westerberg 431e23e5a05SMika Westerberg ret = intel_spi_wait_sw_busy(ispi); 432e23e5a05SMika Westerberg if (ret) 433e23e5a05SMika Westerberg return ret; 434e23e5a05SMika Westerberg 435e23e5a05SMika Westerberg status = readl(ispi->sregs + SSFSTS_CTL); 436e23e5a05SMika Westerberg if (status & SSFSTS_CTL_FCERR) 437e23e5a05SMika Westerberg return -EIO; 438e23e5a05SMika Westerberg else if (status & SSFSTS_CTL_AEL) 439e23e5a05SMika Westerberg return -EACCES; 440e23e5a05SMika Westerberg 441e23e5a05SMika Westerberg return 0; 442e23e5a05SMika Westerberg } 443e23e5a05SMika Westerberg 444e23e5a05SMika Westerberg static int intel_spi_read_reg(struct intel_spi *ispi, 445e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 446e23e5a05SMika Westerberg const struct spi_mem_op *op) 447e23e5a05SMika Westerberg { 448e23e5a05SMika Westerberg size_t nbytes = op->data.nbytes; 449e23e5a05SMika Westerberg u8 opcode = op->cmd.opcode; 450e23e5a05SMika Westerberg int ret; 451e23e5a05SMika Westerberg 452e23e5a05SMika Westerberg /* Address of the first chip */ 453e23e5a05SMika Westerberg writel(0, ispi->base + FADDR); 454e23e5a05SMika Westerberg 455e23e5a05SMika Westerberg if (ispi->swseq_reg) 456e23e5a05SMika Westerberg ret = intel_spi_sw_cycle(ispi, opcode, nbytes, 457e23e5a05SMika Westerberg OPTYPE_READ_NO_ADDR); 458e23e5a05SMika Westerberg else 459e23e5a05SMika Westerberg ret = intel_spi_hw_cycle(ispi, opcode, nbytes); 460e23e5a05SMika Westerberg 461e23e5a05SMika Westerberg if (ret) 462e23e5a05SMika Westerberg return ret; 463e23e5a05SMika Westerberg 464e23e5a05SMika Westerberg return intel_spi_read_block(ispi, op->data.buf.in, nbytes); 465e23e5a05SMika Westerberg } 466e23e5a05SMika Westerberg 467e23e5a05SMika Westerberg static int intel_spi_write_reg(struct intel_spi *ispi, 468e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 469e23e5a05SMika Westerberg const struct spi_mem_op *op) 470e23e5a05SMika Westerberg { 471e23e5a05SMika Westerberg size_t nbytes = op->data.nbytes; 472e23e5a05SMika Westerberg u8 opcode = op->cmd.opcode; 473e23e5a05SMika Westerberg int ret; 474e23e5a05SMika Westerberg 475e23e5a05SMika Westerberg /* 476e23e5a05SMika Westerberg * This is handled with atomic operation and preop code in Intel 477e23e5a05SMika Westerberg * controller so we only verify that it is available. If the 478e23e5a05SMika Westerberg * controller is not locked, program the opcode to the PREOP 479e23e5a05SMika Westerberg * register for later use. 480e23e5a05SMika Westerberg * 481e23e5a05SMika Westerberg * When hardware sequencer is used there is no need to program 482e23e5a05SMika Westerberg * any opcodes (it handles them automatically as part of a command). 483e23e5a05SMika Westerberg */ 484e23e5a05SMika Westerberg if (opcode == SPINOR_OP_WREN) { 485e23e5a05SMika Westerberg u16 preop; 486e23e5a05SMika Westerberg 487e23e5a05SMika Westerberg if (!ispi->swseq_reg) 488e23e5a05SMika Westerberg return 0; 489e23e5a05SMika Westerberg 490e23e5a05SMika Westerberg preop = readw(ispi->sregs + PREOP_OPTYPE); 491e23e5a05SMika Westerberg if ((preop & 0xff) != opcode && (preop >> 8) != opcode) { 492e23e5a05SMika Westerberg if (ispi->locked) 493e23e5a05SMika Westerberg return -EINVAL; 494e23e5a05SMika Westerberg writel(opcode, ispi->sregs + PREOP_OPTYPE); 495e23e5a05SMika Westerberg } 496e23e5a05SMika Westerberg 497e23e5a05SMika Westerberg /* 498e23e5a05SMika Westerberg * This enables atomic sequence on next SW sycle. Will 499e23e5a05SMika Westerberg * be cleared after next operation. 500e23e5a05SMika Westerberg */ 501e23e5a05SMika Westerberg ispi->atomic_preopcode = opcode; 502e23e5a05SMika Westerberg return 0; 503e23e5a05SMika Westerberg } 504e23e5a05SMika Westerberg 505e23e5a05SMika Westerberg /* 506e23e5a05SMika Westerberg * We hope that HW sequencer will do the right thing automatically and 507e23e5a05SMika Westerberg * with the SW sequencer we cannot use preopcode anyway, so just ignore 508e23e5a05SMika Westerberg * the Write Disable operation and pretend it was completed 509e23e5a05SMika Westerberg * successfully. 510e23e5a05SMika Westerberg */ 511e23e5a05SMika Westerberg if (opcode == SPINOR_OP_WRDI) 512e23e5a05SMika Westerberg return 0; 513e23e5a05SMika Westerberg 514e23e5a05SMika Westerberg writel(0, ispi->base + FADDR); 515e23e5a05SMika Westerberg 516e23e5a05SMika Westerberg /* Write the value beforehand */ 517e23e5a05SMika Westerberg ret = intel_spi_write_block(ispi, op->data.buf.out, nbytes); 518e23e5a05SMika Westerberg if (ret) 519e23e5a05SMika Westerberg return ret; 520e23e5a05SMika Westerberg 521e23e5a05SMika Westerberg if (ispi->swseq_reg) 522e23e5a05SMika Westerberg return intel_spi_sw_cycle(ispi, opcode, nbytes, 523e23e5a05SMika Westerberg OPTYPE_WRITE_NO_ADDR); 524e23e5a05SMika Westerberg return intel_spi_hw_cycle(ispi, opcode, nbytes); 525e23e5a05SMika Westerberg } 526e23e5a05SMika Westerberg 527e23e5a05SMika Westerberg static int intel_spi_read(struct intel_spi *ispi, 528e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 529e23e5a05SMika Westerberg const struct spi_mem_op *op) 530e23e5a05SMika Westerberg { 531e23e5a05SMika Westerberg void *read_buf = op->data.buf.in; 532e23e5a05SMika Westerberg size_t block_size, nbytes = op->data.nbytes; 533e23e5a05SMika Westerberg u32 addr = op->addr.val; 534e23e5a05SMika Westerberg u32 val, status; 535e23e5a05SMika Westerberg int ret; 536e23e5a05SMika Westerberg 537e23e5a05SMika Westerberg /* 538e23e5a05SMika Westerberg * Atomic sequence is not expected with HW sequencer reads. Make 539e23e5a05SMika Westerberg * sure it is cleared regardless. 540e23e5a05SMika Westerberg */ 541e23e5a05SMika Westerberg if (WARN_ON_ONCE(ispi->atomic_preopcode)) 542e23e5a05SMika Westerberg ispi->atomic_preopcode = 0; 543e23e5a05SMika Westerberg 544e23e5a05SMika Westerberg while (nbytes > 0) { 545e23e5a05SMika Westerberg block_size = min_t(size_t, nbytes, INTEL_SPI_FIFO_SZ); 546e23e5a05SMika Westerberg 547e23e5a05SMika Westerberg /* Read cannot cross 4K boundary */ 548e23e5a05SMika Westerberg block_size = min_t(loff_t, addr + block_size, 549e23e5a05SMika Westerberg round_up(addr + 1, SZ_4K)) - addr; 550e23e5a05SMika Westerberg 551e23e5a05SMika Westerberg writel(addr, ispi->base + FADDR); 552e23e5a05SMika Westerberg 553e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 554e23e5a05SMika Westerberg val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); 555e23e5a05SMika Westerberg val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; 556e23e5a05SMika Westerberg val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; 557e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCYCLE_READ; 558e23e5a05SMika Westerberg val |= HSFSTS_CTL_FGO; 559e23e5a05SMika Westerberg writel(val, ispi->base + HSFSTS_CTL); 560e23e5a05SMika Westerberg 561e23e5a05SMika Westerberg ret = intel_spi_wait_hw_busy(ispi); 562e23e5a05SMika Westerberg if (ret) 563e23e5a05SMika Westerberg return ret; 564e23e5a05SMika Westerberg 565e23e5a05SMika Westerberg status = readl(ispi->base + HSFSTS_CTL); 566e23e5a05SMika Westerberg if (status & HSFSTS_CTL_FCERR) 567e23e5a05SMika Westerberg ret = -EIO; 568e23e5a05SMika Westerberg else if (status & HSFSTS_CTL_AEL) 569e23e5a05SMika Westerberg ret = -EACCES; 570e23e5a05SMika Westerberg 571e23e5a05SMika Westerberg if (ret < 0) { 572e23e5a05SMika Westerberg dev_err(ispi->dev, "read error: %x: %#x\n", addr, status); 573e23e5a05SMika Westerberg return ret; 574e23e5a05SMika Westerberg } 575e23e5a05SMika Westerberg 576e23e5a05SMika Westerberg ret = intel_spi_read_block(ispi, read_buf, block_size); 577e23e5a05SMika Westerberg if (ret) 578e23e5a05SMika Westerberg return ret; 579e23e5a05SMika Westerberg 580e23e5a05SMika Westerberg nbytes -= block_size; 581e23e5a05SMika Westerberg addr += block_size; 582e23e5a05SMika Westerberg read_buf += block_size; 583e23e5a05SMika Westerberg } 584e23e5a05SMika Westerberg 585e23e5a05SMika Westerberg return 0; 586e23e5a05SMika Westerberg } 587e23e5a05SMika Westerberg 588e23e5a05SMika Westerberg static int intel_spi_write(struct intel_spi *ispi, 589e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 590e23e5a05SMika Westerberg const struct spi_mem_op *op) 591e23e5a05SMika Westerberg { 592e23e5a05SMika Westerberg size_t block_size, nbytes = op->data.nbytes; 593e23e5a05SMika Westerberg const void *write_buf = op->data.buf.out; 594e23e5a05SMika Westerberg u32 addr = op->addr.val; 595e23e5a05SMika Westerberg u32 val, status; 596e23e5a05SMika Westerberg int ret; 597e23e5a05SMika Westerberg 598e23e5a05SMika Westerberg /* Not needed with HW sequencer write, make sure it is cleared */ 599e23e5a05SMika Westerberg ispi->atomic_preopcode = 0; 600e23e5a05SMika Westerberg 601e23e5a05SMika Westerberg while (nbytes > 0) { 602e23e5a05SMika Westerberg block_size = min_t(size_t, nbytes, INTEL_SPI_FIFO_SZ); 603e23e5a05SMika Westerberg 604e23e5a05SMika Westerberg /* Write cannot cross 4K boundary */ 605e23e5a05SMika Westerberg block_size = min_t(loff_t, addr + block_size, 606e23e5a05SMika Westerberg round_up(addr + 1, SZ_4K)) - addr; 607e23e5a05SMika Westerberg 608e23e5a05SMika Westerberg writel(addr, ispi->base + FADDR); 609e23e5a05SMika Westerberg 610e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 611e23e5a05SMika Westerberg val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); 612e23e5a05SMika Westerberg val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; 613e23e5a05SMika Westerberg val |= (block_size - 1) << HSFSTS_CTL_FDBC_SHIFT; 614e23e5a05SMika Westerberg val |= HSFSTS_CTL_FCYCLE_WRITE; 615e23e5a05SMika Westerberg 616e23e5a05SMika Westerberg ret = intel_spi_write_block(ispi, write_buf, block_size); 617e23e5a05SMika Westerberg if (ret) { 618e23e5a05SMika Westerberg dev_err(ispi->dev, "failed to write block\n"); 619e23e5a05SMika Westerberg return ret; 620e23e5a05SMika Westerberg } 621e23e5a05SMika Westerberg 622e23e5a05SMika Westerberg /* Start the write now */ 623e23e5a05SMika Westerberg val |= HSFSTS_CTL_FGO; 624e23e5a05SMika Westerberg writel(val, ispi->base + HSFSTS_CTL); 625e23e5a05SMika Westerberg 626e23e5a05SMika Westerberg ret = intel_spi_wait_hw_busy(ispi); 627e23e5a05SMika Westerberg if (ret) { 628e23e5a05SMika Westerberg dev_err(ispi->dev, "timeout\n"); 629e23e5a05SMika Westerberg return ret; 630e23e5a05SMika Westerberg } 631e23e5a05SMika Westerberg 632e23e5a05SMika Westerberg status = readl(ispi->base + HSFSTS_CTL); 633e23e5a05SMika Westerberg if (status & HSFSTS_CTL_FCERR) 634e23e5a05SMika Westerberg ret = -EIO; 635e23e5a05SMika Westerberg else if (status & HSFSTS_CTL_AEL) 636e23e5a05SMika Westerberg ret = -EACCES; 637e23e5a05SMika Westerberg 638e23e5a05SMika Westerberg if (ret < 0) { 639e23e5a05SMika Westerberg dev_err(ispi->dev, "write error: %x: %#x\n", addr, status); 640e23e5a05SMika Westerberg return ret; 641e23e5a05SMika Westerberg } 642e23e5a05SMika Westerberg 643e23e5a05SMika Westerberg nbytes -= block_size; 644e23e5a05SMika Westerberg addr += block_size; 645e23e5a05SMika Westerberg write_buf += block_size; 646e23e5a05SMika Westerberg } 647e23e5a05SMika Westerberg 648e23e5a05SMika Westerberg return 0; 649e23e5a05SMika Westerberg } 650e23e5a05SMika Westerberg 651e23e5a05SMika Westerberg static int intel_spi_erase(struct intel_spi *ispi, 652e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop, 653e23e5a05SMika Westerberg const struct spi_mem_op *op) 654e23e5a05SMika Westerberg { 655e23e5a05SMika Westerberg u8 opcode = op->cmd.opcode; 656e23e5a05SMika Westerberg u32 addr = op->addr.val; 657e23e5a05SMika Westerberg u32 val, status; 658e23e5a05SMika Westerberg int ret; 659e23e5a05SMika Westerberg 660e23e5a05SMika Westerberg writel(addr, ispi->base + FADDR); 661e23e5a05SMika Westerberg 662e23e5a05SMika Westerberg if (ispi->swseq_erase) 663e23e5a05SMika Westerberg return intel_spi_sw_cycle(ispi, opcode, 0, 664e23e5a05SMika Westerberg OPTYPE_WRITE_WITH_ADDR); 665e23e5a05SMika Westerberg 666e23e5a05SMika Westerberg /* Not needed with HW sequencer erase, make sure it is cleared */ 667e23e5a05SMika Westerberg ispi->atomic_preopcode = 0; 668e23e5a05SMika Westerberg 669e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 670e23e5a05SMika Westerberg val &= ~(HSFSTS_CTL_FDBC_MASK | HSFSTS_CTL_FCYCLE_MASK); 671e23e5a05SMika Westerberg val |= HSFSTS_CTL_AEL | HSFSTS_CTL_FCERR | HSFSTS_CTL_FDONE; 672e23e5a05SMika Westerberg val |= HSFSTS_CTL_FGO; 673e23e5a05SMika Westerberg val |= iop->replacement_op; 674e23e5a05SMika Westerberg writel(val, ispi->base + HSFSTS_CTL); 675e23e5a05SMika Westerberg 676e23e5a05SMika Westerberg ret = intel_spi_wait_hw_busy(ispi); 677e23e5a05SMika Westerberg if (ret) 678e23e5a05SMika Westerberg return ret; 679e23e5a05SMika Westerberg 680e23e5a05SMika Westerberg status = readl(ispi->base + HSFSTS_CTL); 681e23e5a05SMika Westerberg if (status & HSFSTS_CTL_FCERR) 682e23e5a05SMika Westerberg return -EIO; 683e23e5a05SMika Westerberg if (status & HSFSTS_CTL_AEL) 684e23e5a05SMika Westerberg return -EACCES; 685e23e5a05SMika Westerberg 686e23e5a05SMika Westerberg return 0; 687e23e5a05SMika Westerberg } 688e23e5a05SMika Westerberg 689e23e5a05SMika Westerberg static bool intel_spi_cmp_mem_op(const struct intel_spi_mem_op *iop, 690e23e5a05SMika Westerberg const struct spi_mem_op *op) 691e23e5a05SMika Westerberg { 692e23e5a05SMika Westerberg if (iop->mem_op.cmd.nbytes != op->cmd.nbytes || 693e23e5a05SMika Westerberg iop->mem_op.cmd.buswidth != op->cmd.buswidth || 694e23e5a05SMika Westerberg iop->mem_op.cmd.dtr != op->cmd.dtr || 695e23e5a05SMika Westerberg iop->mem_op.cmd.opcode != op->cmd.opcode) 696e23e5a05SMika Westerberg return false; 697e23e5a05SMika Westerberg 698e23e5a05SMika Westerberg if (iop->mem_op.addr.nbytes != op->addr.nbytes || 699e23e5a05SMika Westerberg iop->mem_op.addr.dtr != op->addr.dtr) 700e23e5a05SMika Westerberg return false; 701e23e5a05SMika Westerberg 702e23e5a05SMika Westerberg if (iop->mem_op.data.dir != op->data.dir || 703e23e5a05SMika Westerberg iop->mem_op.data.dtr != op->data.dtr) 704e23e5a05SMika Westerberg return false; 705e23e5a05SMika Westerberg 706e23e5a05SMika Westerberg if (iop->mem_op.data.dir != SPI_MEM_NO_DATA) { 707e23e5a05SMika Westerberg if (iop->mem_op.data.buswidth != op->data.buswidth) 708e23e5a05SMika Westerberg return false; 709e23e5a05SMika Westerberg } 710e23e5a05SMika Westerberg 711e23e5a05SMika Westerberg return true; 712e23e5a05SMika Westerberg } 713e23e5a05SMika Westerberg 714e23e5a05SMika Westerberg static const struct intel_spi_mem_op * 715e23e5a05SMika Westerberg intel_spi_match_mem_op(struct intel_spi *ispi, const struct spi_mem_op *op) 716e23e5a05SMika Westerberg { 717e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop; 718e23e5a05SMika Westerberg 719e23e5a05SMika Westerberg for (iop = ispi->mem_ops; iop->mem_op.cmd.opcode; iop++) { 720e23e5a05SMika Westerberg if (intel_spi_cmp_mem_op(iop, op)) 721e23e5a05SMika Westerberg break; 722e23e5a05SMika Westerberg } 723e23e5a05SMika Westerberg 724e23e5a05SMika Westerberg return iop->mem_op.cmd.opcode ? iop : NULL; 725e23e5a05SMika Westerberg } 726e23e5a05SMika Westerberg 727e23e5a05SMika Westerberg static bool intel_spi_supports_mem_op(struct spi_mem *mem, 728e23e5a05SMika Westerberg const struct spi_mem_op *op) 729e23e5a05SMika Westerberg { 730e23e5a05SMika Westerberg struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master); 731e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop; 732e23e5a05SMika Westerberg 733e23e5a05SMika Westerberg iop = intel_spi_match_mem_op(ispi, op); 734e23e5a05SMika Westerberg if (!iop) { 735e23e5a05SMika Westerberg dev_dbg(ispi->dev, "%#x not supported\n", op->cmd.opcode); 736e23e5a05SMika Westerberg return false; 737e23e5a05SMika Westerberg } 738e23e5a05SMika Westerberg 739e23e5a05SMika Westerberg /* 740e23e5a05SMika Westerberg * For software sequencer check that the opcode is actually 741e23e5a05SMika Westerberg * present in the opmenu if it is locked. 742e23e5a05SMika Westerberg */ 743e23e5a05SMika Westerberg if (ispi->swseq_reg && ispi->locked) { 744e23e5a05SMika Westerberg int i; 745e23e5a05SMika Westerberg 746e23e5a05SMika Westerberg /* Check if it is in the locked opcodes list */ 747e23e5a05SMika Westerberg for (i = 0; i < ARRAY_SIZE(ispi->opcodes); i++) { 748e23e5a05SMika Westerberg if (ispi->opcodes[i] == op->cmd.opcode) 749e23e5a05SMika Westerberg return true; 750e23e5a05SMika Westerberg } 751e23e5a05SMika Westerberg 752e23e5a05SMika Westerberg dev_dbg(ispi->dev, "%#x not supported\n", op->cmd.opcode); 753e23e5a05SMika Westerberg return false; 754e23e5a05SMika Westerberg } 755e23e5a05SMika Westerberg 756e23e5a05SMika Westerberg return true; 757e23e5a05SMika Westerberg } 758e23e5a05SMika Westerberg 759e23e5a05SMika Westerberg static int intel_spi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) 760e23e5a05SMika Westerberg { 761e23e5a05SMika Westerberg struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master); 762e23e5a05SMika Westerberg const struct intel_spi_mem_op *iop; 763e23e5a05SMika Westerberg 764e23e5a05SMika Westerberg iop = intel_spi_match_mem_op(ispi, op); 765e23e5a05SMika Westerberg if (!iop) 766e23e5a05SMika Westerberg return -EOPNOTSUPP; 767e23e5a05SMika Westerberg 768e23e5a05SMika Westerberg return iop->exec_op(ispi, iop, op); 769e23e5a05SMika Westerberg } 770e23e5a05SMika Westerberg 771e23e5a05SMika Westerberg static const char *intel_spi_get_name(struct spi_mem *mem) 772e23e5a05SMika Westerberg { 773e23e5a05SMika Westerberg const struct intel_spi *ispi = spi_master_get_devdata(mem->spi->master); 774e23e5a05SMika Westerberg 775e23e5a05SMika Westerberg /* 776e23e5a05SMika Westerberg * Return name of the flash controller device to be compatible 777e23e5a05SMika Westerberg * with the MTD version. 778e23e5a05SMika Westerberg */ 779e23e5a05SMika Westerberg return dev_name(ispi->dev); 780e23e5a05SMika Westerberg } 781e23e5a05SMika Westerberg 782*c2b5a40cSMika Westerberg static int intel_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) 783*c2b5a40cSMika Westerberg { 784*c2b5a40cSMika Westerberg struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master); 785*c2b5a40cSMika Westerberg const struct intel_spi_mem_op *iop; 786*c2b5a40cSMika Westerberg 787*c2b5a40cSMika Westerberg iop = intel_spi_match_mem_op(ispi, &desc->info.op_tmpl); 788*c2b5a40cSMika Westerberg if (!iop) 789*c2b5a40cSMika Westerberg return -EOPNOTSUPP; 790*c2b5a40cSMika Westerberg 791*c2b5a40cSMika Westerberg desc->priv = (void *)iop; 792*c2b5a40cSMika Westerberg return 0; 793*c2b5a40cSMika Westerberg } 794*c2b5a40cSMika Westerberg 795*c2b5a40cSMika Westerberg static ssize_t intel_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, u64 offs, 796*c2b5a40cSMika Westerberg size_t len, void *buf) 797*c2b5a40cSMika Westerberg { 798*c2b5a40cSMika Westerberg struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master); 799*c2b5a40cSMika Westerberg const struct intel_spi_mem_op *iop = desc->priv; 800*c2b5a40cSMika Westerberg struct spi_mem_op op = desc->info.op_tmpl; 801*c2b5a40cSMika Westerberg int ret; 802*c2b5a40cSMika Westerberg 803*c2b5a40cSMika Westerberg /* Fill in the gaps */ 804*c2b5a40cSMika Westerberg op.addr.val = offs; 805*c2b5a40cSMika Westerberg op.data.nbytes = len; 806*c2b5a40cSMika Westerberg op.data.buf.in = buf; 807*c2b5a40cSMika Westerberg 808*c2b5a40cSMika Westerberg ret = iop->exec_op(ispi, iop, &op); 809*c2b5a40cSMika Westerberg return ret ? ret : len; 810*c2b5a40cSMika Westerberg } 811*c2b5a40cSMika Westerberg 812*c2b5a40cSMika Westerberg static ssize_t intel_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, u64 offs, 813*c2b5a40cSMika Westerberg size_t len, const void *buf) 814*c2b5a40cSMika Westerberg { 815*c2b5a40cSMika Westerberg struct intel_spi *ispi = spi_master_get_devdata(desc->mem->spi->master); 816*c2b5a40cSMika Westerberg const struct intel_spi_mem_op *iop = desc->priv; 817*c2b5a40cSMika Westerberg struct spi_mem_op op = desc->info.op_tmpl; 818*c2b5a40cSMika Westerberg int ret; 819*c2b5a40cSMika Westerberg 820*c2b5a40cSMika Westerberg op.addr.val = offs; 821*c2b5a40cSMika Westerberg op.data.nbytes = len; 822*c2b5a40cSMika Westerberg op.data.buf.out = buf; 823*c2b5a40cSMika Westerberg 824*c2b5a40cSMika Westerberg ret = iop->exec_op(ispi, iop, &op); 825*c2b5a40cSMika Westerberg return ret ? ret : len; 826*c2b5a40cSMika Westerberg } 827*c2b5a40cSMika Westerberg 828e23e5a05SMika Westerberg static const struct spi_controller_mem_ops intel_spi_mem_ops = { 829e23e5a05SMika Westerberg .supports_op = intel_spi_supports_mem_op, 830e23e5a05SMika Westerberg .exec_op = intel_spi_exec_mem_op, 831e23e5a05SMika Westerberg .get_name = intel_spi_get_name, 832*c2b5a40cSMika Westerberg .dirmap_create = intel_spi_dirmap_create, 833*c2b5a40cSMika Westerberg .dirmap_read = intel_spi_dirmap_read, 834*c2b5a40cSMika Westerberg .dirmap_write = intel_spi_dirmap_write, 835e23e5a05SMika Westerberg }; 836e23e5a05SMika Westerberg 837e23e5a05SMika Westerberg #define INTEL_SPI_OP_ADDR(__nbytes) \ 838e23e5a05SMika Westerberg { \ 839e23e5a05SMika Westerberg .nbytes = __nbytes, \ 840e23e5a05SMika Westerberg } 841e23e5a05SMika Westerberg 842e23e5a05SMika Westerberg #define INTEL_SPI_OP_NO_DATA \ 843e23e5a05SMika Westerberg { \ 844e23e5a05SMika Westerberg .dir = SPI_MEM_NO_DATA, \ 845e23e5a05SMika Westerberg } 846e23e5a05SMika Westerberg 847e23e5a05SMika Westerberg #define INTEL_SPI_OP_DATA_IN(__buswidth) \ 848e23e5a05SMika Westerberg { \ 849e23e5a05SMika Westerberg .dir = SPI_MEM_DATA_IN, \ 850e23e5a05SMika Westerberg .buswidth = __buswidth, \ 851e23e5a05SMika Westerberg } 852e23e5a05SMika Westerberg 853e23e5a05SMika Westerberg #define INTEL_SPI_OP_DATA_OUT(__buswidth) \ 854e23e5a05SMika Westerberg { \ 855e23e5a05SMika Westerberg .dir = SPI_MEM_DATA_OUT, \ 856e23e5a05SMika Westerberg .buswidth = __buswidth, \ 857e23e5a05SMika Westerberg } 858e23e5a05SMika Westerberg 859e23e5a05SMika Westerberg #define INTEL_SPI_MEM_OP(__cmd, __addr, __data, __exec_op) \ 860e23e5a05SMika Westerberg { \ 861e23e5a05SMika Westerberg .mem_op = { \ 862e23e5a05SMika Westerberg .cmd = __cmd, \ 863e23e5a05SMika Westerberg .addr = __addr, \ 864e23e5a05SMika Westerberg .data = __data, \ 865e23e5a05SMika Westerberg }, \ 866e23e5a05SMika Westerberg .exec_op = __exec_op, \ 867e23e5a05SMika Westerberg } 868e23e5a05SMika Westerberg 869e23e5a05SMika Westerberg #define INTEL_SPI_MEM_OP_REPL(__cmd, __addr, __data, __exec_op, __repl) \ 870e23e5a05SMika Westerberg { \ 871e23e5a05SMika Westerberg .mem_op = { \ 872e23e5a05SMika Westerberg .cmd = __cmd, \ 873e23e5a05SMika Westerberg .addr = __addr, \ 874e23e5a05SMika Westerberg .data = __data, \ 875e23e5a05SMika Westerberg }, \ 876e23e5a05SMika Westerberg .exec_op = __exec_op, \ 877e23e5a05SMika Westerberg .replacement_op = __repl, \ 878e23e5a05SMika Westerberg } 879e23e5a05SMika Westerberg 880e23e5a05SMika Westerberg /* 881e23e5a05SMika Westerberg * The controller handles pretty much everything internally based on the 882e23e5a05SMika Westerberg * SFDP data but we want to make sure we only support the operations 883e23e5a05SMika Westerberg * actually possible. Only check buswidth and transfer direction, the 884e23e5a05SMika Westerberg * core validates data. 885e23e5a05SMika Westerberg */ 886e23e5a05SMika Westerberg #define INTEL_SPI_GENERIC_OPS \ 887e23e5a05SMika Westerberg /* Status register operations */ \ 888e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1), \ 889e23e5a05SMika Westerberg SPI_MEM_OP_NO_ADDR, \ 890e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 891e23e5a05SMika Westerberg intel_spi_read_reg), \ 892e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDSR, 1), \ 893e23e5a05SMika Westerberg SPI_MEM_OP_NO_ADDR, \ 894e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 895e23e5a05SMika Westerberg intel_spi_read_reg), \ 896e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRSR, 1), \ 897e23e5a05SMika Westerberg SPI_MEM_OP_NO_ADDR, \ 898e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_OUT(1), \ 899e23e5a05SMika Westerberg intel_spi_write_reg), \ 900e23e5a05SMika Westerberg /* Normal read */ \ 901e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 902e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 903e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 904e23e5a05SMika Westerberg intel_spi_read), \ 905e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 906e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 907e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 908e23e5a05SMika Westerberg intel_spi_read), \ 909e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 910e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 911e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 912e23e5a05SMika Westerberg intel_spi_read), \ 913e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 914e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 915e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 916e23e5a05SMika Westerberg intel_spi_read), \ 917e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 918e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 919e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 920e23e5a05SMika Westerberg intel_spi_read), \ 921e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ, 1), \ 922e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 923e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 924e23e5a05SMika Westerberg intel_spi_read), \ 925e23e5a05SMika Westerberg /* Fast read */ \ 926e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 927e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 928e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 929e23e5a05SMika Westerberg intel_spi_read), \ 930e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 931e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 932e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 933e23e5a05SMika Westerberg intel_spi_read), \ 934e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 935e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 936e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 937e23e5a05SMika Westerberg intel_spi_read), \ 938e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 939e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 940e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 941e23e5a05SMika Westerberg intel_spi_read), \ 942e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 943e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 944e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 945e23e5a05SMika Westerberg intel_spi_read), \ 946e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST, 1), \ 947e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 948e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 949e23e5a05SMika Westerberg intel_spi_read), \ 950e23e5a05SMika Westerberg /* Read with 4-byte address opcode */ \ 951e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_4B, 1), \ 952e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 953e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 954e23e5a05SMika Westerberg intel_spi_read), \ 955e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_4B, 1), \ 956e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 957e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 958e23e5a05SMika Westerberg intel_spi_read), \ 959e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_4B, 1), \ 960e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 961e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 962e23e5a05SMika Westerberg intel_spi_read), \ 963e23e5a05SMika Westerberg /* Fast read with 4-byte address opcode */ \ 964e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST_4B, 1), \ 965e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 966e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(1), \ 967e23e5a05SMika Westerberg intel_spi_read), \ 968e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST_4B, 1), \ 969e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 970e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(2), \ 971e23e5a05SMika Westerberg intel_spi_read), \ 972e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_FAST_4B, 1), \ 973e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 974e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_IN(4), \ 975e23e5a05SMika Westerberg intel_spi_read), \ 976e23e5a05SMika Westerberg /* Write operations */ \ 977e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_PP, 1), \ 978e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 979e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_OUT(1), \ 980e23e5a05SMika Westerberg intel_spi_write), \ 981e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_PP, 1), \ 982e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 983e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_OUT(1), \ 984e23e5a05SMika Westerberg intel_spi_write), \ 985e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_PP_4B, 1), \ 986e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 987e23e5a05SMika Westerberg INTEL_SPI_OP_DATA_OUT(1), \ 988e23e5a05SMika Westerberg intel_spi_write), \ 989e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WREN, 1), \ 990e23e5a05SMika Westerberg SPI_MEM_OP_NO_ADDR, \ 991e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, \ 992e23e5a05SMika Westerberg intel_spi_write_reg), \ 993e23e5a05SMika Westerberg INTEL_SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRDI, 1), \ 994e23e5a05SMika Westerberg SPI_MEM_OP_NO_ADDR, \ 995e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, \ 996e23e5a05SMika Westerberg intel_spi_write_reg), \ 997e23e5a05SMika Westerberg /* Erase operations */ \ 998e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_BE_4K, 1), \ 999e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), \ 1000e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, \ 1001e23e5a05SMika Westerberg intel_spi_erase, \ 1002e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE), \ 1003e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_BE_4K, 1), \ 1004e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 1005e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, \ 1006e23e5a05SMika Westerberg intel_spi_erase, \ 1007e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE), \ 1008e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_BE_4K_4B, 1), \ 1009e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), \ 1010e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, \ 1011e23e5a05SMika Westerberg intel_spi_erase, \ 1012e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE) \ 1013e23e5a05SMika Westerberg 1014e23e5a05SMika Westerberg static const struct intel_spi_mem_op generic_mem_ops[] = { 1015e23e5a05SMika Westerberg INTEL_SPI_GENERIC_OPS, 1016e23e5a05SMika Westerberg { }, 1017e23e5a05SMika Westerberg }; 1018e23e5a05SMika Westerberg 1019e23e5a05SMika Westerberg static const struct intel_spi_mem_op erase_64k_mem_ops[] = { 1020e23e5a05SMika Westerberg INTEL_SPI_GENERIC_OPS, 1021e23e5a05SMika Westerberg /* 64k sector erase operations */ 1022e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_SE, 1), 1023e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(3), 1024e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, 1025e23e5a05SMika Westerberg intel_spi_erase, 1026e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE_64K), 1027e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_SE, 1), 1028e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), 1029e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, 1030e23e5a05SMika Westerberg intel_spi_erase, 1031e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE_64K), 1032e23e5a05SMika Westerberg INTEL_SPI_MEM_OP_REPL(SPI_MEM_OP_CMD(SPINOR_OP_SE_4B, 1), 1033e23e5a05SMika Westerberg INTEL_SPI_OP_ADDR(4), 1034e23e5a05SMika Westerberg SPI_MEM_OP_NO_DATA, 1035e23e5a05SMika Westerberg intel_spi_erase, 1036e23e5a05SMika Westerberg HSFSTS_CTL_FCYCLE_ERASE_64K), 1037e23e5a05SMika Westerberg { }, 1038e23e5a05SMika Westerberg }; 1039e23e5a05SMika Westerberg 1040e23e5a05SMika Westerberg static int intel_spi_init(struct intel_spi *ispi) 1041e23e5a05SMika Westerberg { 1042e23e5a05SMika Westerberg u32 opmenu0, opmenu1, lvscc, uvscc, val; 1043e23e5a05SMika Westerberg bool erase_64k = false; 1044e23e5a05SMika Westerberg int i; 1045e23e5a05SMika Westerberg 1046e23e5a05SMika Westerberg switch (ispi->info->type) { 1047e23e5a05SMika Westerberg case INTEL_SPI_BYT: 1048e23e5a05SMika Westerberg ispi->sregs = ispi->base + BYT_SSFSTS_CTL; 1049e23e5a05SMika Westerberg ispi->pregs = ispi->base + BYT_PR; 1050e23e5a05SMika Westerberg ispi->nregions = BYT_FREG_NUM; 1051e23e5a05SMika Westerberg ispi->pr_num = BYT_PR_NUM; 1052e23e5a05SMika Westerberg ispi->swseq_reg = true; 1053e23e5a05SMika Westerberg break; 1054e23e5a05SMika Westerberg 1055e23e5a05SMika Westerberg case INTEL_SPI_LPT: 1056e23e5a05SMika Westerberg ispi->sregs = ispi->base + LPT_SSFSTS_CTL; 1057e23e5a05SMika Westerberg ispi->pregs = ispi->base + LPT_PR; 1058e23e5a05SMika Westerberg ispi->nregions = LPT_FREG_NUM; 1059e23e5a05SMika Westerberg ispi->pr_num = LPT_PR_NUM; 1060e23e5a05SMika Westerberg ispi->swseq_reg = true; 1061e23e5a05SMika Westerberg break; 1062e23e5a05SMika Westerberg 1063e23e5a05SMika Westerberg case INTEL_SPI_BXT: 1064e23e5a05SMika Westerberg ispi->sregs = ispi->base + BXT_SSFSTS_CTL; 1065e23e5a05SMika Westerberg ispi->pregs = ispi->base + BXT_PR; 1066e23e5a05SMika Westerberg ispi->nregions = BXT_FREG_NUM; 1067e23e5a05SMika Westerberg ispi->pr_num = BXT_PR_NUM; 1068e23e5a05SMika Westerberg erase_64k = true; 1069e23e5a05SMika Westerberg break; 1070e23e5a05SMika Westerberg 1071e23e5a05SMika Westerberg case INTEL_SPI_CNL: 1072e23e5a05SMika Westerberg ispi->sregs = NULL; 1073e23e5a05SMika Westerberg ispi->pregs = ispi->base + CNL_PR; 1074e23e5a05SMika Westerberg ispi->nregions = CNL_FREG_NUM; 1075e23e5a05SMika Westerberg ispi->pr_num = CNL_PR_NUM; 1076e23e5a05SMika Westerberg break; 1077e23e5a05SMika Westerberg 1078e23e5a05SMika Westerberg default: 1079e23e5a05SMika Westerberg return -EINVAL; 1080e23e5a05SMika Westerberg } 1081e23e5a05SMika Westerberg 1082e23e5a05SMika Westerberg /* Try to disable write protection if user asked to do so */ 1083e23e5a05SMika Westerberg if (writeable && !intel_spi_set_writeable(ispi)) { 1084e23e5a05SMika Westerberg dev_warn(ispi->dev, "can't disable chip write protection\n"); 1085e23e5a05SMika Westerberg writeable = false; 1086e23e5a05SMika Westerberg } 1087e23e5a05SMika Westerberg 1088e23e5a05SMika Westerberg /* Disable #SMI generation from HW sequencer */ 1089e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 1090e23e5a05SMika Westerberg val &= ~HSFSTS_CTL_FSMIE; 1091e23e5a05SMika Westerberg writel(val, ispi->base + HSFSTS_CTL); 1092e23e5a05SMika Westerberg 1093e23e5a05SMika Westerberg /* 1094e23e5a05SMika Westerberg * Determine whether erase operation should use HW or SW sequencer. 1095e23e5a05SMika Westerberg * 1096e23e5a05SMika Westerberg * The HW sequencer has a predefined list of opcodes, with only the 1097e23e5a05SMika Westerberg * erase opcode being programmable in LVSCC and UVSCC registers. 1098e23e5a05SMika Westerberg * If these registers don't contain a valid erase opcode, erase 1099e23e5a05SMika Westerberg * cannot be done using HW sequencer. 1100e23e5a05SMika Westerberg */ 1101e23e5a05SMika Westerberg lvscc = readl(ispi->base + LVSCC); 1102e23e5a05SMika Westerberg uvscc = readl(ispi->base + UVSCC); 1103e23e5a05SMika Westerberg if (!(lvscc & ERASE_OPCODE_MASK) || !(uvscc & ERASE_OPCODE_MASK)) 1104e23e5a05SMika Westerberg ispi->swseq_erase = true; 1105e23e5a05SMika Westerberg /* SPI controller on Intel BXT supports 64K erase opcode */ 1106e23e5a05SMika Westerberg if (ispi->info->type == INTEL_SPI_BXT && !ispi->swseq_erase) 1107e23e5a05SMika Westerberg if (!(lvscc & ERASE_64K_OPCODE_MASK) || 1108e23e5a05SMika Westerberg !(uvscc & ERASE_64K_OPCODE_MASK)) 1109e23e5a05SMika Westerberg erase_64k = false; 1110e23e5a05SMika Westerberg 1111e23e5a05SMika Westerberg if (!ispi->sregs && (ispi->swseq_reg || ispi->swseq_erase)) { 1112e23e5a05SMika Westerberg dev_err(ispi->dev, "software sequencer not supported, but required\n"); 1113e23e5a05SMika Westerberg return -EINVAL; 1114e23e5a05SMika Westerberg } 1115e23e5a05SMika Westerberg 1116e23e5a05SMika Westerberg /* 1117e23e5a05SMika Westerberg * Some controllers can only do basic operations using hardware 1118e23e5a05SMika Westerberg * sequencer. All other operations are supposed to be carried out 1119e23e5a05SMika Westerberg * using software sequencer. 1120e23e5a05SMika Westerberg */ 1121e23e5a05SMika Westerberg if (ispi->swseq_reg) { 1122e23e5a05SMika Westerberg /* Disable #SMI generation from SW sequencer */ 1123e23e5a05SMika Westerberg val = readl(ispi->sregs + SSFSTS_CTL); 1124e23e5a05SMika Westerberg val &= ~SSFSTS_CTL_FSMIE; 1125e23e5a05SMika Westerberg writel(val, ispi->sregs + SSFSTS_CTL); 1126e23e5a05SMika Westerberg } 1127e23e5a05SMika Westerberg 1128e23e5a05SMika Westerberg /* Check controller's lock status */ 1129e23e5a05SMika Westerberg val = readl(ispi->base + HSFSTS_CTL); 1130e23e5a05SMika Westerberg ispi->locked = !!(val & HSFSTS_CTL_FLOCKDN); 1131e23e5a05SMika Westerberg 1132e23e5a05SMika Westerberg if (ispi->locked && ispi->sregs) { 1133e23e5a05SMika Westerberg /* 1134e23e5a05SMika Westerberg * BIOS programs allowed opcodes and then locks down the 1135e23e5a05SMika Westerberg * register. So read back what opcodes it decided to support. 1136e23e5a05SMika Westerberg * That's the set we are going to support as well. 1137e23e5a05SMika Westerberg */ 1138e23e5a05SMika Westerberg opmenu0 = readl(ispi->sregs + OPMENU0); 1139e23e5a05SMika Westerberg opmenu1 = readl(ispi->sregs + OPMENU1); 1140e23e5a05SMika Westerberg 1141e23e5a05SMika Westerberg if (opmenu0 && opmenu1) { 1142e23e5a05SMika Westerberg for (i = 0; i < ARRAY_SIZE(ispi->opcodes) / 2; i++) { 1143e23e5a05SMika Westerberg ispi->opcodes[i] = opmenu0 >> i * 8; 1144e23e5a05SMika Westerberg ispi->opcodes[i + 4] = opmenu1 >> i * 8; 1145e23e5a05SMika Westerberg } 1146e23e5a05SMika Westerberg } 1147e23e5a05SMika Westerberg } 1148e23e5a05SMika Westerberg 1149e23e5a05SMika Westerberg if (erase_64k) { 1150e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Using erase_64k memory operations"); 1151e23e5a05SMika Westerberg ispi->mem_ops = erase_64k_mem_ops; 1152e23e5a05SMika Westerberg } else { 1153e23e5a05SMika Westerberg dev_dbg(ispi->dev, "Using generic memory operations"); 1154e23e5a05SMika Westerberg ispi->mem_ops = generic_mem_ops; 1155e23e5a05SMika Westerberg } 1156e23e5a05SMika Westerberg 1157e23e5a05SMika Westerberg intel_spi_dump_regs(ispi); 1158e23e5a05SMika Westerberg return 0; 1159e23e5a05SMika Westerberg } 1160e23e5a05SMika Westerberg 1161e23e5a05SMika Westerberg static bool intel_spi_is_protected(const struct intel_spi *ispi, 1162e23e5a05SMika Westerberg unsigned int base, unsigned int limit) 1163e23e5a05SMika Westerberg { 1164e23e5a05SMika Westerberg int i; 1165e23e5a05SMika Westerberg 1166e23e5a05SMika Westerberg for (i = 0; i < ispi->pr_num; i++) { 1167e23e5a05SMika Westerberg u32 pr_base, pr_limit, pr_value; 1168e23e5a05SMika Westerberg 1169e23e5a05SMika Westerberg pr_value = readl(ispi->pregs + PR(i)); 1170e23e5a05SMika Westerberg if (!(pr_value & (PR_WPE | PR_RPE))) 1171e23e5a05SMika Westerberg continue; 1172e23e5a05SMika Westerberg 1173e23e5a05SMika Westerberg pr_limit = (pr_value & PR_LIMIT_MASK) >> PR_LIMIT_SHIFT; 1174e23e5a05SMika Westerberg pr_base = pr_value & PR_BASE_MASK; 1175e23e5a05SMika Westerberg 1176e23e5a05SMika Westerberg if (pr_base >= base && pr_limit <= limit) 1177e23e5a05SMika Westerberg return true; 1178e23e5a05SMika Westerberg } 1179e23e5a05SMika Westerberg 1180e23e5a05SMika Westerberg return false; 1181e23e5a05SMika Westerberg } 1182e23e5a05SMika Westerberg 1183e23e5a05SMika Westerberg /* 1184e23e5a05SMika Westerberg * There will be a single partition holding all enabled flash regions. We 1185e23e5a05SMika Westerberg * call this "BIOS". 1186e23e5a05SMika Westerberg */ 1187e23e5a05SMika Westerberg static void intel_spi_fill_partition(struct intel_spi *ispi, 1188e23e5a05SMika Westerberg struct mtd_partition *part) 1189e23e5a05SMika Westerberg { 1190e23e5a05SMika Westerberg u64 end; 1191e23e5a05SMika Westerberg int i; 1192e23e5a05SMika Westerberg 1193e23e5a05SMika Westerberg memset(part, 0, sizeof(*part)); 1194e23e5a05SMika Westerberg 1195e23e5a05SMika Westerberg /* Start from the mandatory descriptor region */ 1196e23e5a05SMika Westerberg part->size = 4096; 1197e23e5a05SMika Westerberg part->name = "BIOS"; 1198e23e5a05SMika Westerberg 1199e23e5a05SMika Westerberg /* 1200e23e5a05SMika Westerberg * Now try to find where this partition ends based on the flash 1201e23e5a05SMika Westerberg * region registers. 1202e23e5a05SMika Westerberg */ 1203e23e5a05SMika Westerberg for (i = 1; i < ispi->nregions; i++) { 1204e23e5a05SMika Westerberg u32 region, base, limit; 1205e23e5a05SMika Westerberg 1206e23e5a05SMika Westerberg region = readl(ispi->base + FREG(i)); 1207e23e5a05SMika Westerberg base = region & FREG_BASE_MASK; 1208e23e5a05SMika Westerberg limit = (region & FREG_LIMIT_MASK) >> FREG_LIMIT_SHIFT; 1209e23e5a05SMika Westerberg 1210e23e5a05SMika Westerberg if (base >= limit || limit == 0) 1211e23e5a05SMika Westerberg continue; 1212e23e5a05SMika Westerberg 1213e23e5a05SMika Westerberg /* 1214e23e5a05SMika Westerberg * If any of the regions have protection bits set, make the 1215e23e5a05SMika Westerberg * whole partition read-only to be on the safe side. 1216e23e5a05SMika Westerberg * 1217e23e5a05SMika Westerberg * Also if the user did not ask the chip to be writeable 1218e23e5a05SMika Westerberg * mask the bit too. 1219e23e5a05SMika Westerberg */ 1220e23e5a05SMika Westerberg if (!writeable || intel_spi_is_protected(ispi, base, limit)) 1221e23e5a05SMika Westerberg part->mask_flags |= MTD_WRITEABLE; 1222e23e5a05SMika Westerberg 1223e23e5a05SMika Westerberg end = (limit << 12) + 4096; 1224e23e5a05SMika Westerberg if (end > part->size) 1225e23e5a05SMika Westerberg part->size = end; 1226e23e5a05SMika Westerberg } 1227e23e5a05SMika Westerberg } 1228e23e5a05SMika Westerberg 1229e23e5a05SMika Westerberg static int intel_spi_populate_chip(struct intel_spi *ispi) 1230e23e5a05SMika Westerberg { 1231e23e5a05SMika Westerberg struct flash_platform_data *pdata; 1232e23e5a05SMika Westerberg struct spi_board_info chip; 1233e23e5a05SMika Westerberg 1234e23e5a05SMika Westerberg pdata = devm_kzalloc(ispi->dev, sizeof(*pdata), GFP_KERNEL); 1235e23e5a05SMika Westerberg if (!pdata) 1236e23e5a05SMika Westerberg return -ENOMEM; 1237e23e5a05SMika Westerberg 1238e23e5a05SMika Westerberg pdata->nr_parts = 1; 1239e23e5a05SMika Westerberg pdata->parts = devm_kcalloc(ispi->dev, sizeof(*pdata->parts), 1240e23e5a05SMika Westerberg pdata->nr_parts, GFP_KERNEL); 1241e23e5a05SMika Westerberg if (!pdata->parts) 1242e23e5a05SMika Westerberg return -ENOMEM; 1243e23e5a05SMika Westerberg 1244e23e5a05SMika Westerberg intel_spi_fill_partition(ispi, pdata->parts); 1245e23e5a05SMika Westerberg 1246e23e5a05SMika Westerberg memset(&chip, 0, sizeof(chip)); 1247e23e5a05SMika Westerberg snprintf(chip.modalias, 8, "spi-nor"); 1248e23e5a05SMika Westerberg chip.platform_data = pdata; 1249e23e5a05SMika Westerberg 1250e23e5a05SMika Westerberg return spi_new_device(ispi->master, &chip) ? 0 : -ENODEV; 1251e23e5a05SMika Westerberg } 1252e23e5a05SMika Westerberg 1253e23e5a05SMika Westerberg /** 1254e23e5a05SMika Westerberg * intel_spi_probe() - Probe the Intel SPI flash controller 1255e23e5a05SMika Westerberg * @dev: Pointer to the parent device 1256e23e5a05SMika Westerberg * @mem: MMIO resource 12574bbaa857SMika Westerberg * @info: Platform specific information 1258e23e5a05SMika Westerberg * 1259e23e5a05SMika Westerberg * Probes Intel SPI flash controller and creates the flash chip device. 1260e23e5a05SMika Westerberg * Returns %0 on success and negative errno in case of failure. 1261e23e5a05SMika Westerberg */ 1262e23e5a05SMika Westerberg int intel_spi_probe(struct device *dev, struct resource *mem, 1263e23e5a05SMika Westerberg const struct intel_spi_boardinfo *info) 1264e23e5a05SMika Westerberg { 1265e23e5a05SMika Westerberg struct spi_controller *master; 1266e23e5a05SMika Westerberg struct intel_spi *ispi; 1267e23e5a05SMika Westerberg int ret; 1268e23e5a05SMika Westerberg 1269e23e5a05SMika Westerberg master = devm_spi_alloc_master(dev, sizeof(*ispi)); 1270e23e5a05SMika Westerberg if (!master) 1271e23e5a05SMika Westerberg return -ENOMEM; 1272e23e5a05SMika Westerberg 1273e23e5a05SMika Westerberg master->mem_ops = &intel_spi_mem_ops; 1274e23e5a05SMika Westerberg 1275e23e5a05SMika Westerberg ispi = spi_master_get_devdata(master); 1276e23e5a05SMika Westerberg 1277e23e5a05SMika Westerberg ispi->base = devm_ioremap_resource(dev, mem); 1278e23e5a05SMika Westerberg if (IS_ERR(ispi->base)) 1279e23e5a05SMika Westerberg return PTR_ERR(ispi->base); 1280e23e5a05SMika Westerberg 1281e23e5a05SMika Westerberg ispi->dev = dev; 1282e23e5a05SMika Westerberg ispi->master = master; 1283e23e5a05SMika Westerberg ispi->info = info; 1284e23e5a05SMika Westerberg 1285e23e5a05SMika Westerberg ret = intel_spi_init(ispi); 1286e23e5a05SMika Westerberg if (ret) 1287e23e5a05SMika Westerberg return ret; 1288e23e5a05SMika Westerberg 1289e23e5a05SMika Westerberg ret = devm_spi_register_master(dev, master); 1290e23e5a05SMika Westerberg if (ret) 1291e23e5a05SMika Westerberg return ret; 1292e23e5a05SMika Westerberg 1293e23e5a05SMika Westerberg return intel_spi_populate_chip(ispi); 1294e23e5a05SMika Westerberg } 1295e23e5a05SMika Westerberg EXPORT_SYMBOL_GPL(intel_spi_probe); 1296e23e5a05SMika Westerberg 1297e23e5a05SMika Westerberg MODULE_DESCRIPTION("Intel PCH/PCU SPI flash core driver"); 1298e23e5a05SMika Westerberg MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); 1299e23e5a05SMika Westerberg MODULE_LICENSE("GPL v2"); 1300