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