mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
spi_flash: Rework protection translation functions
Previously we defined separate functions to map registers to protect ranges for each supported SPI ROM. This change instead adds a protect range table + flags for each supported SPI ROM and adds common functions for translation between ranges + registers. This makes supporting new parts easier. Since we will never use most supported protection ranges, we can even simplfy the tables. The implementation is now similar to flashrom. BUG=chrome-os-partner:37688 TEST=Manual on Glower. flashwp disable + spi_flash_rsr --> 0 flashinfo --> shows no protection spi_flash_prot 0 0x10000 + spi_flash_rsr --> 0x24 flashinfo --> shows 64KB protected spi_flash_prot 0 0x20000 + spi_flash_rsr --> 0x28 flashinfo --> shows all 96KB protected spi_flash_prot 0 0x40000 + spi_flash_rsr --> 0x2c spi_flash_prot 0 0x80000 + spi_flash_rsr --> 0x10 spi_flash_prot 0 0 + spi_flash_rsr --> 0x00 spi_flash_prot 0 0x1000 --> error spi_flash_prot 0x10000 0x10000 --> error BRANCH=None Change-Id: Ie5908ce687b7ff207b09794c7b001a4fbd9e0f5a Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/259310 Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
committed by
ChromeOS Commit Bot
parent
fa671e6591
commit
746debdf20
@@ -74,7 +74,7 @@ common-$(CONFIG_SHA1)+=sha1.o
|
||||
common-$(CONFIG_SHA256)+=sha256.o
|
||||
common-$(CONFIG_SMBUS)+= smbus.o
|
||||
common-$(CONFIG_SOFTWARE_CLZ)+=clz.o
|
||||
common-$(CONFIG_SPI_FLASH)+=spi_flash.o
|
||||
common-$(CONFIG_SPI_FLASH)+=spi_flash.o spi_flash_reg.o
|
||||
common-$(CONFIG_STREAM)+=in_stream.o out_stream.o stream_adaptor.o
|
||||
common-$(CONFIG_SWITCH)+=switch.o
|
||||
common-$(CONFIG_SW_CRC)+=crc.o
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "shared_mem.h"
|
||||
#include "spi.h"
|
||||
#include "spi_flash.h"
|
||||
#include "spi_flash_reg.h"
|
||||
#include "timer.h"
|
||||
#include "util.h"
|
||||
#include "watchdog.h"
|
||||
@@ -25,241 +26,9 @@
|
||||
*/
|
||||
#define SPI_FLASH_TIMEOUT_USEC (800*MSEC)
|
||||
|
||||
/*
|
||||
* Common registers for SPI flash. All registers may not be valid for
|
||||
* all parts.
|
||||
*/
|
||||
#define SPI_FLASH_SR2_SUS (1 << 7)
|
||||
#define SPI_FLASH_SR2_CMP (1 << 6)
|
||||
#define SPI_FLASH_SR2_LB3 (1 << 5)
|
||||
#define SPI_FLASH_SR2_LB2 (1 << 4)
|
||||
#define SPI_FLASH_SR2_LB1 (1 << 3)
|
||||
#define SPI_FLASH_SR2_QE (1 << 1)
|
||||
#define SPI_FLASH_SR2_SRP1 (1 << 0)
|
||||
#define SPI_FLASH_SR1_SRP0 (1 << 7)
|
||||
#define SPI_FLASH_SR1_SEC (1 << 6)
|
||||
#define SPI_FLASH_SR1_TB (1 << 5)
|
||||
#define SPI_FLASH_SR1_BP2 (1 << 4)
|
||||
#define SPI_FLASH_SR1_BP1 (1 << 3)
|
||||
#define SPI_FLASH_SR1_BP0 (1 << 2)
|
||||
#define SPI_FLASH_SR1_WEL (1 << 1)
|
||||
#define SPI_FLASH_SR1_BUSY (1 << 0)
|
||||
|
||||
/* Internal buffer used by SPI flash driver */
|
||||
static uint8_t buf[SPI_FLASH_MAX_MESSAGE_SIZE];
|
||||
|
||||
/**
|
||||
* Computes block write protection range from registers
|
||||
* Returns start == len == 0 for no protection
|
||||
*
|
||||
* @param sr1 Status register 1
|
||||
* @param sr2 Status register 2
|
||||
* @param start Output pointer for protection start offset
|
||||
* @param len Output pointer for protection length
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
#ifdef CONFIG_SPI_FLASH_W25Q64
|
||||
static int reg_to_protect(uint8_t sr1, uint8_t sr2, unsigned int *start,
|
||||
unsigned int *len)
|
||||
{
|
||||
int blocks;
|
||||
int size;
|
||||
uint8_t cmp;
|
||||
uint8_t sec;
|
||||
uint8_t tb;
|
||||
uint8_t bp;
|
||||
|
||||
/* Determine flags */
|
||||
cmp = (sr2 & SPI_FLASH_SR2_CMP) ? 1 : 0;
|
||||
sec = (sr1 & SPI_FLASH_SR1_SEC) ? 1 : 0;
|
||||
tb = (sr1 & SPI_FLASH_SR1_TB) ? 1 : 0;
|
||||
bp = (sr1 & (SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0))
|
||||
>> 2;
|
||||
|
||||
/* Bad pointers or invalid data */
|
||||
if (!start || !len || sr1 == -1 || sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Not defined by datasheet */
|
||||
if (sec && bp == 6)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Determine granularity (4kb sector or 64kb block) */
|
||||
/* Computation using 2 * 1024 is correct */
|
||||
size = sec ? (2 * 1024) : (64 * 1024);
|
||||
|
||||
/* Determine number of blocks */
|
||||
/* Equivalent to pow(2, bp) with pow(2, 0) = 0 */
|
||||
blocks = bp ? (1 << bp) : 0;
|
||||
/* Datasheet specifies don't care for BP == 4, BP == 5 */
|
||||
if (sec && bp == 5)
|
||||
blocks = (1 << 4);
|
||||
|
||||
/* Determine number of bytes */
|
||||
*len = size * blocks;
|
||||
|
||||
/* Determine bottom/top of memory to protect */
|
||||
*start = tb ? 0 :
|
||||
(CONFIG_SPI_FLASH_SIZE - *len) % CONFIG_SPI_FLASH_SIZE;
|
||||
|
||||
/* Reverse computations if complement set */
|
||||
if (cmp) {
|
||||
*start = (*start + *len) % CONFIG_SPI_FLASH_SIZE;
|
||||
*len = CONFIG_SPI_FLASH_SIZE - *len;
|
||||
}
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#elif defined(CONFIG_SPI_FLASH_W25X40) /* CONFIG_SPI_FLASH_W25Q64 */
|
||||
static int reg_to_protect(uint8_t sr1, uint8_t sr2, unsigned int *start,
|
||||
unsigned int *len)
|
||||
{
|
||||
int blocks;
|
||||
int size;
|
||||
uint8_t tb;
|
||||
uint8_t bp;
|
||||
|
||||
tb = (sr1 & SPI_FLASH_SR1_TB) ? 1 : 0;
|
||||
bp = (sr1 & (SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0))
|
||||
>> 2;
|
||||
|
||||
/* Bad pointers or invalid data */
|
||||
if (!start || !len || sr1 == -1 || sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* 64kb block protection granularity */
|
||||
size = 32 * 1024;
|
||||
|
||||
/* Determine number of blocks */
|
||||
/* Equivalent to pow(2, bp) with pow(2, 0) = 0 */
|
||||
/* BP2 set indicates entire 512kb flash protected */
|
||||
if (!bp)
|
||||
blocks = 0;
|
||||
else
|
||||
blocks = MIN((1 << 4), (1 << bp));
|
||||
*len = size * blocks;
|
||||
*start = tb ? 0 :
|
||||
(CONFIG_SPI_FLASH_SIZE - *len) % CONFIG_SPI_FLASH_SIZE;
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_SPI_FLASH_W25X40 */
|
||||
|
||||
/**
|
||||
* Computes block write protection registers from range
|
||||
*
|
||||
* @param start Desired protection start offset
|
||||
* @param len Desired protection length
|
||||
* @param sr1 Output pointer for status register 1
|
||||
* @param sr2 Output pointer for status register 2
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
#ifdef CONFIG_SPI_FLASH_W25Q64
|
||||
static int protect_to_reg(unsigned int start, unsigned int len,
|
||||
uint8_t *sr1, uint8_t *sr2)
|
||||
{
|
||||
char cmp = 0;
|
||||
char sec = 0;
|
||||
char tb = 0;
|
||||
char bp = 0;
|
||||
int blocks;
|
||||
int size;
|
||||
|
||||
/* Bad pointers */
|
||||
if (!sr1 || !sr2 || *sr1 == -1 || *sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Invalid data */
|
||||
if ((start && !len) || start + len > CONFIG_SPI_FLASH_SIZE)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Set complement bit based on whether length is power of 2 */
|
||||
if ((len & (len - 1)) != 0) {
|
||||
cmp = 1;
|
||||
start = (start + len) % CONFIG_SPI_FLASH_SIZE;
|
||||
len = CONFIG_SPI_FLASH_SIZE - len;
|
||||
}
|
||||
|
||||
/* Set bottom/top bit based on start address */
|
||||
/* Do not set if len == 0 or len == CONFIG_SPI_FLASH_SIZE */
|
||||
if (!start && (len % CONFIG_SPI_FLASH_SIZE))
|
||||
tb = 1;
|
||||
|
||||
/* Set sector bit and determine block length based on protect length */
|
||||
if (len == 0 || len >= 128 * 1024) {
|
||||
sec = 0;
|
||||
size = 64 * 1024;
|
||||
} else if (len >= 4 * 1024 && len <= 32 * 1024) {
|
||||
sec = 1;
|
||||
size = 2 * 1024;
|
||||
} else
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Determine number of blocks */
|
||||
if (len % size != 0)
|
||||
return EC_ERROR_INVAL;
|
||||
blocks = len / size;
|
||||
|
||||
/* Determine bp = log2(blocks) with log2(0) = 0 */
|
||||
bp = blocks ? (31 - __builtin_clz(blocks)) : 0;
|
||||
|
||||
/* Clear bits */
|
||||
*sr1 &= ~(SPI_FLASH_SR1_SEC | SPI_FLASH_SR1_TB |
|
||||
SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0);
|
||||
*sr2 &= ~SPI_FLASH_SR2_CMP;
|
||||
|
||||
/* Set bits */
|
||||
*sr1 |= (sec ? SPI_FLASH_SR1_SEC : 0) | (tb ? SPI_FLASH_SR1_TB : 0)
|
||||
| (bp << 2);
|
||||
*sr2 |= (cmp ? SPI_FLASH_SR2_CMP : 0);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#elif defined(CONFIG_SPI_FLASH_W25X40) /* CONFIG_SPI_FLASH_W25Q64 */
|
||||
static int protect_to_reg(unsigned int start, unsigned int len,
|
||||
uint8_t *sr1, uint8_t *sr2)
|
||||
{
|
||||
char tb = 0;
|
||||
char bp = 0;
|
||||
int blocks;
|
||||
int size;
|
||||
|
||||
/* Bad pointers */
|
||||
if (!sr1 || !sr2 || *sr1 == -1 || *sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Invalid data */
|
||||
if ((start && !len) || start + len > CONFIG_SPI_FLASH_SIZE)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Set bottom/top bit based on start address */
|
||||
if (!start && (len % CONFIG_SPI_FLASH_SIZE))
|
||||
tb = 1;
|
||||
|
||||
/* 64kb block protection granularity */
|
||||
size = 32 * 1024;
|
||||
|
||||
/* Determine number of blocks */
|
||||
if (len % size != 0)
|
||||
return EC_ERROR_INVAL;
|
||||
blocks = len / size;
|
||||
|
||||
/* Determine bp = log2(blocks) with log2(0) = 0 */
|
||||
bp = blocks ? (31 - __builtin_clz(blocks)) : 0;
|
||||
|
||||
/* Clear bits */
|
||||
*sr1 &= ~(SPI_FLASH_SR1_TB | SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 |
|
||||
SPI_FLASH_SR1_BP0);
|
||||
|
||||
/* Set bits */
|
||||
*sr1 |= (tb ? SPI_FLASH_SR1_TB : 0) | (bp << 2);
|
||||
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_SPI_FLASH_W25X40 */
|
||||
|
||||
/**
|
||||
* Waits for chip to finish current operation. Must be called after
|
||||
* erase/write operations to ensure successive commands are executed.
|
||||
@@ -315,8 +84,8 @@ uint8_t spi_flash_get_status2(void)
|
||||
uint8_t cmd = SPI_FLASH_READ_SR2;
|
||||
uint8_t resp;
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_W25X40
|
||||
/* Second status register not present */
|
||||
#ifndef CONFIG_SPI_FLASH_HAS_SR2
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
@@ -349,8 +118,8 @@ int spi_flash_set_status(int reg1, int reg2)
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
#ifdef CONFIG_SPI_FLASH_W25X40
|
||||
/* Second status register not present */
|
||||
#ifndef CONFIG_SPI_FLASH_HAS_SR2
|
||||
reg2 = -1;
|
||||
#endif
|
||||
|
||||
@@ -621,7 +390,7 @@ int spi_flash_check_protect(unsigned int offset, unsigned int bytes)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Compute current protect range */
|
||||
rv = reg_to_protect(sr1, sr2, &start, &len);
|
||||
rv = spi_flash_reg_to_protect(sr1, sr2, &start, &len);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
@@ -652,7 +421,7 @@ int spi_flash_set_protect(unsigned int offset, unsigned int bytes)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Compute desired protect range */
|
||||
rv = protect_to_reg(offset, bytes, &sr1, &sr2);
|
||||
rv = spi_flash_protect_to_reg(offset, bytes, &sr1, &sr2);
|
||||
if (rv)
|
||||
return rv;
|
||||
|
||||
|
||||
168
common/spi_flash_reg.c
Normal file
168
common/spi_flash_reg.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2015 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* SPI flash protection register translation functions for Chrome OS EC.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "spi_flash_reg.h"
|
||||
#include "util.h"
|
||||
|
||||
/* Bit state for protect range table */
|
||||
enum bit_state {
|
||||
OFF = 0,
|
||||
ON = 1,
|
||||
X = -1, /* Don't care */
|
||||
};
|
||||
|
||||
struct protect_range {
|
||||
enum bit_state cmp;
|
||||
enum bit_state sec;
|
||||
enum bit_state tb;
|
||||
enum bit_state bp[3]; /* Ordered {BP2, BP1, BP0} */
|
||||
uint32_t protect_start;
|
||||
uint32_t protect_len;
|
||||
};
|
||||
|
||||
/* Compare macro for (x =? b) for 'X' comparison */
|
||||
#define COMPARE_BIT(a, b) ((a) != X && (a) != (b))
|
||||
/* Assignment macro where 'X' = 0 */
|
||||
#define GET_BIT(a) ((a) == X ? 0 : (a))
|
||||
|
||||
/*
|
||||
* Define flags and protect table for each SPI ROM part. It's not necessary
|
||||
* to define all ranges in the datasheet since we'll usually protect only
|
||||
* none or half of the ROM. The table is searched sequentially, so ordering
|
||||
* according to likely configurations improves performance slightly.
|
||||
*/
|
||||
#ifdef CONFIG_SPI_FLASH_W25X40
|
||||
static const struct protect_range spi_flash_protect_ranges[] = {
|
||||
{ X, X, X, { 0, 0, 0 }, 0, 0 }, /* No protection */
|
||||
{ X, X, 1, { 0, 1, 1 }, 0, 0x40000 }, /* Lower 1/2 */
|
||||
{ X, X, 1, { 0, 0, 1 }, 0, 0x10000 }, /* Lower 1/8 */
|
||||
{ X, X, 1, { 0, 1, 0 }, 0, 0x20000 }, /* Lower 1/4 */
|
||||
{ X, X, X, { 1, X, X }, 0, 0x80000 }, /* All protected */
|
||||
};
|
||||
|
||||
#elif defined(CONFIG_SPI_FLASH_W25Q64)
|
||||
static const struct protect_range spi_flash_protect_ranges[] = {
|
||||
{ 0, X, X, { 0, 0, 0 }, 0, 0 }, /* No protection */
|
||||
{ 0, 0, 1, { 1, 1, 0 }, 0, 0x400000 }, /* Lower 1/2 */
|
||||
{ 0, 1, 1, { 1, 0, X }, 0, 0x008000 }, /* Lower 1/256 */
|
||||
{ 0, 0, 1, { 0, 0, 1 }, 0, 0x020000 }, /* Lower 1/64 */
|
||||
{ 0, 0, 1, { 0, 1, 0 }, 0, 0x040000 }, /* Lower 1/32 */
|
||||
{ 0, 0, 1, { 0, 1, 1 }, 0, 0x080000 }, /* Lower 1/16 */
|
||||
{ 0, 0, 1, { 1, 0, 0 }, 0, 0x100000 }, /* Lower 1/8 */
|
||||
{ 0, 0, 1, { 1, 0, 1 }, 0, 0x200000 }, /* Lower 1/4 */
|
||||
{ 0, X, X, { 1, 1, 1 }, 0, 0x800000 }, /* All protected */
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes block write protection range from registers
|
||||
* Returns start == len == 0 for no protection
|
||||
*
|
||||
* @param sr1 Status register 1
|
||||
* @param sr2 Status register 2
|
||||
* @param start Output pointer for protection start offset
|
||||
* @param len Output pointer for protection length
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
int spi_flash_reg_to_protect(uint8_t sr1, uint8_t sr2, unsigned int *start,
|
||||
unsigned int *len)
|
||||
{
|
||||
const struct protect_range *range;
|
||||
int i;
|
||||
uint8_t cmp;
|
||||
uint8_t sec;
|
||||
uint8_t tb;
|
||||
uint8_t bp;
|
||||
|
||||
/* Determine flags */
|
||||
cmp = (sr2 & SPI_FLASH_SR2_CMP) ? 1 : 0;
|
||||
sec = (sr1 & SPI_FLASH_SR1_SEC) ? 1 : 0;
|
||||
tb = (sr1 & SPI_FLASH_SR1_TB) ? 1 : 0;
|
||||
bp = (sr1 & (SPI_FLASH_SR1_BP2 | SPI_FLASH_SR1_BP1 | SPI_FLASH_SR1_BP0))
|
||||
>> 2;
|
||||
|
||||
/* Bad pointers or invalid data */
|
||||
if (!start || !len || sr1 == -1 || sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spi_flash_protect_ranges); ++i) {
|
||||
range = &spi_flash_protect_ranges[i];
|
||||
if (COMPARE_BIT(range->cmp, cmp))
|
||||
continue;
|
||||
if (COMPARE_BIT(range->sec, sec))
|
||||
continue;
|
||||
if (COMPARE_BIT(range->tb, tb))
|
||||
continue;
|
||||
if (COMPARE_BIT(range->bp[0], bp & 0x4))
|
||||
continue;
|
||||
if (COMPARE_BIT(range->bp[1], bp & 0x2))
|
||||
continue;
|
||||
if (COMPARE_BIT(range->bp[2], bp & 0x1))
|
||||
continue;
|
||||
|
||||
*start = range->protect_start;
|
||||
*len = range->protect_len;
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
|
||||
/* Invalid range, or valid range missing from our table */
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes block write protection registers from range
|
||||
*
|
||||
* @param start Desired protection start offset
|
||||
* @param len Desired protection length
|
||||
* @param sr1 Output pointer for status register 1
|
||||
* @param sr2 Output pointer for status register 2
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
int spi_flash_protect_to_reg(unsigned int start, unsigned int len, uint8_t *sr1,
|
||||
uint8_t *sr2)
|
||||
{
|
||||
const struct protect_range *range;
|
||||
int i;
|
||||
char cmp = 0;
|
||||
char sec = 0;
|
||||
char tb = 0;
|
||||
char bp = 0;
|
||||
|
||||
/* Bad pointers */
|
||||
if (!sr1 || !sr2 || *sr1 == -1 || *sr2 == -1)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
/* Invalid data */
|
||||
if ((start && !len) || start + len > CONFIG_SPI_FLASH_SIZE)
|
||||
return EC_ERROR_INVAL;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spi_flash_protect_ranges); ++i) {
|
||||
range = &spi_flash_protect_ranges[i];
|
||||
if (range->protect_start == start &&
|
||||
range->protect_len == len) {
|
||||
cmp = GET_BIT(range->cmp);
|
||||
sec = GET_BIT(range->sec);
|
||||
tb = GET_BIT(range->tb);
|
||||
bp = GET_BIT(range->bp[0]) << 2 |
|
||||
GET_BIT(range->bp[1]) << 1 |
|
||||
GET_BIT(range->bp[2]);
|
||||
|
||||
*sr1 = (sec ? SPI_FLASH_SR1_SEC : 0) |
|
||||
(tb ? SPI_FLASH_SR1_TB : 0) |
|
||||
(bp << 2);
|
||||
*sr2 = (cmp ? SPI_FLASH_SR2_CMP : 0);
|
||||
return EC_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* Invalid range, or valid range missing from our table */
|
||||
return EC_ERROR_INVAL;
|
||||
}
|
||||
@@ -1045,6 +1045,9 @@
|
||||
/* Support W25X40 SPI flash */
|
||||
#undef CONFIG_SPI_FLASH_W25X40
|
||||
|
||||
/* SPI flash part supports SR2 register */
|
||||
#undef CONFIG_SPI_FLASH_HAS_SR2
|
||||
|
||||
/* Size (bytes) of SPI flash memory */
|
||||
#undef CONFIG_SPI_FLASH_SIZE
|
||||
|
||||
|
||||
68
include/spi_flash_reg.h
Normal file
68
include/spi_flash_reg.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2015 The Chromium OS Authors. All rights reserved.
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*
|
||||
* SPI flash protection register translation functions for Chrome OS EC.
|
||||
*/
|
||||
|
||||
#ifndef __CROS_EC_SPI_FLASH_REGS_H
|
||||
#define __CROS_EC_SPI_FLASH_REGS_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Common register bits for SPI flash. All registers / bits may not be valid
|
||||
* for all parts.
|
||||
*/
|
||||
#define SPI_FLASH_SR2_SUS (1 << 7)
|
||||
#define SPI_FLASH_SR2_CMP (1 << 6)
|
||||
#define SPI_FLASH_SR2_LB3 (1 << 5)
|
||||
#define SPI_FLASH_SR2_LB2 (1 << 4)
|
||||
#define SPI_FLASH_SR2_LB1 (1 << 3)
|
||||
#define SPI_FLASH_SR2_QE (1 << 1)
|
||||
#define SPI_FLASH_SR2_SRP1 (1 << 0)
|
||||
#define SPI_FLASH_SR1_SRP0 (1 << 7)
|
||||
#define SPI_FLASH_SR1_SEC (1 << 6)
|
||||
#define SPI_FLASH_SR1_TB (1 << 5)
|
||||
#define SPI_FLASH_SR1_BP2 (1 << 4)
|
||||
#define SPI_FLASH_SR1_BP1 (1 << 3)
|
||||
#define SPI_FLASH_SR1_BP0 (1 << 2)
|
||||
#define SPI_FLASH_SR1_WEL (1 << 1)
|
||||
#define SPI_FLASH_SR1_BUSY (1 << 0)
|
||||
|
||||
/* SR2 register existence based upon chip */
|
||||
#ifdef CONFIG_SPI_FLASH_W25X40
|
||||
#undef CONFIG_SPI_FLASH_HAS_SR2
|
||||
#elif defined(CONFIG_SPI_FLASH_W25Q64)
|
||||
#define CONFIG_SPI_FLASH_HAS_SR2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Computes block write protection range from registers
|
||||
* Returns start == len == 0 for no protection
|
||||
*
|
||||
* @param sr1 Status register 1
|
||||
* @param sr2 Status register 2
|
||||
* @param start Output pointer for protection start offset
|
||||
* @param len Output pointer for protection length
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
int spi_flash_reg_to_protect(uint8_t sr1, uint8_t sr2, unsigned int *start,
|
||||
unsigned int *len);
|
||||
|
||||
/**
|
||||
* Computes block write protection registers from range
|
||||
*
|
||||
* @param start Desired protection start offset
|
||||
* @param len Desired protection length
|
||||
* @param sr1 Output pointer for status register 1
|
||||
* @param sr2 Output pointer for status register 2
|
||||
*
|
||||
* @return EC_SUCCESS, or non-zero if any error.
|
||||
*/
|
||||
int spi_flash_protect_to_reg(unsigned int start, unsigned int len, uint8_t *sr1,
|
||||
uint8_t *sr2);
|
||||
|
||||
#endif /* __CROS_EC_SPI_FLASH_REGS_H */
|
||||
Reference in New Issue
Block a user