]>
Commit | Line | Data |
---|---|---|
1853030e SG |
1 | /* |
2 | * Copyright (c) 2011-12 The Chromium OS Authors. | |
3 | * | |
1a459660 | 4 | * SPDX-License-Identifier: GPL-2.0+ |
1853030e SG |
5 | * |
6 | * This file is derived from the flashrom project. | |
7 | */ | |
8 | ||
9 | #include <common.h> | |
ba457562 | 10 | #include <dm.h> |
5093badb | 11 | #include <errno.h> |
1853030e SG |
12 | #include <malloc.h> |
13 | #include <spi.h> | |
14 | #include <pci.h> | |
15 | #include <pci_ids.h> | |
16 | #include <asm/io.h> | |
17 | ||
18 | #include "ich.h" | |
19 | ||
20 | #define SPI_OPCODE_WREN 0x06 | |
21 | #define SPI_OPCODE_FAST_READ 0x0b | |
22 | ||
ba457562 | 23 | struct ich_spi_platdata { |
1853030e SG |
24 | pci_dev_t dev; /* PCI device number */ |
25 | int ich_version; /* Controller version, 7 or 9 */ | |
5093badb | 26 | bool use_sbase; /* Use SBASE instead of RCB */ |
ba457562 SG |
27 | }; |
28 | ||
29 | struct ich_spi_priv { | |
1853030e SG |
30 | int ichspi_lock; |
31 | int locked; | |
ba457562 | 32 | int opmenu; |
1853030e SG |
33 | int menubytes; |
34 | void *base; /* Base of register set */ | |
ba457562 SG |
35 | int preop; |
36 | int optype; | |
37 | int addr; | |
38 | int data; | |
1853030e | 39 | unsigned databytes; |
ba457562 SG |
40 | int status; |
41 | int control; | |
42 | int bbar; | |
50787928 | 43 | int bcr; |
1853030e | 44 | uint32_t *pr; /* only for ich9 */ |
ba457562 | 45 | int speed; /* pointer to speed control */ |
1853030e | 46 | ulong max_speed; /* Maximum bus speed in MHz */ |
ba457562 SG |
47 | ulong cur_speed; /* Current bus speed */ |
48 | struct spi_trans trans; /* current transaction in progress */ | |
1853030e SG |
49 | }; |
50 | ||
ba457562 | 51 | static u8 ich_readb(struct ich_spi_priv *priv, int reg) |
1853030e | 52 | { |
ba457562 | 53 | u8 value = readb(priv->base + reg); |
1853030e | 54 | |
ba457562 | 55 | debug("read %2.2x from %4.4x\n", value, reg); |
1853030e SG |
56 | |
57 | return value; | |
58 | } | |
59 | ||
ba457562 | 60 | static u16 ich_readw(struct ich_spi_priv *priv, int reg) |
1853030e | 61 | { |
ba457562 | 62 | u16 value = readw(priv->base + reg); |
1853030e | 63 | |
ba457562 | 64 | debug("read %4.4x from %4.4x\n", value, reg); |
1853030e SG |
65 | |
66 | return value; | |
67 | } | |
68 | ||
ba457562 | 69 | static u32 ich_readl(struct ich_spi_priv *priv, int reg) |
1853030e | 70 | { |
ba457562 | 71 | u32 value = readl(priv->base + reg); |
1853030e | 72 | |
ba457562 | 73 | debug("read %8.8x from %4.4x\n", value, reg); |
1853030e SG |
74 | |
75 | return value; | |
76 | } | |
77 | ||
ba457562 | 78 | static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg) |
1853030e | 79 | { |
ba457562 SG |
80 | writeb(value, priv->base + reg); |
81 | debug("wrote %2.2x to %4.4x\n", value, reg); | |
1853030e SG |
82 | } |
83 | ||
ba457562 | 84 | static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg) |
1853030e | 85 | { |
ba457562 SG |
86 | writew(value, priv->base + reg); |
87 | debug("wrote %4.4x to %4.4x\n", value, reg); | |
1853030e SG |
88 | } |
89 | ||
ba457562 | 90 | static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg) |
1853030e | 91 | { |
ba457562 SG |
92 | writel(value, priv->base + reg); |
93 | debug("wrote %8.8x to %4.4x\n", value, reg); | |
1853030e SG |
94 | } |
95 | ||
ba457562 SG |
96 | static void write_reg(struct ich_spi_priv *priv, const void *value, |
97 | int dest_reg, uint32_t size) | |
1853030e | 98 | { |
ba457562 | 99 | memcpy_toio(priv->base + dest_reg, value, size); |
1853030e SG |
100 | } |
101 | ||
ba457562 SG |
102 | static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value, |
103 | uint32_t size) | |
1853030e | 104 | { |
ba457562 | 105 | memcpy_fromio(value, priv->base + src_reg, size); |
1853030e SG |
106 | } |
107 | ||
ba457562 | 108 | static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr) |
1853030e SG |
109 | { |
110 | const uint32_t bbar_mask = 0x00ffff00; | |
111 | uint32_t ichspi_bbar; | |
112 | ||
113 | minaddr &= bbar_mask; | |
ba457562 | 114 | ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask; |
1853030e | 115 | ichspi_bbar |= minaddr; |
ba457562 | 116 | ich_writel(ctlr, ichspi_bbar, ctlr->bbar); |
1853030e SG |
117 | } |
118 | ||
119 | /* | |
120 | * Check if this device ID matches one of supported Intel PCH devices. | |
121 | * | |
122 | * Return the ICH version if there is a match, or zero otherwise. | |
123 | */ | |
124 | static int get_ich_version(uint16_t device_id) | |
125 | { | |
7e774039 | 126 | if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC || |
728b393f BM |
127 | device_id == PCI_DEVICE_ID_INTEL_ITC_LPC || |
128 | device_id == PCI_DEVICE_ID_INTEL_QRK_ILB) | |
1853030e SG |
129 | return 7; |
130 | ||
131 | if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && | |
132 | device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) || | |
133 | (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && | |
5093badb | 134 | device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) || |
87108cf2 | 135 | device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC || |
5ac98cb9 GM |
136 | device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC || |
137 | device_id == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LPC) | |
1853030e SG |
138 | return 9; |
139 | ||
140 | return 0; | |
141 | } | |
142 | ||
143 | /* @return 1 if the SPI flash supports the 33MHz speed */ | |
144 | static int ich9_can_do_33mhz(pci_dev_t dev) | |
145 | { | |
146 | u32 fdod, speed; | |
147 | ||
148 | /* Observe SPI Descriptor Component Section 0 */ | |
149 | pci_write_config_dword(dev, 0xb0, 0x1000); | |
150 | ||
151 | /* Extract the Write/Erase SPI Frequency from descriptor */ | |
152 | pci_read_config_dword(dev, 0xb4, &fdod); | |
153 | ||
154 | /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */ | |
155 | speed = (fdod >> 21) & 7; | |
156 | ||
157 | return speed == 1; | |
158 | } | |
159 | ||
ba457562 | 160 | static int ich_find_spi_controller(struct ich_spi_platdata *ich) |
1853030e SG |
161 | { |
162 | int last_bus = pci_last_busno(); | |
163 | int bus; | |
164 | ||
165 | if (last_bus == -1) { | |
166 | debug("No PCI busses?\n"); | |
5093badb | 167 | return -ENODEV; |
1853030e SG |
168 | } |
169 | ||
170 | for (bus = 0; bus <= last_bus; bus++) { | |
171 | uint16_t vendor_id, device_id; | |
172 | uint32_t ids; | |
173 | pci_dev_t dev; | |
174 | ||
175 | dev = PCI_BDF(bus, 31, 0); | |
176 | pci_read_config_dword(dev, 0, &ids); | |
177 | vendor_id = ids; | |
178 | device_id = ids >> 16; | |
179 | ||
180 | if (vendor_id == PCI_VENDOR_ID_INTEL) { | |
5093badb SG |
181 | ich->dev = dev; |
182 | ich->ich_version = get_ich_version(device_id); | |
183 | if (device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC) | |
184 | ich->use_sbase = true; | |
185 | return ich->ich_version == 0 ? -ENODEV : 0; | |
1853030e SG |
186 | } |
187 | } | |
188 | ||
189 | debug("ICH SPI: No ICH found.\n"); | |
5093badb | 190 | return -ENODEV; |
1853030e SG |
191 | } |
192 | ||
ba457562 SG |
193 | static int ich_init_controller(struct ich_spi_platdata *plat, |
194 | struct ich_spi_priv *ctlr) | |
1853030e SG |
195 | { |
196 | uint8_t *rcrb; /* Root Complex Register Block */ | |
197 | uint32_t rcba; /* Root Complex Base Address */ | |
5093badb SG |
198 | uint32_t sbase_addr; |
199 | uint8_t *sbase; | |
1853030e | 200 | |
ba457562 | 201 | pci_read_config_dword(plat->dev, 0xf0, &rcba); |
1853030e SG |
202 | /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */ |
203 | rcrb = (uint8_t *)(rcba & 0xffffc000); | |
5093badb SG |
204 | |
205 | /* SBASE is similar */ | |
ba457562 | 206 | pci_read_config_dword(plat->dev, 0x54, &sbase_addr); |
5093badb SG |
207 | sbase = (uint8_t *)(sbase_addr & 0xfffffe00); |
208 | ||
ba457562 | 209 | if (plat->ich_version == 7) { |
1853030e SG |
210 | struct ich7_spi_regs *ich7_spi; |
211 | ||
212 | ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020); | |
ba457562 SG |
213 | ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK; |
214 | ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu); | |
1853030e | 215 | ctlr->menubytes = sizeof(ich7_spi->opmenu); |
ba457562 SG |
216 | ctlr->optype = offsetof(struct ich7_spi_regs, optype); |
217 | ctlr->addr = offsetof(struct ich7_spi_regs, spia); | |
218 | ctlr->data = offsetof(struct ich7_spi_regs, spid); | |
1853030e | 219 | ctlr->databytes = sizeof(ich7_spi->spid); |
ba457562 SG |
220 | ctlr->status = offsetof(struct ich7_spi_regs, spis); |
221 | ctlr->control = offsetof(struct ich7_spi_regs, spic); | |
222 | ctlr->bbar = offsetof(struct ich7_spi_regs, bbar); | |
223 | ctlr->preop = offsetof(struct ich7_spi_regs, preop); | |
1853030e | 224 | ctlr->base = ich7_spi; |
ba457562 | 225 | } else if (plat->ich_version == 9) { |
1853030e SG |
226 | struct ich9_spi_regs *ich9_spi; |
227 | ||
ba457562 | 228 | if (plat->use_sbase) |
5093badb SG |
229 | ich9_spi = (struct ich9_spi_regs *)sbase; |
230 | else | |
231 | ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800); | |
ba457562 SG |
232 | ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN; |
233 | ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu); | |
1853030e | 234 | ctlr->menubytes = sizeof(ich9_spi->opmenu); |
ba457562 SG |
235 | ctlr->optype = offsetof(struct ich9_spi_regs, optype); |
236 | ctlr->addr = offsetof(struct ich9_spi_regs, faddr); | |
237 | ctlr->data = offsetof(struct ich9_spi_regs, fdata); | |
1853030e | 238 | ctlr->databytes = sizeof(ich9_spi->fdata); |
ba457562 SG |
239 | ctlr->status = offsetof(struct ich9_spi_regs, ssfs); |
240 | ctlr->control = offsetof(struct ich9_spi_regs, ssfc); | |
241 | ctlr->speed = ctlr->control + 2; | |
242 | ctlr->bbar = offsetof(struct ich9_spi_regs, bbar); | |
243 | ctlr->preop = offsetof(struct ich9_spi_regs, preop); | |
50787928 | 244 | ctlr->bcr = offsetof(struct ich9_spi_regs, bcr); |
1853030e SG |
245 | ctlr->pr = &ich9_spi->pr[0]; |
246 | ctlr->base = ich9_spi; | |
247 | } else { | |
ba457562 SG |
248 | debug("ICH SPI: Unrecognised ICH version %d\n", |
249 | plat->ich_version); | |
250 | return -EINVAL; | |
1853030e | 251 | } |
1853030e SG |
252 | |
253 | /* Work out the maximum speed we can support */ | |
254 | ctlr->max_speed = 20000000; | |
ba457562 | 255 | if (plat->ich_version == 9 && ich9_can_do_33mhz(plat->dev)) |
1853030e | 256 | ctlr->max_speed = 33000000; |
5093badb | 257 | debug("ICH SPI: Version %d detected at %p, speed %ld\n", |
ba457562 | 258 | plat->ich_version, ctlr->base, ctlr->max_speed); |
1853030e SG |
259 | |
260 | ich_set_bbar(ctlr, 0); | |
261 | ||
262 | return 0; | |
263 | } | |
264 | ||
1853030e SG |
265 | static inline void spi_use_out(struct spi_trans *trans, unsigned bytes) |
266 | { | |
267 | trans->out += bytes; | |
268 | trans->bytesout -= bytes; | |
269 | } | |
270 | ||
271 | static inline void spi_use_in(struct spi_trans *trans, unsigned bytes) | |
272 | { | |
273 | trans->in += bytes; | |
274 | trans->bytesin -= bytes; | |
275 | } | |
276 | ||
277 | static void spi_setup_type(struct spi_trans *trans, int data_bytes) | |
278 | { | |
279 | trans->type = 0xFF; | |
280 | ||
281 | /* Try to guess spi type from read/write sizes. */ | |
282 | if (trans->bytesin == 0) { | |
283 | if (trans->bytesout + data_bytes > 4) | |
284 | /* | |
285 | * If bytesin = 0 and bytesout > 4, we presume this is | |
286 | * a write data operation, which is accompanied by an | |
287 | * address. | |
288 | */ | |
289 | trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; | |
290 | else | |
291 | trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; | |
292 | return; | |
293 | } | |
294 | ||
295 | if (trans->bytesout == 1) { /* and bytesin is > 0 */ | |
296 | trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; | |
297 | return; | |
298 | } | |
299 | ||
300 | if (trans->bytesout == 4) /* and bytesin is > 0 */ | |
301 | trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; | |
302 | ||
303 | /* Fast read command is called with 5 bytes instead of 4 */ | |
304 | if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { | |
305 | trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; | |
306 | --trans->bytesout; | |
307 | } | |
308 | } | |
309 | ||
ba457562 | 310 | static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans) |
1853030e SG |
311 | { |
312 | uint16_t optypes; | |
ba457562 | 313 | uint8_t opmenu[ctlr->menubytes]; |
1853030e SG |
314 | |
315 | trans->opcode = trans->out[0]; | |
316 | spi_use_out(trans, 1); | |
ba457562 | 317 | if (!ctlr->ichspi_lock) { |
1853030e | 318 | /* The lock is off, so just use index 0. */ |
ba457562 SG |
319 | ich_writeb(ctlr, trans->opcode, ctlr->opmenu); |
320 | optypes = ich_readw(ctlr, ctlr->optype); | |
1853030e | 321 | optypes = (optypes & 0xfffc) | (trans->type & 0x3); |
ba457562 | 322 | ich_writew(ctlr, optypes, ctlr->optype); |
1853030e SG |
323 | return 0; |
324 | } else { | |
325 | /* The lock is on. See if what we need is on the menu. */ | |
326 | uint8_t optype; | |
327 | uint16_t opcode_index; | |
328 | ||
329 | /* Write Enable is handled as atomic prefix */ | |
330 | if (trans->opcode == SPI_OPCODE_WREN) | |
331 | return 0; | |
332 | ||
ba457562 SG |
333 | read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu)); |
334 | for (opcode_index = 0; opcode_index < ctlr->menubytes; | |
1853030e SG |
335 | opcode_index++) { |
336 | if (opmenu[opcode_index] == trans->opcode) | |
337 | break; | |
338 | } | |
339 | ||
ba457562 | 340 | if (opcode_index == ctlr->menubytes) { |
1853030e SG |
341 | printf("ICH SPI: Opcode %x not found\n", |
342 | trans->opcode); | |
ba457562 | 343 | return -EINVAL; |
1853030e SG |
344 | } |
345 | ||
ba457562 | 346 | optypes = ich_readw(ctlr, ctlr->optype); |
1853030e SG |
347 | optype = (optypes >> (opcode_index * 2)) & 0x3; |
348 | if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && | |
349 | optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && | |
350 | trans->bytesout >= 3) { | |
351 | /* We guessed wrong earlier. Fix it up. */ | |
352 | trans->type = optype; | |
353 | } | |
354 | if (optype != trans->type) { | |
355 | printf("ICH SPI: Transaction doesn't fit type %d\n", | |
356 | optype); | |
ba457562 | 357 | return -ENOSPC; |
1853030e SG |
358 | } |
359 | return opcode_index; | |
360 | } | |
361 | } | |
362 | ||
363 | static int spi_setup_offset(struct spi_trans *trans) | |
364 | { | |
365 | /* Separate the SPI address and data. */ | |
366 | switch (trans->type) { | |
367 | case SPI_OPCODE_TYPE_READ_NO_ADDRESS: | |
368 | case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: | |
369 | return 0; | |
370 | case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: | |
371 | case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: | |
372 | trans->offset = ((uint32_t)trans->out[0] << 16) | | |
373 | ((uint32_t)trans->out[1] << 8) | | |
374 | ((uint32_t)trans->out[2] << 0); | |
375 | spi_use_out(trans, 3); | |
376 | return 1; | |
377 | default: | |
378 | printf("Unrecognized SPI transaction type %#x\n", trans->type); | |
ba457562 | 379 | return -EPROTO; |
1853030e SG |
380 | } |
381 | } | |
382 | ||
383 | /* | |
384 | * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set | |
472d5460 | 385 | * below is true) or 0. In case the wait was for the bit(s) to set - write |
1853030e SG |
386 | * those bits back, which would cause resetting them. |
387 | * | |
388 | * Return the last read status value on success or -1 on failure. | |
389 | */ | |
ba457562 SG |
390 | static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask, |
391 | int wait_til_set) | |
1853030e SG |
392 | { |
393 | int timeout = 600000; /* This will result in 6s */ | |
394 | u16 status = 0; | |
395 | ||
396 | while (timeout--) { | |
ba457562 | 397 | status = ich_readw(ctlr, ctlr->status); |
1853030e | 398 | if (wait_til_set ^ ((status & bitmask) == 0)) { |
ba457562 SG |
399 | if (wait_til_set) { |
400 | ich_writew(ctlr, status & bitmask, | |
401 | ctlr->status); | |
402 | } | |
1853030e SG |
403 | return status; |
404 | } | |
405 | udelay(10); | |
406 | } | |
407 | ||
408 | printf("ICH SPI: SCIP timeout, read %x, expected %x\n", | |
409 | status, bitmask); | |
ba457562 | 410 | return -ETIMEDOUT; |
1853030e SG |
411 | } |
412 | ||
ba457562 SG |
413 | static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen, |
414 | const void *dout, void *din, unsigned long flags) | |
1853030e | 415 | { |
ba457562 | 416 | struct udevice *bus = dev_get_parent(dev); |
e1e332c8 | 417 | struct ich_spi_platdata *plat = dev_get_platdata(bus); |
ba457562 | 418 | struct ich_spi_priv *ctlr = dev_get_priv(bus); |
1853030e SG |
419 | uint16_t control; |
420 | int16_t opcode_index; | |
421 | int with_address; | |
422 | int status; | |
423 | int bytes = bitlen / 8; | |
ba457562 | 424 | struct spi_trans *trans = &ctlr->trans; |
1853030e SG |
425 | unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END); |
426 | int using_cmd = 0; | |
ba457562 | 427 | int ret; |
1853030e | 428 | |
5d4a757c | 429 | /* We don't support writing partial bytes */ |
1853030e SG |
430 | if (bitlen % 8) { |
431 | debug("ICH SPI: Accessing partial bytes not supported\n"); | |
ba457562 | 432 | return -EPROTONOSUPPORT; |
1853030e SG |
433 | } |
434 | ||
435 | /* An empty end transaction can be ignored */ | |
436 | if (type == SPI_XFER_END && !dout && !din) | |
437 | return 0; | |
438 | ||
439 | if (type & SPI_XFER_BEGIN) | |
440 | memset(trans, '\0', sizeof(*trans)); | |
441 | ||
442 | /* Dp we need to come back later to finish it? */ | |
443 | if (dout && type == SPI_XFER_BEGIN) { | |
444 | if (bytes > ICH_MAX_CMD_LEN) { | |
445 | debug("ICH SPI: Command length limit exceeded\n"); | |
ba457562 | 446 | return -ENOSPC; |
1853030e SG |
447 | } |
448 | memcpy(trans->cmd, dout, bytes); | |
449 | trans->cmd_len = bytes; | |
450 | debug("ICH SPI: Saved %d bytes\n", bytes); | |
451 | return 0; | |
452 | } | |
453 | ||
454 | /* | |
455 | * We process a 'middle' spi_xfer() call, which has no | |
456 | * SPI_XFER_BEGIN/END, as an independent transaction as if it had | |
457 | * an end. We therefore repeat the command. This is because ICH | |
458 | * seems to have no support for this, or because interest (in digging | |
459 | * out the details and creating a special case in the code) is low. | |
460 | */ | |
461 | if (trans->cmd_len) { | |
462 | trans->out = trans->cmd; | |
463 | trans->bytesout = trans->cmd_len; | |
464 | using_cmd = 1; | |
465 | debug("ICH SPI: Using %d bytes\n", trans->cmd_len); | |
466 | } else { | |
467 | trans->out = dout; | |
468 | trans->bytesout = dout ? bytes : 0; | |
469 | } | |
470 | ||
471 | trans->in = din; | |
472 | trans->bytesin = din ? bytes : 0; | |
473 | ||
474 | /* There has to always at least be an opcode. */ | |
475 | if (!trans->bytesout) { | |
476 | debug("ICH SPI: No opcode for transfer\n"); | |
ba457562 | 477 | return -EPROTO; |
1853030e SG |
478 | } |
479 | ||
ba457562 SG |
480 | ret = ich_status_poll(ctlr, SPIS_SCIP, 0); |
481 | if (ret < 0) | |
482 | return ret; | |
1853030e | 483 | |
e1e332c8 SG |
484 | if (plat->ich_version == 7) |
485 | ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); | |
486 | else | |
487 | ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status); | |
1853030e SG |
488 | |
489 | spi_setup_type(trans, using_cmd ? bytes : 0); | |
ba457562 | 490 | opcode_index = spi_setup_opcode(ctlr, trans); |
1853030e | 491 | if (opcode_index < 0) |
ba457562 | 492 | return -EINVAL; |
1853030e SG |
493 | with_address = spi_setup_offset(trans); |
494 | if (with_address < 0) | |
ba457562 | 495 | return -EINVAL; |
1853030e SG |
496 | |
497 | if (trans->opcode == SPI_OPCODE_WREN) { | |
498 | /* | |
499 | * Treat Write Enable as Atomic Pre-Op if possible | |
500 | * in order to prevent the Management Engine from | |
501 | * issuing a transaction between WREN and DATA. | |
502 | */ | |
ba457562 SG |
503 | if (!ctlr->ichspi_lock) |
504 | ich_writew(ctlr, trans->opcode, ctlr->preop); | |
1853030e SG |
505 | return 0; |
506 | } | |
507 | ||
ba457562 | 508 | if (ctlr->speed && ctlr->max_speed >= 33000000) { |
1853030e SG |
509 | int byte; |
510 | ||
ba457562 SG |
511 | byte = ich_readb(ctlr, ctlr->speed); |
512 | if (ctlr->cur_speed >= 33000000) | |
1853030e SG |
513 | byte |= SSFC_SCF_33MHZ; |
514 | else | |
515 | byte &= ~SSFC_SCF_33MHZ; | |
ba457562 | 516 | ich_writeb(ctlr, byte, ctlr->speed); |
1853030e SG |
517 | } |
518 | ||
519 | /* See if we have used up the command data */ | |
520 | if (using_cmd && dout && bytes) { | |
521 | trans->out = dout; | |
522 | trans->bytesout = bytes; | |
523 | debug("ICH SPI: Moving to data, %d bytes\n", bytes); | |
524 | } | |
525 | ||
526 | /* Preset control fields */ | |
ba457562 | 527 | control = ich_readw(ctlr, ctlr->control); |
1853030e SG |
528 | control &= ~SSFC_RESERVED; |
529 | control = SPIC_SCGO | ((opcode_index & 0x07) << 4); | |
530 | ||
531 | /* Issue atomic preop cycle if needed */ | |
ba457562 | 532 | if (ich_readw(ctlr, ctlr->preop)) |
1853030e SG |
533 | control |= SPIC_ACS; |
534 | ||
535 | if (!trans->bytesout && !trans->bytesin) { | |
536 | /* SPI addresses are 24 bit only */ | |
ba457562 SG |
537 | if (with_address) { |
538 | ich_writel(ctlr, trans->offset & 0x00FFFFFF, | |
539 | ctlr->addr); | |
540 | } | |
1853030e SG |
541 | /* |
542 | * This is a 'no data' command (like Write Enable), its | |
543 | * bitesout size was 1, decremented to zero while executing | |
544 | * spi_setup_opcode() above. Tell the chip to send the | |
545 | * command. | |
546 | */ | |
ba457562 | 547 | ich_writew(ctlr, control, ctlr->control); |
1853030e SG |
548 | |
549 | /* wait for the result */ | |
ba457562 SG |
550 | status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1); |
551 | if (status < 0) | |
552 | return status; | |
1853030e SG |
553 | |
554 | if (status & SPIS_FCERR) { | |
555 | debug("ICH SPI: Command transaction error\n"); | |
ba457562 | 556 | return -EIO; |
1853030e SG |
557 | } |
558 | ||
559 | return 0; | |
560 | } | |
561 | ||
562 | /* | |
563 | * Check if this is a write command atempting to transfer more bytes | |
564 | * than the controller can handle. Iterations for writes are not | |
565 | * supported here because each SPI write command needs to be preceded | |
566 | * and followed by other SPI commands, and this sequence is controlled | |
567 | * by the SPI chip driver. | |
568 | */ | |
ba457562 | 569 | if (trans->bytesout > ctlr->databytes) { |
1853030e | 570 | debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n"); |
ba457562 | 571 | return -EPROTO; |
1853030e SG |
572 | } |
573 | ||
574 | /* | |
575 | * Read or write up to databytes bytes at a time until everything has | |
576 | * been sent. | |
577 | */ | |
578 | while (trans->bytesout || trans->bytesin) { | |
579 | uint32_t data_length; | |
1853030e SG |
580 | |
581 | /* SPI addresses are 24 bit only */ | |
ba457562 | 582 | ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr); |
1853030e SG |
583 | |
584 | if (trans->bytesout) | |
ba457562 | 585 | data_length = min(trans->bytesout, ctlr->databytes); |
1853030e | 586 | else |
ba457562 | 587 | data_length = min(trans->bytesin, ctlr->databytes); |
1853030e SG |
588 | |
589 | /* Program data into FDATA0 to N */ | |
590 | if (trans->bytesout) { | |
ba457562 | 591 | write_reg(ctlr, trans->out, ctlr->data, data_length); |
1853030e SG |
592 | spi_use_out(trans, data_length); |
593 | if (with_address) | |
594 | trans->offset += data_length; | |
595 | } | |
596 | ||
597 | /* Add proper control fields' values */ | |
ba457562 | 598 | control &= ~((ctlr->databytes - 1) << 8); |
1853030e SG |
599 | control |= SPIC_DS; |
600 | control |= (data_length - 1) << 8; | |
601 | ||
602 | /* write it */ | |
ba457562 | 603 | ich_writew(ctlr, control, ctlr->control); |
1853030e SG |
604 | |
605 | /* Wait for Cycle Done Status or Flash Cycle Error. */ | |
ba457562 SG |
606 | status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1); |
607 | if (status < 0) | |
608 | return status; | |
1853030e SG |
609 | |
610 | if (status & SPIS_FCERR) { | |
5d4a757c | 611 | debug("ICH SPI: Data transaction error %x\n", status); |
ba457562 | 612 | return -EIO; |
1853030e SG |
613 | } |
614 | ||
615 | if (trans->bytesin) { | |
ba457562 | 616 | read_reg(ctlr, ctlr->data, trans->in, data_length); |
1853030e SG |
617 | spi_use_in(trans, data_length); |
618 | if (with_address) | |
619 | trans->offset += data_length; | |
620 | } | |
621 | } | |
622 | ||
623 | /* Clear atomic preop now that xfer is done */ | |
ba457562 | 624 | ich_writew(ctlr, 0, ctlr->preop); |
1853030e SG |
625 | |
626 | return 0; | |
627 | } | |
628 | ||
1853030e SG |
629 | /* |
630 | * This uses the SPI controller from the Intel Cougar Point and Panther Point | |
631 | * PCH to write-protect portions of the SPI flash until reboot. The changes | |
632 | * don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's | |
633 | * done elsewhere. | |
634 | */ | |
ba457562 SG |
635 | int spi_write_protect_region(struct udevice *dev, uint32_t lower_limit, |
636 | uint32_t length, int hint) | |
1853030e | 637 | { |
ba457562 SG |
638 | struct udevice *bus = dev->parent; |
639 | struct ich_spi_priv *ctlr = dev_get_priv(bus); | |
1853030e SG |
640 | uint32_t tmplong; |
641 | uint32_t upper_limit; | |
642 | ||
ba457562 | 643 | if (!ctlr->pr) { |
1853030e SG |
644 | printf("%s: operation not supported on this chipset\n", |
645 | __func__); | |
ba457562 | 646 | return -ENOSYS; |
1853030e SG |
647 | } |
648 | ||
649 | if (length == 0 || | |
650 | lower_limit > (0xFFFFFFFFUL - length) + 1 || | |
651 | hint < 0 || hint > 4) { | |
652 | printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__, | |
653 | lower_limit, length, hint); | |
ba457562 | 654 | return -EPERM; |
1853030e SG |
655 | } |
656 | ||
657 | upper_limit = lower_limit + length - 1; | |
658 | ||
659 | /* | |
660 | * Determine bits to write, as follows: | |
661 | * 31 Write-protection enable (includes erase operation) | |
662 | * 30:29 reserved | |
663 | * 28:16 Upper Limit (FLA address bits 24:12, with 11:0 == 0xfff) | |
664 | * 15 Read-protection enable | |
665 | * 14:13 reserved | |
666 | * 12:0 Lower Limit (FLA address bits 24:12, with 11:0 == 0x000) | |
667 | */ | |
668 | tmplong = 0x80000000 | | |
669 | ((upper_limit & 0x01fff000) << 4) | | |
670 | ((lower_limit & 0x01fff000) >> 12); | |
671 | ||
672 | printf("%s: writing 0x%08x to %p\n", __func__, tmplong, | |
ba457562 SG |
673 | &ctlr->pr[hint]); |
674 | ctlr->pr[hint] = tmplong; | |
675 | ||
676 | return 0; | |
677 | } | |
678 | ||
679 | static int ich_spi_probe(struct udevice *bus) | |
680 | { | |
681 | struct ich_spi_platdata *plat = dev_get_platdata(bus); | |
682 | struct ich_spi_priv *priv = dev_get_priv(bus); | |
683 | uint8_t bios_cntl; | |
684 | int ret; | |
685 | ||
686 | ret = ich_init_controller(plat, priv); | |
687 | if (ret) | |
688 | return ret; | |
689 | /* | |
690 | * Disable the BIOS write protect so write commands are allowed. On | |
691 | * v9, deassert SMM BIOS Write Protect Disable. | |
692 | */ | |
693 | if (plat->use_sbase) { | |
50787928 | 694 | bios_cntl = ich_readb(priv, priv->bcr); |
69fd4c38 | 695 | bios_cntl &= ~BIT(5); /* clear Enable InSMM_STS (EISS) */ |
ba457562 | 696 | bios_cntl |= 1; /* Write Protect Disable (WPD) */ |
50787928 | 697 | ich_writeb(priv, bios_cntl, priv->bcr); |
ba457562 SG |
698 | } else { |
699 | pci_read_config_byte(plat->dev, 0xdc, &bios_cntl); | |
700 | if (plat->ich_version == 9) | |
69fd4c38 | 701 | bios_cntl &= ~BIT(5); |
ba457562 SG |
702 | pci_write_config_byte(plat->dev, 0xdc, bios_cntl | 0x1); |
703 | } | |
704 | ||
705 | priv->cur_speed = priv->max_speed; | |
706 | ||
707 | return 0; | |
708 | } | |
709 | ||
710 | static int ich_spi_ofdata_to_platdata(struct udevice *bus) | |
711 | { | |
712 | struct ich_spi_platdata *plat = dev_get_platdata(bus); | |
713 | int ret; | |
714 | ||
715 | ret = ich_find_spi_controller(plat); | |
716 | if (ret) | |
717 | return ret; | |
1853030e SG |
718 | |
719 | return 0; | |
720 | } | |
ba457562 SG |
721 | |
722 | static int ich_spi_set_speed(struct udevice *bus, uint speed) | |
723 | { | |
724 | struct ich_spi_priv *priv = dev_get_priv(bus); | |
725 | ||
726 | priv->cur_speed = speed; | |
727 | ||
728 | return 0; | |
729 | } | |
730 | ||
731 | static int ich_spi_set_mode(struct udevice *bus, uint mode) | |
732 | { | |
733 | debug("%s: mode=%d\n", __func__, mode); | |
734 | ||
735 | return 0; | |
736 | } | |
737 | ||
738 | static int ich_spi_child_pre_probe(struct udevice *dev) | |
739 | { | |
740 | struct udevice *bus = dev_get_parent(dev); | |
741 | struct ich_spi_platdata *plat = dev_get_platdata(bus); | |
742 | struct ich_spi_priv *priv = dev_get_priv(bus); | |
bcbe3d15 | 743 | struct spi_slave *slave = dev_get_parent_priv(dev); |
ba457562 SG |
744 | |
745 | /* | |
746 | * Yes this controller can only write a small number of bytes at | |
747 | * once! The limit is typically 64 bytes. | |
748 | */ | |
749 | slave->max_write_size = priv->databytes; | |
750 | /* | |
751 | * ICH 7 SPI controller only supports array read command | |
752 | * and byte program command for SST flash | |
753 | */ | |
754 | if (plat->ich_version == 7) { | |
91292e0b | 755 | slave->mode_rx = SPI_RX_SLOW; |
cdf33938 | 756 | slave->mode = SPI_TX_BYTE; |
ba457562 SG |
757 | } |
758 | ||
759 | return 0; | |
760 | } | |
761 | ||
762 | static const struct dm_spi_ops ich_spi_ops = { | |
763 | .xfer = ich_spi_xfer, | |
764 | .set_speed = ich_spi_set_speed, | |
765 | .set_mode = ich_spi_set_mode, | |
766 | /* | |
767 | * cs_info is not needed, since we require all chip selects to be | |
768 | * in the device tree explicitly | |
769 | */ | |
770 | }; | |
771 | ||
772 | static const struct udevice_id ich_spi_ids[] = { | |
773 | { .compatible = "intel,ich-spi" }, | |
774 | { } | |
775 | }; | |
776 | ||
777 | U_BOOT_DRIVER(ich_spi) = { | |
778 | .name = "ich_spi", | |
779 | .id = UCLASS_SPI, | |
780 | .of_match = ich_spi_ids, | |
781 | .ops = &ich_spi_ops, | |
782 | .ofdata_to_platdata = ich_spi_ofdata_to_platdata, | |
783 | .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata), | |
784 | .priv_auto_alloc_size = sizeof(struct ich_spi_priv), | |
785 | .child_pre_probe = ich_spi_child_pre_probe, | |
786 | .probe = ich_spi_probe, | |
787 | }; |