/* * 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 #include #include 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; }