aboutsummaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block/spi/fch_spi_special.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/common/block/spi/fch_spi_special.c')
-rw-r--r--src/soc/amd/common/block/spi/fch_spi_special.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/soc/amd/common/block/spi/fch_spi_special.c b/src/soc/amd/common/block/spi/fch_spi_special.c
new file mode 100644
index 0000000000..456a3896f5
--- /dev/null
+++ b/src/soc/amd/common/block/spi/fch_spi_special.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2019 Silverback Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <console/console.h>
+#include <spi-generic.h>
+#include <amdblocks/fch_spi.h>
+#include <string.h>
+
+int non_standard_sst_byte_write(u32 offset, const void *buf)
+{
+ int ret;
+ u8 cmd[4] = {
+ CMD_SST_BP,
+ offset >> 16,
+ offset >> 8,
+ offset,
+ };
+
+ ret = fch_spi_enable_write();
+ if (ret)
+ return ret;
+
+ ret = fch_spi_flash_cmd_write(cmd, sizeof(cmd), buf, 1);
+ if (ret)
+ return ret;
+
+ return fch_spi_wait_cmd_ready(SPI_FLASH_PROG_TIMEOUT_MS);
+}
+
+int non_standard_sst_write_aai(u32 offset, size_t len, const void *buf, size_t start)
+{
+ size_t actual, cmd_len;
+ int ret = 0;
+ u8 cmd[4];
+
+ ret = fch_spi_enable_write();
+ if (ret)
+ goto done;
+
+ cmd_len = 4;
+ cmd[0] = CMD_SST_AAI_WP;
+ cmd[1] = offset >> 16;
+ cmd[2] = offset >> 8;
+ cmd[3] = offset;
+
+ for (actual = start; actual < len - 1; actual += 2) {
+#if CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)
+ printk(BIOS_DEBUG, "PP: 0x%p => cmd = { 0x%02x 0x%06lx }"
+ " chunk_len = 2\n",
+ buf + actual, cmd[0], (offset + actual));
+#endif
+
+ ret = fch_spi_enable_write();
+ if (ret < 0) {
+ printk(BIOS_WARNING, "SF: Enabling Write failed\n");
+ break;
+ }
+
+ ret = fch_spi_flash_cmd_write(cmd, cmd_len, buf + actual, 2);
+ if (ret < 0) {
+ printk(BIOS_WARNING, "SF: SST word Program failed\n");
+ break;
+ }
+
+ ret = fch_spi_wait_cmd_ready(SPI_FLASH_PROG_TIMEOUT_MS);
+ if (ret)
+ break;
+
+ offset += 2;
+ cmd_len = 1;
+ }
+ /* If there is a single trailing byte, write it out */
+ if (!ret && actual != len)
+ ret = non_standard_sst_byte_write(offset, buf + actual);
+done:
+ return ret;
+}