blob: 1efb2ce86af02f2a311331824514b8726f3ebf50 [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 .type = SPI_CONTROLLER_SB600,
65 .max_data_read = FIFO_SIZE_OLD,
66 .max_data_write = FIFO_SIZE_OLD - 3,
67 .command = sb600_spi_send_command,
68 .multicommand = default_spi_send_multicommand,
69 .read = default_spi_read,
70 .write_256 = default_spi_write_256,
71 .write_aai = default_spi_write_aai,
72};
73
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +000074static struct spi_master spi_master_yangtze = {
Wei Hu31402ee2014-05-16 21:39:33 +000075 .type = SPI_CONTROLLER_YANGTZE,
76 .max_data_read = FIFO_SIZE_YANGTZE - 3, /* Apparently the big SPI 100 buffer is not a ring buffer. */
77 .max_data_write = FIFO_SIZE_YANGTZE - 3,
78 .command = spi100_spi_send_command,
79 .multicommand = default_spi_send_multicommand,
80 .read = default_spi_read,
81 .write_256 = default_spi_write_256,
82 .write_aai = default_spi_write_aai,
83};
84
Stefan Tauner463dd692013-08-08 12:00:19 +000085static void determine_generation(struct pci_dev *dev)
86{
87 amd_gen = CHIPSET_AMD_UNKNOWN;
Stefan Tauner4442b812013-09-12 15:48:35 +000088 msg_pdbg2("Trying to determine the generation of the SPI interface... ");
89 if (dev->device_id == 0x438d) {
90 amd_gen = CHIPSET_SB6XX;
91 msg_pdbg("SB6xx detected.\n");
92 } else if (dev->device_id == 0x439d) {
93 struct pci_dev *smbus_dev = pci_dev_find(0x1002, 0x4385);
94 if (smbus_dev == NULL)
95 return;
96 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
97 if (rev >= 0x39 && rev <= 0x3D) {
98 amd_gen = CHIPSET_SB7XX;
99 msg_pdbg("SB7xx/SP5100 detected.\n");
100 } else if (rev >= 0x40 && rev <= 0x42) {
101 amd_gen = CHIPSET_SB89XX;
102 msg_pdbg("SB8xx/SB9xx/Hudson-1 detected.\n");
103 } else {
104 msg_pwarn("SB device found but SMBus revision 0x%02x does not match known values.\n"
105 "Assuming SB8xx/SB9xx/Hudson-1. Please send a log to flashrom@flashrom.org\n",
106 rev);
107 amd_gen = CHIPSET_SB89XX;
108 }
109 } else if (dev->device_id == 0x780e) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000110 /* The PCI ID of the LPC bridge doesn't change between Hudson-2/3/4 and Yangtze (Kabini/Temash)
111 * although they use different SPI interfaces. */
112#ifdef USE_YANGTZE_HEURISTICS
113 /* This heuristic accesses the SPI interface MMIO BAR at locations beyond those supported by
114 * Hudson in the hope of getting 0xff readback on older chipsets and non-0xff readback on
115 * Yangtze (and newer, compatible chipsets). */
116 int i;
117 msg_pdbg("Checking for AMD Yangtze (Kabini/Temash) or later... ");
118 for (i = 0x20; i <= 0x4f; i++) {
119 if (mmio_readb(sb600_spibar + i) != 0xff) {
120 amd_gen = CHIPSET_YANGTZE;
121 msg_pdbg("found.\n");
122 return;
123 }
124 }
125 msg_pdbg("not found. Assuming Hudson.\n");
126 amd_gen = CHIPSET_HUDSON234;
127#else
128 struct pci_dev *smbus_dev = pci_dev_find(0x1022, 0x780B);
129 if (smbus_dev == NULL) {
130 msg_pdbg("No SMBus device with ID 1022:780B found.\n");
131 return;
132 }
133 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
134 if (rev >= 0x11 && rev <= 0x15) {
135 amd_gen = CHIPSET_HUDSON234;
136 msg_pdbg("Hudson-2/3/4 detected.\n");
Martin Roth82b6ec12014-07-15 13:50:58 +0000137 } else if (rev == 0x16) {
138 amd_gen = CHIPSET_BOLTON;
139 msg_pdbg("Bolton detected.\n");
Stefan Tauner5c316f92015-02-08 21:57:52 +0000140 } else if ((rev >= 0x39 && rev <= 0x3A) || rev == 0x42) {
Stefan Tauner463dd692013-08-08 12:00:19 +0000141 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 }
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100148 } else if (dev->device_id == 0x790e) {
149 struct pci_dev *smbus_dev = pci_dev_find(0x1022, 0x790B);
150 if (smbus_dev == NULL) {
151 msg_pdbg("No SMBus device with ID 1022:790B found.\n");
152 return;
153 }
154 uint8_t rev = pci_read_byte(smbus_dev, PCI_REVISION_ID);
155 if (rev == 0x4a) {
156 amd_gen = CHIPSET_YANGTZE;
157 msg_pdbg("Yangtze detected.\n");
158 } else {
159 msg_pwarn("FCH device found but SMBus revision 0x%02x does not match known values.\n"
160 "Please report this to flashrom@flashrom.org and include this log and\n"
161 "the output of lspci -nnvx, thanks!.\n", rev);
162 }
163
164
Stefan Tauner463dd692013-08-08 12:00:19 +0000165#endif
Stefan Tauner4442b812013-09-12 15:48:35 +0000166 } else
167 msg_pwarn("%s: Unknown LPC device %" PRIx16 ":%" PRIx16 ".\n"
168 "Please report this to flashrom@flashrom.org and include this log and\n"
169 "the output of lspci -nnvx, thanks!\n",
170 __func__, dev->vendor_id, dev->device_id);
Stefan Tauner463dd692013-08-08 12:00:19 +0000171}
Jason Wanga3f04be2008-11-28 21:36:51 +0000172
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000173static void reset_internal_fifo_pointer(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000174{
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000175 mmio_writeb(mmio_readb(sb600_spibar + 2) | 0x10, sb600_spibar + 2);
Jason Wanga3f04be2008-11-28 21:36:51 +0000176
Rudolf Marek70e14592013-07-25 22:58:56 +0000177 /* FIXME: This loop needs a timeout and a clearer message. */
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000178 while (mmio_readb(sb600_spibar + 0xD) & 0x7)
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000179 msg_pspew("reset\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000180}
181
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000182static int compare_internal_fifo_pointer(uint8_t want)
183{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000184 uint8_t have = mmio_readb(sb600_spibar + 0xd) & 0x07;
185 want %= FIFO_SIZE_OLD;
186 if (have != want) {
187 msg_perr("AMD SPI FIFO pointer corruption! Pointer is %d, wanted %d\n", have, want);
188 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
189 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000190 return 1;
191 } else {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000192 msg_pspew("AMD SPI FIFO pointer is %d, wanted %d\n", have, want);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000193 return 0;
194 }
195}
196
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000197/* Check the number of bytes to be transmitted and extract opcode. */
198static int check_readwritecnt(struct flashctx *flash, unsigned int writecnt, unsigned int readcnt)
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000199{
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000200 unsigned int maxwritecnt = flash->mst->spi.max_data_write + 3;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000201 if (writecnt > maxwritecnt) {
202 msg_pinfo("%s: SPI controller can not send %d bytes, it is limited to %d bytes\n",
203 __func__, writecnt, maxwritecnt);
204 return SPI_INVALID_LENGTH;
205 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000206
Stefan Tauner6697f712014-08-06 15:09:15 +0000207 unsigned int maxreadcnt = flash->mst->spi.max_data_read;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000208 if (readcnt > maxreadcnt) {
209 msg_pinfo("%s: SPI controller can not receive %d bytes, it is limited to %d bytes\n",
210 __func__, readcnt, maxreadcnt);
211 return SPI_INVALID_LENGTH;
212 }
213 return 0;
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000214}
215
Carl-Daniel Hailfinger2c7ba8c2009-06-23 00:47:26 +0000216static void execute_command(void)
Jason Wanga3f04be2008-11-28 21:36:51 +0000217{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000218 msg_pspew("Executing... ");
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000219 mmio_writeb(mmio_readb(sb600_spibar + 2) | 1, sb600_spibar + 2);
Carl-Daniel Hailfinger78185dc2009-05-17 15:49:24 +0000220 while (mmio_readb(sb600_spibar + 2) & 1)
Jason Wanga3f04be2008-11-28 21:36:51 +0000221 ;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000222 msg_pspew("done\n");
Jason Wanga3f04be2008-11-28 21:36:51 +0000223}
224
Carl-Daniel Hailfinger8a3c60c2011-12-18 15:01:24 +0000225static int sb600_spi_send_command(struct flashctx *flash, unsigned int writecnt,
226 unsigned int readcnt,
227 const unsigned char *writearr,
228 unsigned char *readarr)
Jason Wanga3f04be2008-11-28 21:36:51 +0000229{
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000230 /* First byte is cmd which can not be sent through the FIFO. */
Jason Wanga3f04be2008-11-28 21:36:51 +0000231 unsigned char cmd = *writearr++;
Jason Wanga3f04be2008-11-28 21:36:51 +0000232 writecnt--;
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000233 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
234 mmio_writeb(cmd, sb600_spibar + 0);
Jason Wanga3f04be2008-11-28 21:36:51 +0000235
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000236 int ret = check_readwritecnt(flash, writecnt, readcnt);
237 if (ret != 0)
238 return ret;
Jason Wanga3f04be2008-11-28 21:36:51 +0000239
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000240 /* This is a workaround for a bug in SPI controller. If we only send
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000241 * an opcode and no additional data/address, the SPI controller will
242 * read one byte too few from the chip. Basically, the last byte of
243 * the chip response is discarded and will not end up in the FIFO.
244 * It is unclear if the CS# line is set high too early as well.
245 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000246 unsigned int readoffby1 = (writecnt > 0) ? 0 : 1;
247 uint8_t readwrite = (readcnt + readoffby1) << 4 | (writecnt);
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000248 mmio_writeb(readwrite, sb600_spibar + 1);
Jason Wanga3f04be2008-11-28 21:36:51 +0000249
Jason Wanga3f04be2008-11-28 21:36:51 +0000250 reset_internal_fifo_pointer();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000251 msg_pspew("Filling FIFO: ");
252 int count;
253 for (count = 0; count < writecnt; count++) {
254 msg_pspew("[%02x]", writearr[count]);
255 mmio_writeb(writearr[count], sb600_spibar + 0xC);
Jason Wanga3f04be2008-11-28 21:36:51 +0000256 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000257 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000258 if (compare_internal_fifo_pointer(writecnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000259 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000260
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000261 /*
262 * We should send the data in sequence, which means we need to reset
263 * the FIFO pointer to the first byte we want to send.
264 */
265 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000266 execute_command();
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000267 if (compare_internal_fifo_pointer(writecnt + readcnt))
268 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000269
270 /*
271 * After the command executed, we should find out the index of the
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000272 * received byte. Here we just reset the FIFO pointer and skip the
273 * writecnt.
274 * It would be possible to increase the FIFO pointer by one instead
275 * of reading and discarding one byte from the FIFO.
276 * The FIFO is implemented on top of an 8 byte ring buffer and the
277 * buffer is never cleared. For every byte that is shifted out after
278 * the opcode, the FIFO already stores the response from the chip.
279 * Usually, the chip will respond with 0x00 or 0xff.
Jason Wanga3f04be2008-11-28 21:36:51 +0000280 */
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000281 reset_internal_fifo_pointer();
Jason Wanga3f04be2008-11-28 21:36:51 +0000282
Carl-Daniel Hailfingerf8555e22009-07-23 01:36:08 +0000283 /* Skip the bytes we sent. */
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000284 msg_pspew("Skipping: ");
Jason Wanga3f04be2008-11-28 21:36:51 +0000285 for (count = 0; count < writecnt; count++) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000286 msg_pspew("[%02x]", mmio_readb(sb600_spibar + 0xC));
Jason Wanga3f04be2008-11-28 21:36:51 +0000287 }
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000288 msg_pspew("\n");
289 if (compare_internal_fifo_pointer(writecnt))
290 return SPI_PROGRAMMER_ERROR;
Jason Wanga3f04be2008-11-28 21:36:51 +0000291
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000292 msg_pspew("Reading FIFO: ");
293 for (count = 0; count < readcnt; count++) {
294 readarr[count] = mmio_readb(sb600_spibar + 0xC);
295 msg_pspew("[%02x]", readarr[count]);
Jason Wanga3f04be2008-11-28 21:36:51 +0000296 }
Carl-Daniel Hailfinger643415b2010-01-10 01:59:50 +0000297 msg_pspew("\n");
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000298 if (compare_internal_fifo_pointer(writecnt+readcnt))
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000299 return SPI_PROGRAMMER_ERROR;
300
301 if (mmio_readb(sb600_spibar + 1) != readwrite) {
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000302 msg_perr("Unexpected change in AMD SPI read/write count!\n");
303 msg_perr("Something else is accessing the flash chip and causes random corruption.\n"
304 "Please stop all applications and drivers and IPMI which access the flash chip.\n");
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000305 return SPI_PROGRAMMER_ERROR;
306 }
Jason Wanga3f04be2008-11-28 21:36:51 +0000307
308 return 0;
309}
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000310
Wei Hu31402ee2014-05-16 21:39:33 +0000311static int spi100_spi_send_command(struct flashctx *flash, unsigned int writecnt,
312 unsigned int readcnt,
313 const unsigned char *writearr,
314 unsigned char *readarr)
315{
316 /* First byte is cmd which can not be sent through the buffer. */
317 unsigned char cmd = *writearr++;
318 writecnt--;
319 msg_pspew("%s, cmd=0x%02x, writecnt=%d, readcnt=%d\n", __func__, cmd, writecnt, readcnt);
320 mmio_writeb(cmd, sb600_spibar + 0);
321
322 int ret = check_readwritecnt(flash, writecnt, readcnt);
323 if (ret != 0)
324 return ret;
325
326 /* Use the extended TxByteCount and RxByteCount registers. */
327 mmio_writeb(writecnt, sb600_spibar + 0x48);
328 mmio_writeb(readcnt, sb600_spibar + 0x4b);
329
330 msg_pspew("Filling buffer: ");
331 int count;
332 for (count = 0; count < writecnt; count++) {
333 msg_pspew("[%02x]", writearr[count]);
334 mmio_writeb(writearr[count], sb600_spibar + 0x80 + count);
335 }
336 msg_pspew("\n");
337
338 execute_command();
339
340 msg_pspew("Reading buffer: ");
341 for (count = 0; count < readcnt; count++) {
342 readarr[count] = mmio_readb(sb600_spibar + 0x80 + (writecnt + count) % FIFO_SIZE_YANGTZE);
343 msg_pspew("[%02x]", readarr[count]);
344 }
345 msg_pspew("\n");
346
347 return 0;
348}
349
Stefan Taunera6a0d202013-09-15 14:17:39 +0000350struct spispeed {
351 const char *const name;
352 const uint8_t speed;
353};
354
355static const struct spispeed spispeeds[] = {
356 { "66 MHz", 0x00 },
357 { "33 MHz", 0x01 },
358 { "22 MHz", 0x02 },
359 { "16.5 MHz", 0x03 },
Wei Hu31402ee2014-05-16 21:39:33 +0000360 { "100 MHz", 0x04 },
361 { "Reserved", 0x05 },
362 { "Reserved", 0x06 },
363 { "800 kHz", 0x07 },
Stefan Taunera6a0d202013-09-15 14:17:39 +0000364};
365
366static int set_speed(struct pci_dev *dev, const struct spispeed *spispeed)
367{
368 bool success = false;
369 uint8_t speed = spispeed->speed;
370
371 msg_pdbg("Setting SPI clock to %s (0x%x).\n", spispeed->name, speed);
Wei Hu31402ee2014-05-16 21:39:33 +0000372 if (amd_gen >= CHIPSET_YANGTZE) {
373 rmmio_writew((speed << 12) | (speed << 8) | (speed << 4) | speed, sb600_spibar + 0x22);
374 uint16_t tmp = mmio_readw(sb600_spibar + 0x22);
375 success = (((tmp >> 12) & 0xf) == speed && ((tmp >> 8) & 0xf) == speed &&
376 ((tmp >> 4) & 0xf) == speed && ((tmp >> 0) & 0xf) == speed);
377 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000378 rmmio_writeb((mmio_readb(sb600_spibar + 0xd) & ~(0x3 << 4)) | (speed << 4), sb600_spibar + 0xd);
379 success = (speed == ((mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3));
380 }
381
382 if (!success) {
383 msg_perr("Setting SPI clock failed.\n");
384 return 1;
385 }
386 return 0;
387}
388
Wei Hu31402ee2014-05-16 21:39:33 +0000389static int set_mode(struct pci_dev *dev, uint8_t read_mode)
390{
391 uint32_t tmp = mmio_readl(sb600_spibar + 0x00);
392 tmp &= ~(0x6 << 28 | 0x1 << 18); /* Clear mode bits */
393 tmp |= ((read_mode & 0x6) << 28) | ((read_mode & 0x1) << 18);
394 rmmio_writel(tmp, sb600_spibar + 0x00);
395 if (tmp != mmio_readl(sb600_spibar + 0x00))
396 return 1;
397 return 0;
398}
399
Stefan Taunera6a0d202013-09-15 14:17:39 +0000400static int handle_speed(struct pci_dev *dev)
401{
402 uint32_t tmp;
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000403 uint8_t spispeed_idx = 3; /* Default to 16.5 MHz */
Stefan Taunera6a0d202013-09-15 14:17:39 +0000404
Stefan Tauner21071b02014-05-16 21:39:48 +0000405 char *spispeed = extract_programmer_param("spispeed");
406 if (spispeed != NULL) {
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000407 unsigned int i;
408 for (i = 0; i < ARRAY_SIZE(spispeeds); i++) {
409 if (strcasecmp(spispeeds[i].name, spispeed) == 0) {
410 spispeed_idx = i;
411 break;
Stefan Tauner21071b02014-05-16 21:39:48 +0000412 }
Stefan Tauner21071b02014-05-16 21:39:48 +0000413 }
Carl-Daniel Hailfinger57cdd6b2016-03-12 19:49:14 +0000414 /* "reserved" is not a valid speed.
415 * Error out on speeds not present in the spispeeds array.
416 * Only Yangtze supports the second half of indices.
417 * No 66 MHz before SB8xx. */
418 if ((strcasecmp(spispeed, "reserved") == 0) ||
419 (i == ARRAY_SIZE(spispeeds)) ||
420 (amd_gen < CHIPSET_YANGTZE && spispeed_idx > 3) ||
421 (amd_gen < CHIPSET_SB89XX && spispeed_idx == 0)) {
Stefan Tauner21071b02014-05-16 21:39:48 +0000422 msg_perr("Error: Invalid spispeed value: '%s'.\n", spispeed);
423 free(spispeed);
424 return 1;
425 }
426 free(spispeed);
427 }
428
Stefan Taunera6a0d202013-09-15 14:17:39 +0000429 /* See the chipset support matrix for SPI Base_Addr below for an explanation of the symbols used.
Martin Roth82b6ec12014-07-15 13:50:58 +0000430 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson234 bolton/yangtze
Stefan Taunera6a0d202013-09-15 14:17:39 +0000431 * 18 rsvd <- fastReadEnable ? <- ? SpiReadMode[0]
432 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]
433 */
Martin Roth82b6ec12014-07-15 13:50:58 +0000434 if (amd_gen >= CHIPSET_BOLTON) {
Wei Hu31402ee2014-05-16 21:39:33 +0000435 static const char *spireadmodes[] = {
436 "Normal (up to 33 MHz)", /* 0 */
437 "Reserved", /* 1 */
438 "Dual IO (1-1-2)", /* 2 */
439 "Quad IO (1-1-4)", /* 3 */
440 "Dual IO (1-2-2)", /* 4 */
441 "Quad IO (1-4-4)", /* 5 */
442 "Normal (up to 66 MHz)", /* 6 */
Martin Roth82b6ec12014-07-15 13:50:58 +0000443 "Fast Read", /* 7 (Not defined in the Bolton datasheet.) */
Wei Hu31402ee2014-05-16 21:39:33 +0000444 };
445 tmp = mmio_readl(sb600_spibar + 0x00);
446 uint8_t read_mode = ((tmp >> 28) & 0x6) | ((tmp >> 18) & 0x1);
447 msg_pdbg("SpiReadMode=%s (%i)\n", spireadmodes[read_mode], read_mode);
448 if (read_mode != 6) {
449 read_mode = 6; /* Default to "Normal (up to 66 MHz)" */
450 if (set_mode(dev, read_mode) != 0) {
451 msg_perr("Setting read mode to \"%s\" failed.\n", spireadmodes[read_mode]);
452 return 1;
453 }
454 msg_pdbg("Setting read mode to \"%s\" succeeded.\n", spireadmodes[read_mode]);
455 }
456
Martin Roth82b6ec12014-07-15 13:50:58 +0000457 if (amd_gen >= CHIPSET_YANGTZE) {
458 tmp = mmio_readb(sb600_spibar + 0x20);
459 msg_pdbg("UseSpi100 is %sabled\n", (tmp & 0x1) ? "en" : "dis");
460 if ((tmp & 0x1) == 0) {
461 rmmio_writeb(tmp | 0x1, sb600_spibar + 0x20);
462 tmp = mmio_readb(sb600_spibar + 0x20) & 0x1;
463 if (tmp == 0) {
464 msg_perr("Enabling Spi100 failed.\n");
465 return 1;
466 }
467 msg_pdbg("Enabling Spi100 succeeded.\n");
468 }
469
470 tmp = mmio_readw(sb600_spibar + 0x22); /* SPI 100 Speed Config */
471 msg_pdbg("NormSpeedNew is %s\n", spispeeds[(tmp >> 12) & 0xf].name);
472 msg_pdbg("FastSpeedNew is %s\n", spispeeds[(tmp >> 8) & 0xf].name);
473 msg_pdbg("AltSpeedNew is %s\n", spispeeds[(tmp >> 4) & 0xf].name);
474 msg_pdbg("TpmSpeedNew is %s\n", spispeeds[(tmp >> 0) & 0xf].name);
475 }
Wei Hu31402ee2014-05-16 21:39:33 +0000476 } else {
Stefan Taunera6a0d202013-09-15 14:17:39 +0000477 if (amd_gen >= CHIPSET_SB89XX && amd_gen <= CHIPSET_HUDSON234) {
478 bool fast_read = (mmio_readl(sb600_spibar + 0x00) >> 18) & 0x1;
479 msg_pdbg("Fast Reads are %sabled\n", fast_read ? "en" : "dis");
480 if (fast_read) {
481 msg_pdbg("Disabling them temporarily.\n");
482 rmmio_writel(mmio_readl(sb600_spibar + 0x00) & ~(0x1 << 18),
483 sb600_spibar + 0x00);
484 }
485 }
486 tmp = (mmio_readb(sb600_spibar + 0xd) >> 4) & 0x3;
487 msg_pdbg("NormSpeed is %s\n", spispeeds[tmp].name);
488 }
489 return set_speed(dev, &spispeeds[spispeed_idx]);
490}
491
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000492static int handle_imc(struct pci_dev *dev)
Rudolf Marek70e14592013-07-25 22:58:56 +0000493{
494 /* Handle IMC everywhere but sb600 which does not have one. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000495 if (amd_gen == CHIPSET_SB6XX)
Rudolf Marek70e14592013-07-25 22:58:56 +0000496 return 0;
497
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000498 bool amd_imc_force = false;
499 char *arg = extract_programmer_param("amd_imc_force");
500 if (arg && !strcmp(arg, "yes")) {
501 amd_imc_force = true;
502 msg_pspew("amd_imc_force enabled.\n");
503 } else if (arg && !strlen(arg)) {
504 msg_perr("Missing argument for amd_imc_force.\n");
505 free(arg);
506 return 1;
507 } else if (arg) {
508 msg_perr("Unknown argument for amd_imc_force: \"%s\" (not \"yes\").\n", arg);
509 free(arg);
510 return 1;
511 }
512 free(arg);
513
Rudolf Marek70e14592013-07-25 22:58:56 +0000514 /* TODO: we should not only look at IntegratedImcPresent (LPC Dev 20, Func 3, 40h) but also at
Stefan Tauner5c316f92015-02-08 21:57:52 +0000515 * IMCEnable(Strap) and Override EcEnable(Strap) (sb8xx, sb9xx?, a50, Bolton: Misc_Reg: 80h-87h;
Rudolf Marek70e14592013-07-25 22:58:56 +0000516 * sb7xx, sp5100: PM_Reg: B0h-B1h) etc. */
517 uint8_t reg = pci_read_byte(dev, 0x40);
518 if ((reg & (1 << 7)) == 0) {
519 msg_pdbg("IMC is not active.\n");
520 return 0;
521 }
522
523 if (!amd_imc_force)
524 programmer_may_write = 0;
Stefan Tauner463dd692013-08-08 12:00:19 +0000525 msg_pinfo("Writes have been disabled for safety reasons because the presence of the IMC\n"
526 "was detected and it could interfere with accessing flash memory. Flashrom will\n"
527 "try to disable it temporarily but even then this might not be safe:\n"
Stefan Tauner0be072c2016-03-13 15:16:30 +0000528 "when it is re-enabled and after a reboot it expects to find working code\n"
Rudolf Marek70e14592013-07-25 22:58:56 +0000529 "in the flash and it is unpredictable what happens if there is none.\n"
530 "\n"
531 "To be safe make sure that there is a working IMC firmware at the right\n"
532 "location in the image you intend to write and do not attempt to erase.\n"
533 "\n"
534 "You can enforce write support with the amd_imc_force programmer option.\n");
535 if (amd_imc_force)
536 msg_pinfo("Continuing with write support because the user forced us to!\n");
537
538 return amd_imc_shutdown(dev);
539}
540
Michael Karcherb05b9e12010-07-22 18:04:19 +0000541int sb600_probe_spi(struct pci_dev *dev)
542{
543 struct pci_dev *smbus_dev;
544 uint32_t tmp;
545 uint8_t reg;
Rudolf Marek70e14592013-07-25 22:58:56 +0000546
Michael Karcherb05b9e12010-07-22 18:04:19 +0000547 /* Read SPI_BaseAddr */
548 tmp = pci_read_long(dev, 0xa0);
549 tmp &= 0xffffffe0; /* remove bits 4-0 (reserved) */
550 msg_pdbg("SPI base address is at 0x%x\n", tmp);
551
552 /* If the BAR has address 0, it is unlikely SPI is used. */
553 if (!tmp)
554 return 0;
555
556 /* Physical memory has to be mapped at page (4k) boundaries. */
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000557 sb600_spibar = rphysmap("SB600 SPI registers", tmp & 0xfffff000, 0x1000);
558 if (sb600_spibar == ERROR_PTR)
Niklas Söderlund5d307202013-09-14 09:02:27 +0000559 return ERROR_FATAL;
Stefan Tauner7fb5aa02013-08-14 15:48:44 +0000560
Michael Karcherb05b9e12010-07-22 18:04:19 +0000561 /* The low bits of the SPI base address are used as offset into
562 * the mapped page.
563 */
564 sb600_spibar += tmp & 0xfff;
565
Stefan Tauner463dd692013-08-08 12:00:19 +0000566 determine_generation(dev);
Stefan Tauner4442b812013-09-12 15:48:35 +0000567 if (amd_gen == CHIPSET_AMD_UNKNOWN) {
568 msg_perr("Could not determine chipset generation.");
569 return ERROR_NONFATAL;
570 }
Stefan Tauner463dd692013-08-08 12:00:19 +0000571
Stefan Tauner4442b812013-09-12 15:48:35 +0000572 /* How to read the following table and similar ones in this file:
573 * "?" means we have no datasheet for this chipset generation or it doesn't have any relevant info.
574 * "<-" means the bit/register meaning is identical to the next non-"?" chipset to the left. "<-" thus
575 * never refers to another "?".
576 * If a "?" chipset is between two chipsets with identical meaning, we assume the meaning didn't change
577 * twice in between, i.e. the meaning is unchanged for the "?" chipset. Usually we assume that
578 * succeeding hardware supports the same functionality as its predecessor unless proven different by
579 * tests or documentation, hence "?" will often be implemented equally to "<-".
580 *
581 * Chipset support matrix for SPI Base_Addr (LPC PCI reg 0xa0)
582 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
583 * 3 rsvd <- <- ? <- ? RouteTpm2Spi
584 * 2 rsvd AbortEnable rsvd ? <- ? <-
585 * 1 rsvd SpiRomEnable <- ? <- ? <-
586 * 0 rsvd AltSpiCSEnable rsvd ? <- ? <-
587 */
588 if (amd_gen >= CHIPSET_SB7XX) {
589 tmp = pci_read_long(dev, 0xa0);
590 msg_pdbg("SpiRomEnable=%i", (tmp >> 1) & 0x1);
591 if (amd_gen == CHIPSET_SB7XX)
592 msg_pdbg(", AltSpiCSEnable=%i, AbortEnable=%i", tmp & 0x1, (tmp >> 2) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000593 else if (amd_gen == CHIPSET_YANGTZE)
594 msg_pdbg(", RouteTpm2Sp=%i", (tmp >> 3) & 0x1);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000595
Stefan Tauner4442b812013-09-12 15:48:35 +0000596 tmp = pci_read_byte(dev, 0xba);
597 msg_pdbg(", PrefetchEnSPIFromIMC=%i", (tmp & 0x4) >> 2);
598
599 tmp = pci_read_byte(dev, 0xbb);
600 /* FIXME: Set bit 3,6,7 if not already set.
601 * Set bit 5, otherwise SPI accesses are pointless in LPC mode.
602 * See doc 42413 AMD SB700/710/750 RPR.
603 */
604 if (amd_gen == CHIPSET_SB7XX)
605 msg_pdbg(", SpiOpEnInLpcMode=%i", (tmp >> 5) & 0x1);
606 msg_pdbg(", PrefetchEnSPIFromHost=%i\n", tmp & 0x1);
607 }
608
609 /* Chipset support matrix for SPI_Cntrl0 (spibar + 0x0)
610 * See the chipset support matrix for SPI Base_Addr above for an explanation of the symbols used.
611 * bit 6xx 7xx/SP5100 8xx 9xx hudson1 hudson2+ yangtze
612 * 17 rsvd <- <- ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000613 * 18 rsvd <- fastReadEnable<1> ? <- ? SpiReadMode[0]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000614 * 19 SpiArbEnable <- <- ? <- ? <-
615 * 20 (FifoPtrClr) <- <- ? <- ? <-
616 * 21 (FifoPtrInc) <- <- ? <- ? IllegalAccess
617 * 22 SpiAccessMacRomEn <- <- ? <- ? <-
618 * 23 SpiHostAccessRomEn <- <- ? <- ? <-
619 * 24:26 ArbWaitCount <- <- ? <- ? <-
620 * 27 SpiBridgeDisable <- <- ? <- ? rsvd
621 * 28 rsvd DropOneClkOnRd = SPIClkGate ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000622 * 29:30 rsvd <- <- ? <- ? SpiReadMode[2:1]<1>
Stefan Tauner4442b812013-09-12 15:48:35 +0000623 * 31 rsvd <- SpiBusy ? <- ? <-
Stefan Taunera6a0d202013-09-15 14:17:39 +0000624 *
625 * <1> see handle_speed
Carl-Daniel Hailfingereb0e7fc2010-08-18 15:12:43 +0000626 */
Stefan Tauner4442b812013-09-12 15:48:35 +0000627 tmp = mmio_readl(sb600_spibar + 0x00);
628 msg_pdbg("(0x%08" PRIx32 ") SpiArbEnable=%i", tmp, (tmp >> 19) & 0x1);
Wei Hu31402ee2014-05-16 21:39:33 +0000629 if (amd_gen == CHIPSET_YANGTZE)
630 msg_pdbg(", IllegalAccess=%i", (tmp >> 21) & 0x1);
Stefan Tauner4442b812013-09-12 15:48:35 +0000631
632 msg_pdbg(", SpiAccessMacRomEn=%i, SpiHostAccessRomEn=%i, ArbWaitCount=%i",
633 (tmp >> 22) & 0x1, (tmp >> 23) & 0x1, (tmp >> 24) & 0x7);
634
635 if (amd_gen != CHIPSET_YANGTZE)
636 msg_pdbg(", SpiBridgeDisable=%i", (tmp >> 27) & 0x1);
637
638 switch (amd_gen) {
639 case CHIPSET_SB7XX:
640 msg_pdbg(", DropOneClkOnRd/SpiClkGate=%i", (tmp >> 28) & 0x1);
Richard Hughesdb7482b2018-12-19 12:04:30 +0000641 /* Fall through. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000642 case CHIPSET_SB89XX:
643 case CHIPSET_HUDSON234:
Wei Hu31402ee2014-05-16 21:39:33 +0000644 case CHIPSET_YANGTZE:
Stefan Tauner4442b812013-09-12 15:48:35 +0000645 msg_pdbg(", SpiBusy=%i", (tmp >> 31) & 0x1);
646 default: break;
647 }
648 msg_pdbg("\n");
649
650 if (((tmp >> 22) & 0x1) == 0 || ((tmp >> 23) & 0x1) == 0) {
651 msg_perr("ERROR: State of SpiAccessMacRomEn or SpiHostAccessRomEn prohibits full access.\n");
652 return ERROR_NONFATAL;
653 }
654
Stefan Tauner4442b812013-09-12 15:48:35 +0000655 if (amd_gen >= CHIPSET_SB89XX) {
656 tmp = mmio_readb(sb600_spibar + 0x1D);
657 msg_pdbg("Using SPI_CS%d\n", tmp & 0x3);
Wei Hu31402ee2014-05-16 21:39:33 +0000658 /* FIXME: Handle SpiProtect* configuration on Yangtze. */
Stefan Tauner4442b812013-09-12 15:48:35 +0000659 }
660
Michael Karcherb05b9e12010-07-22 18:04:19 +0000661 /* Look for the SMBus device. */
662 smbus_dev = pci_dev_find(0x1002, 0x4385);
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100663 if (!smbus_dev)
Stefan Tauner463dd692013-08-08 12:00:19 +0000664 smbus_dev = pci_dev_find(0x1022, 0x780b); /* AMD FCH */
Ricardo Ribalda Delgado7b629bc2017-03-22 14:08:31 +0100665 if (!smbus_dev)
666 smbus_dev = pci_dev_find(0x1022, 0x790b); /* AMD FP4 */
667 if (!smbus_dev) {
668 msg_perr("ERROR: SMBus device not found. Not enabling SPI.\n");
669 return ERROR_NONFATAL;
Michael Karcherb05b9e12010-07-22 18:04:19 +0000670 }
671
672 /* Note about the bit tests below: If a bit is zero, the GPIO is SPI. */
673 /* GPIO11/SPI_DO and GPIO12/SPI_DI status */
674 reg = pci_read_byte(smbus_dev, 0xAB);
675 reg &= 0xC0;
676 msg_pdbg("GPIO11 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_DO");
677 msg_pdbg("GPIO12 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_DI");
678 if (reg != 0x00) {
679 msg_pdbg("Not enabling SPI");
680 return 0;
681 }
682 /* GPIO31/SPI_HOLD and GPIO32/SPI_CS status */
683 reg = pci_read_byte(smbus_dev, 0x83);
684 reg &= 0xC0;
685 msg_pdbg("GPIO31 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_HOLD");
686 msg_pdbg("GPIO32 used for %s\n", (reg & (1 << 7)) ? "GPIO" : "SPI_CS");
687 /* SPI_HOLD is not used on all boards, filter it out. */
688 if ((reg & 0x80) != 0x00) {
689 msg_pdbg("Not enabling SPI");
690 return 0;
691 }
692 /* GPIO47/SPI_CLK status */
693 reg = pci_read_byte(smbus_dev, 0xA7);
694 reg &= 0x40;
695 msg_pdbg("GPIO47 used for %s\n", (reg & (1 << 6)) ? "GPIO" : "SPI_CLK");
696 if (reg != 0x00) {
697 msg_pdbg("Not enabling SPI");
698 return 0;
699 }
700
Stefan Taunera6a0d202013-09-15 14:17:39 +0000701 if (handle_speed(dev) != 0)
702 return ERROR_FATAL;
703
Stefan Taunerd5b2aef2014-05-16 21:39:28 +0000704 if (handle_imc(dev) != 0)
Rudolf Marek70e14592013-07-25 22:58:56 +0000705 return ERROR_FATAL;
Carl-Daniel Hailfinger39446e32010-09-15 12:02:07 +0000706
Wei Hu31402ee2014-05-16 21:39:33 +0000707 /* Starting with Yangtze the SPI controller got a different interface with a much bigger buffer. */
708 if (amd_gen != CHIPSET_YANGTZE)
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000709 register_spi_master(&spi_master_sb600);
Wei Hu31402ee2014-05-16 21:39:33 +0000710 else
Carl-Daniel Hailfingera5bcbce2014-07-19 22:03:29 +0000711 register_spi_master(&spi_master_yangtze);
Michael Karcherb05b9e12010-07-22 18:04:19 +0000712 return 0;
713}
714
Carl-Daniel Hailfingercceafa22010-05-26 01:45:41 +0000715#endif