blob: 845cf58864b72fd4bf6ca0216deb546b40ca5a3d [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"
Sean Nelson14ba6682010-02-26 05:48:29 +000027#include "chipdrivers.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000028#include "programmer.h"
Jason Wanga3f04be2008-11-28 21:36:51 +000029#include "spi.h"
30
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000031/* This struct is unused, but helps visualize the SB600 SPI BAR layout.
32 *struct sb600_spi_controller {
33 * unsigned int spi_cntrl0; / * 00h * /
34 * unsigned int restrictedcmd1; / * 04h * /
35 * unsigned int restrictedcmd2; / * 08h * /
36 * unsigned int spi_cntrl1; / * 0ch * /
37 * unsigned int spi_cmdvalue0; / * 10h * /
38 * unsigned int spi_cmdvalue1; / * 14h * /
39 * unsigned int spi_cmdvalue2; / * 18h * /
40 * unsigned int spi_fakeid; / * 1Ch * /
41 *};
42 */
Jason Wanga3f04be2008-11-28 21:36:51 +000043
Michael Karcherb05b9e12010-07-22 18:04:19 +000044static uint8_t *sb600_spibar = NULL;
Jason Wanga3f04be2008-11-28 21:36:51 +000045
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +000046int sb600_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len)
Jason Wanga3f04be2008-11-28 21:36:51 +000047{
Carl-Daniel Hailfinger38a059d2009-06-13 12:04:03 +000048 /* Maximum read length is 8 bytes. */
Carl-Daniel Hailfingercbf563c2009-06-16 08:55:44 +000049 return spi_read_chunked(flash, buf, start, len, 8);
Jason Wanga3f04be2008-11-28 21:36:51 +000050}
51
Carl-Daniel Hailfinger9a795d82010-07-14 16:19:05 +000052int sb600_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len)
Jason Wanga3f04be2008-11-28 21:36:51 +000053{
Carl-Daniel Hailfinger9a795d82010-07-14 16:19:05 +000054 return spi_write_chunked(flash, buf, start, len, 5);
Jason Wanga3f04be2008-11-28 21:36:51 +000055}
56
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000057static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000058{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000059 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000060
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000061 /* FIXME: This loop makes no sense at all. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000062 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +000063 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +000064}
65
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000066static int compare_internal_fifo_pointer(uint8_t want)
67{
68 uint8_t tmp;
69
70 tmp = mmio_readb(sb600_spibar + 0xd) & 0x07;
71 want &= 0x7;
72 if (want != tmp) {
73 msg_perr("SB600 FIFO pointer corruption! Pointer is %d, wanted "
74 "%d\n", tmp, want);
75 msg_perr("Something else is accessing the flash chip and "
76 "causes random corruption.\nPlease stop all "
77 "applications and drivers and IPMI which access the "
78 "flash chip.\n");
79 return 1;
80 } else {
81 msg_pspew("SB600 FIFO pointer is %d, wanted %d\n", tmp, want);
82 return 0;
83 }
84}
85
86static int reset_compare_internal_fifo_pointer(uint8_t want)
87{
88 int ret;
89
90 ret = compare_internal_fifo_pointer(want);
91 reset_internal_fifo_pointer();
92 return ret;
93}
94
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000095static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000096{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000097 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000098
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000099 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +0000100 ;
101}
102
Carl-Daniel Hailfingerd0478292009-07-10 21:08:55 +0000103int sb600_spi_send_command(unsigned int writecnt, unsigned int readcnt,
Jason Wanga3f04be2008-11-28 21:36:51 +0000104 const unsigned char *writearr, unsigned char *readarr)
105{
106 int count;
107 /* First byte is cmd which can not being sent through FIFO. */
108 unsigned char cmd = *writearr++;
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000109 unsigned int readoffby1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000110 unsigned char readwrite;
Jason Wanga3f04be2008-11-28 21:36:51 +0000111
112 writecnt--;
113
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000114 msg_pspew("%s, cmd=%x, writecnt=%x, readcnt=%x\n",
115 __func__, cmd, writecnt, readcnt);
Jason Wanga3f04be2008-11-28 21:36:51 +0000116
117 if (readcnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000118 msg_pinfo("%s, SB600 SPI controller can not receive %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000119 "it is limited to 8 bytes\n", __func__, readcnt);
120 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000121 }
122
123 if (writecnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000124 msg_pinfo("%s, SB600 SPI controller can not send %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000125 "it is limited to 8 bytes\n", __func__, writecnt);
126 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000127 }
128
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000129 /* This is a workaround for a bug in SB600 and SB700. If we only send
130 * an opcode and no additional data/address, the SPI controller will
131 * read one byte too few from the chip. Basically, the last byte of
132 * the chip response is discarded and will not end up in the FIFO.
133 * It is unclear if the CS# line is set high too early as well.
134 */
135 readoffby1 = (writecnt) ? 0 : 1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000136 readwrite = (readcnt + readoffby1) << 4 | (writecnt);
137 mmio_writeb(readwrite, sb600_spibar + 1);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000138 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000139
140 /* Before we use the FIFO, reset it first. */
141 reset_internal_fifo_pointer();
142
143 /* Send the write byte to FIFO. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000144 msg_pspew("Writing: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000145 for (count = 0; count < writecnt; count++, writearr++) {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000146 msg_pspew("[%02x]", *writearr);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000147 mmio_writeb(*writearr, sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000148 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000149 msg_pspew("\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000150
151 /*
152 * We should send the data by sequence, which means we need to reset
153 * the FIFO pointer to the first byte we want to send.
154 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000155 if (reset_compare_internal_fifo_pointer(writecnt))
156 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000157
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000158 msg_pspew("Executing: \n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000159 execute_command();
160
161 /*
162 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000163 * received byte. Here we just reset the FIFO pointer and skip the
164 * writecnt.
165 * It would be possible to increase the FIFO pointer by one instead
166 * of reading and discarding one byte from the FIFO.
167 * The FIFO is implemented on top of an 8 byte ring buffer and the
168 * buffer is never cleared. For every byte that is shifted out after
169 * the opcode, the FIFO already stores the response from the chip.
170 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000171 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000172 if (reset_compare_internal_fifo_pointer(writecnt + readcnt))
173 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000174
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000175 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000176 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000177 for (count = 0; count < writecnt; count++) {
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000178 cmd = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000179 msg_pspew("[%02x]", cmd);
Jason Wanga3f04be2008-11-28 21:36:51 +0000180 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000181 msg_pspew("\n");
182 if (compare_internal_fifo_pointer(writecnt))
183 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000184
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000185 msg_pspew("Reading: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000186 for (count = 0; count < readcnt; count++, readarr++) {
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000187 *readarr = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000188 msg_pspew("[%02x]", *readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +0000189 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000190 msg_pspew("\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000191 if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
192 return SPI_PROGRAMMER_ERROR;
193
194 if (mmio_readb(sb600_spibar + 1) != readwrite) {
195 msg_perr("Unexpected change in SB600 read/write count!\n");
196 msg_perr("Something else is accessing the flash chip and "
197 "causes random corruption.\nPlease stop all "
198 "applications and drivers and IPMI which access the "
199 "flash chip.\n");
200 return SPI_PROGRAMMER_ERROR;
201 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000202
203 return 0;
204}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000205
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) {
264 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
265 return ERROR_NONFATAL;
266 }
267
268 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
269 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
270 reg = pci_read_byte(smbus_dev, 0xAB);
271 reg &= 0xC0;
272 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
273 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
274 if (reg != 0x00) {
275 msg_pdbg("Not enabling SPI");
276 return 0;
277 }
278 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
279 reg = pci_read_byte(smbus_dev, 0x83);
280 reg &= 0xC0;
281 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
282 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
283 /* SPI_HOLD is not used on all boards, filter it out. */
284 if ((reg & 0x80) != 0x00) {
285 msg_pdbg("Not enabling SPI");
286 return 0;
287 }
288 /* GPIO47/SPI_CLK status */
289 reg = pci_read_byte(smbus_dev, 0xA7);
290 reg &= 0x40;
291 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
292 if (reg != 0x00) {
293 msg_pdbg("Not enabling SPI");
294 return 0;
295 }
296
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000297 reg = pci_read_byte(dev, 0x40);
298 msg_pdbg("SB700 IMC is %sactive.\n", (reg & (1 << 7)) ? "" : "not ");
299 if (reg & (1 << 7)) {
300 /* If we touch any region used by the IMC, the IMC and the SPI
301 * interface will lock up, and the only way to recover is a
302 * hard reset, but that is a bad choice for a half-erased or
303 * half-written flash chip.
304 * There appears to be an undocumented register which can freeze
305 * or disable the IMC, but for now we want to play it safe.
306 */
307 msg_perr("The SB700 IMC is active and may interfere with SPI "
308 "commands. Disabling write.\n");
309 /* FIXME: Should we only disable SPI writes, or will the lockup
310 * affect LPC/FWH chips as well?
311 */
312 programmer_may_write = 0;
313 }
314
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000315 /* Bring the FIFO to a clean state. */
316 reset_internal_fifo_pointer();
317
Michael Karcherb05b9e12010-07-22 18:04:19 +0000318 buses_supported |= CHIP_BUSTYPE_SPI;
319 spi_controller = SPI_CONTROLLER_SB600;
320 return 0;
321}
322
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000323#endif