xref: /openbmc/linux/drivers/spi/spi-intel.c (revision c2b5a40c)
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