[coreboot-gerrit] Change in coreboot[master]: amdfwtool: Add SPI mode and SPI speed support

Marc Jones (Code Review) gerrit at coreboot.org
Fri Jan 5 07:59:57 CET 2018


Marc Jones has uploaded this change for review. ( https://review.coreboot.org/23132


Change subject: amdfwtool: Add SPI mode and SPI speed support
......................................................................

amdfwtool: Add SPI mode and SPI speed support

Add SPI mode and SPI speed setting to the ROMSIG.
This is used by AGESA and the PSP for optimal SPI ROM reads.

BUG=b:70844938
TEST=build with mode and speed options.
     Check ROMSIG offset 0x40 is set as expected.

Change-Id: I025ab969893553982bb2191111912f7334143440
Signed-off-by: Marc Jones <marcj303 at gmail.com>
---
M util/amdfwtool/amdfwtool.c
1 file changed, 175 insertions(+), 4 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/23132/1

diff --git a/util/amdfwtool/amdfwtool.c b/util/amdfwtool/amdfwtool.c
index 61c2a05..5a06e2a 100644
--- a/util/amdfwtool/amdfwtool.c
+++ b/util/amdfwtool/amdfwtool.c
@@ -21,6 +21,12 @@
  *  +------------+---------------+----------------+------------+
  *  | PSPDIR ADDR|PSPDIR ADDR    |<-- Field 0x14 could be either
  *  +------------+---------------+   2nd PSP directory or PSP COMBO directory
+ * ...
+ *  40
+ *  +------------+
+ *  | SPI Mode   | <- SPI mode(0x40) and SPI fast read speed(0x41)
+ *  +------------+
+ *
  *  EC ROM should be 64K aligned.
  *
  *  PSP directory (Where "PSPDIR ADDR" points)
@@ -58,7 +64,6 @@
  *  +------------+---------------+----------------+------------+
  *
  */
-
 #include <fcntl.h>
 #include <errno.h>
 #include <stdio.h>
@@ -77,6 +82,7 @@
 #define MIN_ROM_KB		256
 
 #define ALIGN(val, by) (((val) + (by) - 1) & ~((by) - 1))
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
 /*
   Reserved for future.
@@ -191,6 +197,10 @@
 		MIN_ROM_KB);
 	printf("                               and must a multiple of 1024\n");
 	printf("-l | --location                Location of Directory\n");
+	printf("-q | --spimode <MODE>          norm33, norm66\n");
+	printf("                               dual112, dual122\n");
+	printf("                               quad114, quad144, fast\n");
+	printf("-z | --spispeed <SPEED>        16, 22, 33, 66, 100 (Mhz)\n");
 	printf("-h | --help                    show this help\n");
 
 }
@@ -376,17 +386,129 @@
 	return pos;
 }
 
+/*
+ * SPI read modes
+ * 000b Normal read (up to 33M)
+ * 001b Reserved
+ * 010b Dual IO (1-1-2)
+ * 011b Quad IO (1-1-4)
+ * 100b Dual IO (1-2-2)
+ * 101b Quad IO (1-4-4)
+ * 110b Normal read (up to 66M)
+ * 111b Fast Read
+ */
+
+struct spimodes {
+	char *mode;
+	uint8_t val;
+};
+
+static const struct spimodes modesettings[] = {
+	{
+		.mode = "norm33",
+		.val =  0
+	},
+	{
+		.mode = "norm66",
+		.val =  6,
+	},
+	{
+		.mode = "dual112",
+		.val = 2,
+	},
+	{
+		.mode = "dual122",
+		.val = 4,
+	},
+	{
+		.mode = "quad114",
+		.val = 3,
+	},
+	{
+		.mode = "quad144",
+		.val = 5
+	},
+	{
+		.mode = "fast",
+		.val = 7,
+	},
+};
+
+/*
+ * SPI read speed
+ * 0000b 66.66 MHz    0100b 100 MHz
+ * 0001b 33.33 MHz    0101b 800 KHz
+ * 0010b 22.22 MHz    1111b-0110b Reserved
+ * 0011b 16.66 MHz
+ */
+
+
+struct spispeeds {
+	uint8_t speed;
+	uint8_t val;
+};
+
+static const struct spispeeds speedsettings[] = {
+	{
+		.speed = 66,
+		.val = 0,
+	},
+	{
+		.speed = 33,
+		.val = 1,
+	},
+	{
+		.speed = 22,
+		.val = 2,
+	},
+	{
+		.speed = 16,
+		.val = 3,
+	},
+	{
+		.speed = 100,
+		.val = 4,
+	},
+};
+
+/*
+ * Set the mode in ROM_SIG offset 0x40 and the speed in offset 0x41.
+ */
+static void spi_mode_speed(uint32_t *romsig, char *spimode, uint8_t spispeed)
+{
+	uint8_t modeval;
+	uint8_t speedval;
+	int i;
+
+	for (i  = 0; i < ARRAY_SIZE(modesettings); i++) {
+		if (strcmp(spimode, modesettings[i].mode) == 0) {
+			modeval = modesettings[i].val;
+			break;
+		}
+	}
+
+	for (i  = 0; i < ARRAY_SIZE(speedsettings); i++) {
+		if (spispeed == speedsettings[i].speed) {
+			speedval = speedsettings[i].val;
+			break;
+		}
+	}
+
+	romsig[16] = modeval | speedval << 8 | 0xDEAD << 16;
+}
+
 #if PSP2
 static const char *optstring  =
-	"x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:P:B:S:L:R:K:C:N:D:T:U:W:E:M:o:f:l:h";
+	"x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:P:B:S:L:R:K:C:N:D:T:U:W:E:M:o:f:l:q:z:h";
 #else
-static const char *optstring  = "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:o:f:l:h";
+static const char *optstring  = "x:i:g:p:b:s:r:k:c:n:d:t:u:w:m:o:f:l:q:z:h";
 #endif
 
 static struct option long_options[] = {
 	{"xhci",             required_argument, 0, 'x' },
 	{"imc",              required_argument, 0, 'i' },
 	{"gec",              required_argument, 0, 'g' },
+
 	/* PSP */
 	{"pubkey",           required_argument, 0, 'p' },
 	{"bootloader",       required_argument, 0, 'b' },
@@ -422,6 +544,8 @@
 	{"output",           required_argument, 0, 'o' },
 	{"flashsize",        required_argument, 0, 'f' },
 	{"location",         required_argument, 0, 'l' },
+	{"spimode",          required_argument, 0, 'q' },
+	{"spispeed",         required_argument, 0, 'z' },
 	{"help",             no_argument,       0, 'h' },
 
 	{NULL,               0,                 0,  0  }
@@ -484,6 +608,9 @@
 	uint32_t dir_location = 0;
 	uint32_t romsig_offset;
 	uint32_t rom_base_address;
+	uint8_t spispeed = 0;
+	char *spimode = NULL;
+	int i;
 
 	while (1) {
 		int optindex = 0;
@@ -636,6 +763,17 @@
 				retval = 1;
 			}
 			break;
+		case 'q':
+			spimode = optarg;
+			break;
+		case 'z':
+			spispeed = (uint8_t)strtoul(optarg, &tmp, 10);
+			if (*tmp != '\0') {
+				printf("Error: spispeed  specified"
+					" incorrectly (%s)\n\n", optarg);
+				retval = 1;
+			}
+			break;
 
 		case 'h':
 			usage();
@@ -667,6 +805,36 @@
 		retval = 1;
 	}
 
+	if (spimode) {
+		for (i  = 0; i < ARRAY_SIZE(modesettings); i++) {
+			if (strcmp(spimode, modesettings[i].mode) == 0)
+				break;
+		}
+
+		if (i == ARRAY_SIZE(modesettings)) {
+			printf("Error: spimode %s is not supported.\n",
+				spimode);
+			printf("   Valid values are: norm33, norm66\n");
+			printf("                     dual112, dual122\n");
+			printf("                     quad114, quad144\n");
+			printf("                     fast\n\n");
+			retval = 1;
+		}
+	}
+
+	if (spispeed) {
+		for (i  = 0; i < ARRAY_SIZE(speedsettings); i++) {
+			if (spispeed == speedsettings[i].speed)
+			break;
+		}
+
+		if (i == ARRAY_SIZE(speedsettings)) {
+			printf("Error: spispeed %d is not supported.\n", spispeed);
+			printf("   Valid speeds are 16, 33, 66, and 100 (Mhz).\n\n");
+			retval = 1;
+		}
+	}
+
 	if (retval) {
 		usage();
 		return retval;
@@ -714,7 +882,9 @@
 	amd_romsig[2] = 0;
 	amd_romsig[3] = 0;
 
-	current += 0x20;	    /* size of ROMSIG */
+	spi_mode_speed(amd_romsig, spimode, spispeed);
+
+	current += 0x50;		/* size of ROMSIG */
 	current = ALIGN(current, 0x1000U);
 	current = integrate_firmwares(rom, current, amd_romsig,
 			amd_fw_table, rom_size);
@@ -769,6 +939,7 @@
 	}
 #endif
 
+
 	targetfd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0666);
 	if (targetfd >= 0) {
 		write(targetfd, amd_romsig, current - romsig_offset);

-- 
To view, visit https://review.coreboot.org/23132
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I025ab969893553982bb2191111912f7334143440
Gerrit-Change-Number: 23132
Gerrit-PatchSet: 1
Gerrit-Owner: Marc Jones <marc at marcjonesconsulting.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20180105/b5de84ff/attachment-0001.html>


More information about the coreboot-gerrit mailing list