spi/winbond: Use spi_flash_bpbits in winbond_bpbits_to_region
This consolidates the bp, tb, cmp, srp0 and srp1 variables under the new spi_flash_bpbits struct to allow treating them as one unit in the refactoring to follow. Change-Id: I2a1a77fb73047df733498c0fa8b8de1153c3b09e Signed-off-by: Daniel Gröber <dxld@darkboxed.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/42113 Reviewed-by: Jakub Czapiga <czapiga@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
f20d7d6aa4
commit
c841880c12
@ -19,14 +19,14 @@ union status_reg1 {
|
|||||||
uint8_t tb : 1;
|
uint8_t tb : 1;
|
||||||
uint8_t sec : 1;
|
uint8_t sec : 1;
|
||||||
uint8_t srp0 : 1;
|
uint8_t srp0 : 1;
|
||||||
} bp3;
|
} bp3; /* for example: W25Q128FW */
|
||||||
struct {
|
struct {
|
||||||
uint8_t busy : 1;
|
uint8_t busy : 1;
|
||||||
uint8_t wel : 1;
|
uint8_t wel : 1;
|
||||||
uint8_t bp : 4;
|
uint8_t bp : 4;
|
||||||
uint8_t tb : 1;
|
uint8_t tb : 1;
|
||||||
uint8_t srp0 : 1;
|
uint8_t srp0 : 1;
|
||||||
} bp4;
|
} bp4; /* for example: W25Q256J */
|
||||||
};
|
};
|
||||||
|
|
||||||
union status_reg2 {
|
union status_reg2 {
|
||||||
@ -254,16 +254,15 @@ static const struct spi_flash_part_id flash_table[] = {
|
|||||||
* SEC (if available) must be zero.
|
* SEC (if available) must be zero.
|
||||||
*/
|
*/
|
||||||
static void winbond_bpbits_to_region(const size_t granularity,
|
static void winbond_bpbits_to_region(const size_t granularity,
|
||||||
const u8 bp,
|
const struct spi_flash_bpbits *bits,
|
||||||
bool tb,
|
|
||||||
const bool cmp,
|
|
||||||
const size_t flash_size,
|
const size_t flash_size,
|
||||||
struct region *out)
|
struct region *out)
|
||||||
{
|
{
|
||||||
size_t protected_size =
|
size_t protected_size =
|
||||||
MIN(bp ? granularity << (bp - 1) : 0, flash_size);
|
MIN(bits->bp ? granularity << (bits->bp - 1) : 0, flash_size);
|
||||||
|
|
||||||
if (cmp) {
|
int tb = bits->tb;
|
||||||
|
if (bits->cmp) {
|
||||||
protected_size = flash_size - protected_size;
|
protected_size = flash_size - protected_size;
|
||||||
tb = !tb;
|
tb = !tb;
|
||||||
}
|
}
|
||||||
@ -287,8 +286,7 @@ static int winbond_get_write_protection(const struct spi_flash *flash,
|
|||||||
{
|
{
|
||||||
const struct spi_flash_part_id *params;
|
const struct spi_flash_part_id *params;
|
||||||
struct region wp_region;
|
struct region wp_region;
|
||||||
union status_reg2 reg2;
|
struct spi_flash_bpbits bpbits;
|
||||||
u8 bp, tb;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
params = flash->part;
|
params = flash->part;
|
||||||
@ -299,34 +297,75 @@ static int winbond_get_write_protection(const struct spi_flash *flash,
|
|||||||
const size_t granularity = (1 << params->protection_granularity_shift);
|
const size_t granularity = (1 << params->protection_granularity_shift);
|
||||||
|
|
||||||
union status_reg1 reg1 = { .u = 0 };
|
union status_reg1 reg1 = { .u = 0 };
|
||||||
|
union status_reg2 reg2 = { .u = 0 };
|
||||||
|
|
||||||
ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u,
|
ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u,
|
||||||
sizeof(reg1.u));
|
sizeof(reg1.u));
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u,
|
||||||
|
sizeof(reg2.u));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (params->bp_bits == 3) {
|
if (params->bp_bits == 3) {
|
||||||
if (reg1.bp3.sec) {
|
if (reg1.bp3.sec) {
|
||||||
// FIXME: not supported
|
// FIXME: not supported
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bp = reg1.bp3.bp;
|
bpbits = (struct spi_flash_bpbits){
|
||||||
tb = reg1.bp3.tb;
|
.bp = reg1.bp3.bp,
|
||||||
|
.cmp = reg2.cmp,
|
||||||
|
.tb = reg1.bp3.tb,
|
||||||
|
/*
|
||||||
|
* For W25Q*{,F}* parts:
|
||||||
|
* srp1 srp0
|
||||||
|
* 0 0 | writable if WEL==1
|
||||||
|
* 0 1 | writable if WEL==1 && #WP==Vcc
|
||||||
|
* 1 0 | not writable until next power-down
|
||||||
|
* 1 1 | not writable, permanently
|
||||||
|
*
|
||||||
|
* checked datasheets: W25Q128FV, (W25Q80, W25Q16,
|
||||||
|
* W25Q32)
|
||||||
|
*/
|
||||||
|
.winbond = {
|
||||||
|
.srp0 = reg1.bp3.srp0,
|
||||||
|
.srp1 = reg2.srp1,
|
||||||
|
},
|
||||||
|
};
|
||||||
} else if (params->bp_bits == 4) {
|
} else if (params->bp_bits == 4) {
|
||||||
bp = reg1.bp4.bp;
|
bpbits = (struct spi_flash_bpbits){
|
||||||
tb = reg1.bp4.tb;
|
.bp = reg1.bp4.bp,
|
||||||
|
.cmp = reg2.cmp,
|
||||||
|
.tb = reg1.bp4.tb,
|
||||||
|
/*
|
||||||
|
* For W25Q*{J,D}* parts:
|
||||||
|
*
|
||||||
|
* srp1 srp0
|
||||||
|
* 0 0 | writable if WEL==1
|
||||||
|
* 0 1 | writable if WEL==1 && #WP==Vcc
|
||||||
|
* 1 x | not writable until next power-down
|
||||||
|
*
|
||||||
|
* checked datasheets: W25Q132JW, W25Q128JW, W25Q256JV.
|
||||||
|
* W25Q16DW
|
||||||
|
*
|
||||||
|
* The srp0/srp1 bits got renamed to srp/srl in the
|
||||||
|
* datasheets, we retain the prior naming
|
||||||
|
* convention for the structs though.
|
||||||
|
*/
|
||||||
|
.winbond = {
|
||||||
|
.srp0 = reg1.bp4.srp0,
|
||||||
|
.srp1 = reg2.srp1,
|
||||||
|
},
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
// FIXME: not supported
|
// FIXME: not supported
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u,
|
winbond_bpbits_to_region(granularity, &bpbits, flash->size,
|
||||||
sizeof(reg2.u));
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
winbond_bpbits_to_region(granularity, bp, tb, reg2.cmp, flash->size,
|
|
||||||
&wp_region);
|
&wp_region);
|
||||||
|
|
||||||
if (!region_sz(&wp_region)) {
|
if (!region_sz(&wp_region)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user