blob: 5ad578216ad838d3f5a95113b9fb0ec996f79068 [file] [log] [blame]
Jason Wanga3f04be2008-11-28 21:36:51 +00001/*
2 * This file is part of the flashrom project.
3 *
Jason Wang13f98ce2008-11-29 15:07:15 +00004 * Copyright (C) 2008 Wang Qingpei <Qingpei.Wang@amd.com>
5 * Copyright (C) 2008 Joe Bao <Zheng.Bao@amd.com>
Uwe Hermann97e8f222009-04-13 21:35:49 +00006 * Copyright (C) 2008 Advanced Micro Devices, Inc.
Carl-Daniel Hailfinger5824fbf2010-05-21 23:09:42 +00007 * Copyright (C) 2009, 2010 Carl-Daniel Hailfinger
Jason Wanga3f04be2008-11-28 21:36:51 +00008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000024#if defined(__i386__) || defined(__x86_64__)
25
Jason Wanga3f04be2008-11-28 21:36:51 +000026#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000027#include "programmer.h"
Jason Wanga3f04be2008-11-28 21:36:51 +000028#include "spi.h"
29
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000030/* This struct is unused, but helps visualize the SB600 SPI BAR layout.
31 *struct sb600_spi_controller {
32 * unsigned int spi_cntrl0; / * 00h * /
33 * unsigned int restrictedcmd1; / * 04h * /
34 * unsigned int restrictedcmd2; / * 08h * /
35 * unsigned int spi_cntrl1; / * 0ch * /
36 * unsigned int spi_cmdvalue0; / * 10h * /
37 * unsigned int spi_cmdvalue1; / * 14h * /
38 * unsigned int spi_cmdvalue2; / * 18h * /
39 * unsigned int spi_fakeid; / * 1Ch * /
40 *};
41 */
Jason Wanga3f04be2008-11-28 21:36:51 +000042
Michael Karcherb05b9e12010-07-22 18:04:19 +000043static uint8_t *sb600_spibar = NULL;
Jason Wanga3f04be2008-11-28 21:36:51 +000044
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000045static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000046{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000047 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000048
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000049 /* FIXME: This loop makes no sense at all. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000050 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +000051 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +000052}
53
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000054static int compare_internal_fifo_pointer(uint8_t want)
55{
56 uint8_t tmp;
57
58 tmp = mmio_readb(sb600_spibar + 0xd) & 0x07;
59 want &= 0x7;
60 if (want != tmp) {
61 msg_perr("SB600 FIFO pointer corruption! Pointer is %d, wanted "
62 "%d\n", tmp, want);
63 msg_perr("Something else is accessing the flash chip and "
64 "causes random corruption.\nPlease stop all "
65 "applications and drivers and IPMI which access the "
66 "flash chip.\n");
67 return 1;
68 } else {
69 msg_pspew("SB600 FIFO pointer is %d, wanted %d\n", tmp, want);
70 return 0;
71 }
72}
73
74static int reset_compare_internal_fifo_pointer(uint8_t want)
75{
76 int ret;
77
78 ret = compare_internal_fifo_pointer(want);
79 reset_internal_fifo_pointer();
80 return ret;
81}
82
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000083static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000084{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000085 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000086
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000087 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +000088 ;
89}
90
Michael Karcherb9dbe482011-05-11 17:07:07 +000091static int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
Jason Wanga3f04be2008-11-28 21:36:51 +000092 const unsigned char *writearr, unsigned char *readarr)
93{
94 int count;
95 /* First byte is cmd which can not being sent through FIFO. */
96 unsigned char cmd = *writearr++;
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +000097 unsigned int readoffby1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000098 unsigned char readwrite;
Jason Wanga3f04be2008-11-28 21:36:51 +000099
100 writecnt--;
101
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000102 msg_pspew("%s, cmd=%x, writecnt=%x, readcnt=%x\n",
103 __func__, cmd, writecnt, readcnt);
Jason Wanga3f04be2008-11-28 21:36:51 +0000104
105 if (readcnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000106 msg_pinfo("%s, SB600 SPI controller can not receive %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000107 "it is limited to 8 bytes\n", __func__, readcnt);
108 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000109 }
110
111 if (writecnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000112 msg_pinfo("%s, SB600 SPI controller can not send %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000113 "it is limited to 8 bytes\n", __func__, writecnt);
114 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000115 }
116
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000117 /* This is a workaround for a bug in SB600 and SB700. If we only send
118 * an opcode and no additional data/address, the SPI controller will
119 * read one byte too few from the chip. Basically, the last byte of
120 * the chip response is discarded and will not end up in the FIFO.
121 * It is unclear if the CS# line is set high too early as well.
122 */
123 readoffby1 = (writecnt) ? 0 : 1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000124 readwrite = (readcnt + readoffby1) << 4 | (writecnt);
125 mmio_writeb(readwrite, sb600_spibar + 1);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000126 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000127
128 /* Before we use the FIFO, reset it first. */
129 reset_internal_fifo_pointer();
130
131 /* Send the write byte to FIFO. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000132 msg_pspew("Writing: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000133 for (count = 0; count < writecnt; count++, writearr++) {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000134 msg_pspew("[%02x]", *writearr);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000135 mmio_writeb(*writearr, sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000136 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000137 msg_pspew("\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000138
139 /*
140 * We should send the data by sequence, which means we need to reset
141 * the FIFO pointer to the first byte we want to send.
142 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000143 if (reset_compare_internal_fifo_pointer(writecnt))
144 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000145
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000146 msg_pspew("Executing: \n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000147 execute_command();
148
149 /*
150 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000151 * received byte. Here we just reset the FIFO pointer and skip the
152 * writecnt.
153 * It would be possible to increase the FIFO pointer by one instead
154 * of reading and discarding one byte from the FIFO.
155 * The FIFO is implemented on top of an 8 byte ring buffer and the
156 * buffer is never cleared. For every byte that is shifted out after
157 * the opcode, the FIFO already stores the response from the chip.
158 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000159 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000160 if (reset_compare_internal_fifo_pointer(writecnt + readcnt))
161 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000162
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000163 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000164 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000165 for (count = 0; count < writecnt; count++) {
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000166 cmd = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000167 msg_pspew("[%02x]", cmd);
Jason Wanga3f04be2008-11-28 21:36:51 +0000168 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000169 msg_pspew("\n");
170 if (compare_internal_fifo_pointer(writecnt))
171 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000172
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000173 msg_pspew("Reading: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000174 for (count = 0; count < readcnt; count++, readarr++) {
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000175 *readarr = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000176 msg_pspew("[%02x]", *readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +0000177 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000178 msg_pspew("\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000179 if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
180 return SPI_PROGRAMMER_ERROR;
181
182 if (mmio_readb(sb600_spibar + 1) != readwrite) {
183 msg_perr("Unexpected change in SB600 read/write count!\n");
184 msg_perr("Something else is accessing the flash chip and "
185 "causes random corruption.\nPlease stop all "
186 "applications and drivers and IPMI which access the "
187 "flash chip.\n");
188 return SPI_PROGRAMMER_ERROR;
189 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000190
191 return 0;
192}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000193
Michael Karcherb9dbe482011-05-11 17:07:07 +0000194static const struct spi_programmer spi_programmer_sb600 = {
195 .type = SPI_CONTROLLER_SB600,
196 .max_data_read = 8,
197 .max_data_write = 5,
198 .command = sb600_spi_send_command,
199 .multicommand = default_spi_send_multicommand,
200 .read = default_spi_read,
201 .write_256 = default_spi_write_256,
202};
203
Michael Karcherb05b9e12010-07-22 18:04:19 +0000204int sb600_probe_spi(struct pci_dev *dev)
205{
206 struct pci_dev *smbus_dev;
207 uint32_t tmp;
208 uint8_t reg;
Mathias Krausea60faab2011-01-17 07:50:42 +0000209 static const char *const speed_names[4] = {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000210 "Reserved", "33", "22", "16.5"
211 };
212
Michael Karcherb05b9e12010-07-22 18:04:19 +0000213 /* Read SPI_BaseAddr */
214 tmp = pci_read_long(dev, 0xa0);
215 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
216 msg_pdbg("SPI base address is at 0x%x\n", tmp);
217
218 /* If the BAR has address 0, it is unlikely SPI is used. */
219 if (!tmp)
220 return 0;
221
222 /* Physical memory has to be mapped at page (4k) boundaries. */
223 sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000,
224 0x1000);
225 /* The low bits of the SPI base address are used as offset into
226 * the mapped page.
227 */
228 sb600_spibar += tmp & 0xfff;
229
230 tmp = pci_read_long(dev, 0xa0);
231 msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, "
232 "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1,
233 (tmp & 0x4) >> 2);
234 tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2;
235 msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp);
236
237 tmp = pci_read_byte(dev, 0xbb);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000238 /* FIXME: Set bit 3,6,7 if not already set.
239 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
240 * See doc 42413 AMD SB700/710/750 RPR.
241 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000242 msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n",
243 tmp & 0x1, (tmp & 0x20) >> 5);
244 tmp = mmio_readl(sb600_spibar);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000245 /* FIXME: If SpiAccessMacRomEn or SpiHostAccessRomEn are zero on
246 * SB700 or later, reads and writes will be corrupted. Abort in this
247 * case. Make sure to avoid this check on SB600.
248 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000249 msg_pdbg("SpiArbEnable=%i, SpiAccessMacRomEn=%i, "
250 "SpiHostAccessRomEn=%i, ArbWaitCount=%i, "
251 "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n",
252 (tmp >> 19) & 0x1, (tmp >> 22) & 0x1,
253 (tmp >> 23) & 0x1, (tmp >> 24) & 0x7,
254 (tmp >> 27) & 0x1, (tmp >> 28) & 0x1);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000255 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
256 msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000257
258 /* Look for the SMBus device. */
259 smbus_dev = pci_dev_find(0x1002, 0x4385);
260
261 if (!smbus_dev) {
262 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
263 return ERROR_NONFATAL;
264 }
265
266 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
267 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
268 reg = pci_read_byte(smbus_dev, 0xAB);
269 reg &= 0xC0;
270 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
271 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
272 if (reg != 0x00) {
273 msg_pdbg("Not enabling SPI");
274 return 0;
275 }
276 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
277 reg = pci_read_byte(smbus_dev, 0x83);
278 reg &= 0xC0;
279 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
280 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
281 /* SPI_HOLD is not used on all boards, filter it out. */
282 if ((reg & 0x80) != 0x00) {
283 msg_pdbg("Not enabling SPI");
284 return 0;
285 }
286 /* GPIO47/SPI_CLK status */
287 reg = pci_read_byte(smbus_dev, 0xA7);
288 reg &= 0x40;
289 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
290 if (reg != 0x00) {
291 msg_pdbg("Not enabling SPI");
292 return 0;
293 }
294
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000295 reg = pci_read_byte(dev, 0x40);
296 msg_pdbg("SB700 IMC is %sactive.\n", (reg & (1 << 7)) ? "" : "not ");
297 if (reg & (1 << 7)) {
298 /* If we touch any region used by the IMC, the IMC and the SPI
299 * interface will lock up, and the only way to recover is a
300 * hard reset, but that is a bad choice for a half-erased or
301 * half-written flash chip.
302 * There appears to be an undocumented register which can freeze
303 * or disable the IMC, but for now we want to play it safe.
304 */
305 msg_perr("The SB700 IMC is active and may interfere with SPI "
306 "commands. Disabling write.\n");
307 /* FIXME: Should we only disable SPI writes, or will the lockup
308 * affect LPC/FWH chips as well?
309 */
310 programmer_may_write = 0;
311 }
312
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000313 /* Bring the FIFO to a clean state. */
314 reset_internal_fifo_pointer();
315
Michael Karcherb9dbe482011-05-11 17:07:07 +0000316 register_spi_programmer(&spi_programmer_sb600);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000317 return 0;
318}
319
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000320#endif