blob: db895a396d3c44535ed72f3a18d8693924543dbf [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass18530302013-03-19 04:58:56 +00002/*
3 * Copyright (c) 2011-12 The Chromium OS Authors.
4 *
Simon Glass18530302013-03-19 04:58:56 +00005 * This file is derived from the flashrom project.
6 */
Bin Meng9eb43392016-02-01 01:40:36 -08007
Simon Glassa5506622019-12-06 21:42:41 -07008#define LOG_CATEGORY UCLASS_SPI
9
Simon Glass18530302013-03-19 04:58:56 +000010#include <common.h>
Simon Glassb47aa262019-12-06 21:42:40 -070011#include <div64.h>
Simon Glassba457562015-03-26 09:29:26 -060012#include <dm.h>
Simon Glass0d3ee3e2019-12-06 21:42:45 -070013#include <dt-structs.h>
Simon Glass5093bad2015-01-27 22:13:43 -070014#include <errno.h>
Simon Glass18530302013-03-19 04:58:56 +000015#include <malloc.h>
Simon Glassf2b85ab2016-01-18 20:19:21 -070016#include <pch.h>
Simon Glass18530302013-03-19 04:58:56 +000017#include <pci.h>
18#include <pci_ids.h>
Simon Glassf2b85ab2016-01-18 20:19:21 -070019#include <spi.h>
Simon Glass1facebd2019-12-06 21:42:46 -070020#include <spi_flash.h>
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +020021#include <spi-mem.h>
Simon Glass1facebd2019-12-06 21:42:46 -070022#include <asm/fast_spi.h>
Simon Glassb47aa262019-12-06 21:42:40 -070023#include <asm/io.h>
Simon Glass18530302013-03-19 04:58:56 +000024
25#include "ich.h"
26
Simon Glassfffe25d2016-01-18 20:19:20 -070027#ifdef DEBUG_TRACE
28#define debug_trace(fmt, args...) debug(fmt, ##args)
29#else
30#define debug_trace(x, args...)
31#endif
32
Simon Glass75214b02019-12-06 21:42:42 -070033struct ich_spi_platdata {
Simon Glass0d3ee3e2019-12-06 21:42:45 -070034#if CONFIG_IS_ENABLED(OF_PLATDATA)
35 struct dtd_intel_fast_spi dtplat;
36#endif
Simon Glass75214b02019-12-06 21:42:42 -070037 enum ich_version ich_version; /* Controller version, 7 or 9 */
38 bool lockdown; /* lock down controller settings? */
39 ulong mmio_base; /* Base of MMIO registers */
Simon Glass0d3ee3e2019-12-06 21:42:45 -070040 pci_dev_t bdf; /* PCI address used by of-platdata */
Simon Glass1facebd2019-12-06 21:42:46 -070041 bool hwseq; /* Use hardware sequencing (not s/w) */
Simon Glass75214b02019-12-06 21:42:42 -070042};
43
Simon Glassba457562015-03-26 09:29:26 -060044static u8 ich_readb(struct ich_spi_priv *priv, int reg)
Simon Glass18530302013-03-19 04:58:56 +000045{
Simon Glassba457562015-03-26 09:29:26 -060046 u8 value = readb(priv->base + reg);
Simon Glass18530302013-03-19 04:58:56 +000047
Simon Glassfffe25d2016-01-18 20:19:20 -070048 debug_trace("read %2.2x from %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000049
50 return value;
51}
52
Simon Glassba457562015-03-26 09:29:26 -060053static u16 ich_readw(struct ich_spi_priv *priv, int reg)
Simon Glass18530302013-03-19 04:58:56 +000054{
Simon Glassba457562015-03-26 09:29:26 -060055 u16 value = readw(priv->base + reg);
Simon Glass18530302013-03-19 04:58:56 +000056
Simon Glassfffe25d2016-01-18 20:19:20 -070057 debug_trace("read %4.4x from %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000058
59 return value;
60}
61
Simon Glassba457562015-03-26 09:29:26 -060062static u32 ich_readl(struct ich_spi_priv *priv, int reg)
Simon Glass18530302013-03-19 04:58:56 +000063{
Simon Glassba457562015-03-26 09:29:26 -060064 u32 value = readl(priv->base + reg);
Simon Glass18530302013-03-19 04:58:56 +000065
Simon Glassfffe25d2016-01-18 20:19:20 -070066 debug_trace("read %8.8x from %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000067
68 return value;
69}
70
Simon Glassba457562015-03-26 09:29:26 -060071static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg)
Simon Glass18530302013-03-19 04:58:56 +000072{
Simon Glassba457562015-03-26 09:29:26 -060073 writeb(value, priv->base + reg);
Simon Glassfffe25d2016-01-18 20:19:20 -070074 debug_trace("wrote %2.2x to %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000075}
76
Simon Glassba457562015-03-26 09:29:26 -060077static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg)
Simon Glass18530302013-03-19 04:58:56 +000078{
Simon Glassba457562015-03-26 09:29:26 -060079 writew(value, priv->base + reg);
Simon Glassfffe25d2016-01-18 20:19:20 -070080 debug_trace("wrote %4.4x to %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000081}
82
Simon Glassba457562015-03-26 09:29:26 -060083static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg)
Simon Glass18530302013-03-19 04:58:56 +000084{
Simon Glassba457562015-03-26 09:29:26 -060085 writel(value, priv->base + reg);
Simon Glassfffe25d2016-01-18 20:19:20 -070086 debug_trace("wrote %8.8x to %4.4x\n", value, reg);
Simon Glass18530302013-03-19 04:58:56 +000087}
88
Simon Glassba457562015-03-26 09:29:26 -060089static void write_reg(struct ich_spi_priv *priv, const void *value,
90 int dest_reg, uint32_t size)
Simon Glass18530302013-03-19 04:58:56 +000091{
Simon Glassba457562015-03-26 09:29:26 -060092 memcpy_toio(priv->base + dest_reg, value, size);
Simon Glass18530302013-03-19 04:58:56 +000093}
94
Simon Glassba457562015-03-26 09:29:26 -060095static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value,
96 uint32_t size)
Simon Glass18530302013-03-19 04:58:56 +000097{
Simon Glassba457562015-03-26 09:29:26 -060098 memcpy_fromio(value, priv->base + src_reg, size);
Simon Glass18530302013-03-19 04:58:56 +000099}
100
Simon Glassba457562015-03-26 09:29:26 -0600101static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr)
Simon Glass18530302013-03-19 04:58:56 +0000102{
103 const uint32_t bbar_mask = 0x00ffff00;
104 uint32_t ichspi_bbar;
105
106 minaddr &= bbar_mask;
Simon Glassba457562015-03-26 09:29:26 -0600107 ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
Simon Glass18530302013-03-19 04:58:56 +0000108 ichspi_bbar |= minaddr;
Simon Glassba457562015-03-26 09:29:26 -0600109 ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
Simon Glass18530302013-03-19 04:58:56 +0000110}
111
Simon Glass18530302013-03-19 04:58:56 +0000112/* @return 1 if the SPI flash supports the 33MHz speed */
Simon Glassa5506622019-12-06 21:42:41 -0700113static bool ich9_can_do_33mhz(struct udevice *dev)
Simon Glass18530302013-03-19 04:58:56 +0000114{
Simon Glass17e75442019-12-06 21:42:38 -0700115 struct ich_spi_priv *priv = dev_get_priv(dev);
Simon Glass18530302013-03-19 04:58:56 +0000116 u32 fdod, speed;
117
118 /* Observe SPI Descriptor Component Section 0 */
Simon Glass17e75442019-12-06 21:42:38 -0700119 dm_pci_write_config32(priv->pch, 0xb0, 0x1000);
Simon Glass18530302013-03-19 04:58:56 +0000120
121 /* Extract the Write/Erase SPI Frequency from descriptor */
Simon Glass17e75442019-12-06 21:42:38 -0700122 dm_pci_read_config32(priv->pch, 0xb4, &fdod);
Simon Glass18530302013-03-19 04:58:56 +0000123
124 /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
125 speed = (fdod >> 21) & 7;
126
127 return speed == 1;
128}
129
Bin Mengab201072017-10-18 18:20:57 -0700130static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
131{
132 if (plat->ich_version == ICHV_7) {
133 struct ich7_spi_regs *ich7_spi = sbase;
134
135 setbits_le16(&ich7_spi->spis, SPIS_LOCK);
136 } else if (plat->ich_version == ICHV_9) {
137 struct ich9_spi_regs *ich9_spi = sbase;
138
139 setbits_le16(&ich9_spi->hsfs, HSFS_FLOCKDN);
140 }
141}
142
Bin Meng3e791412017-08-15 22:38:29 -0700143static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
144{
145 int lock = 0;
146
147 if (plat->ich_version == ICHV_7) {
148 struct ich7_spi_regs *ich7_spi = sbase;
149
150 lock = readw(&ich7_spi->spis) & SPIS_LOCK;
151 } else if (plat->ich_version == ICHV_9) {
152 struct ich9_spi_regs *ich9_spi = sbase;
153
154 lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
155 }
156
157 return lock != 0;
158}
159
Bin Meng3e791412017-08-15 22:38:29 -0700160static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
161 bool lock)
Simon Glass18530302013-03-19 04:58:56 +0000162{
163 uint16_t optypes;
Simon Glassba457562015-03-26 09:29:26 -0600164 uint8_t opmenu[ctlr->menubytes];
Simon Glass18530302013-03-19 04:58:56 +0000165
Bin Meng3e791412017-08-15 22:38:29 -0700166 if (!lock) {
Simon Glass18530302013-03-19 04:58:56 +0000167 /* The lock is off, so just use index 0. */
Simon Glassba457562015-03-26 09:29:26 -0600168 ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
169 optypes = ich_readw(ctlr, ctlr->optype);
Simon Glass18530302013-03-19 04:58:56 +0000170 optypes = (optypes & 0xfffc) | (trans->type & 0x3);
Simon Glassba457562015-03-26 09:29:26 -0600171 ich_writew(ctlr, optypes, ctlr->optype);
Simon Glass18530302013-03-19 04:58:56 +0000172 return 0;
173 } else {
174 /* The lock is on. See if what we need is on the menu. */
175 uint8_t optype;
176 uint16_t opcode_index;
177
178 /* Write Enable is handled as atomic prefix */
179 if (trans->opcode == SPI_OPCODE_WREN)
180 return 0;
181
Simon Glassba457562015-03-26 09:29:26 -0600182 read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu));
183 for (opcode_index = 0; opcode_index < ctlr->menubytes;
Simon Glass18530302013-03-19 04:58:56 +0000184 opcode_index++) {
185 if (opmenu[opcode_index] == trans->opcode)
186 break;
187 }
188
Simon Glassba457562015-03-26 09:29:26 -0600189 if (opcode_index == ctlr->menubytes) {
Simon Glassa5506622019-12-06 21:42:41 -0700190 debug("ICH SPI: Opcode %x not found\n", trans->opcode);
Simon Glassba457562015-03-26 09:29:26 -0600191 return -EINVAL;
Simon Glass18530302013-03-19 04:58:56 +0000192 }
193
Simon Glassba457562015-03-26 09:29:26 -0600194 optypes = ich_readw(ctlr, ctlr->optype);
Simon Glass18530302013-03-19 04:58:56 +0000195 optype = (optypes >> (opcode_index * 2)) & 0x3;
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200196
Simon Glass18530302013-03-19 04:58:56 +0000197 if (optype != trans->type) {
Simon Glassa5506622019-12-06 21:42:41 -0700198 debug("ICH SPI: Transaction doesn't fit type %d\n",
199 optype);
Simon Glassba457562015-03-26 09:29:26 -0600200 return -ENOSPC;
Simon Glass18530302013-03-19 04:58:56 +0000201 }
202 return opcode_index;
203 }
204}
205
Simon Glass18530302013-03-19 04:58:56 +0000206/*
207 * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
York Sun472d5462013-04-01 11:29:11 -0700208 * below is true) or 0. In case the wait was for the bit(s) to set - write
Simon Glass18530302013-03-19 04:58:56 +0000209 * those bits back, which would cause resetting them.
210 *
211 * Return the last read status value on success or -1 on failure.
212 */
Simon Glassba457562015-03-26 09:29:26 -0600213static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
214 int wait_til_set)
Simon Glass18530302013-03-19 04:58:56 +0000215{
216 int timeout = 600000; /* This will result in 6s */
217 u16 status = 0;
218
219 while (timeout--) {
Simon Glassba457562015-03-26 09:29:26 -0600220 status = ich_readw(ctlr, ctlr->status);
Simon Glass18530302013-03-19 04:58:56 +0000221 if (wait_til_set ^ ((status & bitmask) == 0)) {
Simon Glassba457562015-03-26 09:29:26 -0600222 if (wait_til_set) {
223 ich_writew(ctlr, status & bitmask,
224 ctlr->status);
225 }
Simon Glass18530302013-03-19 04:58:56 +0000226 return status;
227 }
228 udelay(10);
229 }
Simon Glassa5506622019-12-06 21:42:41 -0700230 debug("ICH SPI: SCIP timeout, read %x, expected %x, wts %x %x\n",
231 status, bitmask, wait_til_set, status & bitmask);
Simon Glass18530302013-03-19 04:58:56 +0000232
Simon Glassba457562015-03-26 09:29:26 -0600233 return -ETIMEDOUT;
Simon Glass18530302013-03-19 04:58:56 +0000234}
235
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200236static void ich_spi_config_opcode(struct udevice *dev)
Bin Mengb42711f2017-08-15 22:38:30 -0700237{
238 struct ich_spi_priv *ctlr = dev_get_priv(dev);
239
240 /*
241 * PREOP, OPTYPE, OPMENU1/OPMENU2 registers can be locked down
242 * to prevent accidental or intentional writes. Before they get
243 * locked down, these registers should be initialized properly.
244 */
245 ich_writew(ctlr, SPI_OPPREFIX, ctlr->preop);
246 ich_writew(ctlr, SPI_OPTYPE, ctlr->optype);
247 ich_writel(ctlr, SPI_OPMENU_LOWER, ctlr->opmenu);
248 ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
249}
250
Simon Glass1facebd2019-12-06 21:42:46 -0700251static int ich_spi_exec_op_swseq(struct spi_slave *slave,
252 const struct spi_mem_op *op)
Simon Glass18530302013-03-19 04:58:56 +0000253{
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200254 struct udevice *bus = dev_get_parent(slave->dev);
Simon Glasse1e332c2015-07-03 18:28:21 -0600255 struct ich_spi_platdata *plat = dev_get_platdata(bus);
Simon Glassba457562015-03-26 09:29:26 -0600256 struct ich_spi_priv *ctlr = dev_get_priv(bus);
Simon Glass18530302013-03-19 04:58:56 +0000257 uint16_t control;
258 int16_t opcode_index;
259 int with_address;
260 int status;
Simon Glassba457562015-03-26 09:29:26 -0600261 struct spi_trans *trans = &ctlr->trans;
Bin Meng3e791412017-08-15 22:38:29 -0700262 bool lock = spi_lock_status(plat, ctlr->base);
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200263 int ret = 0;
Simon Glass18530302013-03-19 04:58:56 +0000264
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200265 trans->in = NULL;
266 trans->out = NULL;
267 trans->type = 0xFF;
Simon Glass18530302013-03-19 04:58:56 +0000268
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200269 if (op->data.nbytes) {
270 if (op->data.dir == SPI_MEM_DATA_IN) {
271 trans->in = op->data.buf.in;
272 trans->bytesin = op->data.nbytes;
273 } else {
274 trans->out = op->data.buf.out;
275 trans->bytesout = op->data.nbytes;
Simon Glass18530302013-03-19 04:58:56 +0000276 }
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200277 }
278
279 if (trans->opcode != op->cmd.opcode)
280 trans->opcode = op->cmd.opcode;
281
282 if (lock && trans->opcode == SPI_OPCODE_WRDIS)
Simon Glass18530302013-03-19 04:58:56 +0000283 return 0;
Simon Glass18530302013-03-19 04:58:56 +0000284
285 if (trans->opcode == SPI_OPCODE_WREN) {
286 /*
287 * Treat Write Enable as Atomic Pre-Op if possible
288 * in order to prevent the Management Engine from
289 * issuing a transaction between WREN and DATA.
290 */
Bin Meng3e791412017-08-15 22:38:29 -0700291 if (!lock)
Simon Glassba457562015-03-26 09:29:26 -0600292 ich_writew(ctlr, trans->opcode, ctlr->preop);
Simon Glass18530302013-03-19 04:58:56 +0000293 return 0;
294 }
295
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200296 ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
297 if (ret < 0)
298 return ret;
299
300 if (plat->ich_version == ICHV_7)
301 ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
302 else
303 ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
304
305 /* Try to guess spi transaction type */
306 if (op->data.dir == SPI_MEM_DATA_OUT) {
307 if (op->addr.nbytes)
308 trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
309 else
310 trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
311 } else {
312 if (op->addr.nbytes)
313 trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
314 else
315 trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
316 }
317 /* Special erase case handling */
318 if (op->addr.nbytes && !op->data.buswidth)
319 trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
320
321 opcode_index = spi_setup_opcode(ctlr, trans, lock);
322 if (opcode_index < 0)
323 return -EINVAL;
324
325 if (op->addr.nbytes) {
326 trans->offset = op->addr.val;
327 with_address = 1;
328 }
329
Simon Glassba457562015-03-26 09:29:26 -0600330 if (ctlr->speed && ctlr->max_speed >= 33000000) {
Simon Glass18530302013-03-19 04:58:56 +0000331 int byte;
332
Simon Glassba457562015-03-26 09:29:26 -0600333 byte = ich_readb(ctlr, ctlr->speed);
334 if (ctlr->cur_speed >= 33000000)
Simon Glass18530302013-03-19 04:58:56 +0000335 byte |= SSFC_SCF_33MHZ;
336 else
337 byte &= ~SSFC_SCF_33MHZ;
Simon Glassba457562015-03-26 09:29:26 -0600338 ich_writeb(ctlr, byte, ctlr->speed);
Simon Glass18530302013-03-19 04:58:56 +0000339 }
340
Simon Glass18530302013-03-19 04:58:56 +0000341 /* Preset control fields */
Simon Glass18530302013-03-19 04:58:56 +0000342 control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
343
344 /* Issue atomic preop cycle if needed */
Simon Glassba457562015-03-26 09:29:26 -0600345 if (ich_readw(ctlr, ctlr->preop))
Simon Glass18530302013-03-19 04:58:56 +0000346 control |= SPIC_ACS;
347
348 if (!trans->bytesout && !trans->bytesin) {
349 /* SPI addresses are 24 bit only */
Simon Glassba457562015-03-26 09:29:26 -0600350 if (with_address) {
351 ich_writel(ctlr, trans->offset & 0x00FFFFFF,
352 ctlr->addr);
353 }
Simon Glass18530302013-03-19 04:58:56 +0000354 /*
355 * This is a 'no data' command (like Write Enable), its
356 * bitesout size was 1, decremented to zero while executing
357 * spi_setup_opcode() above. Tell the chip to send the
358 * command.
359 */
Simon Glassba457562015-03-26 09:29:26 -0600360 ich_writew(ctlr, control, ctlr->control);
Simon Glass18530302013-03-19 04:58:56 +0000361
362 /* wait for the result */
Simon Glassba457562015-03-26 09:29:26 -0600363 status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
364 if (status < 0)
365 return status;
Simon Glass18530302013-03-19 04:58:56 +0000366
367 if (status & SPIS_FCERR) {
368 debug("ICH SPI: Command transaction error\n");
Simon Glassba457562015-03-26 09:29:26 -0600369 return -EIO;
Simon Glass18530302013-03-19 04:58:56 +0000370 }
371
372 return 0;
373 }
374
Simon Glass18530302013-03-19 04:58:56 +0000375 while (trans->bytesout || trans->bytesin) {
376 uint32_t data_length;
Simon Glass18530302013-03-19 04:58:56 +0000377
378 /* SPI addresses are 24 bit only */
Simon Glassba457562015-03-26 09:29:26 -0600379 ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr);
Simon Glass18530302013-03-19 04:58:56 +0000380
381 if (trans->bytesout)
Simon Glassba457562015-03-26 09:29:26 -0600382 data_length = min(trans->bytesout, ctlr->databytes);
Simon Glass18530302013-03-19 04:58:56 +0000383 else
Simon Glassba457562015-03-26 09:29:26 -0600384 data_length = min(trans->bytesin, ctlr->databytes);
Simon Glass18530302013-03-19 04:58:56 +0000385
386 /* Program data into FDATA0 to N */
387 if (trans->bytesout) {
Simon Glassba457562015-03-26 09:29:26 -0600388 write_reg(ctlr, trans->out, ctlr->data, data_length);
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200389 trans->bytesout -= data_length;
Simon Glass18530302013-03-19 04:58:56 +0000390 }
391
392 /* Add proper control fields' values */
Simon Glassba457562015-03-26 09:29:26 -0600393 control &= ~((ctlr->databytes - 1) << 8);
Simon Glass18530302013-03-19 04:58:56 +0000394 control |= SPIC_DS;
395 control |= (data_length - 1) << 8;
396
397 /* write it */
Simon Glassba457562015-03-26 09:29:26 -0600398 ich_writew(ctlr, control, ctlr->control);
Simon Glass18530302013-03-19 04:58:56 +0000399
Bin Meng9eb43392016-02-01 01:40:36 -0800400 /* Wait for Cycle Done Status or Flash Cycle Error */
Simon Glassba457562015-03-26 09:29:26 -0600401 status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
402 if (status < 0)
403 return status;
Simon Glass18530302013-03-19 04:58:56 +0000404
405 if (status & SPIS_FCERR) {
Simon Glass5d4a7572015-06-07 08:50:33 -0600406 debug("ICH SPI: Data transaction error %x\n", status);
Simon Glassba457562015-03-26 09:29:26 -0600407 return -EIO;
Simon Glass18530302013-03-19 04:58:56 +0000408 }
409
410 if (trans->bytesin) {
Simon Glassba457562015-03-26 09:29:26 -0600411 read_reg(ctlr, ctlr->data, trans->in, data_length);
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200412 trans->bytesin -= data_length;
Simon Glass18530302013-03-19 04:58:56 +0000413 }
414 }
415
416 /* Clear atomic preop now that xfer is done */
Bin Mengd2ca80c2017-08-26 19:22:59 -0700417 if (!lock)
418 ich_writew(ctlr, 0, ctlr->preop);
Simon Glass18530302013-03-19 04:58:56 +0000419
420 return 0;
421}
422
Simon Glass1facebd2019-12-06 21:42:46 -0700423/*
424 * Ensure read/write xfer len is not greater than SPIBAR_FDATA_FIFO_SIZE and
425 * that the operation does not cross page boundary.
426 */
427static uint get_xfer_len(u32 offset, int len, int page_size)
428{
429 uint xfer_len = min(len, SPIBAR_FDATA_FIFO_SIZE);
430 uint bytes_left = ALIGN(offset, page_size) - offset;
431
432 if (bytes_left)
433 xfer_len = min(xfer_len, bytes_left);
434
435 return xfer_len;
436}
437
438/* Fill FDATAn FIFO in preparation for a write transaction */
439static void fill_xfer_fifo(struct fast_spi_regs *regs, const void *data,
440 uint len)
441{
442 memcpy(regs->fdata, data, len);
443}
444
445/* Drain FDATAn FIFO after a read transaction populates data */
446static void drain_xfer_fifo(struct fast_spi_regs *regs, void *dest, uint len)
447{
448 memcpy(dest, regs->fdata, len);
449}
450
451/* Fire up a transfer using the hardware sequencer */
452static void start_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
453 uint offset, uint len)
454{
455 /* Make sure all W1C status bits get cleared */
456 u32 hsfsts;
457
458 hsfsts = readl(&regs->hsfsts_ctl);
459 hsfsts &= ~(HSFSTS_FCYCLE_MASK | HSFSTS_FDBC_MASK);
460 hsfsts |= HSFSTS_AEL | HSFSTS_FCERR | HSFSTS_FDONE;
461
462 /* Set up transaction parameters */
463 hsfsts |= hsfsts_cycle << HSFSTS_FCYCLE_SHIFT;
464 hsfsts |= ((len - 1) << HSFSTS_FDBC_SHIFT) & HSFSTS_FDBC_MASK;
465 hsfsts |= HSFSTS_FGO;
466
467 writel(offset, &regs->faddr);
468 writel(hsfsts, &regs->hsfsts_ctl);
469}
470
471static int wait_for_hwseq_xfer(struct fast_spi_regs *regs, uint offset)
472{
473 ulong start;
474 u32 hsfsts;
475
476 start = get_timer(0);
477 do {
478 hsfsts = readl(&regs->hsfsts_ctl);
479 if (hsfsts & HSFSTS_FCERR) {
480 debug("SPI transaction error at offset %x HSFSTS = %08x\n",
481 offset, hsfsts);
482 return -EIO;
483 }
484 if (hsfsts & HSFSTS_AEL)
485 return -EPERM;
486
487 if (hsfsts & HSFSTS_FDONE)
488 return 0;
489 } while (get_timer(start) < SPIBAR_HWSEQ_XFER_TIMEOUT_MS);
490
491 debug("SPI transaction timeout at offset %x HSFSTS = %08x, timer %d\n",
492 offset, hsfsts, (uint)get_timer(start));
493
494 return -ETIMEDOUT;
495}
496
497/**
498 * exec_sync_hwseq_xfer() - Execute flash transfer by hardware sequencing
499 *
500 * This waits until complete or timeout
501 *
502 * @regs: SPI registers
503 * @hsfsts_cycle: Cycle type (enum hsfsts_cycle_t)
504 * @offset: Offset to access
505 * @len: Number of bytes to transfer (can be 0)
506 * @return 0 if OK, -EIO on flash-cycle error (FCERR), -EPERM on access error
507 * (AEL), -ETIMEDOUT on timeout
508 */
509static int exec_sync_hwseq_xfer(struct fast_spi_regs *regs, uint hsfsts_cycle,
510 uint offset, uint len)
511{
512 start_hwseq_xfer(regs, hsfsts_cycle, offset, len);
513
514 return wait_for_hwseq_xfer(regs, offset);
515}
516
517static int ich_spi_exec_op_hwseq(struct spi_slave *slave,
518 const struct spi_mem_op *op)
519{
520 struct spi_flash *flash = dev_get_uclass_priv(slave->dev);
521 struct udevice *bus = dev_get_parent(slave->dev);
522 struct ich_spi_priv *priv = dev_get_priv(bus);
523 struct fast_spi_regs *regs = priv->base;
524 uint page_size;
525 uint offset;
526 int cycle;
527 uint len;
528 bool out;
529 int ret;
530 u8 *buf;
531
532 offset = op->addr.val;
533 len = op->data.nbytes;
534
535 switch (op->cmd.opcode) {
536 case SPINOR_OP_RDID:
537 cycle = HSFSTS_CYCLE_RDID;
538 break;
539 case SPINOR_OP_READ_FAST:
540 cycle = HSFSTS_CYCLE_READ;
541 break;
542 case SPINOR_OP_PP:
543 cycle = HSFSTS_CYCLE_WRITE;
544 break;
545 case SPINOR_OP_WREN:
546 /* Nothing needs to be done */
547 return 0;
548 case SPINOR_OP_WRSR:
549 cycle = HSFSTS_CYCLE_WR_STATUS;
550 break;
551 case SPINOR_OP_RDSR:
552 cycle = HSFSTS_CYCLE_RD_STATUS;
553 break;
554 case SPINOR_OP_WRDI:
555 return 0; /* ignore */
556 case SPINOR_OP_BE_4K:
557 cycle = HSFSTS_CYCLE_4K_ERASE;
558 while (len) {
559 uint xfer_len = 0x1000;
560
561 ret = exec_sync_hwseq_xfer(regs, cycle, offset, 0);
562 if (ret)
563 return ret;
564 offset += xfer_len;
565 len -= xfer_len;
566 }
567 return 0;
568 default:
569 debug("Unknown cycle %x\n", op->cmd.opcode);
570 return -EINVAL;
571 };
572
573 out = op->data.dir == SPI_MEM_DATA_OUT;
574 buf = out ? (u8 *)op->data.buf.out : op->data.buf.in;
575 page_size = flash->page_size ? : 256;
576
577 while (len) {
578 uint xfer_len = get_xfer_len(offset, len, page_size);
579
580 if (out)
581 fill_xfer_fifo(regs, buf, xfer_len);
582
583 ret = exec_sync_hwseq_xfer(regs, cycle, offset, xfer_len);
584 if (ret)
585 return ret;
586
587 if (!out)
588 drain_xfer_fifo(regs, buf, xfer_len);
589
590 offset += xfer_len;
591 buf += xfer_len;
592 len -= xfer_len;
593 }
594
595 return 0;
596}
597
598static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
599{
600 struct udevice *bus = dev_get_parent(slave->dev);
601 struct ich_spi_platdata *plat = dev_get_platdata(bus);
602 int ret;
603
604 bootstage_start(BOOTSTAGE_ID_ACCUM_SPI, "fast_spi");
605 if (plat->hwseq)
606 ret = ich_spi_exec_op_hwseq(slave, op);
607 else
608 ret = ich_spi_exec_op_swseq(slave, op);
609 bootstage_accum(BOOTSTAGE_ID_ACCUM_SPI);
610
611 return ret;
612}
613
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200614static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op)
615{
616 unsigned int page_offset;
617 int addr = op->addr.val;
618 unsigned int byte_count = op->data.nbytes;
619
620 if (hweight32(ICH_BOUNDARY) == 1) {
621 page_offset = addr & (ICH_BOUNDARY - 1);
622 } else {
623 u64 aux = addr;
624
625 page_offset = do_div(aux, ICH_BOUNDARY);
626 }
627
Simon Glass43c145b2019-12-06 21:42:44 -0700628 if (op->data.dir == SPI_MEM_DATA_IN) {
629 if (slave->max_read_size) {
630 op->data.nbytes = min(ICH_BOUNDARY - page_offset,
631 slave->max_read_size);
632 }
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200633 } else if (slave->max_write_size) {
634 op->data.nbytes = min(ICH_BOUNDARY - page_offset,
635 slave->max_write_size);
636 }
637
638 op->data.nbytes = min(op->data.nbytes, byte_count);
639
640 return 0;
641}
642
Simon Glass17e75442019-12-06 21:42:38 -0700643static int ich_protect_lockdown(struct udevice *dev)
644{
645 struct ich_spi_platdata *plat = dev_get_platdata(dev);
646 struct ich_spi_priv *priv = dev_get_priv(dev);
647 int ret = -ENOSYS;
648
649 /* Disable the BIOS write protect so write commands are allowed */
650 if (priv->pch)
651 ret = pch_set_spi_protect(priv->pch, false);
652 if (ret == -ENOSYS) {
653 u8 bios_cntl;
654
655 bios_cntl = ich_readb(priv, priv->bcr);
656 bios_cntl &= ~BIT(5); /* clear Enable InSMM_STS (EISS) */
657 bios_cntl |= 1; /* Write Protect Disable (WPD) */
658 ich_writeb(priv, bios_cntl, priv->bcr);
659 } else if (ret) {
660 debug("%s: Failed to disable write-protect: err=%d\n",
661 __func__, ret);
662 return ret;
663 }
664
665 /* Lock down SPI controller settings if required */
666 if (plat->lockdown) {
667 ich_spi_config_opcode(dev);
668 spi_lock_down(plat, priv->base);
669 }
670
671 return 0;
672}
673
Simon Glass674990c2019-12-06 21:42:37 -0700674static int ich_init_controller(struct udevice *dev,
675 struct ich_spi_platdata *plat,
676 struct ich_spi_priv *ctlr)
677{
Simon Glass75214b02019-12-06 21:42:42 -0700678 ctlr->base = (void *)plat->mmio_base;
Simon Glass674990c2019-12-06 21:42:37 -0700679 if (plat->ich_version == ICHV_7) {
Simon Glass75214b02019-12-06 21:42:42 -0700680 struct ich7_spi_regs *ich7_spi = ctlr->base;
Simon Glass674990c2019-12-06 21:42:37 -0700681
682 ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
683 ctlr->menubytes = sizeof(ich7_spi->opmenu);
684 ctlr->optype = offsetof(struct ich7_spi_regs, optype);
685 ctlr->addr = offsetof(struct ich7_spi_regs, spia);
686 ctlr->data = offsetof(struct ich7_spi_regs, spid);
687 ctlr->databytes = sizeof(ich7_spi->spid);
688 ctlr->status = offsetof(struct ich7_spi_regs, spis);
689 ctlr->control = offsetof(struct ich7_spi_regs, spic);
690 ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
691 ctlr->preop = offsetof(struct ich7_spi_regs, preop);
Simon Glass674990c2019-12-06 21:42:37 -0700692 } else if (plat->ich_version == ICHV_9) {
Simon Glass75214b02019-12-06 21:42:42 -0700693 struct ich9_spi_regs *ich9_spi = ctlr->base;
Simon Glass674990c2019-12-06 21:42:37 -0700694
695 ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
696 ctlr->menubytes = sizeof(ich9_spi->opmenu);
697 ctlr->optype = offsetof(struct ich9_spi_regs, optype);
698 ctlr->addr = offsetof(struct ich9_spi_regs, faddr);
699 ctlr->data = offsetof(struct ich9_spi_regs, fdata);
700 ctlr->databytes = sizeof(ich9_spi->fdata);
701 ctlr->status = offsetof(struct ich9_spi_regs, ssfs);
702 ctlr->control = offsetof(struct ich9_spi_regs, ssfc);
703 ctlr->speed = ctlr->control + 2;
704 ctlr->bbar = offsetof(struct ich9_spi_regs, bbar);
705 ctlr->preop = offsetof(struct ich9_spi_regs, preop);
706 ctlr->bcr = offsetof(struct ich9_spi_regs, bcr);
707 ctlr->pr = &ich9_spi->pr[0];
Simon Glass674990c2019-12-06 21:42:37 -0700708 } else {
709 debug("ICH SPI: Unrecognised ICH version %d\n",
710 plat->ich_version);
711 return -EINVAL;
712 }
713
714 /* Work out the maximum speed we can support */
715 ctlr->max_speed = 20000000;
716 if (plat->ich_version == ICHV_9 && ich9_can_do_33mhz(dev))
717 ctlr->max_speed = 33000000;
Simon Glass75214b02019-12-06 21:42:42 -0700718 debug("ICH SPI: Version ID %d detected at %lx, speed %ld\n",
719 plat->ich_version, plat->mmio_base, ctlr->max_speed);
Simon Glass674990c2019-12-06 21:42:37 -0700720
721 ich_set_bbar(ctlr, 0);
722
723 return 0;
724}
725
Simon Glassf2b85ab2016-01-18 20:19:21 -0700726static int ich_spi_probe(struct udevice *dev)
Simon Glassba457562015-03-26 09:29:26 -0600727{
Simon Glassf2b85ab2016-01-18 20:19:21 -0700728 struct ich_spi_platdata *plat = dev_get_platdata(dev);
729 struct ich_spi_priv *priv = dev_get_priv(dev);
Simon Glassba457562015-03-26 09:29:26 -0600730 int ret;
731
Simon Glassf2b85ab2016-01-18 20:19:21 -0700732 ret = ich_init_controller(dev, plat, priv);
Simon Glassba457562015-03-26 09:29:26 -0600733 if (ret)
734 return ret;
Simon Glassba457562015-03-26 09:29:26 -0600735
Simon Glass17e75442019-12-06 21:42:38 -0700736 ret = ich_protect_lockdown(dev);
737 if (ret)
738 return ret;
Bin Mengab201072017-10-18 18:20:57 -0700739
Simon Glassba457562015-03-26 09:29:26 -0600740 priv->cur_speed = priv->max_speed;
741
742 return 0;
743}
744
Stefan Roese4759dff2017-04-24 09:48:04 +0200745static int ich_spi_remove(struct udevice *bus)
746{
Stefan Roese4759dff2017-04-24 09:48:04 +0200747 /*
748 * Configure SPI controller so that the Linux MTD driver can fully
749 * access the SPI NOR chip
750 */
Bin Mengb42711f2017-08-15 22:38:30 -0700751 ich_spi_config_opcode(bus);
Stefan Roese4759dff2017-04-24 09:48:04 +0200752
753 return 0;
754}
755
Simon Glassba457562015-03-26 09:29:26 -0600756static int ich_spi_set_speed(struct udevice *bus, uint speed)
757{
758 struct ich_spi_priv *priv = dev_get_priv(bus);
759
760 priv->cur_speed = speed;
761
762 return 0;
763}
764
765static int ich_spi_set_mode(struct udevice *bus, uint mode)
766{
767 debug("%s: mode=%d\n", __func__, mode);
768
769 return 0;
770}
771
772static int ich_spi_child_pre_probe(struct udevice *dev)
773{
774 struct udevice *bus = dev_get_parent(dev);
775 struct ich_spi_platdata *plat = dev_get_platdata(bus);
776 struct ich_spi_priv *priv = dev_get_priv(bus);
Simon Glassbcbe3d12015-09-28 23:32:01 -0600777 struct spi_slave *slave = dev_get_parent_priv(dev);
Simon Glassba457562015-03-26 09:29:26 -0600778
779 /*
780 * Yes this controller can only write a small number of bytes at
Simon Glass1facebd2019-12-06 21:42:46 -0700781 * once! The limit is typically 64 bytes. For hardware sequencing a
782 * a loop is used to get around this.
Simon Glassba457562015-03-26 09:29:26 -0600783 */
Simon Glass1facebd2019-12-06 21:42:46 -0700784 if (!plat->hwseq)
785 slave->max_write_size = priv->databytes;
Simon Glassba457562015-03-26 09:29:26 -0600786 /*
787 * ICH 7 SPI controller only supports array read command
788 * and byte program command for SST flash
789 */
Jagan Teki08fe9c22016-08-08 17:12:12 +0530790 if (plat->ich_version == ICHV_7)
791 slave->mode = SPI_RX_SLOW | SPI_TX_BYTE;
Simon Glassba457562015-03-26 09:29:26 -0600792
793 return 0;
794}
795
Bin Meng1f9eb592016-02-01 01:40:37 -0800796static int ich_spi_ofdata_to_platdata(struct udevice *dev)
797{
798 struct ich_spi_platdata *plat = dev_get_platdata(dev);
Simon Glass0d3ee3e2019-12-06 21:42:45 -0700799
800#if !CONFIG_IS_ENABLED(OF_PLATDATA)
Simon Glass17e75442019-12-06 21:42:38 -0700801 struct ich_spi_priv *priv = dev_get_priv(dev);
Bin Meng1f9eb592016-02-01 01:40:37 -0800802
Simon Glass17e75442019-12-06 21:42:38 -0700803 /* Find a PCH if there is one */
804 uclass_first_device(UCLASS_PCH, &priv->pch);
805 if (!priv->pch)
806 priv->pch = dev_get_parent(dev);
807
Simon Glass702b28a2019-12-06 21:42:39 -0700808 plat->ich_version = dev_get_driver_data(dev);
809 plat->lockdown = dev_read_bool(dev, "intel,spi-lock-down");
Simon Glass75214b02019-12-06 21:42:42 -0700810 pch_get_spi_base(priv->pch, &plat->mmio_base);
Simon Glass1facebd2019-12-06 21:42:46 -0700811 /*
812 * Use an int so that the property is present in of-platdata even
813 * when false.
814 */
815 plat->hwseq = dev_read_u32_default(dev, "intel,hardware-seq", 0);
Simon Glass0d3ee3e2019-12-06 21:42:45 -0700816#else
817 plat->ich_version = ICHV_APL;
818 plat->mmio_base = plat->dtplat.early_regs[0];
819 plat->bdf = pci_ofplat_get_devfn(plat->dtplat.reg[0]);
Simon Glass1facebd2019-12-06 21:42:46 -0700820 plat->hwseq = plat->dtplat.intel_hardware_seq;
Simon Glass0d3ee3e2019-12-06 21:42:45 -0700821#endif
822 debug("%s: mmio_base=%lx\n", __func__, plat->mmio_base);
Simon Glass75214b02019-12-06 21:42:42 -0700823
Simon Glass702b28a2019-12-06 21:42:39 -0700824 return 0;
Bin Meng1f9eb592016-02-01 01:40:37 -0800825}
826
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200827static const struct spi_controller_mem_ops ich_controller_mem_ops = {
828 .adjust_op_size = ich_spi_adjust_size,
829 .supports_op = NULL,
830 .exec_op = ich_spi_exec_op,
831};
832
Simon Glassba457562015-03-26 09:29:26 -0600833static const struct dm_spi_ops ich_spi_ops = {
Simon Glassccdabd82019-12-06 21:42:35 -0700834 /* xfer is not supported */
Simon Glassba457562015-03-26 09:29:26 -0600835 .set_speed = ich_spi_set_speed,
836 .set_mode = ich_spi_set_mode,
Bernhard Messerklinger0709ddb2019-08-02 08:38:34 +0200837 .mem_ops = &ich_controller_mem_ops,
Simon Glassba457562015-03-26 09:29:26 -0600838 /*
839 * cs_info is not needed, since we require all chip selects to be
840 * in the device tree explicitly
841 */
842};
843
844static const struct udevice_id ich_spi_ids[] = {
Simon Glass702b28a2019-12-06 21:42:39 -0700845 { .compatible = "intel,ich7-spi", ICHV_7 },
846 { .compatible = "intel,ich9-spi", ICHV_9 },
Simon Glassba457562015-03-26 09:29:26 -0600847 { }
848};
849
Simon Glass0d3ee3e2019-12-06 21:42:45 -0700850U_BOOT_DRIVER(intel_fast_spi) = {
851 .name = "intel_fast_spi",
Simon Glassba457562015-03-26 09:29:26 -0600852 .id = UCLASS_SPI,
853 .of_match = ich_spi_ids,
854 .ops = &ich_spi_ops,
Bin Meng1f9eb592016-02-01 01:40:37 -0800855 .ofdata_to_platdata = ich_spi_ofdata_to_platdata,
Simon Glassba457562015-03-26 09:29:26 -0600856 .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata),
857 .priv_auto_alloc_size = sizeof(struct ich_spi_priv),
858 .child_pre_probe = ich_spi_child_pre_probe,
859 .probe = ich_spi_probe,
Stefan Roese4759dff2017-04-24 09:48:04 +0200860 .remove = ich_spi_remove,
861 .flags = DM_FLAG_OS_PREPARE,
Simon Glassba457562015-03-26 09:29:26 -0600862};