Skip to content

Commit

Permalink
m25p80: Introduce quad and equad modes.
Browse files Browse the repository at this point in the history
Quad and Equad modes for Spansion and Macronix flash devices.
This commit also includes modification and new command to manipulate
quad mode (status registers and dedicated commands).
This work is based on Pawel Lenkow work.

Signed-off-by: Marcin Krzeminski <marcin.krzeminski@nokia.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Message-id: 1466755631-25201-7-git-send-email-marcin.krzeminski@nokia.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
Marcin Krzeminski authored and pm215 committed Jun 27, 2016
1 parent 30467af commit 7a69c10
Showing 1 changed file with 65 additions and 5 deletions.
70 changes: 65 additions & 5 deletions hw/block/m25p80.c
Expand Up @@ -281,6 +281,7 @@ typedef enum {
JEDEC_READ = 0x9f,
BULK_ERASE = 0xc7,
READ_FSR = 0x70,
RDCR = 0x15,

READ = 0x03,
READ4 = 0x13,
Expand Down Expand Up @@ -317,6 +318,13 @@ typedef enum {
RESET_ENABLE = 0x66,
RESET_MEMORY = 0x99,

/*
* Micron: 0x35 - enable QPI
* Spansion: 0x35 - read control register
*/
RDCR_EQIO = 0x35,
RSTQIO = 0xf5,

RNVCR = 0xB5,
WNVCR = 0xB1,

Expand Down Expand Up @@ -366,6 +374,7 @@ typedef struct Flash {
bool write_enable;
bool four_bytes_address_mode;
bool reset_enable;
bool quad_enable;
uint8_t ear;

int64_t dirty_page;
Expand Down Expand Up @@ -586,6 +595,16 @@ static void complete_collecting_data(Flash *s)
flash_erase(s, s->cur_addr, s->cmd_in_progress);
break;
case WRSR:
switch (get_man(s)) {
case MAN_SPANSION:
s->quad_enable = !!(s->data[1] & 0x02);
break;
case MAN_MACRONIX:
s->quad_enable = extract32(s->data[0], 6, 1);
break;
default:
break;
}
if (s->write_enable) {
s->write_enable = false;
}
Expand Down Expand Up @@ -619,6 +638,7 @@ static void reset_memory(Flash *s)
s->state = STATE_IDLE;
s->write_enable = false;
s->reset_enable = false;
s->quad_enable = false;

switch (get_man(s)) {
case MAN_NUMONYX:
Expand Down Expand Up @@ -747,10 +767,20 @@ static void decode_new_cmd(Flash *s, uint32_t value)

case WRSR:
if (s->write_enable) {
s->needed_bytes = 1;
switch (get_man(s)) {
case MAN_SPANSION:
s->needed_bytes = 2;
s->state = STATE_COLLECTING_DATA;
break;
case MAN_MACRONIX:
s->needed_bytes = 2;
s->state = STATE_COLLECTING_VAR_LEN_DATA;
break;
default:
s->needed_bytes = 1;
s->state = STATE_COLLECTING_DATA;
}
s->pos = 0;
s->len = 0;
s->state = STATE_COLLECTING_DATA;
}
break;

Expand All @@ -763,6 +793,9 @@ static void decode_new_cmd(Flash *s, uint32_t value)

case RDSR:
s->data[0] = (!!s->write_enable) << 1;
if (get_man(s) == MAN_MACRONIX) {
s->data[0] |= (!!s->quad_enable) << 6;
}
s->pos = 0;
s->len = 1;
s->state = STATE_READING_DATA;
Expand All @@ -789,6 +822,14 @@ static void decode_new_cmd(Flash *s, uint32_t value)
s->state = STATE_READING_DATA;
break;

case RDCR:
s->data[0] = s->volatile_cfg & 0xFF;
s->data[0] |= (!!s->four_bytes_address_mode) << 5;
s->pos = 0;
s->len = 1;
s->state = STATE_READING_DATA;
break;

case BULK_ERASE:
if (s->write_enable) {
DB_PRINT_L(0, "chip erase\n");
Expand Down Expand Up @@ -828,7 +869,7 @@ static void decode_new_cmd(Flash *s, uint32_t value)
s->state = STATE_READING_DATA;
break;
case WNVCR:
if (s->write_enable) {
if (s->write_enable && get_man(s) == MAN_NUMONYX) {
s->needed_bytes = 2;
s->pos = 0;
s->len = 0;
Expand Down Expand Up @@ -871,6 +912,24 @@ static void decode_new_cmd(Flash *s, uint32_t value)
reset_memory(s);
}
break;
case RDCR_EQIO:
switch (get_man(s)) {
case MAN_SPANSION:
s->data[0] = (!!s->quad_enable) << 1;
s->pos = 0;
s->len = 1;
s->state = STATE_READING_DATA;
break;
case MAN_MACRONIX:
s->quad_enable = true;
break;
default:
break;
}
break;
case RSTQIO:
s->quad_enable = false;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
break;
Expand Down Expand Up @@ -999,7 +1058,7 @@ static Property m25p80_properties[] = {

static const VMStateDescription vmstate_m25p80 = {
.name = "xilinx_spi",
.version_id = 2,
.version_id = 3,
.minimum_version_id = 1,
.pre_save = m25p80_pre_save,
.fields = (VMStateField[]) {
Expand All @@ -1017,6 +1076,7 @@ static const VMStateDescription vmstate_m25p80 = {
VMSTATE_UINT32_V(nonvolatile_cfg, Flash, 2),
VMSTATE_UINT32_V(volatile_cfg, Flash, 2),
VMSTATE_UINT32_V(enh_volatile_cfg, Flash, 2),
VMSTATE_BOOL_V(quad_enable, Flash, 3),
VMSTATE_END_OF_LIST()
}
};
Expand Down

0 comments on commit 7a69c10

Please sign in to comment.