blob: fe60aa9df1f284b29f2ba55cbf395cf1712e11f1 [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"
Patrick Georgi32508eb2012-07-20 20:35:14 +000028#include "hwaccess.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 Hailfinger2c7ba8c2009-06-23 00:47:26 +000046static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000047{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000048 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000049
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000050 /* FIXME: This loop makes no sense at all. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000051 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +000052 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +000053}
54
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000055static int compare_internal_fifo_pointer(uint8_t want)
56{
57 uint8_t tmp;
58
59 tmp = mmio_readb(sb600_spibar + 0xd) & 0x07;
60 want &= 0x7;
61 if (want != tmp) {
62 msg_perr("SB600 FIFO pointer corruption! Pointer is %d, wanted "
63 "%d\n", tmp, want);
64 msg_perr("Something else is accessing the flash chip and "
65 "causes random corruption.\nPlease stop all "
66 "applications and drivers and IPMI which access the "
67 "flash chip.\n");
68 return 1;
69 } else {
70 msg_pspew("SB600 FIFO pointer is %d, wanted %d\n", tmp, want);
71 return 0;
72 }
73}
74
75static int reset_compare_internal_fifo_pointer(uint8_t want)
76{
77 int ret;
78
79 ret = compare_internal_fifo_pointer(want);
80 reset_internal_fifo_pointer();
81 return ret;
82}
83
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000084static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000085{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000086 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000087
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000088 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +000089 ;
90}
91
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000092static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
93 unsigned int readcnt,
94 const unsigned char *writearr,
95 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +000096{
97 int count;
98 /* First byte is cmd which can not being sent through FIFO. */
99 unsigned char cmd = *writearr++;
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000100 unsigned int readoffby1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000101 unsigned char readwrite;
Jason Wanga3f04be2008-11-28 21:36:51 +0000102
103 writecnt--;
104
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000105 msg_pspew("%s, cmd=%x, writecnt=%x, readcnt=%x\n",
106 __func__, cmd, writecnt, readcnt);
Jason Wanga3f04be2008-11-28 21:36:51 +0000107
108 if (readcnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000109 msg_pinfo("%s, SB600 SPI controller can not receive %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000110 "it is limited to 8 bytes\n", __func__, readcnt);
111 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000112 }
113
114 if (writecnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000115 msg_pinfo("%s, SB600 SPI controller can not send %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000116 "it is limited to 8 bytes\n", __func__, writecnt);
117 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000118 }
119
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000120 /* This is a workaround for a bug in SB600 and SB700. If we only send
121 * an opcode and no additional data/address, the SPI controller will
122 * read one byte too few from the chip. Basically, the last byte of
123 * the chip response is discarded and will not end up in the FIFO.
124 * It is unclear if the CS# line is set high too early as well.
125 */
126 readoffby1 = (writecnt) ? 0 : 1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000127 readwrite = (readcnt + readoffby1) << 4 | (writecnt);
128 mmio_writeb(readwrite, sb600_spibar + 1);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000129 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000130
131 /* Before we use the FIFO, reset it first. */
132 reset_internal_fifo_pointer();
133
134 /* Send the write byte to FIFO. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000135 msg_pspew("Writing: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000136 for (count = 0; count < writecnt; count++, writearr++) {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000137 msg_pspew("[%02x]", *writearr);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000138 mmio_writeb(*writearr, sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000139 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000140 msg_pspew("\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000141
142 /*
143 * We should send the data by sequence, which means we need to reset
144 * the FIFO pointer to the first byte we want to send.
145 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000146 if (reset_compare_internal_fifo_pointer(writecnt))
147 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000148
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000149 msg_pspew("Executing: \n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000150 execute_command();
151
152 /*
153 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000154 * received byte. Here we just reset the FIFO pointer and skip the
155 * writecnt.
156 * It would be possible to increase the FIFO pointer by one instead
157 * of reading and discarding one byte from the FIFO.
158 * The FIFO is implemented on top of an 8 byte ring buffer and the
159 * buffer is never cleared. For every byte that is shifted out after
160 * the opcode, the FIFO already stores the response from the chip.
161 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000162 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000163 if (reset_compare_internal_fifo_pointer(writecnt + readcnt))
164 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000165
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000166 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000167 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000168 for (count = 0; count < writecnt; count++) {
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000169 cmd = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000170 msg_pspew("[%02x]", cmd);
Jason Wanga3f04be2008-11-28 21:36:51 +0000171 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000172 msg_pspew("\n");
173 if (compare_internal_fifo_pointer(writecnt))
174 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000175
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000176 msg_pspew("Reading: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000177 for (count = 0; count < readcnt; count++, readarr++) {
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000178 *readarr = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000179 msg_pspew("[%02x]", *readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +0000180 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000181 msg_pspew("\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000182 if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
183 return SPI_PROGRAMMER_ERROR;
184
185 if (mmio_readb(sb600_spibar + 1) != readwrite) {
186 msg_perr("Unexpected change in SB600 read/write count!\n");
187 msg_perr("Something else is accessing the flash chip and "
188 "causes random corruption.\nPlease stop all "
189 "applications and drivers and IPMI which access the "
190 "flash chip.\n");
191 return SPI_PROGRAMMER_ERROR;
192 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000193
194 return 0;
195}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000196
Michael Karcherb9dbe482011-05-11 17:07:07 +0000197static const struct spi_programmer spi_programmer_sb600 = {
198 .type = SPI_CONTROLLER_SB600,
199 .max_data_read = 8,
200 .max_data_write = 5,
201 .command = sb600_spi_send_command,
202 .multicommand = default_spi_send_multicommand,
203 .read = default_spi_read,
204 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000205 .write_aai = default_spi_write_aai,
Michael Karcherb9dbe482011-05-11 17:07:07 +0000206};
207
Michael Karcherb05b9e12010-07-22 18:04:19 +0000208int sb600_probe_spi(struct pci_dev *dev)
209{
210 struct pci_dev *smbus_dev;
211 uint32_t tmp;
212 uint8_t reg;
Mathias Krausea60faab2011-01-17 07:50:42 +0000213 static const char *const speed_names[4] = {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000214 "Reserved", "33", "22", "16.5"
215 };
216
Michael Karcherb05b9e12010-07-22 18:04:19 +0000217 /* Read SPI_BaseAddr */
218 tmp = pci_read_long(dev, 0xa0);
219 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
220 msg_pdbg("SPI base address is at 0x%x\n", tmp);
221
222 /* If the BAR has address 0, it is unlikely SPI is used. */
223 if (!tmp)
224 return 0;
225
226 /* Physical memory has to be mapped at page (4k) boundaries. */
227 sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000,
228 0x1000);
229 /* The low bits of the SPI base address are used as offset into
230 * the mapped page.
231 */
232 sb600_spibar += tmp & 0xfff;
233
234 tmp = pci_read_long(dev, 0xa0);
235 msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, "
236 "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1,
237 (tmp & 0x4) >> 2);
238 tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2;
239 msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp);
240
241 tmp = pci_read_byte(dev, 0xbb);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000242 /* FIXME: Set bit 3,6,7 if not already set.
243 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
244 * See doc 42413 AMD SB700/710/750 RPR.
245 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000246 msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n",
247 tmp & 0x1, (tmp & 0x20) >> 5);
248 tmp = mmio_readl(sb600_spibar);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000249 /* FIXME: If SpiAccessMacRomEn or SpiHostAccessRomEn are zero on
250 * SB700 or later, reads and writes will be corrupted. Abort in this
251 * case. Make sure to avoid this check on SB600.
252 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000253 msg_pdbg("SpiArbEnable=%i, SpiAccessMacRomEn=%i, "
254 "SpiHostAccessRomEn=%i, ArbWaitCount=%i, "
255 "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n",
256 (tmp >> 19) & 0x1, (tmp >> 22) & 0x1,
257 (tmp >> 23) & 0x1, (tmp >> 24) & 0x7,
258 (tmp >> 27) & 0x1, (tmp >> 28) & 0x1);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000259 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
260 msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000261
262 /* Look for the SMBus device. */
263 smbus_dev = pci_dev_find(0x1002, 0x4385);
264
265 if (!smbus_dev) {
Wang Qing Pei6e9e2ee2011-08-26 21:11:41 +0000266 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD Hudson */
267 if (!smbus_dev) {
268 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
269 return ERROR_NONFATAL;
270 }
Michael Karcherb05b9e12010-07-22 18:04:19 +0000271 }
272
273 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
274 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
275 reg = pci_read_byte(smbus_dev, 0xAB);
276 reg &= 0xC0;
277 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
278 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
279 if (reg != 0x00) {
280 msg_pdbg("Not enabling SPI");
281 return 0;
282 }
283 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
284 reg = pci_read_byte(smbus_dev, 0x83);
285 reg &= 0xC0;
286 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
287 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
288 /* SPI_HOLD is not used on all boards, filter it out. */
289 if ((reg & 0x80) != 0x00) {
290 msg_pdbg("Not enabling SPI");
291 return 0;
292 }
293 /* GPIO47/SPI_CLK status */
294 reg = pci_read_byte(smbus_dev, 0xA7);
295 reg &= 0x40;
296 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
297 if (reg != 0x00) {
298 msg_pdbg("Not enabling SPI");
299 return 0;
300 }
301
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000302 reg = pci_read_byte(dev, 0x40);
303 msg_pdbg("SB700 IMC is %sactive.\n", (reg & (1 << 7)) ? "" : "not ");
304 if (reg & (1 << 7)) {
305 /* If we touch any region used by the IMC, the IMC and the SPI
306 * interface will lock up, and the only way to recover is a
307 * hard reset, but that is a bad choice for a half-erased or
308 * half-written flash chip.
309 * There appears to be an undocumented register which can freeze
310 * or disable the IMC, but for now we want to play it safe.
311 */
312 msg_perr("The SB700 IMC is active and may interfere with SPI "
313 "commands. Disabling write.\n");
314 /* FIXME: Should we only disable SPI writes, or will the lockup
315 * affect LPC/FWH chips as well?
316 */
317 programmer_may_write = 0;
318 }
319
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000320 /* Bring the FIFO to a clean state. */
321 reset_internal_fifo_pointer();
322
Michael Karcherb9dbe482011-05-11 17:07:07 +0000323 register_spi_programmer(&spi_programmer_sb600);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000324 return 0;
325}
326
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000327#endif