blob: 9d70c00c3955e48e2a8aa4b6f572628567595d3c [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.
Wei Hu31402ee2014-05-16 21:39:33 +00007 * Copyright (C) 2009, 2010, 2013 Carl-Daniel Hailfinger
8 * Copyright (C) 2013 Stefan Tauner
Jason Wanga3f04be2008-11-28 21:36:51 +00009 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000025#if defined(__i386__) || defined(__x86_64__)
26
Rudolf Marek70e14592013-07-25 22:58:56 +000027#include <string.h>
28#include <stdlib.h>
Jason Wanga3f04be2008-11-28 21:36:51 +000029#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000030#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000031#include "hwaccess.h"
Jason Wanga3f04be2008-11-28 21:36:51 +000032#include "spi.h"
33
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000034/* This struct is unused, but helps visualize the SB600 SPI BAR layout.
35 *struct sb600_spi_controller {
36 * unsigned int spi_cntrl0; / * 00h * /
37 * unsigned int restrictedcmd1; / * 04h * /
38 * unsigned int restrictedcmd2; / * 08h * /
39 * unsigned int spi_cntrl1; / * 0ch * /
40 * unsigned int spi_cmdvalue0; / * 10h * /
41 * unsigned int spi_cmdvalue1; / * 14h * /
42 * unsigned int spi_cmdvalue2; / * 18h * /
43 * unsigned int spi_fakeid; / * 1Ch * /
44 *};
45 */
Jason Wanga3f04be2008-11-28 21:36:51 +000046
Michael Karcherb05b9e12010-07-22 18:04:19 +000047static uint8_t *sb600_spibar = NULL;
Stefan Tauner463dd692013-08-08 12:00:19 +000048enum amd_chipset {
49 CHIPSET_AMD_UNKNOWN,
50 CHIPSET_SB6XX,
51 CHIPSET_SB7XX, /* SP5100 too */
52 CHIPSET_SB89XX, /* Hudson-1 too */
53 CHIPSET_HUDSON234,
54 CHIPSET_YANGTZE,
55};
56static enum amd_chipset amd_gen = CHIPSET_AMD_UNKNOWN;
57
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000058#define FIFO_SIZE_OLD 8
Wei Hu31402ee2014-05-16 21:39:33 +000059#define FIFO_SIZE_YANGTZE 71
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000060
61static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
62 const unsigned char *writearr, unsigned char *readarr);
Wei Hu31402ee2014-05-16 21:39:33 +000063static int spi100_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
64 const unsigned char *writearr, unsigned char *readarr);
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000065
66static struct spi_programmer spi_programmer_sb600 = {
67 .type = SPI_CONTROLLER_SB600,
68 .max_data_read = FIFO_SIZE_OLD,
69 .max_data_write = FIFO_SIZE_OLD - 3,
70 .command = sb600_spi_send_command,
71 .multicommand = default_spi_send_multicommand,
72 .read = default_spi_read,
73 .write_256 = default_spi_write_256,
74 .write_aai = default_spi_write_aai,
75};
76
Wei Hu31402ee2014-05-16 21:39:33 +000077static struct spi_programmer spi_programmer_yangtze = {
78 .type = SPI_CONTROLLER_YANGTZE,
79 .max_data_read = FIFO_SIZE_YANGTZE - 3, /* Apparently the big SPI 100 buffer is not a ring buffer. */
80 .max_data_write = FIFO_SIZE_YANGTZE - 3,
81 .command = spi100_spi_send_command,
82 .multicommand = default_spi_send_multicommand,
83 .read = default_spi_read,
84 .write_256 = default_spi_write_256,
85 .write_aai = default_spi_write_aai,
86};
87
Stefan Tauner463dd692013-08-08 12:00:19 +000088static void determine_generation(struct pci_dev *dev)
89{
90 amd_gen = CHIPSET_AMD_UNKNOWN;
Stefan Tauner4442b812013-09-12 15:48:35 +000091 msg_pdbg2("Trying to determine the generation of the SPI interface... ");
92 if (dev->device_id == 0x438d) {
93 amd_gen = CHIPSET_SB6XX;
94 msg_pdbg("SB6xx detected.\n");
95 } else if (dev->device_id == 0x439d) {
96 struct pci_dev *smbus_dev = pci_dev_find(0x1002, 0x4385);
97 if (smbus_dev == NULL)
98 return;
99 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
100 if (rev >= 0x39 && rev <= 0x3D) {
101 amd_gen = CHIPSET_SB7XX;
102 msg_pdbg("SB7xx/SP5100 detected.\n");
103 } else if (rev >= 0x40 && rev <= 0x42) {
104 amd_gen = CHIPSET_SB89XX;
105 msg_pdbg("SB8xx/SB9xx/Hudson-1 detected.\n");
106 } else {
107 msg_pwarn("SB device found but SMBus revision 0x%02x does not match known values.\n"
108 "Assuming SB8xx/SB9xx/Hudson-1. Please send a log to flashrom@flashrom.org\n",
109 rev);
110 amd_gen = CHIPSET_SB89XX;
111 }
112 } else if (dev->device_id == 0x780e) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000113 /* The PCI ID of the LPC bridge doesn't change between Hudson-2/3/4 and Yangtze (Kabini/Temash)
114 * although they use different SPI interfaces. */
115#ifdef USE_YANGTZE_HEURISTICS
116 /* This heuristic accesses the SPI interface MMIO BAR at locations beyond those supported by
117 * Hudson in the hope of getting 0xff readback on older chipsets and non-0xff readback on
118 * Yangtze (and newer, compatible chipsets). */
119 int i;
120 msg_pdbg("Checking for AMD Yangtze (Kabini/Temash) or later... ");
121 for (i = 0x20; i <= 0x4f; i++) {
122 if (mmio_readb(sb600_spibar + i) != 0xff) {
123 amd_gen = CHIPSET_YANGTZE;
124 msg_pdbg("found.\n");
125 return;
126 }
127 }
128 msg_pdbg("not found. Assuming Hudson.\n");
129 amd_gen = CHIPSET_HUDSON234;
130#else
131 struct pci_dev *smbus_dev = pci_dev_find(0x1022, 0x780B);
132 if (smbus_dev == NULL) {
133 msg_pdbg("No SMBus device with ID 1022:780B found.\n");
134 return;
135 }
136 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
137 if (rev >= 0x11 && rev <= 0x15) {
138 amd_gen = CHIPSET_HUDSON234;
139 msg_pdbg("Hudson-2/3/4 detected.\n");
140 } else if (rev >= 0x39 && rev <= 0x3A) {
141 amd_gen = CHIPSET_YANGTZE;
142 msg_pdbg("Yangtze detected.\n");
143 } else {
144 msg_pwarn("FCH device found but SMBus revision 0x%02x does not match known values.\n"
145 "Please report this to flashrom@flashrom.org and include this log and\n"
146 "the output of lspci -nnvx, thanks!.\n", rev);
147 }
148#endif
Stefan Tauner4442b812013-09-12 15:48:35 +0000149 } else
150 msg_pwarn("%s: Unknown LPC device %" PRIx16 ":%" PRIx16 ".\n"
151 "Please report this to flashrom@flashrom.org and include this log and\n"
152 "the output of lspci -nnvx, thanks!\n",
153 __func__, dev->vendor_id, dev->device_id);
Stefan Tauner463dd692013-08-08 12:00:19 +0000154}
Jason Wanga3f04be2008-11-28 21:36:51 +0000155
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000156static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000157{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000158 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +0000159
Rudolf Marek70e14592013-07-25 22:58:56 +0000160 /* FIXME: This loop needs a timeout and a clearer message. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000161 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000162 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000163}
164
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000165static int compare_internal_fifo_pointer(uint8_t want)
166{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000167 uint8_t have = mmio_readb(sb600_spibar + 0xd) & 0x07;
168 want %= FIFO_SIZE_OLD;
169 if (have != want) {
170 msg_perr("AMD SPI FIFO pointer corruption! Pointer is %d, wanted %d\n", have, want);
171 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
172 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000173 return 1;
174 } else {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000175 msg_pspew("AMD SPI FIFO pointer is %d, wanted %d\n", have, want);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000176 return 0;
177 }
178}
179
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000180/* Check the number of bytes to be transmitted and extract opcode. */
181static int check_readwritecnt(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt)
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000182{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000183 unsigned int maxwritecnt = flash->pgm->spi.max_data_write + 3;
184 if (writecnt > maxwritecnt) {
185 msg_pinfo("%s: SPI controller can not send %d bytes, it is limited to %d bytes\n",
186 __func__, writecnt, maxwritecnt);
187 return SPI_INVALID_LENGTH;
188 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000189
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000190 unsigned int maxreadcnt = flash->pgm->spi.max_data_read + 3;
191 if (readcnt > maxreadcnt) {
192 msg_pinfo("%s: SPI controller can not receive %d bytes, it is limited to %d bytes\n",
193 __func__, readcnt, maxreadcnt);
194 return SPI_INVALID_LENGTH;
195 }
196 return 0;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000197}
198
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000199static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000200{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000201 msg_pspew("Executing... ");
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000202 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000203 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +0000204 ;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000205 msg_pspew("done\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000206}
207
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000208static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
209 unsigned int readcnt,
210 const unsigned char *writearr,
211 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +0000212{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000213 /* First byte is cmd which can not be sent through the FIFO. */
Jason Wanga3f04be2008-11-28 21:36:51 +0000214 unsigned char cmd = *writearr++;
Jason Wanga3f04be2008-11-28 21:36:51 +0000215 writecnt--;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000216 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
217 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000218
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000219 int ret = check_readwritecnt(flash, writecnt, readcnt);
220 if (ret != 0)
221 return ret;
Jason Wanga3f04be2008-11-28 21:36:51 +0000222
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000223 /* This is a workaround for a bug in SPI controller. If we only send
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000224 * an opcode and no additional data/address, the SPI controller will
225 * read one byte too few from the chip. Basically, the last byte of
226 * the chip response is discarded and will not end up in the FIFO.
227 * It is unclear if the CS# line is set high too early as well.
228 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000229 unsigned int readoffby1 = (writecnt > 0) ? 0 : 1;
230 uint8_t readwrite = (readcnt + readoffby1) << 4 | (writecnt);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000231 mmio_writeb(readwrite, sb600_spibar + 1);
Jason Wanga3f04be2008-11-28 21:36:51 +0000232
Jason Wanga3f04be2008-11-28 21:36:51 +0000233 reset_internal_fifo_pointer();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000234 msg_pspew("Filling FIFO: ");
235 int count;
236 for (count = 0; count < writecnt; count++) {
237 msg_pspew("[%02x]", writearr[count]);
238 mmio_writeb(writearr[count], sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000239 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000240 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000241 if (compare_internal_fifo_pointer(writecnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000242 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000243
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000244 /*
245 * We should send the data in sequence, which means we need to reset
246 * the FIFO pointer to the first byte we want to send.
247 */
248 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000249 execute_command();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000250 if (compare_internal_fifo_pointer(writecnt + readcnt))
251 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000252
253 /*
254 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000255 * received byte. Here we just reset the FIFO pointer and skip the
256 * writecnt.
257 * It would be possible to increase the FIFO pointer by one instead
258 * of reading and discarding one byte from the FIFO.
259 * The FIFO is implemented on top of an 8 byte ring buffer and the
260 * buffer is never cleared. For every byte that is shifted out after
261 * the opcode, the FIFO already stores the response from the chip.
262 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000263 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000264 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000265
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000266 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000267 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000268 for (count = 0; count < writecnt; count++) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000269 msg_pspew("[%02x]", mmio_readb(sb600_spibar + 0xC));
Jason Wanga3f04be2008-11-28 21:36:51 +0000270 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000271 msg_pspew("\n");
272 if (compare_internal_fifo_pointer(writecnt))
273 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000274
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000275 msg_pspew("Reading FIFO: ");
276 for (count = 0; count < readcnt; count++) {
277 readarr[count] = mmio_readb(sb600_spibar + 0xC);
278 msg_pspew("[%02x]", readarr[count]);
Jason Wanga3f04be2008-11-28 21:36:51 +0000279 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000280 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000281 if (compare_internal_fifo_pointer(writecnt+readcnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000282 return SPI_PROGRAMMER_ERROR;
283
284 if (mmio_readb(sb600_spibar + 1) != readwrite) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000285 msg_perr("Unexpected change in AMD SPI read/write count!\n");
286 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
287 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000288 return SPI_PROGRAMMER_ERROR;
289 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000290
291 return 0;
292}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000293
Wei Hu31402ee2014-05-16 21:39:33 +0000294static int spi100_spi_send_command(struct flashctx *flash, unsigned int writecnt,
295 unsigned int readcnt,
296 const unsigned char *writearr,
297 unsigned char *readarr)
298{
299 /* First byte is cmd which can not be sent through the buffer. */
300 unsigned char cmd = *writearr++;
301 writecnt--;
302 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
303 mmio_writeb(cmd, sb600_spibar + 0);
304
305 int ret = check_readwritecnt(flash, writecnt, readcnt);
306 if (ret != 0)
307 return ret;
308
309 /* Use the extended TxByteCount and RxByteCount registers. */
310 mmio_writeb(writecnt, sb600_spibar + 0x48);
311 mmio_writeb(readcnt, sb600_spibar + 0x4b);
312
313 msg_pspew("Filling buffer: ");
314 int count;
315 for (count = 0; count < writecnt; count++) {
316 msg_pspew("[%02x]", writearr[count]);
317 mmio_writeb(writearr[count], sb600_spibar + 0x80 + count);
318 }
319 msg_pspew("\n");
320
321 execute_command();
322
323 msg_pspew("Reading buffer: ");
324 for (count = 0; count < readcnt; count++) {
325 readarr[count] = mmio_readb(sb600_spibar + 0x80 + (writecnt + count) % FIFO_SIZE_YANGTZE);
326 msg_pspew("[%02x]", readarr[count]);
327 }
328 msg_pspew("\n");
329
330 return 0;
331}
332
Stefan Taunera6a0d202013-09-15 14:17:39 +0000333struct spispeed {
334 const char *const name;
335 const uint8_t speed;
336};
337
338static const struct spispeed spispeeds[] = {
339 { "66 MHz", 0x00 },
340 { "33 MHz", 0x01 },
341 { "22 MHz", 0x02 },
342 { "16.5 MHz", 0x03 },
Wei Hu31402ee2014-05-16 21:39:33 +0000343 { "100 MHz", 0x04 },
344 { "Reserved", 0x05 },
345 { "Reserved", 0x06 },
346 { "800 kHz", 0x07 },
Stefan Taunera6a0d202013-09-15 14:17:39 +0000347};
348
349static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed)
350{
351 bool success = false;
352 uint8_t speed = spispeed->speed;
353
354 msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed);
Wei Hu31402ee2014-05-16 21:39:33 +0000355 if (amd_gen >= CHIPSET_YANGTZE) {
356 rmmio_writew((speed << 12) | (speed << 8) | (speed << 4) | speed, sb600_spibar + 0x22);
357 uint16_t tmp = mmio_readw(sb600_spibar + 0x22);
358 success = (((tmp >> 12) & 0xf) == speed && ((tmp >> 8) & 0xf) == speed &&
359 ((tmp >> 4) & 0xf) == speed && ((tmp >> 0) & 0xf) == speed);
360 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000361 rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd);
362 success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3));
363 }
364
365 if (!success) {
366 msg_perr("Setting SPI clock failed.\n");
367 return 1;
368 }
369 return 0;
370}
371
Wei Hu31402ee2014-05-16 21:39:33 +0000372static int set_mode(struct pci_dev *dev, uint8_t read_mode)
373{
374 uint32_t tmp = mmio_readl(sb600_spibar + 0x00);
375 tmp &= ~(0x6 << 28 | 0x1 << 18); /* Clear mode bits */
376 tmp |= ((read_mode & 0x6) << 28) | ((read_mode & 0x1) << 18);
377 rmmio_writel(tmp, sb600_spibar + 0x00);
378 if (tmp != mmio_readl(sb600_spibar + 0x00))
379 return 1;
380 return 0;
381}
382
Stefan Taunera6a0d202013-09-15 14:17:39 +0000383static int handle_speed(struct pci_dev *dev)
384{
385 uint32_t tmp;
386 int8_t spispeed_idx = 3; /* Default to 16.5 MHz */
387
Stefan Tauner21071b02014-05-16 21:39:48 +0000388 char *spispeed = extract_programmer_param("spispeed");
389 if (spispeed != NULL) {
390 if (strcasecmp(spispeed, "reserved") != 0) {
391 int i;
392 for (i = 0; i < ARRAY_SIZE(spispeeds); i++) {
393 if (strcasecmp(spispeeds[i].name, spispeed) == 0) {
394 spispeed_idx = i;
395 break;
396 }
397 }
398 /* Only Yangtze supports the second half of indices; no 66 MHz before SB8xx. */
399 if ((amd_gen < CHIPSET_YANGTZE && spispeed_idx > 3) ||
400 (amd_gen < CHIPSET_SB89XX && spispeed_idx == 0))
401 spispeed_idx = -1;
402 }
403 if (spispeed_idx < 0) {
404 msg_perr("Error: Invalid spispeed value: '%s'.\n", spispeed);
405 free(spispeed);
406 return 1;
407 }
408 free(spispeed);
409 }
410
Stefan Taunera6a0d202013-09-15 14:17:39 +0000411 /* See the chipset support matrix for SPI Base_Addr below for an explanation of the symbols used.
412 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson234 yangtze
413 * 18 rsvd <- fastReadEnable ? <- ? SpiReadMode[0]
414 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]
415 */
Wei Hu31402ee2014-05-16 21:39:33 +0000416 if (amd_gen >= CHIPSET_YANGTZE) {
417 tmp = mmio_readb(sb600_spibar + 0x20);
418 msg_pdbg("UseSpi100 is %sabled\n", (tmp & 0x1) ? "en" : "dis");
419 if ((tmp & 0x1) == 0) {
420 rmmio_writeb(tmp | 0x1, sb600_spibar + 0x20);
421 tmp = mmio_readb(sb600_spibar + 0x20) & 0x1;
422 if (tmp == 0) {
423 msg_perr("Enabling Spi100 failed.\n");
424 return 1;
425 }
426 msg_pdbg("Enabling Spi100 succeeded.\n");
427 }
428
429 static const char *spireadmodes[] = {
430 "Normal (up to 33 MHz)", /* 0 */
431 "Reserved", /* 1 */
432 "Dual IO (1-1-2)", /* 2 */
433 "Quad IO (1-1-4)", /* 3 */
434 "Dual IO (1-2-2)", /* 4 */
435 "Quad IO (1-4-4)", /* 5 */
436 "Normal (up to 66 MHz)", /* 6 */
437 "Fast Read", /* 7 */
438 };
439 tmp = mmio_readl(sb600_spibar + 0x00);
440 uint8_t read_mode = ((tmp >> 28) & 0x6) | ((tmp >> 18) & 0x1);
441 msg_pdbg("SpiReadMode=%s (%i)\n", spireadmodes[read_mode], read_mode);
442 if (read_mode != 6) {
443 read_mode = 6; /* Default to "Normal (up to 66 MHz)" */
444 if (set_mode(dev, read_mode) != 0) {
445 msg_perr("Setting read mode to \"%s\" failed.\n", spireadmodes[read_mode]);
446 return 1;
447 }
448 msg_pdbg("Setting read mode to \"%s\" succeeded.\n", spireadmodes[read_mode]);
449 }
450
451 tmp = mmio_readw(sb600_spibar + 0x22); /* SPI 100 Speed Config */
452 msg_pdbg("NormSpeedNew is %s\n", spispeeds[(tmp >> 12) & 0xf].name);
453 msg_pdbg("FastSpeedNew is %s\n", spispeeds[(tmp >> 8) & 0xf].name);
454 msg_pdbg("AltSpeedNew is %s\n", spispeeds[(tmp >> 4) & 0xf].name);
455 msg_pdbg("TpmSpeedNew is %s\n", spispeeds[(tmp >> 0) & 0xf].name);
456 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000457 if (amd_gen >= CHIPSET_SB89XX && amd_gen <= CHIPSET_HUDSON234) {
458 bool fast_read = (mmio_readl(sb600_spibar + 0x00) >> 18) & 0x1;
459 msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis");
460 if (fast_read) {
461 msg_pdbg("Disabling them temporarily.\n");
462 rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18),
463 sb600_spibar + 0x00);
464 }
465 }
466 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
467 msg_pdbg("NormSpeed is %s\n", spispeeds[tmp].name);
468 }
469 return set_speed(dev, &spispeeds[spispeed_idx]);
470}
471
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000472static int handle_imc(struct pci_dev *dev)
Rudolf Marek70e14592013-07-25 22:58:56 +0000473{
474 /* Handle IMC everywhere but sb600 which does not have one. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000475 if (amd_gen == CHIPSET_SB6XX)
Rudolf Marek70e14592013-07-25 22:58:56 +0000476 return 0;
477
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000478 bool amd_imc_force = false;
479 char *arg = extract_programmer_param("amd_imc_force");
480 if (arg && !strcmp(arg, "yes")) {
481 amd_imc_force = true;
482 msg_pspew("amd_imc_force enabled.\n");
483 } else if (arg && !strlen(arg)) {
484 msg_perr("Missing argument for amd_imc_force.\n");
485 free(arg);
486 return 1;
487 } else if (arg) {
488 msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
489 free(arg);
490 return 1;
491 }
492 free(arg);
493
Rudolf Marek70e14592013-07-25 22:58:56 +0000494 /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
495 * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50: Misc_Reg: 80h-87h;
496 * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
497 uint8_t reg = pci_read_byte(dev, 0x40);
498 if ((reg & (1 << 7)) == 0) {
499 msg_pdbg("IMC is not active.\n");
500 return 0;
501 }
502
503 if (!amd_imc_force)
504 programmer_may_write = 0;
Stefan Tauner463dd692013-08-08 12:00:19 +0000505 msg_pinfo("Writes have been disabled for safety reasons because the presence of the IMC\n"
506 "was detected and it could interfere with accessing flash memory. Flashrom will\n"
507 "try to disable it temporarily but even then this might not be safe:\n"
Rudolf Marek70e14592013-07-25 22:58:56 +0000508 "when it is reenabled and after a reboot it expects to find working code\n"
509 "in the flash and it is unpredictable what happens if there is none.\n"
510 "\n"
511 "To be safe make sure that there is a working IMC firmware at the right\n"
512 "location in the image you intend to write and do not attempt to erase.\n"
513 "\n"
514 "You can enforce write support with the amd_imc_force programmer option.\n");
515 if (amd_imc_force)
516 msg_pinfo("Continuing with write support because the user forced us to!\n");
517
518 return amd_imc_shutdown(dev);
519}
520
Michael Karcherb05b9e12010-07-22 18:04:19 +0000521int sb600_probe_spi(struct pci_dev *dev)
522{
523 struct pci_dev *smbus_dev;
524 uint32_t tmp;
525 uint8_t reg;
Rudolf Marek70e14592013-07-25 22:58:56 +0000526
Michael Karcherb05b9e12010-07-22 18:04:19 +0000527 /* Read SPI_BaseAddr */
528 tmp = pci_read_long(dev, 0xa0);
529 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
530 msg_pdbg("SPI base address is at 0x%x\n", tmp);
531
532 /* If the BAR has address 0, it is unlikely SPI is used. */
533 if (!tmp)
534 return 0;
535
536 /* Physical memory has to be mapped at page (4k) boundaries. */
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000537 sb600_spibar = rphysmap("SB600 SPI registers", tmp & 0xfffff000, 0x1000);
538 if (sb600_spibar == ERROR_PTR)
Niklas Söderlund5d307202013-09-14 09:02:27 +0000539 return ERROR_FATAL;
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000540
Michael Karcherb05b9e12010-07-22 18:04:19 +0000541 /* The low bits of the SPI base address are used as offset into
542 * the mapped page.
543 */
544 sb600_spibar += tmp & 0xfff;
545
Stefan Tauner463dd692013-08-08 12:00:19 +0000546 determine_generation(dev);
Stefan Tauner4442b812013-09-12 15:48:35 +0000547 if (amd_gen == CHIPSET_AMD_UNKNOWN) {
548 msg_perr("Could not determine chipset generation.");
549 return ERROR_NONFATAL;
550 }
Stefan Tauner463dd692013-08-08 12:00:19 +0000551
Stefan Tauner4442b812013-09-12 15:48:35 +0000552 /* How to read the following table and similar ones in this file:
553 * "?" means we have no datasheet for this chipset generation or it doesn't have any relevant info.
554 * "<-" means the bit/register meaning is identical to the next non-"?" chipset to the left. "<-" thus
555 * never refers to another "?".
556 * If a "?" chipset is between two chipsets with identical meaning, we assume the meaning didn't change
557 * twice in between, i.e. the meaning is unchanged for the "?" chipset. Usually we assume that
558 * succeeding hardware supports the same functionality as its predecessor unless proven different by
559 * tests or documentation, hence "?" will often be implemented equally to "<-".
560 *
561 * Chipset support matrix for SPI Base_Addr (LPC PCI reg 0xa0)
562 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
563 * 3 rsvd <- <- ? <- ? RouteTpm2Spi
564 * 2 rsvd AbortEnable rsvd ? <- ? <-
565 * 1 rsvd SpiRomEnable <- ? <- ? <-
566 * 0 rsvd AltSpiCSEnable rsvd ? <- ? <-
567 */
568 if (amd_gen >= CHIPSET_SB7XX) {
569 tmp = pci_read_long(dev, 0xa0);
570 msg_pdbg("SpiRomEnable=%i", (tmp >> 1) & 0x1);
571 if (amd_gen == CHIPSET_SB7XX)
572 msg_pdbg(", AltSpiCSEnable=%i, AbortEnable=%i", tmp & 0x1, (tmp >> 2) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000573 else if (amd_gen == CHIPSET_YANGTZE)
574 msg_pdbg(", RouteTpm2Sp=%i", (tmp >> 3) & 0x1);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000575
Stefan Tauner4442b812013-09-12 15:48:35 +0000576 tmp = pci_read_byte(dev, 0xba);
577 msg_pdbg(", PrefetchEnSPIFromIMC=%i", (tmp & 0x4) >> 2);
578
579 tmp = pci_read_byte(dev, 0xbb);
580 /* FIXME: Set bit 3,6,7 if not already set.
581 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
582 * See doc 42413 AMD SB700/710/750 RPR.
583 */
584 if (amd_gen == CHIPSET_SB7XX)
585 msg_pdbg(", SpiOpEnInLpcMode=%i", (tmp >> 5) & 0x1);
586 msg_pdbg(", PrefetchEnSPIFromHost=%i\n", tmp & 0x1);
587 }
588
589 /* Chipset support matrix for SPI_Cntrl0 (spibar + 0x0)
590 * See the chipset support matrix for SPI Base_Addr above for an explanation of the symbols used.
591 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
592 * 17 rsvd <- <- ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000593 * 18 rsvd <- fastReadEnable<1> ? <- ? SpiReadMode[0]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000594 * 19 SpiArbEnable <- <- ? <- ? <-
595 * 20 (FifoPtrClr) <- <- ? <- ? <-
596 * 21 (FifoPtrInc) <- <- ? <- ? IllegalAccess
597 * 22 SpiAccessMacRomEn <- <- ? <- ? <-
598 * 23 SpiHostAccessRomEn <- <- ? <- ? <-
599 * 24:26 ArbWaitCount <- <- ? <- ? <-
600 * 27 SpiBridgeDisable <- <- ? <- ? rsvd
601 * 28 rsvd DropOneClkOnRd = SPIClkGate ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000602 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000603 * 31 rsvd <- SpiBusy ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000604 *
605 * <1> see handle_speed
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000606 */
Stefan Tauner4442b812013-09-12 15:48:35 +0000607 tmp = mmio_readl(sb600_spibar + 0x00);
608 msg_pdbg("(0x%08" PRIx32 ") SpiArbEnable=%i", tmp, (tmp >> 19) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000609 if (amd_gen == CHIPSET_YANGTZE)
610 msg_pdbg(", IllegalAccess=%i", (tmp >> 21) & 0x1);
Stefan Tauner4442b812013-09-12 15:48:35 +0000611
612 msg_pdbg(", SpiAccessMacRomEn=%i, SpiHostAccessRomEn=%i, ArbWaitCount=%i",
613 (tmp >> 22) & 0x1, (tmp >> 23) & 0x1, (tmp >> 24) & 0x7);
614
615 if (amd_gen != CHIPSET_YANGTZE)
616 msg_pdbg(", SpiBridgeDisable=%i", (tmp >> 27) & 0x1);
617
618 switch (amd_gen) {
619 case CHIPSET_SB7XX:
620 msg_pdbg(", DropOneClkOnRd/SpiClkGate=%i", (tmp >> 28) & 0x1);
621 case CHIPSET_SB89XX:
622 case CHIPSET_HUDSON234:
Wei Hu31402ee2014-05-16 21:39:33 +0000623 case CHIPSET_YANGTZE:
Stefan Tauner4442b812013-09-12 15:48:35 +0000624 msg_pdbg(", SpiBusy=%i", (tmp >> 31) & 0x1);
625 default: break;
626 }
627 msg_pdbg("\n");
628
629 if (((tmp >> 22) & 0x1) == 0 || ((tmp >> 23) & 0x1) == 0) {
630 msg_perr("ERROR: State of SpiAccessMacRomEn or SpiHostAccessRomEn prohibits full access.\n");
631 return ERROR_NONFATAL;
632 }
633
Stefan Tauner4442b812013-09-12 15:48:35 +0000634 if (amd_gen >= CHIPSET_SB89XX) {
635 tmp = mmio_readb(sb600_spibar + 0x1D);
636 msg_pdbg("Using SPI_CS%d\n", tmp & 0x3);
Wei Hu31402ee2014-05-16 21:39:33 +0000637 /* FIXME: Handle SpiProtect* configuration on Yangtze. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000638 }
639
Michael Karcherb05b9e12010-07-22 18:04:19 +0000640 /* Look for the SMBus device. */
641 smbus_dev = pci_dev_find(0x1002, 0x4385);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000642 if (!smbus_dev) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000643 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD FCH */
Wang Qing Pei6e9e2ee2011-08-26 21:11:41 +0000644 if (!smbus_dev) {
645 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
646 return ERROR_NONFATAL;
647 }
Michael Karcherb05b9e12010-07-22 18:04:19 +0000648 }
649
650 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
651 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
652 reg = pci_read_byte(smbus_dev, 0xAB);
653 reg &= 0xC0;
654 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
655 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
656 if (reg != 0x00) {
657 msg_pdbg("Not enabling SPI");
658 return 0;
659 }
660 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
661 reg = pci_read_byte(smbus_dev, 0x83);
662 reg &= 0xC0;
663 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
664 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
665 /* SPI_HOLD is not used on all boards, filter it out. */
666 if ((reg & 0x80) != 0x00) {
667 msg_pdbg("Not enabling SPI");
668 return 0;
669 }
670 /* GPIO47/SPI_CLK status */
671 reg = pci_read_byte(smbus_dev, 0xA7);
672 reg &= 0x40;
673 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
674 if (reg != 0x00) {
675 msg_pdbg("Not enabling SPI");
676 return 0;
677 }
678
Stefan Taunera6a0d202013-09-15 14:17:39 +0000679 if (handle_speed(dev) != 0)
680 return ERROR_FATAL;
681
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000682 if (handle_imc(dev) != 0)
Rudolf Marek70e14592013-07-25 22:58:56 +0000683 return ERROR_FATAL;
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000684
Wei Hu31402ee2014-05-16 21:39:33 +0000685 /* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */
686 if (amd_gen != CHIPSET_YANGTZE)
687 register_spi_programmer(&spi_programmer_sb600);
688 else
689 register_spi_programmer(&spi_programmer_yangtze);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000690 return 0;
691}
692
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000693#endif