Lines Matching +full:- +full:- +full:-
29 #include "hw/qdev-properties.h"
89 #define IXR_ALL ((1 << 13) - 1)
218 return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS && in num_effective_busses()
219 s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1; in num_effective_busses()
226 for (i = 0; i < s->num_cs * s->num_busses; i++) { in xilinx_spips_update_cs()
227 bool old_state = s->cs_lines_state[i]; in xilinx_spips_update_cs()
231 s->cs_lines_state[i] = new_state; in xilinx_spips_update_cs()
232 s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD); in xilinx_spips_update_cs()
236 qemu_set_irq(s->cs_lines[i], !new_state); in xilinx_spips_update_cs()
238 if (!(field & ((1 << (s->num_cs * s->num_busses)) - 1))) { in xilinx_spips_update_cs()
239 s->snoop_state = SNOOP_CHECKING; in xilinx_spips_update_cs()
240 s->cmd_dummies = 0; in xilinx_spips_update_cs()
241 s->link_state = 1; in xilinx_spips_update_cs()
242 s->link_state_next = 1; in xilinx_spips_update_cs()
243 s->link_state_next_when = 0; in xilinx_spips_update_cs()
250 if (s->regs[R_GQSPI_GF_SNAPSHOT]) { in xlnx_zynqmp_qspips_update_cs_lines()
251 int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT); in xlnx_zynqmp_qspips_update_cs_lines()
259 buses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT); in xlnx_zynqmp_qspips_update_cs_lines()
291 int field = ~((s->regs[R_CONFIG] & CS) >> CS_SHIFT); in xilinx_spips_update_cs_lines()
295 /* Single bit chip-select for qspi */ in xilinx_spips_update_cs_lines()
298 /* Dual stack U-Page */ in xilinx_spips_update_cs_lines()
299 } else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM && in xilinx_spips_update_cs_lines()
300 s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) { in xilinx_spips_update_cs_lines()
301 /* Single bit chip-select for qspi */ in xilinx_spips_update_cs_lines()
307 if (!(s->regs[R_CONFIG] & MANUAL_CS) && in xilinx_spips_update_cs_lines()
308 fifo8_is_empty(&s->tx_fifo)) { in xilinx_spips_update_cs_lines()
316 if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) { in xilinx_spips_update_ixr()
317 s->regs[R_INTR_STATUS] &= ~IXR_SELF_CLEAR; in xilinx_spips_update_ixr()
318 s->regs[R_INTR_STATUS] |= in xilinx_spips_update_ixr()
319 (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) | in xilinx_spips_update_ixr()
320 (s->rx_fifo.num >= s->regs[R_RX_THRES] ? in xilinx_spips_update_ixr()
322 (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) | in xilinx_spips_update_ixr()
323 (fifo8_is_empty(&s->tx_fifo) ? IXR_TX_FIFO_EMPTY : 0) | in xilinx_spips_update_ixr()
324 (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0); in xilinx_spips_update_ixr()
326 int new_irqline = !!(s->regs[R_INTR_MASK] & s->regs[R_INTR_STATUS] & in xilinx_spips_update_ixr()
328 if (new_irqline != s->irqline) { in xilinx_spips_update_ixr()
329 s->irqline = new_irqline; in xilinx_spips_update_ixr()
330 qemu_set_irq(s->irq, s->irqline); in xilinx_spips_update_ixr()
339 s->regs[R_GQSPI_ISR] &= ~IXR_SELF_CLEAR; in xlnx_zynqmp_qspips_update_ixr()
340 s->regs[R_GQSPI_ISR] |= in xlnx_zynqmp_qspips_update_ixr()
341 (fifo32_is_empty(&s->fifo_g) ? IXR_GENERIC_FIFO_EMPTY : 0) | in xlnx_zynqmp_qspips_update_ixr()
342 (fifo32_is_full(&s->fifo_g) ? IXR_GENERIC_FIFO_FULL : 0) | in xlnx_zynqmp_qspips_update_ixr()
343 (s->fifo_g.fifo.num < s->regs[R_GQSPI_GFIFO_THRESH] ? in xlnx_zynqmp_qspips_update_ixr()
345 (fifo8_is_empty(&s->rx_fifo_g) ? IXR_RX_FIFO_EMPTY : 0) | in xlnx_zynqmp_qspips_update_ixr()
346 (fifo8_is_full(&s->rx_fifo_g) ? IXR_RX_FIFO_FULL : 0) | in xlnx_zynqmp_qspips_update_ixr()
347 (s->rx_fifo_g.num >= s->regs[R_GQSPI_RX_THRESH] ? in xlnx_zynqmp_qspips_update_ixr()
349 (fifo8_is_empty(&s->tx_fifo_g) ? IXR_TX_FIFO_EMPTY : 0) | in xlnx_zynqmp_qspips_update_ixr()
350 (fifo8_is_full(&s->tx_fifo_g) ? IXR_TX_FIFO_FULL : 0) | in xlnx_zynqmp_qspips_update_ixr()
351 (s->tx_fifo_g.num < s->regs[R_GQSPI_TX_THRESH] ? in xlnx_zynqmp_qspips_update_ixr()
355 gqspi_int = (~s->regs[R_GQSPI_IMR]) & s->regs[R_GQSPI_ISR] & GQSPI_IXR_MASK; in xlnx_zynqmp_qspips_update_ixr()
359 if (new_irqline != s->gqspi_irqline) { in xlnx_zynqmp_qspips_update_ixr()
360 s->gqspi_irqline = new_irqline; in xlnx_zynqmp_qspips_update_ixr()
361 qemu_set_irq(XILINX_SPIPS(s)->irq, s->gqspi_irqline); in xlnx_zynqmp_qspips_update_ixr()
369 memset(s->regs, 0, sizeof(s->regs)); in xilinx_spips_reset()
371 fifo8_reset(&s->rx_fifo); in xilinx_spips_reset()
372 fifo8_reset(&s->rx_fifo); in xilinx_spips_reset()
374 s->regs[R_CONFIG] |= MODEFAIL_GEN_EN; in xilinx_spips_reset()
375 s->regs[R_SLAVE_IDLE_COUNT] = 0xFF; in xilinx_spips_reset()
376 s->regs[R_TX_THRES] = 1; in xilinx_spips_reset()
377 s->regs[R_RX_THRES] = 1; in xilinx_spips_reset()
379 s->regs[R_MOD_ID] = 0x01090106; in xilinx_spips_reset()
380 s->regs[R_LQSPI_CFG] = R_LQSPI_CFG_RESET; in xilinx_spips_reset()
381 s->link_state = 1; in xilinx_spips_reset()
382 s->link_state_next = 1; in xilinx_spips_reset()
383 s->link_state_next_when = 0; in xilinx_spips_reset()
384 s->snoop_state = SNOOP_CHECKING; in xilinx_spips_reset()
385 s->cmd_dummies = 0; in xilinx_spips_reset()
386 s->man_start_com = false; in xilinx_spips_reset()
397 memset(s->regs, 0, sizeof(s->regs)); in xlnx_zynqmp_qspips_reset()
399 fifo8_reset(&s->rx_fifo_g); in xlnx_zynqmp_qspips_reset()
400 fifo8_reset(&s->rx_fifo_g); in xlnx_zynqmp_qspips_reset()
401 fifo32_reset(&s->fifo_g); in xlnx_zynqmp_qspips_reset()
402 s->regs[R_INTR_STATUS] = R_INTR_STATUS_RESET; in xlnx_zynqmp_qspips_reset()
403 s->regs[R_GPIO] = 1; in xlnx_zynqmp_qspips_reset()
404 s->regs[R_LPBK_DLY_ADJ] = R_LPBK_DLY_ADJ_RESET; in xlnx_zynqmp_qspips_reset()
405 s->regs[R_GQSPI_GFIFO_THRESH] = 0x10; in xlnx_zynqmp_qspips_reset()
406 s->regs[R_MOD_ID] = 0x01090101; in xlnx_zynqmp_qspips_reset()
407 s->regs[R_GQSPI_IMR] = R_GQSPI_IMR_RESET; in xlnx_zynqmp_qspips_reset()
408 s->regs[R_GQSPI_TX_THRESH] = 1; in xlnx_zynqmp_qspips_reset()
409 s->regs[R_GQSPI_RX_THRESH] = 1; in xlnx_zynqmp_qspips_reset()
410 s->regs[R_GQSPI_GPIO] = 1; in xlnx_zynqmp_qspips_reset()
411 s->regs[R_GQSPI_LPBK_DLY_ADJ] = R_GQSPI_LPBK_DLY_ADJ_RESET; in xlnx_zynqmp_qspips_reset()
412 s->regs[R_GQSPI_MOD_ID] = R_GQSPI_MOD_ID_RESET; in xlnx_zynqmp_qspips_reset()
413 s->man_start_com_g = false; in xlnx_zynqmp_qspips_reset()
414 s->gqspi_irqline = 0; in xlnx_zynqmp_qspips_reset()
420 * column wise (from element 0 to N-1). num is the length of x, and dir
424 * {{ 76543210, } ----- stripe (dir == false) -----> {{ 741gdaFC, }
426 * { HGFEDCBA, }} <---- upstripe (dir == true) ----- { 52hebGDA, }}
440 for (bit[0] = 7; bit[0] >= 0; bit[0]--) { in stripe8()
444 bit[1]--; in stripe8()
453 while (s->regs[R_GQSPI_DATA_STS] || !fifo32_is_empty(&s->fifo_g)) { in xlnx_zynqmp_qspips_flush_fifo_g()
459 if (!s->regs[R_GQSPI_DATA_STS]) { in xlnx_zynqmp_qspips_flush_fifo_g()
462 s->regs[R_GQSPI_GF_SNAPSHOT] = fifo32_pop(&s->fifo_g); in xlnx_zynqmp_qspips_flush_fifo_g()
463 DB_PRINT_L(0, "GQSPI command: %x\n", s->regs[R_GQSPI_GF_SNAPSHOT]); in xlnx_zynqmp_qspips_flush_fifo_g()
464 if (!s->regs[R_GQSPI_GF_SNAPSHOT]) { in xlnx_zynqmp_qspips_flush_fifo_g()
470 imm = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA); in xlnx_zynqmp_qspips_flush_fifo_g()
471 if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) { in xlnx_zynqmp_qspips_flush_fifo_g()
473 if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) || in xlnx_zynqmp_qspips_flush_fifo_g()
474 ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) { in xlnx_zynqmp_qspips_flush_fifo_g()
475 s->regs[R_GQSPI_DATA_STS] = 1; in xlnx_zynqmp_qspips_flush_fifo_g()
476 /* CS setup/hold - do nothing */ in xlnx_zynqmp_qspips_flush_fifo_g()
478 s->regs[R_GQSPI_DATA_STS] = 0; in xlnx_zynqmp_qspips_flush_fifo_g()
480 } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, EXPONENT)) { in xlnx_zynqmp_qspips_flush_fifo_g()
483 " long - 2 ^ %" PRId8 " requested\n", imm); in xlnx_zynqmp_qspips_flush_fifo_g()
485 s->regs[R_GQSPI_DATA_STS] = 1ul << imm; in xlnx_zynqmp_qspips_flush_fifo_g()
487 s->regs[R_GQSPI_DATA_STS] = imm; in xlnx_zynqmp_qspips_flush_fifo_g()
491 if (!s->regs[R_GQSPI_DATA_STS]) { in xlnx_zynqmp_qspips_flush_fifo_g()
494 if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE) && in xlnx_zynqmp_qspips_flush_fifo_g()
495 fifo8_is_full(&s->rx_fifo_g)) { in xlnx_zynqmp_qspips_flush_fifo_g()
496 /* No space in RX fifo for transfer - try again later */ in xlnx_zynqmp_qspips_flush_fifo_g()
499 if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, STRIPE) && in xlnx_zynqmp_qspips_flush_fifo_g()
500 (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) || in xlnx_zynqmp_qspips_flush_fifo_g()
501 ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE))) { in xlnx_zynqmp_qspips_flush_fifo_g()
504 if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) { in xlnx_zynqmp_qspips_flush_fifo_g()
505 tx_rx[0] = ARRAY_FIELD_EX32(s->regs, in xlnx_zynqmp_qspips_flush_fifo_g()
507 } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT)) { in xlnx_zynqmp_qspips_flush_fifo_g()
509 if (!fifo8_is_empty(&s->tx_fifo_g)) { in xlnx_zynqmp_qspips_flush_fifo_g()
510 tx_rx[i] = fifo8_pop(&s->tx_fifo_g); in xlnx_zynqmp_qspips_flush_fifo_g()
511 s->tx_fifo_g_align++; in xlnx_zynqmp_qspips_flush_fifo_g()
521 busses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT); in xlnx_zynqmp_qspips_flush_fifo_g()
524 tx_rx[i] = ssi_transfer(XILINX_SPIPS(s)->spi[i], tx_rx[i]); in xlnx_zynqmp_qspips_flush_fifo_g()
527 if (s->regs[R_GQSPI_DATA_STS] > 1 && in xlnx_zynqmp_qspips_flush_fifo_g()
529 s->regs[R_GQSPI_DATA_STS] -= 2; in xlnx_zynqmp_qspips_flush_fifo_g()
530 } else if (s->regs[R_GQSPI_DATA_STS] > 0) { in xlnx_zynqmp_qspips_flush_fifo_g()
531 s->regs[R_GQSPI_DATA_STS]--; in xlnx_zynqmp_qspips_flush_fifo_g()
533 if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) { in xlnx_zynqmp_qspips_flush_fifo_g()
537 fifo8_push(&s->rx_fifo_g, tx_rx[i]); in xlnx_zynqmp_qspips_flush_fifo_g()
538 s->rx_fifo_g_align++; in xlnx_zynqmp_qspips_flush_fifo_g()
542 if (!s->regs[R_GQSPI_DATA_STS]) { in xlnx_zynqmp_qspips_flush_fifo_g()
543 for (; s->tx_fifo_g_align % 4; s->tx_fifo_g_align++) { in xlnx_zynqmp_qspips_flush_fifo_g()
544 fifo8_pop(&s->tx_fifo_g); in xlnx_zynqmp_qspips_flush_fifo_g()
546 for (; s->rx_fifo_g_align % 4; s->rx_fifo_g_align++) { in xlnx_zynqmp_qspips_flush_fifo_g()
547 fifo8_push(&s->rx_fifo_g, 0); in xlnx_zynqmp_qspips_flush_fifo_g()
557 return -1; in xilinx_spips_num_dummies()
583 return -1; in xilinx_spips_num_dummies()
600 return (s->regs[R_CMND] & R_CMND_EXT_ADD) ? 4 : 3; in get_addr_length()
617 if (fifo8_is_empty(&s->tx_fifo)) { in xilinx_spips_flush_txfifo()
620 } else if (s->snoop_state == SNOOP_STRIPING || in xilinx_spips_flush_txfifo()
621 s->snoop_state == SNOOP_NONE) { in xilinx_spips_flush_txfifo()
623 if (!fifo8_is_empty(&s->tx_fifo)) { in xilinx_spips_flush_txfifo()
624 tx_rx[i] = fifo8_pop(&s->tx_fifo); in xilinx_spips_flush_txfifo()
628 } else if (s->snoop_state >= SNOOP_ADDR) { in xilinx_spips_flush_txfifo()
629 tx = fifo8_pop(&s->tx_fifo); in xilinx_spips_flush_txfifo()
638 tx = fifo8_pop(&s->tx_fifo); in xilinx_spips_flush_txfifo()
639 dummy_cycles = 8 / s->link_state; in xilinx_spips_flush_txfifo()
643 int bus = num_effective_busses(s) - 1 - i; in xilinx_spips_flush_txfifo()
647 tx_rx[0] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[0]); in xilinx_spips_flush_txfifo()
651 tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]); in xilinx_spips_flush_txfifo()
656 if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) { in xilinx_spips_flush_txfifo()
659 } else if (s->rx_discard) { in xilinx_spips_flush_txfifo()
661 s->rx_discard -= 8 / s->link_state; in xilinx_spips_flush_txfifo()
662 } else if (fifo8_is_full(&s->rx_fifo)) { in xilinx_spips_flush_txfifo()
663 s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW; in xilinx_spips_flush_txfifo()
665 } else if (s->snoop_state == SNOOP_STRIPING) { in xilinx_spips_flush_txfifo()
668 fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[i]); in xilinx_spips_flush_txfifo()
673 fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]); in xilinx_spips_flush_txfifo()
676 if (s->link_state_next_when) { in xilinx_spips_flush_txfifo()
677 s->link_state_next_when--; in xilinx_spips_flush_txfifo()
678 if (!s->link_state_next_when) { in xilinx_spips_flush_txfifo()
679 s->link_state = s->link_state_next; in xilinx_spips_flush_txfifo()
684 (unsigned)s->snoop_state); in xilinx_spips_flush_txfifo()
685 switch (s->snoop_state) { in xilinx_spips_flush_txfifo()
688 s->cmd_dummies = xilinx_spips_num_dummies(q, tx); in xilinx_spips_flush_txfifo()
690 if (s->cmd_dummies < 0) { in xilinx_spips_flush_txfifo()
691 s->snoop_state = SNOOP_NONE; in xilinx_spips_flush_txfifo()
693 s->snoop_state = SNOOP_ADDR + addr_length - 1; in xilinx_spips_flush_txfifo()
699 s->link_state_next = 2; in xilinx_spips_flush_txfifo()
700 s->link_state_next_when = addr_length + s->cmd_dummies; in xilinx_spips_flush_txfifo()
706 s->link_state_next = 4; in xilinx_spips_flush_txfifo()
707 s->link_state_next_when = addr_length + s->cmd_dummies; in xilinx_spips_flush_txfifo()
711 s->link_state = 2; in xilinx_spips_flush_txfifo()
715 s->link_state = 4; in xilinx_spips_flush_txfifo()
723 if (s->cmd_dummies < 0) { in xilinx_spips_flush_txfifo()
724 s->snoop_state = SNOOP_NONE; in xilinx_spips_flush_txfifo()
726 s->snoop_state = s->cmd_dummies; in xilinx_spips_flush_txfifo()
731 /* Once we hit the boring stuff - squelch debug noise */ in xilinx_spips_flush_txfifo()
738 s->snoop_state--; in xilinx_spips_flush_txfifo()
741 (unsigned)s->snoop_state); in xilinx_spips_flush_txfifo()
761 if (!s->regs[R_TRANSFER_SIZE]) { in xilinx_spips_check_zero_pump()
764 if (!fifo8_is_empty(&s->tx_fifo) && s->regs[R_CMND] & R_CMND_PUSH_WAIT) { in xilinx_spips_check_zero_pump()
771 while (s->regs[R_TRANSFER_SIZE] && in xilinx_spips_check_zero_pump()
772 s->rx_fifo.num + s->tx_fifo.num < RXFF_A_Q - 3) { in xilinx_spips_check_zero_pump()
774 tx_data_bytes(&s->tx_fifo, 0, 4, false); in xilinx_spips_check_zero_pump()
775 s->regs[R_TRANSFER_SIZE] &= ~0x03ull; in xilinx_spips_check_zero_pump()
776 s->regs[R_TRANSFER_SIZE] -= 4; in xilinx_spips_check_zero_pump()
782 if (s->man_start_com || in xilinx_spips_check_flush()
783 (!fifo8_is_empty(&s->tx_fifo) && in xilinx_spips_check_flush()
784 !(s->regs[R_CONFIG] & MAN_START_EN))) { in xilinx_spips_check_flush()
788 if (fifo8_is_empty(&s->tx_fifo) && !s->regs[R_TRANSFER_SIZE]) { in xilinx_spips_check_flush()
789 s->man_start_com = false; in xilinx_spips_check_flush()
796 bool gqspi_has_work = s->regs[R_GQSPI_DATA_STS] || in xlnx_zynqmp_qspips_check_flush()
797 !fifo32_is_empty(&s->fifo_g); in xlnx_zynqmp_qspips_check_flush()
799 if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) { in xlnx_zynqmp_qspips_check_flush()
800 if (s->man_start_com_g || (gqspi_has_work && in xlnx_zynqmp_qspips_check_flush()
801 !ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE))) { in xlnx_zynqmp_qspips_check_flush()
808 s->man_start_com_g = false; in xlnx_zynqmp_qspips_check_flush()
820 return max - i; in rx_data_bytes()
827 if (max == 0 || max > fifo->num) { in pop_buf()
830 *num = MIN(fifo->capacity - fifo->head, max); in pop_buf()
831 ret = &fifo->data[fifo->head]; in pop_buf()
832 fifo->head += *num; in pop_buf()
833 fifo->head %= fifo->capacity; in pop_buf()
834 fifo->num -= *num; in pop_buf()
844 if (ARRAY_FIELD_EX32(rq->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) { in xlnx_zynqmp_qspips_notify()
845 if (!(ARRAY_FIELD_EX32(rq->regs, GQSPI_CNFG, MODE_EN) == 2)) { in xlnx_zynqmp_qspips_notify()
848 recv_fifo = &rq->rx_fifo_g; in xlnx_zynqmp_qspips_notify()
850 if (!(s->regs[R_CMND] & R_CMND_DMA_EN)) { in xlnx_zynqmp_qspips_notify()
853 recv_fifo = &s->rx_fifo; in xlnx_zynqmp_qspips_notify()
855 while (recv_fifo->num >= 4 in xlnx_zynqmp_qspips_notify()
856 && stream_can_push(rq->dma, xlnx_zynqmp_qspips_notify, rq)) in xlnx_zynqmp_qspips_notify()
863 len = recv_fifo->num >= rq->dma_burst_size ? rq->dma_burst_size : in xlnx_zynqmp_qspips_notify()
864 recv_fifo->num; in xlnx_zynqmp_qspips_notify()
867 memcpy(rq->dma_buf, rxd, num); in xlnx_zynqmp_qspips_notify()
869 ret = stream_push(rq->dma, rq->dma_buf, num, false); in xlnx_zynqmp_qspips_notify()
890 ret = s->regs[addr] & IXR_ALL; in xilinx_spips_read()
891 s->regs[addr] = 0; in xilinx_spips_read()
914 shortfall = rx_data_bytes(&s->rx_fifo, rx_buf, s->num_txrx_bytes); in xilinx_spips_read()
915 ret = s->regs[R_CONFIG] & R_CONFIG_ENDIAN ? in xilinx_spips_read()
918 if (!(s->regs[R_CONFIG] & R_CONFIG_ENDIAN)) { in xilinx_spips_read()
927 s->regs[addr] & mask); in xilinx_spips_read()
928 return s->regs[addr] & mask; in xilinx_spips_read()
946 if (fifo8_is_empty(&s->rx_fifo_g)) { in xlnx_zynqmp_qspips_read()
952 shortfall = rx_data_bytes(&s->rx_fifo_g, rx_buf, in xlnx_zynqmp_qspips_read()
953 XILINX_SPIPS(s)->num_txrx_bytes); in xlnx_zynqmp_qspips_read()
954 ret = ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN) ? in xlnx_zynqmp_qspips_read()
957 if (!ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN)) { in xlnx_zynqmp_qspips_read()
964 return s->regs[reg]; in xlnx_zynqmp_qspips_read()
983 if ((value & MAN_START_COM) && (s->regs[R_CONFIG] & MAN_START_EN)) { in xilinx_spips_write()
984 s->man_start_com = true; in xilinx_spips_write()
989 s->regs[R_INTR_STATUS] &= ~(mask & value); in xilinx_spips_write()
993 s->regs[R_INTR_MASK] &= ~(mask & value); in xilinx_spips_write()
997 s->regs[R_INTR_MASK] |= mask & value; in xilinx_spips_write()
1011 tx_data_bytes(&s->tx_fifo, (uint32_t)value, s->num_txrx_bytes, in xilinx_spips_write()
1012 s->regs[R_CONFIG] & R_CONFIG_ENDIAN); in xilinx_spips_write()
1015 tx_data_bytes(&s->tx_fifo, (uint32_t)value, 1, in xilinx_spips_write()
1016 s->regs[R_CONFIG] & R_CONFIG_ENDIAN); in xilinx_spips_write()
1019 tx_data_bytes(&s->tx_fifo, (uint32_t)value, 2, in xilinx_spips_write()
1020 s->regs[R_CONFIG] & R_CONFIG_ENDIAN); in xilinx_spips_write()
1023 tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3, in xilinx_spips_write()
1024 s->regs[R_CONFIG] & R_CONFIG_ENDIAN); in xilinx_spips_write()
1035 s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask); in xilinx_spips_write()
1053 q->lqspi_cached_addr = ~0ULL; in xilinx_qspips_invalidate_mmio_ptr()
1068 if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) { in xilinx_qspips_write()
1069 fifo8_reset(&s->rx_fifo); in xilinx_qspips_write()
1085 ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE)) { in xlnx_zynqmp_qspips_write()
1086 s->man_start_com_g = true; in xlnx_zynqmp_qspips_write()
1088 s->regs[reg] = value & ~(R_GQSPI_CNFG_GEN_FIFO_START_MASK); in xlnx_zynqmp_qspips_write()
1091 if (!fifo32_is_full(&s->fifo_g)) { in xlnx_zynqmp_qspips_write()
1092 fifo32_push(&s->fifo_g, value); in xlnx_zynqmp_qspips_write()
1096 tx_data_bytes(&s->tx_fifo_g, (uint32_t)value, 4, in xlnx_zynqmp_qspips_write()
1097 ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN)); in xlnx_zynqmp_qspips_write()
1101 fifo32_reset(&s->fifo_g); in xlnx_zynqmp_qspips_write()
1104 fifo8_reset(&s->tx_fifo_g); in xlnx_zynqmp_qspips_write()
1107 fifo8_reset(&s->rx_fifo_g); in xlnx_zynqmp_qspips_write()
1111 s->regs[R_GQSPI_IMR] |= value; in xlnx_zynqmp_qspips_write()
1114 s->regs[R_GQSPI_IMR] &= ~value; in xlnx_zynqmp_qspips_write()
1117 s->regs[R_GQSPI_ISR] &= ~value; in xlnx_zynqmp_qspips_write()
1125 s->regs[reg] = value; in xlnx_zynqmp_qspips_write()
1155 int flash_addr = ((addr & ~(LQSPI_CACHE_SIZE - 1)) in lqspi_load_cache()
1159 uint32_t u_page_save = s->regs[R_LQSPI_STS] & ~LQSPI_CFG_U_PAGE; in lqspi_load_cache()
1161 if (addr < q->lqspi_cached_addr || in lqspi_load_cache()
1162 addr > q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) { in lqspi_load_cache()
1164 s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE; in lqspi_load_cache()
1165 s->regs[R_LQSPI_STS] |= peripheral ? LQSPI_CFG_U_PAGE : 0; in lqspi_load_cache()
1167 DB_PRINT_L(0, "config reg status: %08x\n", s->regs[R_LQSPI_CFG]); in lqspi_load_cache()
1169 fifo8_reset(&s->tx_fifo); in lqspi_load_cache()
1170 fifo8_reset(&s->rx_fifo); in lqspi_load_cache()
1174 (unsigned)(uint8_t)(s->regs[R_LQSPI_CFG] & in lqspi_load_cache()
1176 fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE); in lqspi_load_cache()
1179 if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_ADDR4) { in lqspi_load_cache()
1180 fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 24)); in lqspi_load_cache()
1182 fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16)); in lqspi_load_cache()
1183 fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8)); in lqspi_load_cache()
1184 fifo8_push(&s->tx_fifo, (uint8_t)flash_addr); in lqspi_load_cache()
1186 if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_MODE_EN) { in lqspi_load_cache()
1187 fifo8_push(&s->tx_fifo, extract32(s->regs[R_LQSPI_CFG], in lqspi_load_cache()
1192 for (i = 0; i < (extract32(s->regs[R_LQSPI_CFG], LQSPI_CFG_DUMMY_SHIFT, in lqspi_load_cache()
1195 fifo8_push(&s->tx_fifo, 0); in lqspi_load_cache()
1199 fifo8_reset(&s->rx_fifo); in lqspi_load_cache()
1205 tx_data_bytes(&s->tx_fifo, 0, 1, false); in lqspi_load_cache()
1209 rx_data_bytes(&s->rx_fifo, &q->lqspi_buf[cache_entry++], 1); in lqspi_load_cache()
1213 s->regs[R_LQSPI_STS] &= ~LQSPI_CFG_U_PAGE; in lqspi_load_cache()
1214 s->regs[R_LQSPI_STS] |= u_page_save; in lqspi_load_cache()
1217 q->lqspi_cached_addr = flash_addr * num_effective_busses(s); in lqspi_load_cache()
1226 if (addr >= q->lqspi_cached_addr && in lqspi_read()
1227 addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) { in lqspi_read()
1228 uint8_t *retp = &q->lqspi_buf[addr - q->lqspi_cached_addr]; in lqspi_read()
1243 * From UG1085, Chapter 24 (Quad-SPI controllers): in lqspi_write()
1244 * - Writes are ignored in lqspi_write()
1245 * - AXI writes generate an external AXI slave error (SLVERR) in lqspi_write()
1247 qemu_log_mask(LOG_GUEST_ERROR, "%s Unexpected %u-bit access to 0x%" PRIx64 in lqspi_write()
1277 if (s->num_busses > MAX_NUM_BUSSES) { in xilinx_spips_realize()
1280 s->num_busses, MAX_NUM_BUSSES); in xilinx_spips_realize()
1283 if (s->num_busses < MIN_NUM_BUSSES) { in xilinx_spips_realize()
1286 s->num_busses, MIN_NUM_BUSSES); in xilinx_spips_realize()
1290 s->spi = g_new(SSIBus *, s->num_busses); in xilinx_spips_realize()
1291 for (i = 0; i < s->num_busses; ++i) { in xilinx_spips_realize()
1294 s->spi[i] = ssi_create_bus(dev, bus_name); in xilinx_spips_realize()
1297 s->cs_lines = g_new0(qemu_irq, s->num_cs * s->num_busses); in xilinx_spips_realize()
1298 s->cs_lines_state = g_new0(bool, s->num_cs * s->num_busses); in xilinx_spips_realize()
1300 sysbus_init_irq(sbd, &s->irq); in xilinx_spips_realize()
1301 for (i = 0; i < s->num_cs * s->num_busses; ++i) { in xilinx_spips_realize()
1302 sysbus_init_irq(sbd, &s->cs_lines[i]); in xilinx_spips_realize()
1305 memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s, in xilinx_spips_realize()
1306 "spi", xsc->reg_size); in xilinx_spips_realize()
1307 sysbus_init_mmio(sbd, &s->iomem); in xilinx_spips_realize()
1309 s->irqline = -1; in xilinx_spips_realize()
1311 fifo8_create(&s->rx_fifo, xsc->rx_fifo_size); in xilinx_spips_realize()
1312 fifo8_create(&s->tx_fifo, xsc->tx_fifo_size); in xilinx_spips_realize()
1323 s->num_busses = 2; in xilinx_qspips_realize()
1324 s->num_cs = 2; in xilinx_qspips_realize()
1325 s->num_txrx_bytes = 4; in xilinx_qspips_realize()
1328 memory_region_init_io(&s->mmlqspi, OBJECT(s), &lqspi_ops, s, "lqspi", in xilinx_qspips_realize()
1330 sysbus_init_mmio(sbd, &s->mmlqspi); in xilinx_qspips_realize()
1332 q->lqspi_cached_addr = ~0ULL; in xilinx_qspips_realize()
1340 if (s->dma_burst_size > QSPI_DMA_MAX_BURST_SIZE) { in xlnx_zynqmp_qspips_realize()
1343 s->dma_burst_size, QSPI_DMA_MAX_BURST_SIZE); in xlnx_zynqmp_qspips_realize()
1347 fifo8_create(&s->rx_fifo_g, xsc->rx_fifo_size); in xlnx_zynqmp_qspips_realize()
1348 fifo8_create(&s->tx_fifo_g, xsc->tx_fifo_size); in xlnx_zynqmp_qspips_realize()
1349 fifo32_create(&s->fifo_g, 32); in xlnx_zynqmp_qspips_realize()
1356 object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SINK, in xlnx_zynqmp_qspips_init()
1357 (Object **)&rq->dma, in xlnx_zynqmp_qspips_init()
1388 if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN) && in xlnx_zynqmp_qspips_post_load()
1389 fifo8_is_empty(&qs->rx_fifo) && fifo8_is_empty(&qs->tx_fifo)) { in xlnx_zynqmp_qspips_post_load()
1424 DEFINE_PROP_UINT32("dma-burst-size", XlnxZynqMPQSPIPS, dma_burst_size, 64),
1428 DEFINE_PROP_UINT8("num-busses", XilinxSPIPS, num_busses, 1),
1429 DEFINE_PROP_UINT8("num-ss-bits", XilinxSPIPS, num_cs, 4),
1430 DEFINE_PROP_UINT8("num-txrx-bytes", XilinxSPIPS, num_txrx_bytes, 1),
1438 dc->realize = xilinx_qspips_realize; in xilinx_qspips_class_init()
1439 xsc->reg_ops = &qspips_ops; in xilinx_qspips_class_init()
1440 xsc->reg_size = XLNX_SPIPS_R_MAX * 4; in xilinx_qspips_class_init()
1441 xsc->rx_fifo_size = RXFF_A_Q; in xilinx_qspips_class_init()
1442 xsc->tx_fifo_size = TXFF_A_Q; in xilinx_qspips_class_init()
1450 dc->realize = xilinx_spips_realize; in xilinx_spips_class_init()
1453 dc->vmsd = &vmstate_xilinx_spips; in xilinx_spips_class_init()
1455 xsc->reg_ops = &spips_ops; in xilinx_spips_class_init()
1456 xsc->reg_size = XLNX_SPIPS_R_MAX * 4; in xilinx_spips_class_init()
1457 xsc->rx_fifo_size = RXFF_A; in xilinx_spips_class_init()
1458 xsc->tx_fifo_size = TXFF_A; in xilinx_spips_class_init()
1466 dc->realize = xlnx_zynqmp_qspips_realize; in xlnx_zynqmp_qspips_class_init()
1468 dc->vmsd = &vmstate_xlnx_zynqmp_qspips; in xlnx_zynqmp_qspips_class_init()
1470 xsc->reg_ops = &xlnx_zynqmp_qspips_ops; in xlnx_zynqmp_qspips_class_init()
1471 xsc->reg_size = XLNX_ZYNQMP_SPIPS_R_MAX * 4; in xlnx_zynqmp_qspips_class_init()
1472 xsc->rx_fifo_size = RXFF_A_Q; in xlnx_zynqmp_qspips_class_init()
1473 xsc->tx_fifo_size = TXFF_A_Q; in xlnx_zynqmp_qspips_class_init()