blob: 3026836da16c6f5ad73b63b55ee278edeb3db96e [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.
Jason Wanga3f04be2008-11-28 21:36:51 +000019 */
20
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +000021#if defined(__i386__) || defined(__x86_64__)
22
Rudolf Marek70e14592013-07-25 22:58:56 +000023#include <string.h>
24#include <stdlib.h>
Jason Wanga3f04be2008-11-28 21:36:51 +000025#include "flash.h"
Carl-Daniel Hailfinger5b997c32010-07-27 22:41:39 +000026#include "programmer.h"
Patrick Georgi32508eb2012-07-20 20:35:14 +000027#include "hwaccess.h"
Jason Wanga3f04be2008-11-28 21:36:51 +000028#include "spi.h"
29
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +000030/* This struct is unused, but helps visualize the SB600 SPI BAR layout.
31 *struct sb600_spi_controller {
32 * unsigned int spi_cntrl0; / * 00h * /
33 * unsigned int restrictedcmd1; / * 04h * /
34 * unsigned int restrictedcmd2; / * 08h * /
35 * unsigned int spi_cntrl1; / * 0ch * /
36 * unsigned int spi_cmdvalue0; / * 10h * /
37 * unsigned int spi_cmdvalue1; / * 14h * /
38 * unsigned int spi_cmdvalue2; / * 18h * /
39 * unsigned int spi_fakeid; / * 1Ch * /
40 *};
41 */
Jason Wanga3f04be2008-11-28 21:36:51 +000042
Michael Karcherb05b9e12010-07-22 18:04:19 +000043static uint8_t *sb600_spibar = NULL;
Stefan Tauner463dd692013-08-08 12:00:19 +000044enum amd_chipset {
45 CHIPSET_AMD_UNKNOWN,
46 CHIPSET_SB6XX,
47 CHIPSET_SB7XX, /* SP5100 too */
48 CHIPSET_SB89XX, /* Hudson-1 too */
49 CHIPSET_HUDSON234,
Martin Roth82b6ec12014-07-15 13:50:58 +000050 CHIPSET_BOLTON,
Stefan Tauner463dd692013-08-08 12:00:19 +000051 CHIPSET_YANGTZE,
52};
53static enum amd_chipset amd_gen = CHIPSET_AMD_UNKNOWN;
54
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000055#define FIFO_SIZE_OLD 8
Wei Hu31402ee2014-05-16 21:39:33 +000056#define FIFO_SIZE_YANGTZE 71
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000057
58static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
59 const unsigned char *writearr, unsigned char *readarr);
Wei Hu31402ee2014-05-16 21:39:33 +000060static int spi100_spi_send_command(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt,
61 const unsigned char *writearr, unsigned char *readarr);
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000062
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +000063static struct spi_master spi_master_sb600 = {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +000064 .max_data_read = FIFO_SIZE_OLD,
65 .max_data_write = FIFO_SIZE_OLD - 3,
66 .command = sb600_spi_send_command,
67 .multicommand = default_spi_send_multicommand,
68 .read = default_spi_read,
69 .write_256 = default_spi_write_256,
70 .write_aai = default_spi_write_aai,
71};
72
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +000073static struct spi_master spi_master_yangtze = {
Wei Hu31402ee2014-05-16 21:39:33 +000074 .max_data_read = FIFO_SIZE_YANGTZE - 3, /* Apparently the big SPI 100 buffer is not a ring buffer. */
75 .max_data_write = FIFO_SIZE_YANGTZE - 3,
76 .command = spi100_spi_send_command,
77 .multicommand = default_spi_send_multicommand,
78 .read = default_spi_read,
79 .write_256 = default_spi_write_256,
80 .write_aai = default_spi_write_aai,
81};
82
Stefan Tauner463dd692013-08-08 12:00:19 +000083static void determine_generation(struct pci_dev *dev)
84{
85 amd_gen = CHIPSET_AMD_UNKNOWN;
Stefan Tauner4442b812013-09-12 15:48:35 +000086 msg_pdbg2("Trying to determine the generation of the SPI interface... ");
87 if (dev->device_id == 0x438d) {
88 amd_gen = CHIPSET_SB6XX;
89 msg_pdbg("SB6xx detected.\n");
90 } else if (dev->device_id == 0x439d) {
91 struct pci_dev *smbus_dev = pci_dev_find(0x1002, 0x4385);
92 if (smbus_dev == NULL)
93 return;
94 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
95 if (rev >= 0x39 && rev <= 0x3D) {
96 amd_gen = CHIPSET_SB7XX;
97 msg_pdbg("SB7xx/SP5100 detected.\n");
98 } else if (rev >= 0x40 && rev <= 0x42) {
99 amd_gen = CHIPSET_SB89XX;
100 msg_pdbg("SB8xx/SB9xx/Hudson-1 detected.\n");
101 } else {
102 msg_pwarn("SB device found but SMBus revision 0x%02x does not match known values.\n"
103 "Assuming SB8xx/SB9xx/Hudson-1. Please send a log to flashrom@flashrom.org\n",
104 rev);
105 amd_gen = CHIPSET_SB89XX;
106 }
107 } else if (dev->device_id == 0x780e) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000108 /* The PCI ID of the LPC bridge doesn't change between Hudson-2/3/4 and Yangtze (Kabini/Temash)
109 * although they use different SPI interfaces. */
110#ifdef USE_YANGTZE_HEURISTICS
111 /* This heuristic accesses the SPI interface MMIO BAR at locations beyond those supported by
112 * Hudson in the hope of getting 0xff readback on older chipsets and non-0xff readback on
113 * Yangtze (and newer, compatible chipsets). */
114 int i;
115 msg_pdbg("Checking for AMD Yangtze (Kabini/Temash) or later... ");
116 for (i = 0x20; i <= 0x4f; i++) {
117 if (mmio_readb(sb600_spibar + i) != 0xff) {
118 amd_gen = CHIPSET_YANGTZE;
119 msg_pdbg("found.\n");
120 return;
121 }
122 }
123 msg_pdbg("not found. Assuming Hudson.\n");
124 amd_gen = CHIPSET_HUDSON234;
125#else
126 struct pci_dev *smbus_dev = pci_dev_find(0x1022, 0x780B);
127 if (smbus_dev == NULL) {
128 msg_pdbg("No SMBus device with ID 1022:780B found.\n");
129 return;
130 }
131 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
132 if (rev >= 0x11 && rev <= 0x15) {
133 amd_gen = CHIPSET_HUDSON234;
134 msg_pdbg("Hudson-2/3/4 detected.\n");
Martin Roth82b6ec12014-07-15 13:50:58 +0000135 } else if (rev == 0x16) {
136 amd_gen = CHIPSET_BOLTON;
137 msg_pdbg("Bolton detected.\n");
Stefan Tauner5c316f92015-02-08 21:57:52 +0000138 } else if ((rev >= 0x39 && rev <= 0x3A) || rev == 0x42) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000139 amd_gen = CHIPSET_YANGTZE;
140 msg_pdbg("Yangtze detected.\n");
141 } else {
142 msg_pwarn("FCH device found but SMBus revision 0x%02x does not match known values.\n"
143 "Please report this to flashrom@flashrom.org and include this log and\n"
144 "the output of lspci -nnvx, thanks!.\n", rev);
145 }
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100146 } else if (dev->device_id == 0x790e) {
147 struct pci_dev *smbus_dev = pci_dev_find(0x1022, 0x790B);
148 if (smbus_dev == NULL) {
149 msg_pdbg("No SMBus device with ID 1022:790B found.\n");
150 return;
151 }
152 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
153 if (rev == 0x4a) {
154 amd_gen = CHIPSET_YANGTZE;
155 msg_pdbg("Yangtze detected.\n");
156 } else {
157 msg_pwarn("FCH device found but SMBus revision 0x%02x does not match known values.\n"
158 "Please report this to flashrom@flashrom.org and include this log and\n"
159 "the output of lspci -nnvx, thanks!.\n", rev);
160 }
161
162
Stefan Tauner463dd692013-08-08 12:00:19 +0000163#endif
Stefan Tauner4442b812013-09-12 15:48:35 +0000164 } else
165 msg_pwarn("%s: Unknown LPC device %" PRIx16 ":%" PRIx16 ".\n"
166 "Please report this to flashrom@flashrom.org and include this log and\n"
167 "the output of lspci -nnvx, thanks!\n",
168 __func__, dev->vendor_id, dev->device_id);
Stefan Tauner463dd692013-08-08 12:00:19 +0000169}
Jason Wanga3f04be2008-11-28 21:36:51 +0000170
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000171static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000172{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000173 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +0000174
Rudolf Marek70e14592013-07-25 22:58:56 +0000175 /* FIXME: This loop needs a timeout and a clearer message. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000176 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000177 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000178}
179
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000180static int compare_internal_fifo_pointer(uint8_t want)
181{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000182 uint8_t have = mmio_readb(sb600_spibar + 0xd) & 0x07;
183 want %= FIFO_SIZE_OLD;
184 if (have != want) {
185 msg_perr("AMD SPI FIFO pointer corruption! Pointer is %d, wanted %d\n", have, want);
186 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
187 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000188 return 1;
189 } else {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000190 msg_pspew("AMD SPI FIFO pointer is %d, wanted %d\n", have, want);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000191 return 0;
192 }
193}
194
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000195/* Check the number of bytes to be transmitted and extract opcode. */
196static int check_readwritecnt(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt)
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000197{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000198 unsigned int maxwritecnt = flash->mst->spi.max_data_write + 3;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000199 if (writecnt > maxwritecnt) {
200 msg_pinfo("%s: SPI controller can not send %d bytes, it is limited to %d bytes\n",
201 __func__, writecnt, maxwritecnt);
202 return SPI_INVALID_LENGTH;
203 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000204
Stefan Tauner6697f712014-08-06 15:09:15 +0000205 unsigned int maxreadcnt = flash->mst->spi.max_data_read;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000206 if (readcnt > maxreadcnt) {
207 msg_pinfo("%s: SPI controller can not receive %d bytes, it is limited to %d bytes\n",
208 __func__, readcnt, maxreadcnt);
209 return SPI_INVALID_LENGTH;
210 }
211 return 0;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000212}
213
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000214static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000215{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000216 msg_pspew("Executing... ");
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000217 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000218 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +0000219 ;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000220 msg_pspew("done\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000221}
222
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000223static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
224 unsigned int readcnt,
225 const unsigned char *writearr,
226 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +0000227{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000228 /* First byte is cmd which can not be sent through the FIFO. */
Jason Wanga3f04be2008-11-28 21:36:51 +0000229 unsigned char cmd = *writearr++;
Jason Wanga3f04be2008-11-28 21:36:51 +0000230 writecnt--;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000231 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
232 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000233
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000234 int ret = check_readwritecnt(flash, writecnt, readcnt);
235 if (ret != 0)
236 return ret;
Jason Wanga3f04be2008-11-28 21:36:51 +0000237
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000238 /* This is a workaround for a bug in SPI controller. If we only send
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000239 * an opcode and no additional data/address, the SPI controller will
240 * read one byte too few from the chip. Basically, the last byte of
241 * the chip response is discarded and will not end up in the FIFO.
242 * It is unclear if the CS# line is set high too early as well.
243 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000244 unsigned int readoffby1 = (writecnt > 0) ? 0 : 1;
245 uint8_t readwrite = (readcnt + readoffby1) << 4 | (writecnt);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000246 mmio_writeb(readwrite, sb600_spibar + 1);
Jason Wanga3f04be2008-11-28 21:36:51 +0000247
Jason Wanga3f04be2008-11-28 21:36:51 +0000248 reset_internal_fifo_pointer();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000249 msg_pspew("Filling FIFO: ");
Nico Huber519be662018-12-23 20:03:35 +0100250 unsigned int count;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000251 for (count = 0; count < writecnt; count++) {
252 msg_pspew("[%02x]", writearr[count]);
253 mmio_writeb(writearr[count], sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000254 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000255 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000256 if (compare_internal_fifo_pointer(writecnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000257 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000258
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000259 /*
260 * We should send the data in sequence, which means we need to reset
261 * the FIFO pointer to the first byte we want to send.
262 */
263 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000264 execute_command();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000265 if (compare_internal_fifo_pointer(writecnt + readcnt))
266 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000267
268 /*
269 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000270 * received byte. Here we just reset the FIFO pointer and skip the
271 * writecnt.
272 * It would be possible to increase the FIFO pointer by one instead
273 * of reading and discarding one byte from the FIFO.
274 * The FIFO is implemented on top of an 8 byte ring buffer and the
275 * buffer is never cleared. For every byte that is shifted out after
276 * the opcode, the FIFO already stores the response from the chip.
277 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000278 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000279 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000280
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000281 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000282 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000283 for (count = 0; count < writecnt; count++) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000284 msg_pspew("[%02x]", mmio_readb(sb600_spibar + 0xC));
Jason Wanga3f04be2008-11-28 21:36:51 +0000285 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000286 msg_pspew("\n");
287 if (compare_internal_fifo_pointer(writecnt))
288 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000289
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000290 msg_pspew("Reading FIFO: ");
291 for (count = 0; count < readcnt; count++) {
292 readarr[count] = mmio_readb(sb600_spibar + 0xC);
293 msg_pspew("[%02x]", readarr[count]);
Jason Wanga3f04be2008-11-28 21:36:51 +0000294 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000295 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000296 if (compare_internal_fifo_pointer(writecnt+readcnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000297 return SPI_PROGRAMMER_ERROR;
298
299 if (mmio_readb(sb600_spibar + 1) != readwrite) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000300 msg_perr("Unexpected change in AMD SPI read/write count!\n");
301 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
302 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000303 return SPI_PROGRAMMER_ERROR;
304 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000305
306 return 0;
307}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000308
Wei Hu31402ee2014-05-16 21:39:33 +0000309static int spi100_spi_send_command(struct flashctx *flash, unsigned int writecnt,
310 unsigned int readcnt,
311 const unsigned char *writearr,
312 unsigned char *readarr)
313{
314 /* First byte is cmd which can not be sent through the buffer. */
315 unsigned char cmd = *writearr++;
316 writecnt--;
317 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
318 mmio_writeb(cmd, sb600_spibar + 0);
319
320 int ret = check_readwritecnt(flash, writecnt, readcnt);
321 if (ret != 0)
322 return ret;
323
324 /* Use the extended TxByteCount and RxByteCount registers. */
325 mmio_writeb(writecnt, sb600_spibar + 0x48);
326 mmio_writeb(readcnt, sb600_spibar + 0x4b);
327
328 msg_pspew("Filling buffer: ");
Nico Huber519be662018-12-23 20:03:35 +0100329 unsigned int count;
Wei Hu31402ee2014-05-16 21:39:33 +0000330 for (count = 0; count < writecnt; count++) {
331 msg_pspew("[%02x]", writearr[count]);
332 mmio_writeb(writearr[count], sb600_spibar + 0x80 + count);
333 }
334 msg_pspew("\n");
335
336 execute_command();
337
338 msg_pspew("Reading buffer: ");
339 for (count = 0; count < readcnt; count++) {
340 readarr[count] = mmio_readb(sb600_spibar + 0x80 + (writecnt + count) % FIFO_SIZE_YANGTZE);
341 msg_pspew("[%02x]", readarr[count]);
342 }
343 msg_pspew("\n");
344
345 return 0;
346}
347
Stefan Taunera6a0d202013-09-15 14:17:39 +0000348struct spispeed {
349 const char *const name;
350 const uint8_t speed;
351};
352
353static const struct spispeed spispeeds[] = {
354 { "66 MHz", 0x00 },
355 { "33 MHz", 0x01 },
356 { "22 MHz", 0x02 },
357 { "16.5 MHz", 0x03 },
Wei Hu31402ee2014-05-16 21:39:33 +0000358 { "100 MHz", 0x04 },
359 { "Reserved", 0x05 },
360 { "Reserved", 0x06 },
361 { "800 kHz", 0x07 },
Stefan Taunera6a0d202013-09-15 14:17:39 +0000362};
363
364static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed)
365{
366 bool success = false;
367 uint8_t speed = spispeed->speed;
368
369 msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed);
Wei Hu31402ee2014-05-16 21:39:33 +0000370 if (amd_gen >= CHIPSET_YANGTZE) {
371 rmmio_writew((speed << 12) | (speed << 8) | (speed << 4) | speed, sb600_spibar + 0x22);
372 uint16_t tmp = mmio_readw(sb600_spibar + 0x22);
373 success = (((tmp >> 12) & 0xf) == speed && ((tmp >> 8) & 0xf) == speed &&
374 ((tmp >> 4) & 0xf) == speed && ((tmp >> 0) & 0xf) == speed);
375 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000376 rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd);
377 success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3));
378 }
379
380 if (!success) {
381 msg_perr("Setting SPI clock failed.\n");
382 return 1;
383 }
384 return 0;
385}
386
Wei Hu31402ee2014-05-16 21:39:33 +0000387static int set_mode(struct pci_dev *dev, uint8_t read_mode)
388{
389 uint32_t tmp = mmio_readl(sb600_spibar + 0x00);
390 tmp &= ~(0x6 << 28 | 0x1 << 18); /* Clear mode bits */
391 tmp |= ((read_mode & 0x6) << 28) | ((read_mode & 0x1) << 18);
392 rmmio_writel(tmp, sb600_spibar + 0x00);
393 if (tmp != mmio_readl(sb600_spibar + 0x00))
394 return 1;
395 return 0;
396}
397
Stefan Taunera6a0d202013-09-15 14:17:39 +0000398static int handle_speed(struct pci_dev *dev)
399{
400 uint32_t tmp;
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000401 uint8_t spispeed_idx = 3; /* Default to 16.5 MHz */
Stefan Taunera6a0d202013-09-15 14:17:39 +0000402
Stefan Tauner21071b02014-05-16 21:39:48 +0000403 char *spispeed = extract_programmer_param("spispeed");
404 if (spispeed != NULL) {
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000405 unsigned int i;
406 for (i = 0; i < ARRAY_SIZE(spispeeds); i++) {
407 if (strcasecmp(spispeeds[i].name, spispeed) == 0) {
408 spispeed_idx = i;
409 break;
Stefan Tauner21071b02014-05-16 21:39:48 +0000410 }
Stefan Tauner21071b02014-05-16 21:39:48 +0000411 }
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000412 /* "reserved" is not a valid speed.
413 * Error out on speeds not present in the spispeeds array.
414 * Only Yangtze supports the second half of indices.
415 * No 66 MHz before SB8xx. */
416 if ((strcasecmp(spispeed, "reserved") == 0) ||
417 (i == ARRAY_SIZE(spispeeds)) ||
418 (amd_gen < CHIPSET_YANGTZE && spispeed_idx > 3) ||
419 (amd_gen < CHIPSET_SB89XX && spispeed_idx == 0)) {
Stefan Tauner21071b02014-05-16 21:39:48 +0000420 msg_perr("Error: Invalid spispeed value: '%s'.\n", spispeed);
421 free(spispeed);
422 return 1;
423 }
424 free(spispeed);
425 }
426
Stefan Taunera6a0d202013-09-15 14:17:39 +0000427 /* See the chipset support matrix for SPI Base_Addr below for an explanation of the symbols used.
Martin Roth82b6ec12014-07-15 13:50:58 +0000428 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson234 bolton/yangtze
Stefan Taunera6a0d202013-09-15 14:17:39 +0000429 * 18 rsvd <- fastReadEnable ? <- ? SpiReadMode[0]
430 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]
431 */
Martin Roth82b6ec12014-07-15 13:50:58 +0000432 if (amd_gen >= CHIPSET_BOLTON) {
Wei Hu31402ee2014-05-16 21:39:33 +0000433 static const char *spireadmodes[] = {
434 "Normal (up to 33 MHz)", /* 0 */
435 "Reserved", /* 1 */
436 "Dual IO (1-1-2)", /* 2 */
437 "Quad IO (1-1-4)", /* 3 */
438 "Dual IO (1-2-2)", /* 4 */
439 "Quad IO (1-4-4)", /* 5 */
440 "Normal (up to 66 MHz)", /* 6 */
Martin Roth82b6ec12014-07-15 13:50:58 +0000441 "Fast Read", /* 7 (Not defined in the Bolton datasheet.) */
Wei Hu31402ee2014-05-16 21:39:33 +0000442 };
443 tmp = mmio_readl(sb600_spibar + 0x00);
444 uint8_t read_mode = ((tmp >> 28) & 0x6) | ((tmp >> 18) & 0x1);
445 msg_pdbg("SpiReadMode=%s (%i)\n", spireadmodes[read_mode], read_mode);
446 if (read_mode != 6) {
447 read_mode = 6; /* Default to "Normal (up to 66 MHz)" */
448 if (set_mode(dev, read_mode) != 0) {
449 msg_perr("Setting read mode to \"%s\" failed.\n", spireadmodes[read_mode]);
450 return 1;
451 }
452 msg_pdbg("Setting read mode to \"%s\" succeeded.\n", spireadmodes[read_mode]);
453 }
454
Martin Roth82b6ec12014-07-15 13:50:58 +0000455 if (amd_gen >= CHIPSET_YANGTZE) {
456 tmp = mmio_readb(sb600_spibar + 0x20);
457 msg_pdbg("UseSpi100 is %sabled\n", (tmp & 0x1) ? "en" : "dis");
458 if ((tmp & 0x1) == 0) {
459 rmmio_writeb(tmp | 0x1, sb600_spibar + 0x20);
460 tmp = mmio_readb(sb600_spibar + 0x20) & 0x1;
461 if (tmp == 0) {
462 msg_perr("Enabling Spi100 failed.\n");
463 return 1;
464 }
465 msg_pdbg("Enabling Spi100 succeeded.\n");
466 }
467
468 tmp = mmio_readw(sb600_spibar + 0x22); /* SPI 100 Speed Config */
469 msg_pdbg("NormSpeedNew is %s\n", spispeeds[(tmp >> 12) & 0xf].name);
470 msg_pdbg("FastSpeedNew is %s\n", spispeeds[(tmp >> 8) & 0xf].name);
471 msg_pdbg("AltSpeedNew is %s\n", spispeeds[(tmp >> 4) & 0xf].name);
472 msg_pdbg("TpmSpeedNew is %s\n", spispeeds[(tmp >> 0) & 0xf].name);
473 }
Wei Hu31402ee2014-05-16 21:39:33 +0000474 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000475 if (amd_gen >= CHIPSET_SB89XX && amd_gen <= CHIPSET_HUDSON234) {
476 bool fast_read = (mmio_readl(sb600_spibar + 0x00) >> 18) & 0x1;
477 msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis");
478 if (fast_read) {
479 msg_pdbg("Disabling them temporarily.\n");
480 rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18),
481 sb600_spibar + 0x00);
482 }
483 }
484 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
485 msg_pdbg("NormSpeed is %s\n", spispeeds[tmp].name);
486 }
487 return set_speed(dev, &spispeeds[spispeed_idx]);
488}
489
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000490static int handle_imc(struct pci_dev *dev)
Rudolf Marek70e14592013-07-25 22:58:56 +0000491{
492 /* Handle IMC everywhere but sb600 which does not have one. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000493 if (amd_gen == CHIPSET_SB6XX)
Rudolf Marek70e14592013-07-25 22:58:56 +0000494 return 0;
495
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000496 bool amd_imc_force = false;
497 char *arg = extract_programmer_param("amd_imc_force");
498 if (arg && !strcmp(arg, "yes")) {
499 amd_imc_force = true;
500 msg_pspew("amd_imc_force enabled.\n");
501 } else if (arg && !strlen(arg)) {
502 msg_perr("Missing argument for amd_imc_force.\n");
503 free(arg);
504 return 1;
505 } else if (arg) {
506 msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
507 free(arg);
508 return 1;
509 }
510 free(arg);
511
Rudolf Marek70e14592013-07-25 22:58:56 +0000512 /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
Stefan Tauner5c316f92015-02-08 21:57:52 +0000513 * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50, Bolton: Misc_Reg: 80h-87h;
Rudolf Marek70e14592013-07-25 22:58:56 +0000514 * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
515 uint8_t reg = pci_read_byte(dev, 0x40);
516 if ((reg & (1 << 7)) == 0) {
517 msg_pdbg("IMC is not active.\n");
518 return 0;
519 }
520
521 if (!amd_imc_force)
522 programmer_may_write = 0;
Stefan Tauner463dd692013-08-08 12:00:19 +0000523 msg_pinfo("Writes have been disabled for safety reasons because the presence of the IMC\n"
524 "was detected and it could interfere with accessing flash memory. Flashrom will\n"
525 "try to disable it temporarily but even then this might not be safe:\n"
Stefan Tauner0be072c2016-03-13 15:16:30 +0000526 "when it is re-enabled and after a reboot it expects to find working code\n"
Rudolf Marek70e14592013-07-25 22:58:56 +0000527 "in the flash and it is unpredictable what happens if there is none.\n"
528 "\n"
529 "To be safe make sure that there is a working IMC firmware at the right\n"
530 "location in the image you intend to write and do not attempt to erase.\n"
531 "\n"
532 "You can enforce write support with the amd_imc_force programmer option.\n");
533 if (amd_imc_force)
534 msg_pinfo("Continuing with write support because the user forced us to!\n");
535
536 return amd_imc_shutdown(dev);
537}
538
Michael Karcherb05b9e12010-07-22 18:04:19 +0000539int sb600_probe_spi(struct pci_dev *dev)
540{
541 struct pci_dev *smbus_dev;
542 uint32_t tmp;
543 uint8_t reg;
Rudolf Marek70e14592013-07-25 22:58:56 +0000544
Michael Karcherb05b9e12010-07-22 18:04:19 +0000545 /* Read SPI_BaseAddr */
546 tmp = pci_read_long(dev, 0xa0);
547 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
548 msg_pdbg("SPI base address is at 0x%x\n", tmp);
549
550 /* If the BAR has address 0, it is unlikely SPI is used. */
551 if (!tmp)
552 return 0;
553
554 /* Physical memory has to be mapped at page (4k) boundaries. */
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000555 sb600_spibar = rphysmap("SB600 SPI registers", tmp & 0xfffff000, 0x1000);
556 if (sb600_spibar == ERROR_PTR)
Niklas Söderlund5d307202013-09-14 09:02:27 +0000557 return ERROR_FATAL;
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000558
Michael Karcherb05b9e12010-07-22 18:04:19 +0000559 /* The low bits of the SPI base address are used as offset into
560 * the mapped page.
561 */
562 sb600_spibar += tmp & 0xfff;
563
Stefan Tauner463dd692013-08-08 12:00:19 +0000564 determine_generation(dev);
Stefan Tauner4442b812013-09-12 15:48:35 +0000565 if (amd_gen == CHIPSET_AMD_UNKNOWN) {
566 msg_perr("Could not determine chipset generation.");
567 return ERROR_NONFATAL;
568 }
Stefan Tauner463dd692013-08-08 12:00:19 +0000569
Stefan Tauner4442b812013-09-12 15:48:35 +0000570 /* How to read the following table and similar ones in this file:
571 * "?" means we have no datasheet for this chipset generation or it doesn't have any relevant info.
572 * "<-" means the bit/register meaning is identical to the next non-"?" chipset to the left. "<-" thus
573 * never refers to another "?".
574 * If a "?" chipset is between two chipsets with identical meaning, we assume the meaning didn't change
575 * twice in between, i.e. the meaning is unchanged for the "?" chipset. Usually we assume that
576 * succeeding hardware supports the same functionality as its predecessor unless proven different by
577 * tests or documentation, hence "?" will often be implemented equally to "<-".
578 *
579 * Chipset support matrix for SPI Base_Addr (LPC PCI reg 0xa0)
580 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
581 * 3 rsvd <- <- ? <- ? RouteTpm2Spi
582 * 2 rsvd AbortEnable rsvd ? <- ? <-
583 * 1 rsvd SpiRomEnable <- ? <- ? <-
584 * 0 rsvd AltSpiCSEnable rsvd ? <- ? <-
585 */
586 if (amd_gen >= CHIPSET_SB7XX) {
587 tmp = pci_read_long(dev, 0xa0);
588 msg_pdbg("SpiRomEnable=%i", (tmp >> 1) & 0x1);
589 if (amd_gen == CHIPSET_SB7XX)
590 msg_pdbg(", AltSpiCSEnable=%i, AbortEnable=%i", tmp & 0x1, (tmp >> 2) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000591 else if (amd_gen == CHIPSET_YANGTZE)
592 msg_pdbg(", RouteTpm2Sp=%i", (tmp >> 3) & 0x1);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000593
Stefan Tauner4442b812013-09-12 15:48:35 +0000594 tmp = pci_read_byte(dev, 0xba);
595 msg_pdbg(", PrefetchEnSPIFromIMC=%i", (tmp & 0x4) >> 2);
596
597 tmp = pci_read_byte(dev, 0xbb);
598 /* FIXME: Set bit 3,6,7 if not already set.
599 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
600 * See doc 42413 AMD SB700/710/750 RPR.
601 */
602 if (amd_gen == CHIPSET_SB7XX)
603 msg_pdbg(", SpiOpEnInLpcMode=%i", (tmp >> 5) & 0x1);
604 msg_pdbg(", PrefetchEnSPIFromHost=%i\n", tmp & 0x1);
605 }
606
607 /* Chipset support matrix for SPI_Cntrl0 (spibar + 0x0)
608 * See the chipset support matrix for SPI Base_Addr above for an explanation of the symbols used.
609 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
610 * 17 rsvd <- <- ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000611 * 18 rsvd <- fastReadEnable<1> ? <- ? SpiReadMode[0]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000612 * 19 SpiArbEnable <- <- ? <- ? <-
613 * 20 (FifoPtrClr) <- <- ? <- ? <-
614 * 21 (FifoPtrInc) <- <- ? <- ? IllegalAccess
615 * 22 SpiAccessMacRomEn <- <- ? <- ? <-
616 * 23 SpiHostAccessRomEn <- <- ? <- ? <-
617 * 24:26 ArbWaitCount <- <- ? <- ? <-
618 * 27 SpiBridgeDisable <- <- ? <- ? rsvd
619 * 28 rsvd DropOneClkOnRd = SPIClkGate ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000620 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000621 * 31 rsvd <- SpiBusy ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000622 *
623 * <1> see handle_speed
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000624 */
Stefan Tauner4442b812013-09-12 15:48:35 +0000625 tmp = mmio_readl(sb600_spibar + 0x00);
626 msg_pdbg("(0x%08" PRIx32 ") SpiArbEnable=%i", tmp, (tmp >> 19) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000627 if (amd_gen == CHIPSET_YANGTZE)
628 msg_pdbg(", IllegalAccess=%i", (tmp >> 21) & 0x1);
Stefan Tauner4442b812013-09-12 15:48:35 +0000629
630 msg_pdbg(", SpiAccessMacRomEn=%i, SpiHostAccessRomEn=%i, ArbWaitCount=%i",
631 (tmp >> 22) & 0x1, (tmp >> 23) & 0x1, (tmp >> 24) & 0x7);
632
633 if (amd_gen != CHIPSET_YANGTZE)
634 msg_pdbg(", SpiBridgeDisable=%i", (tmp >> 27) & 0x1);
635
636 switch (amd_gen) {
637 case CHIPSET_SB7XX:
638 msg_pdbg(", DropOneClkOnRd/SpiClkGate=%i", (tmp >> 28) & 0x1);
Richard Hughesdb7482b2018-12-19 12:04:30 +0000639 /* Fall through. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000640 case CHIPSET_SB89XX:
641 case CHIPSET_HUDSON234:
Wei Hu31402ee2014-05-16 21:39:33 +0000642 case CHIPSET_YANGTZE:
Stefan Tauner4442b812013-09-12 15:48:35 +0000643 msg_pdbg(", SpiBusy=%i", (tmp >> 31) & 0x1);
644 default: break;
645 }
646 msg_pdbg("\n");
647
648 if (((tmp >> 22) & 0x1) == 0 || ((tmp >> 23) & 0x1) == 0) {
649 msg_perr("ERROR: State of SpiAccessMacRomEn or SpiHostAccessRomEn prohibits full access.\n");
650 return ERROR_NONFATAL;
651 }
652
Stefan Tauner4442b812013-09-12 15:48:35 +0000653 if (amd_gen >= CHIPSET_SB89XX) {
654 tmp = mmio_readb(sb600_spibar + 0x1D);
655 msg_pdbg("Using SPI_CS%d\n", tmp & 0x3);
Wei Hu31402ee2014-05-16 21:39:33 +0000656 /* FIXME: Handle SpiProtect* configuration on Yangtze. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000657 }
658
Michael Karcherb05b9e12010-07-22 18:04:19 +0000659 /* Look for the SMBus device. */
660 smbus_dev = pci_dev_find(0x1002, 0x4385);
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100661 if (!smbus_dev)
Stefan Tauner463dd692013-08-08 12:00:19 +0000662 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD FCH */
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100663 if (!smbus_dev)
664 smbus_dev = pci_dev_find(0x1022, 0x790b); /* AMD FP4 */
665 if (!smbus_dev) {
666 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
667 return ERROR_NONFATAL;
Michael Karcherb05b9e12010-07-22 18:04:19 +0000668 }
669
670 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
671 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
672 reg = pci_read_byte(smbus_dev, 0xAB);
673 reg &= 0xC0;
674 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
675 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
676 if (reg != 0x00) {
677 msg_pdbg("Not enabling SPI");
678 return 0;
679 }
680 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
681 reg = pci_read_byte(smbus_dev, 0x83);
682 reg &= 0xC0;
683 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
684 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
685 /* SPI_HOLD is not used on all boards, filter it out. */
686 if ((reg & 0x80) != 0x00) {
687 msg_pdbg("Not enabling SPI");
688 return 0;
689 }
690 /* GPIO47/SPI_CLK status */
691 reg = pci_read_byte(smbus_dev, 0xA7);
692 reg &= 0x40;
693 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
694 if (reg != 0x00) {
695 msg_pdbg("Not enabling SPI");
696 return 0;
697 }
698
Stefan Taunera6a0d202013-09-15 14:17:39 +0000699 if (handle_speed(dev) != 0)
700 return ERROR_FATAL;
701
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000702 if (handle_imc(dev) != 0)
Rudolf Marek70e14592013-07-25 22:58:56 +0000703 return ERROR_FATAL;
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000704
Wei Hu31402ee2014-05-16 21:39:33 +0000705 /* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */
706 if (amd_gen != CHIPSET_YANGTZE)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000707 register_spi_master(&spi_master_sb600);
Wei Hu31402ee2014-05-16 21:39:33 +0000708 else
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000709 register_spi_master(&spi_master_yangtze);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000710 return 0;
711}
712
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000713#endif