hw/ssi/pnv_spi: Use local var seq_index instead of get_seq_index().

Use a local variable seq_index instead of repeatedly calling
get_seq_index() method and open-code next_sequencer_fsm().

Signed-off-by: Chalapathi V <chalapathi.v@linux.ibm.com>
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Message-ID: <20250303141328.23991-3-chalapathi.v@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
This commit is contained in:
Chalapathi V 2025-03-03 08:13:26 -06:00 committed by Nicholas Piggin
parent 17befecda8
commit f1f756f305

View File

@ -227,18 +227,6 @@ static void transfer(PnvSpi *s)
fifo8_reset(&s->rx_fifo); fifo8_reset(&s->rx_fifo);
} }
static inline uint8_t get_seq_index(PnvSpi *s)
{
return GETFIELD(SPI_STS_SEQ_INDEX, s->status);
}
static inline void next_sequencer_fsm(PnvSpi *s)
{
uint8_t seq_index = get_seq_index(s);
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, (seq_index + 1));
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT);
}
/* /*
* Calculate the N1 counters based on passed in opcode and * Calculate the N1 counters based on passed in opcode and
* internal register values. * internal register values.
@ -664,6 +652,7 @@ static void operation_sequencer(PnvSpi *s)
bool stop = false; /* Flag to stop the sequencer */ bool stop = false; /* Flag to stop the sequencer */
uint8_t opcode = 0; uint8_t opcode = 0;
uint8_t masked_opcode = 0; uint8_t masked_opcode = 0;
uint8_t seq_index;
/* /*
* Clear the sequencer FSM error bit - general_SPI_status[3] * Clear the sequencer FSM error bit - general_SPI_status[3]
@ -677,12 +666,17 @@ static void operation_sequencer(PnvSpi *s)
if (GETFIELD(SPI_STS_SEQ_FSM, s->status) == SEQ_STATE_IDLE) { if (GETFIELD(SPI_STS_SEQ_FSM, s->status) == SEQ_STATE_IDLE) {
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0); s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0);
} }
/*
* SPI_STS_SEQ_INDEX of status register is kept in seq_index variable and
* updated back to status register at the end of operation_sequencer().
*/
seq_index = GETFIELD(SPI_STS_SEQ_INDEX, s->status);
/* /*
* There are only 8 possible operation IDs to iterate through though * There are only 8 possible operation IDs to iterate through though
* some operations may cause more than one frame to be sequenced. * some operations may cause more than one frame to be sequenced.
*/ */
while (get_seq_index(s) < NUM_SEQ_OPS) { while (seq_index < NUM_SEQ_OPS) {
opcode = s->seq_op[get_seq_index(s)]; opcode = s->seq_op[seq_index];
/* Set sequencer state to decode */ /* Set sequencer state to decode */
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_DECODE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_DECODE);
/* /*
@ -699,7 +693,7 @@ static void operation_sequencer(PnvSpi *s)
case SEQ_OP_STOP: case SEQ_OP_STOP:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
/* A stop operation in any position stops the sequencer */ /* A stop operation in any position stops the sequencer */
trace_pnv_spi_sequencer_op("STOP", get_seq_index(s)); trace_pnv_spi_sequencer_op("STOP", seq_index);
stop = true; stop = true;
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE);
@ -710,7 +704,7 @@ static void operation_sequencer(PnvSpi *s)
case SEQ_OP_SELECT_SLAVE: case SEQ_OP_SELECT_SLAVE:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("SELECT_SLAVE", get_seq_index(s)); trace_pnv_spi_sequencer_op("SELECT_SLAVE", seq_index);
/* /*
* This device currently only supports a single responder * This device currently only supports a single responder
* connection at position 0. De-selecting a responder is fine * connection at position 0. De-selecting a responder is fine
@ -721,8 +715,7 @@ static void operation_sequencer(PnvSpi *s)
if (s->responder_select == 0) { if (s->responder_select == 0) {
trace_pnv_spi_shifter_done(); trace_pnv_spi_shifter_done();
qemu_set_irq(s->cs_line[0], 1); qemu_set_irq(s->cs_line[0], 1);
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index++;
(get_seq_index(s) + 1));
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_DONE); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_DONE);
} else if (s->responder_select != 1) { } else if (s->responder_select != 1) {
qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than 1 " qemu_log_mask(LOG_GUEST_ERROR, "Slave selection other than 1 "
@ -747,13 +740,15 @@ static void operation_sequencer(PnvSpi *s)
* applies once a valid responder select has occurred. * applies once a valid responder select has occurred.
*/ */
s->shift_n1_done = false; s->shift_n1_done = false;
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} }
break; break;
case SEQ_OP_SHIFT_N1: case SEQ_OP_SHIFT_N1:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("SHIFT_N1", get_seq_index(s)); trace_pnv_spi_sequencer_op("SHIFT_N1", seq_index);
/* /*
* Only allow a shift_n1 when the state is not IDLE or DONE. * Only allow a shift_n1 when the state is not IDLE or DONE.
* In either of those two cases the sequencer is not in a proper * In either of those two cases the sequencer is not in a proper
@ -785,8 +780,9 @@ static void operation_sequencer(PnvSpi *s)
* transmission to the responder without requiring a refill of * transmission to the responder without requiring a refill of
* the TDR between the two operations. * the TDR between the two operations.
*/ */
if (PNV_SPI_MASKED_OPCODE(s->seq_op[get_seq_index(s) + 1]) if ((seq_index != 7) &&
== SEQ_OP_SHIFT_N2) { PNV_SPI_MASKED_OPCODE(s->seq_op[(seq_index + 1)]) ==
SEQ_OP_SHIFT_N2) {
send_n1_alone = false; send_n1_alone = false;
} }
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_SHIFT_N1); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_SHIFT_N1);
@ -806,9 +802,8 @@ static void operation_sequencer(PnvSpi *s)
if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) { if (GETFIELD(SPI_STS_TDR_UNDERRUN, s->status)) {
s->shift_n1_done = true; s->shift_n1_done = true;
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status,
FSM_SHIFT_N2); FSM_SHIFT_N2);
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index++;
(get_seq_index(s) + 1));
} else { } else {
/* /*
* This is case (1) or (2) so the sequencer needs to * This is case (1) or (2) so the sequencer needs to
@ -819,14 +814,16 @@ static void operation_sequencer(PnvSpi *s)
} else { } else {
/* Ok to move on to the next index */ /* Ok to move on to the next index */
s->shift_n1_done = true; s->shift_n1_done = true;
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} }
} }
break; break;
case SEQ_OP_SHIFT_N2: case SEQ_OP_SHIFT_N2:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("SHIFT_N2", get_seq_index(s)); trace_pnv_spi_sequencer_op("SHIFT_N2", seq_index);
if (!s->shift_n1_done) { if (!s->shift_n1_done) {
qemu_log_mask(LOG_GUEST_ERROR, "Shift_N2 is not allowed if a " qemu_log_mask(LOG_GUEST_ERROR, "Shift_N2 is not allowed if a "
"Shift_N1 is not done, shifter state = 0x%llx", "Shift_N1 is not done, shifter state = 0x%llx",
@ -851,14 +848,16 @@ static void operation_sequencer(PnvSpi *s)
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_WAIT);
} else { } else {
/* Ok to move on to the next index */ /* Ok to move on to the next index */
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} }
} }
break; break;
case SEQ_OP_BRANCH_IFNEQ_RDR: case SEQ_OP_BRANCH_IFNEQ_RDR:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_RDR", get_seq_index(s)); trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_RDR", seq_index);
/* /*
* The memory mapping register RDR match value is compared against * The memory mapping register RDR match value is compared against
* the 16 rightmost bytes of the RDR (potentially with masking). * the 16 rightmost bytes of the RDR (potentially with masking).
@ -874,15 +873,16 @@ static void operation_sequencer(PnvSpi *s)
if (rdr_matched) { if (rdr_matched) {
trace_pnv_spi_RDR_match("success"); trace_pnv_spi_RDR_match("success");
/* A match occurred, increment the sequencer index. */ /* A match occurred, increment the sequencer index. */
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} else { } else {
trace_pnv_spi_RDR_match("failed"); trace_pnv_spi_RDR_match("failed");
/* /*
* Branch the sequencer to the index coded into the op * Branch the sequencer to the index coded into the op
* code. * code.
*/ */
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
PNV_SPI_OPCODE_LO_NIBBLE(opcode));
} }
/* /*
* Regardless of where the branch ended up we want the * Regardless of where the branch ended up we want the
@ -901,12 +901,13 @@ static void operation_sequencer(PnvSpi *s)
case SEQ_OP_TRANSFER_TDR: case SEQ_OP_TRANSFER_TDR:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
qemu_log_mask(LOG_GUEST_ERROR, "Transfer TDR is not supported\n"); qemu_log_mask(LOG_GUEST_ERROR, "Transfer TDR is not supported\n");
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT);
break; break;
case SEQ_OP_BRANCH_IFNEQ_INC_1: case SEQ_OP_BRANCH_IFNEQ_INC_1:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_1", get_seq_index(s)); trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_1", seq_index);
/* /*
* The spec says the loop should execute count compare + 1 times. * The spec says the loop should execute count compare + 1 times.
* However we learned from engineering that we really only loop * However we learned from engineering that we really only loop
@ -920,19 +921,21 @@ static void operation_sequencer(PnvSpi *s)
* mask off all but the first three bits so we don't try to * mask off all but the first three bits so we don't try to
* access beyond the sequencer_operation_reg boundary. * access beyond the sequencer_operation_reg boundary.
*/ */
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
PNV_SPI_OPCODE_LO_NIBBLE(opcode));
s->loop_counter_1++; s->loop_counter_1++;
} else { } else {
/* Continue to next index if loop counter is reached */ /* Continue to next index if loop counter is reached */
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} }
break; break;
case SEQ_OP_BRANCH_IFNEQ_INC_2: case SEQ_OP_BRANCH_IFNEQ_INC_2:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", get_seq_index(s)); trace_pnv_spi_sequencer_op("BRANCH_IFNEQ_INC_2", seq_index);
uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2, s->regs[SPI_CTR_CFG_REG]); uint8_t condition2 = GETFIELD(SPI_CTR_CFG_CMP2,
s->regs[SPI_CTR_CFG_REG]);
/* /*
* The spec says the loop should execute count compare + 1 times. * The spec says the loop should execute count compare + 1 times.
* However we learned from engineering that we really only loop * However we learned from engineering that we really only loop
@ -945,19 +948,21 @@ static void operation_sequencer(PnvSpi *s)
* mask off all but the first three bits so we don't try to * mask off all but the first three bits so we don't try to
* access beyond the sequencer_operation_reg boundary. * access beyond the sequencer_operation_reg boundary.
*/ */
s->status = SETFIELD(SPI_STS_SEQ_INDEX, seq_index = PNV_SPI_OPCODE_LO_NIBBLE(opcode);
s->status, PNV_SPI_OPCODE_LO_NIBBLE(opcode));
s->loop_counter_2++; s->loop_counter_2++;
} else { } else {
/* Continue to next index if loop counter is reached */ /* Continue to next index if loop counter is reached */
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status,
SEQ_STATE_INDEX_INCREMENT);
} }
break; break;
default: default:
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_EXECUTE);
/* Ignore unsupported operations. */ /* Ignore unsupported operations. */
next_sequencer_fsm(s); seq_index++;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_INDEX_INCREMENT);
break; break;
} /* end of switch */ } /* end of switch */
/* /*
@ -965,10 +970,10 @@ static void operation_sequencer(PnvSpi *s)
* we need to go ahead and end things as if there was a STOP at the * we need to go ahead and end things as if there was a STOP at the
* end. * end.
*/ */
if (get_seq_index(s) == NUM_SEQ_OPS) { if (seq_index == NUM_SEQ_OPS) {
/* All 8 opcodes completed, sequencer idling */ /* All 8 opcodes completed, sequencer idling */
s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE); s->status = SETFIELD(SPI_STS_SHIFTER_FSM, s->status, FSM_IDLE);
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, 0); seq_index = 0;
s->loop_counter_1 = 0; s->loop_counter_1 = 0;
s->loop_counter_2 = 0; s->loop_counter_2 = 0;
s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_IDLE); s->status = SETFIELD(SPI_STS_SEQ_FSM, s->status, SEQ_STATE_IDLE);
@ -979,6 +984,8 @@ static void operation_sequencer(PnvSpi *s)
break; break;
} }
} /* end of while */ } /* end of while */
/* Update sequencer index field in status.*/
s->status = SETFIELD(SPI_STS_SEQ_INDEX, s->status, seq_index);
return; return;
} /* end of operation_sequencer() */ } /* end of operation_sequencer() */