blob: c3d77106e59ec65ecff0f5c2c8baa3dbf6b98b33 [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
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000091static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
92 unsigned int readcnt,
93 const unsigned char *writearr,
94 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +000095{
96 int count;
97 /* First byte is cmd which can not being sent through FIFO. */
98 unsigned char cmd = *writearr++;
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +000099 unsigned int readoffby1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000100 unsigned char readwrite;
Jason Wanga3f04be2008-11-28 21:36:51 +0000101
102 writecnt--;
103
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000104 msg_pspew("%s, cmd=%x, writecnt=%x, readcnt=%x\n",
105 __func__, cmd, writecnt, readcnt);
Jason Wanga3f04be2008-11-28 21:36:51 +0000106
107 if (readcnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000108 msg_pinfo("%s, SB600 SPI controller can not receive %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000109 "it is limited to 8 bytes\n", __func__, readcnt);
110 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000111 }
112
113 if (writecnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000114 msg_pinfo("%s, SB600 SPI controller can not send %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000115 "it is limited to 8 bytes\n", __func__, writecnt);
116 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000117 }
118
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000119 /* This is a workaround for a bug in SB600 and SB700. If we only send
120 * an opcode and no additional data/address, the SPI controller will
121 * read one byte too few from the chip. Basically, the last byte of
122 * the chip response is discarded and will not end up in the FIFO.
123 * It is unclear if the CS# line is set high too early as well.
124 */
125 readoffby1 = (writecnt) ? 0 : 1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000126 readwrite = (readcnt + readoffby1) << 4 | (writecnt);
127 mmio_writeb(readwrite, sb600_spibar + 1);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000128 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000129
130 /* Before we use the FIFO, reset it first. */
131 reset_internal_fifo_pointer();
132
133 /* Send the write byte to FIFO. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000134 msg_pspew("Writing: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000135 for (count = 0; count < writecnt; count++, writearr++) {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000136 msg_pspew("[%02x]", *writearr);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000137 mmio_writeb(*writearr, sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000138 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000139 msg_pspew("\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000140
141 /*
142 * We should send the data by sequence, which means we need to reset
143 * the FIFO pointer to the first byte we want to send.
144 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000145 if (reset_compare_internal_fifo_pointer(writecnt))
146 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000147
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000148 msg_pspew("Executing: \n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000149 execute_command();
150
151 /*
152 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000153 * received byte. Here we just reset the FIFO pointer and skip the
154 * writecnt.
155 * It would be possible to increase the FIFO pointer by one instead
156 * of reading and discarding one byte from the FIFO.
157 * The FIFO is implemented on top of an 8 byte ring buffer and the
158 * buffer is never cleared. For every byte that is shifted out after
159 * the opcode, the FIFO already stores the response from the chip.
160 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000161 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000162 if (reset_compare_internal_fifo_pointer(writecnt + readcnt))
163 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000164
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000165 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000166 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000167 for (count = 0; count < writecnt; count++) {
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000168 cmd = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000169 msg_pspew("[%02x]", cmd);
Jason Wanga3f04be2008-11-28 21:36:51 +0000170 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000171 msg_pspew("\n");
172 if (compare_internal_fifo_pointer(writecnt))
173 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000174
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000175 msg_pspew("Reading: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000176 for (count = 0; count < readcnt; count++, readarr++) {
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000177 *readarr = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000178 msg_pspew("[%02x]", *readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +0000179 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000180 msg_pspew("\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000181 if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
182 return SPI_PROGRAMMER_ERROR;
183
184 if (mmio_readb(sb600_spibar + 1) != readwrite) {
185 msg_perr("Unexpected change in SB600 read/write count!\n");
186 msg_perr("Something else is accessing the flash chip and "
187 "causes random corruption.\nPlease stop all "
188 "applications and drivers and IPMI which access the "
189 "flash chip.\n");
190 return SPI_PROGRAMMER_ERROR;
191 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000192
193 return 0;
194}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000195
Michael Karcherb9dbe482011-05-11 17:07:07 +0000196static const struct spi_programmer spi_programmer_sb600 = {
197 .type = SPI_CONTROLLER_SB600,
198 .max_data_read = 8,
199 .max_data_write = 5,
200 .command = sb600_spi_send_command,
201 .multicommand = default_spi_send_multicommand,
202 .read = default_spi_read,
203 .write_256 = default_spi_write_256,
204};
205
Michael Karcherb05b9e12010-07-22 18:04:19 +0000206int sb600_probe_spi(struct pci_dev *dev)
207{
208 struct pci_dev *smbus_dev;
209 uint32_t tmp;
210 uint8_t reg;
Mathias Krausea60faab2011-01-17 07:50:42 +0000211 static const char *const speed_names[4] = {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000212 "Reserved", "33", "22", "16.5"
213 };
214
Michael Karcherb05b9e12010-07-22 18:04:19 +0000215 /* Read SPI_BaseAddr */
216 tmp = pci_read_long(dev, 0xa0);
217 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
218 msg_pdbg("SPI base address is at 0x%x\n", tmp);
219
220 /* If the BAR has address 0, it is unlikely SPI is used. */
221 if (!tmp)
222 return 0;
223
224 /* Physical memory has to be mapped at page (4k) boundaries. */
225 sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000,
226 0x1000);
227 /* The low bits of the SPI base address are used as offset into
228 * the mapped page.
229 */
230 sb600_spibar += tmp & 0xfff;
231
232 tmp = pci_read_long(dev, 0xa0);
233 msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, "
234 "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1,
235 (tmp & 0x4) >> 2);
236 tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2;
237 msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp);
238
239 tmp = pci_read_byte(dev, 0xbb);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000240 /* FIXME: Set bit 3,6,7 if not already set.
241 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
242 * See doc 42413 AMD SB700/710/750 RPR.
243 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000244 msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n",
245 tmp & 0x1, (tmp & 0x20) >> 5);
246 tmp = mmio_readl(sb600_spibar);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000247 /* FIXME: If SpiAccessMacRomEn or SpiHostAccessRomEn are zero on
248 * SB700 or later, reads and writes will be corrupted. Abort in this
249 * case. Make sure to avoid this check on SB600.
250 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000251 msg_pdbg("SpiArbEnable=%i, SpiAccessMacRomEn=%i, "
252 "SpiHostAccessRomEn=%i, ArbWaitCount=%i, "
253 "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n",
254 (tmp >> 19) & 0x1, (tmp >> 22) & 0x1,
255 (tmp >> 23) & 0x1, (tmp >> 24) & 0x7,
256 (tmp >> 27) & 0x1, (tmp >> 28) & 0x1);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000257 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
258 msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000259
260 /* Look for the SMBus device. */
261 smbus_dev = pci_dev_find(0x1002, 0x4385);
262
263 if (!smbus_dev) {
Wang Qing Pei6e9e2ee2011-08-26 21:11:41 +0000264 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD Hudson */
265 if (!smbus_dev) {
266 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
267 return ERROR_NONFATAL;
268 }
Michael Karcherb05b9e12010-07-22 18:04:19 +0000269 }
270
271 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
272 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
273 reg = pci_read_byte(smbus_dev, 0xAB);
274 reg &= 0xC0;
275 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
276 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
277 if (reg != 0x00) {
278 msg_pdbg("Not enabling SPI");
279 return 0;
280 }
281 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
282 reg = pci_read_byte(smbus_dev, 0x83);
283 reg &= 0xC0;
284 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
285 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
286 /* SPI_HOLD is not used on all boards, filter it out. */
287 if ((reg & 0x80) != 0x00) {
288 msg_pdbg("Not enabling SPI");
289 return 0;
290 }
291 /* GPIO47/SPI_CLK status */
292 reg = pci_read_byte(smbus_dev, 0xA7);
293 reg &= 0x40;
294 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
295 if (reg != 0x00) {
296 msg_pdbg("Not enabling SPI");
297 return 0;
298 }
299
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000300 reg = pci_read_byte(dev, 0x40);
301 msg_pdbg("SB700 IMC is %sactive.\n", (reg & (1 << 7)) ? "" : "not ");
302 if (reg & (1 << 7)) {
303 /* If we touch any region used by the IMC, the IMC and the SPI
304 * interface will lock up, and the only way to recover is a
305 * hard reset, but that is a bad choice for a half-erased or
306 * half-written flash chip.
307 * There appears to be an undocumented register which can freeze
308 * or disable the IMC, but for now we want to play it safe.
309 */
310 msg_perr("The SB700 IMC is active and may interfere with SPI "
311 "commands. Disabling write.\n");
312 /* FIXME: Should we only disable SPI writes, or will the lockup
313 * affect LPC/FWH chips as well?
314 */
315 programmer_may_write = 0;
316 }
317
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000318 /* Bring the FIFO to a clean state. */
319 reset_internal_fifo_pointer();
320
Michael Karcherb9dbe482011-05-11 17:07:07 +0000321 register_spi_programmer(&spi_programmer_sb600);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000322 return 0;
323}
324
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000325#endif