blob: e76c04aea912f5d952bc6f5ac520a92da49b4a94 [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
Rudolf Marek70e14592013-07-25 22:58:56 +000026#include <string.h>
27#include <stdlib.h>
Jason Wanga3f04be2008-11-28 21:36:51 +000028#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000029#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000030#include "hwaccess.h"
Jason Wanga3f04be2008-11-28 21:36:51 +000031#include "spi.h"
32
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000033/* This struct is unused, but helps visualize the SB600 SPI BAR layout.
34 *struct sb600_spi_controller {
35 * unsigned int spi_cntrl0; / * 00h * /
36 * unsigned int restrictedcmd1; / * 04h * /
37 * unsigned int restrictedcmd2; / * 08h * /
38 * unsigned int spi_cntrl1; / * 0ch * /
39 * unsigned int spi_cmdvalue0; / * 10h * /
40 * unsigned int spi_cmdvalue1; / * 14h * /
41 * unsigned int spi_cmdvalue2; / * 18h * /
42 * unsigned int spi_fakeid; / * 1Ch * /
43 *};
44 */
Jason Wanga3f04be2008-11-28 21:36:51 +000045
Michael Karcherb05b9e12010-07-22 18:04:19 +000046static uint8_t *sb600_spibar = NULL;
Jason Wanga3f04be2008-11-28 21:36:51 +000047
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000048static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000049{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000050 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000051
Rudolf Marek70e14592013-07-25 22:58:56 +000052 /* FIXME: This loop needs a timeout and a clearer message. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000053 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +000054 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +000055}
56
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000057static int compare_internal_fifo_pointer(uint8_t want)
58{
59 uint8_t tmp;
60
61 tmp = mmio_readb(sb600_spibar + 0xd) & 0x07;
62 want &= 0x7;
63 if (want != tmp) {
Rudolf Marek70e14592013-07-25 22:58:56 +000064 msg_perr("FIFO pointer corruption! Pointer is %d, wanted %d\n", tmp, want);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +000065 msg_perr("Something else is accessing the flash chip and "
66 "causes random corruption.\nPlease stop all "
67 "applications and drivers and IPMI which access the "
68 "flash chip.\n");
69 return 1;
70 } else {
71 msg_pspew("SB600 FIFO pointer is %d, wanted %d\n", tmp, want);
72 return 0;
73 }
74}
75
76static int reset_compare_internal_fifo_pointer(uint8_t want)
77{
78 int ret;
79
80 ret = compare_internal_fifo_pointer(want);
81 reset_internal_fifo_pointer();
82 return ret;
83}
84
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000085static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +000086{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000087 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +000088
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +000089 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +000090 ;
91}
92
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +000093static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
94 unsigned int readcnt,
95 const unsigned char *writearr,
96 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +000097{
98 int count;
99 /* First byte is cmd which can not being sent through FIFO. */
100 unsigned char cmd = *writearr++;
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000101 unsigned int readoffby1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000102 unsigned char readwrite;
Jason Wanga3f04be2008-11-28 21:36:51 +0000103
104 writecnt--;
105
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000106 msg_pspew("%s, cmd=%x, writecnt=%x, readcnt=%x\n",
107 __func__, cmd, writecnt, readcnt);
Jason Wanga3f04be2008-11-28 21:36:51 +0000108
109 if (readcnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000110 msg_pinfo("%s, SB600 SPI controller can not receive %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000111 "it is limited to 8 bytes\n", __func__, readcnt);
112 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000113 }
114
115 if (writecnt > 8) {
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000116 msg_pinfo("%s, SB600 SPI controller can not send %d bytes, "
Carl-Daniel Hailfinger142e30f2009-07-14 10:26:56 +0000117 "it is limited to 8 bytes\n", __func__, writecnt);
118 return SPI_INVALID_LENGTH;
Jason Wanga3f04be2008-11-28 21:36:51 +0000119 }
120
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000121 /* This is a workaround for a bug in SB600 and SB700. If we only send
122 * an opcode and no additional data/address, the SPI controller will
123 * read one byte too few from the chip. Basically, the last byte of
124 * the chip response is discarded and will not end up in the FIFO.
125 * It is unclear if the CS# line is set high too early as well.
126 */
127 readoffby1 = (writecnt) ? 0 : 1;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000128 readwrite = (readcnt + readoffby1) << 4 | (writecnt);
129 mmio_writeb(readwrite, sb600_spibar + 1);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000130 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000131
132 /* Before we use the FIFO, reset it first. */
133 reset_internal_fifo_pointer();
134
135 /* Send the write byte to FIFO. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000136 msg_pspew("Writing: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000137 for (count = 0; count < writecnt; count++, writearr++) {
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000138 msg_pspew("[%02x]", *writearr);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000139 mmio_writeb(*writearr, sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000140 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000141 msg_pspew("\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000142
143 /*
144 * We should send the data by sequence, which means we need to reset
145 * the FIFO pointer to the first byte we want to send.
146 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000147 if (reset_compare_internal_fifo_pointer(writecnt))
148 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000149
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000150 msg_pspew("Executing: \n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000151 execute_command();
152
153 /*
154 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000155 * received byte. Here we just reset the FIFO pointer and skip the
156 * writecnt.
157 * It would be possible to increase the FIFO pointer by one instead
158 * of reading and discarding one byte from the FIFO.
159 * The FIFO is implemented on top of an 8 byte ring buffer and the
160 * buffer is never cleared. For every byte that is shifted out after
161 * the opcode, the FIFO already stores the response from the chip.
162 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000163 */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000164 if (reset_compare_internal_fifo_pointer(writecnt + readcnt))
165 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000166
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000167 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000168 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000169 for (count = 0; count < writecnt; count++) {
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000170 cmd = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000171 msg_pspew("[%02x]", cmd);
Jason Wanga3f04be2008-11-28 21:36:51 +0000172 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000173 msg_pspew("\n");
174 if (compare_internal_fifo_pointer(writecnt))
175 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000176
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000177 msg_pspew("Reading: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000178 for (count = 0; count < readcnt; count++, readarr++) {
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000179 *readarr = mmio_readb(sb600_spibar + 0xC);
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000180 msg_pspew("[%02x]", *readarr);
Jason Wanga3f04be2008-11-28 21:36:51 +0000181 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000182 msg_pspew("\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000183 if (reset_compare_internal_fifo_pointer(readcnt + writecnt))
184 return SPI_PROGRAMMER_ERROR;
185
186 if (mmio_readb(sb600_spibar + 1) != readwrite) {
187 msg_perr("Unexpected change in SB600 read/write count!\n");
188 msg_perr("Something else is accessing the flash chip and "
189 "causes random corruption.\nPlease stop all "
190 "applications and drivers and IPMI which access the "
191 "flash chip.\n");
192 return SPI_PROGRAMMER_ERROR;
193 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000194
195 return 0;
196}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000197
Rudolf Marek70e14592013-07-25 22:58:56 +0000198static int sb600_handle_imc(struct pci_dev *dev, bool amd_imc_force)
199{
200 /* Handle IMC everywhere but sb600 which does not have one. */
201 if (dev->device_id == 0x438d)
202 return 0;
203
204 /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
205 * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50: Misc_Reg: 80h-87h;
206 * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
207 uint8_t reg = pci_read_byte(dev, 0x40);
208 if ((reg & (1 << 7)) == 0) {
209 msg_pdbg("IMC is not active.\n");
210 return 0;
211 }
212
213 if (!amd_imc_force)
214 programmer_may_write = 0;
215 msg_pinfo("Writes have been disabled for safety reasons because the IMC is active\n"
216 "and it could interfere with accessing flash memory. Flashrom will try\n"
217 "to disable it temporarily but even then this might not be safe:\n"
218 "when it is reenabled and after a reboot it expects to find working code\n"
219 "in the flash and it is unpredictable what happens if there is none.\n"
220 "\n"
221 "To be safe make sure that there is a working IMC firmware at the right\n"
222 "location in the image you intend to write and do not attempt to erase.\n"
223 "\n"
224 "You can enforce write support with the amd_imc_force programmer option.\n");
225 if (amd_imc_force)
226 msg_pinfo("Continuing with write support because the user forced us to!\n");
227
228 return amd_imc_shutdown(dev);
229}
230
Michael Karcherb9dbe482011-05-11 17:07:07 +0000231static const struct spi_programmer spi_programmer_sb600 = {
232 .type = SPI_CONTROLLER_SB600,
233 .max_data_read = 8,
234 .max_data_write = 5,
235 .command = sb600_spi_send_command,
236 .multicommand = default_spi_send_multicommand,
237 .read = default_spi_read,
238 .write_256 = default_spi_write_256,
Nico Huber7bca1262012-06-15 22:28:12 +0000239 .write_aai = default_spi_write_aai,
Michael Karcherb9dbe482011-05-11 17:07:07 +0000240};
241
Michael Karcherb05b9e12010-07-22 18:04:19 +0000242int sb600_probe_spi(struct pci_dev *dev)
243{
244 struct pci_dev *smbus_dev;
245 uint32_t tmp;
246 uint8_t reg;
Rudolf Marek70e14592013-07-25 22:58:56 +0000247 bool amd_imc_force = false;
Mathias Krausea60faab2011-01-17 07:50:42 +0000248 static const char *const speed_names[4] = {
Stefan Tauner0466c812013-06-16 10:30:08 +0000249 "66/reserved", "33", "22", "16.5"
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000250 };
251
Rudolf Marek70e14592013-07-25 22:58:56 +0000252 char *arg = extract_programmer_param("amd_imc_force");
253 if (arg && !strcmp(arg, "yes")) {
254 amd_imc_force = true;
255 msg_pspew("amd_imc_force enabled.\n");
256 } else if (arg && !strlen(arg)) {
257 msg_perr("Missing argument for amd_imc_force.\n");
258 free(arg);
259 return ERROR_FATAL;
260 } else if (arg) {
261 msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
262 free(arg);
263 return ERROR_FATAL;
264 }
265 free(arg);
266
Michael Karcherb05b9e12010-07-22 18:04:19 +0000267 /* Read SPI_BaseAddr */
268 tmp = pci_read_long(dev, 0xa0);
269 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
270 msg_pdbg("SPI base address is at 0x%x\n", tmp);
271
272 /* If the BAR has address 0, it is unlikely SPI is used. */
273 if (!tmp)
274 return 0;
275
276 /* Physical memory has to be mapped at page (4k) boundaries. */
277 sb600_spibar = physmap("SB600 SPI registers", tmp & 0xfffff000,
278 0x1000);
279 /* The low bits of the SPI base address are used as offset into
280 * the mapped page.
281 */
282 sb600_spibar += tmp & 0xfff;
283
284 tmp = pci_read_long(dev, 0xa0);
285 msg_pdbg("AltSpiCSEnable=%i, SpiRomEnable=%i, "
286 "AbortEnable=%i\n", tmp & 0x1, (tmp & 0x2) >> 1,
287 (tmp & 0x4) >> 2);
288 tmp = (pci_read_byte(dev, 0xba) & 0x4) >> 2;
289 msg_pdbg("PrefetchEnSPIFromIMC=%i, ", tmp);
290
291 tmp = pci_read_byte(dev, 0xbb);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000292 /* FIXME: Set bit 3,6,7 if not already set.
293 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
294 * See doc 42413 AMD SB700/710/750 RPR.
295 */
Michael Karcherb05b9e12010-07-22 18:04:19 +0000296 msg_pdbg("PrefetchEnSPIFromHost=%i, SpiOpEnInLpcMode=%i\n",
297 tmp & 0x1, (tmp & 0x20) >> 5);
298 tmp = mmio_readl(sb600_spibar);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000299 /* FIXME: If SpiAccessMacRomEn or SpiHostAccessRomEn are zero on
300 * SB700 or later, reads and writes will be corrupted. Abort in this
301 * case. Make sure to avoid this check on SB600.
302 */
Stefan Tauner0466c812013-06-16 10:30:08 +0000303 msg_pdbg("(0x%08" PRIx32 ") fastReadEnable=%u, SpiArbEnable=%i, SpiAccessMacRomEn=%i, "
Michael Karcherb05b9e12010-07-22 18:04:19 +0000304 "SpiHostAccessRomEn=%i, ArbWaitCount=%i, "
305 "SpiBridgeDisable=%i, DropOneClkOnRd=%i\n",
Stefan Tauner0466c812013-06-16 10:30:08 +0000306 tmp, (tmp >> 18) & 0x1,
Michael Karcherb05b9e12010-07-22 18:04:19 +0000307 (tmp >> 19) & 0x1, (tmp >> 22) & 0x1,
308 (tmp >> 23) & 0x1, (tmp >> 24) & 0x7,
309 (tmp >> 27) & 0x1, (tmp >> 28) & 0x1);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000310 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
311 msg_pdbg("NormSpeed is %s MHz\n", speed_names[tmp]);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000312
313 /* Look for the SMBus device. */
314 smbus_dev = pci_dev_find(0x1002, 0x4385);
315
316 if (!smbus_dev) {
Wang Qing Pei6e9e2ee2011-08-26 21:11:41 +0000317 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD Hudson */
318 if (!smbus_dev) {
319 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
320 return ERROR_NONFATAL;
321 }
Michael Karcherb05b9e12010-07-22 18:04:19 +0000322 }
323
324 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
325 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
326 reg = pci_read_byte(smbus_dev, 0xAB);
327 reg &= 0xC0;
328 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
329 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
330 if (reg != 0x00) {
331 msg_pdbg("Not enabling SPI");
332 return 0;
333 }
334 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
335 reg = pci_read_byte(smbus_dev, 0x83);
336 reg &= 0xC0;
337 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
338 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
339 /* SPI_HOLD is not used on all boards, filter it out. */
340 if ((reg & 0x80) != 0x00) {
341 msg_pdbg("Not enabling SPI");
342 return 0;
343 }
344 /* GPIO47/SPI_CLK status */
345 reg = pci_read_byte(smbus_dev, 0xA7);
346 reg &= 0x40;
347 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
348 if (reg != 0x00) {
349 msg_pdbg("Not enabling SPI");
350 return 0;
351 }
352
Rudolf Marek70e14592013-07-25 22:58:56 +0000353 if (sb600_handle_imc(dev, amd_imc_force) != 0)
354 return ERROR_FATAL;
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000355
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000356 /* Bring the FIFO to a clean state. */
357 reset_internal_fifo_pointer();
358
Michael Karcherb9dbe482011-05-11 17:07:07 +0000359 register_spi_programmer(&spi_programmer_sb600);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000360 return 0;
361}
362
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000363#endif