/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2025 * Altera Corporation */ #ifndef __CADENCE_XSPI_H__ #define __CADENCE_XSPI_H__ #include #include #include #include #include #define CDNS_XSPI_MAGIC_NUM_VALUE 0x6522 #define CDNS_XSPI_MAX_BANKS 8 #define CDNS_XSPI_NAME "cadence_xspi" /* * Note: below are additional auxiliary registers to * configure XSPI controller pin-strap settings */ /* PHY DQ timing register */ #define CDNS_XSPI_CCP_PHY_DQ_TIMING 0x0000 /* PHY DQS timing register */ #define CDNS_XSPI_CCP_PHY_DQS_TIMING 0x0004 /* PHY gate loopback control register */ #define CDNS_XSPI_CCP_PHY_GATE_LPBCK_CTRL 0x0008 /* PHY DLL slave control register */ #define CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL 0x0010 /* DLL PHY control register */ #define CDNS_XSPI_DLL_PHY_CTRL 0x1034 /* Command registers */ #define CDNS_XSPI_CMD_REG_0 0x0000 #define CDNS_XSPI_CMD_REG_1 0x0004 #define CDNS_XSPI_CMD_REG_2 0x0008 #define CDNS_XSPI_CMD_REG_3 0x000C #define CDNS_XSPI_CMD_REG_4 0x0010 #define CDNS_XSPI_CMD_REG_5 0x0014 /* Command status registers */ #define CDNS_XSPI_CMD_STATUS_REG 0x0044 /* Controller status register */ #define CDNS_XSPI_CTRL_STATUS_REG 0x0100 #define CDNS_XSPI_INIT_COMPLETED BIT(16) #define CDNS_XSPI_INIT_LEGACY BIT(9) #define CDNS_XSPI_INIT_FAIL BIT(8) #define CDNS_XSPI_CTRL_BUSY BIT(7) /* Controller interrupt status register */ #define CDNS_XSPI_INTR_STATUS_REG 0x0110 #define CDNS_XSPI_STIG_DONE BIT(23) #define CDNS_XSPI_SDMA_ERROR BIT(22) #define CDNS_XSPI_SDMA_TRIGGER BIT(21) #define CDNS_XSPI_CMD_IGNRD_EN BIT(20) #define CDNS_XSPI_DDMA_TERR_EN BIT(18) #define CDNS_XSPI_CDMA_TREE_EN BIT(17) #define CDNS_XSPI_CTRL_IDLE_EN BIT(16) #define CDNS_XSPI_TRD_COMP_INTR_STATUS 0x0120 #define CDNS_XSPI_TRD_ERR_INTR_STATUS 0x0130 #define CDNS_XSPI_TRD_ERR_INTR_EN 0x0134 /* Controller interrupt enable register */ #define CDNS_XSPI_INTR_ENABLE_REG 0x0114 #define CDNS_XSPI_INTR_EN BIT(31) #define CDNS_XSPI_STIG_DONE_EN BIT(23) #define CDNS_XSPI_SDMA_ERROR_EN BIT(22) #define CDNS_XSPI_SDMA_TRIGGER_EN BIT(21) #define CDNS_XSPI_INTR_MASK (CDNS_XSPI_INTR_EN | \ CDNS_XSPI_STIG_DONE_EN | \ CDNS_XSPI_SDMA_ERROR_EN | \ CDNS_XSPI_SDMA_TRIGGER_EN) /* Controller config register */ #define CDNS_XSPI_CTRL_CONFIG_REG 0x0230 #define CDNS_XSPI_CTRL_WORK_MODE GENMASK(6, 5) #define CDNS_XSPI_WORK_MODE_DIRECT 0 #define CDNS_XSPI_WORK_MODE_STIG 1 #define CDNS_XSPI_WORK_MODE_ACMD 3 /* SDMA trigger transaction registers */ #define CDNS_XSPI_SDMA_SIZE_REG 0x0240 #define CDNS_XSPI_SDMA_TRD_INFO_REG 0x0244 #define CDNS_XSPI_SDMA_DIR BIT(8) /* Controller features register */ #define CDNS_XSPI_CTRL_FEATURES_REG 0x0F04 #define CDNS_XSPI_NUM_BANKS GENMASK(25, 24) #define CDNS_XSPI_DMA_DATA_WIDTH BIT(21) #define CDNS_XSPI_NUM_THREADS GENMASK(3, 0) /* Controller version register */ #define CDNS_XSPI_CTRL_VERSION_REG 0x0F00 #define CDNS_XSPI_MAGIC_NUM GENMASK(31, 16) #define CDNS_XSPI_CTRL_REV GENMASK(7, 0) /* STIG Profile 1.0 instruction fields (split into registers) */ #define CDNS_XSPI_CMD_INSTR_TYPE GENMASK(6, 0) #define CDNS_XSPI_CMD_P1_R1_ADDR0 GENMASK(31, 24) #define CDNS_XSPI_CMD_P1_R2_ADDR1 GENMASK(7, 0) #define CDNS_XSPI_CMD_P1_R2_ADDR2 GENMASK(15, 8) #define CDNS_XSPI_CMD_P1_R2_ADDR3 GENMASK(23, 16) #define CDNS_XSPI_CMD_P1_R2_ADDR4 GENMASK(31, 24) #define CDNS_XSPI_CMD_P1_R3_ADDR5 GENMASK(7, 0) #define CDNS_XSPI_CMD_P1_R3_CMD GENMASK(23, 16) #define CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES GENMASK(30, 28) #define CDNS_XSPI_CMD_P1_R4_ADDR_IOS GENMASK(1, 0) #define CDNS_XSPI_CMD_P1_R4_CMD_IOS GENMASK(9, 8) #define CDNS_XSPI_CMD_P1_R4_BANK GENMASK(14, 12) /* STIG data sequence instruction fields (split into registers) */ #define CDNS_XSPI_CMD_DSEQ_R2_DCNT_L GENMASK(31, 16) #define CDNS_XSPI_CMD_DSEQ_R3_DCNT_H GENMASK(15, 0) #define CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY GENMASK(25, 20) #define CDNS_XSPI_CMD_DSEQ_R4_BANK GENMASK(14, 12) #define CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS GENMASK(9, 8) #define CDNS_XSPI_CMD_DSEQ_R4_DIR BIT(4) /* STIG command status fields */ #define CDNS_XSPI_CMD_STATUS_COMPLETED BIT(15) #define CDNS_XSPI_CMD_STATUS_FAILED BIT(14) #define CDNS_XSPI_CMD_STATUS_DQS_ERROR BIT(3) #define CDNS_XSPI_CMD_STATUS_CRC_ERROR BIT(2) #define CDNS_XSPI_CMD_STATUS_BUS_ERROR BIT(1) #define CDNS_XSPI_CMD_STATUS_INV_SEQ_ERROR BIT(0) #define CDNS_XSPI_STIG_DONE_FLAG BIT(0) #define CDNS_XSPI_TRD_STATUS 0x0104 #define MODE_NO_OF_BYTES GENMASK(25, 24) #define MODEBYTES_COUNT 1 /* Helper macros for filling command registers */ #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_1(op, data_phase) ( \ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, (data_phase) ? \ CDNS_XSPI_STIG_INSTR_TYPE_1 : CDNS_XSPI_STIG_INSTR_TYPE_0) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R1_ADDR0, (op)->addr.val & 0xff)) #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_2(op) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR1, ((op)->addr.val >> 8) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR2, ((op)->addr.val >> 16) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR3, ((op)->addr.val >> 24) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R2_ADDR4, ((op)->addr.val >> 32) & 0xFF)) #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_3(op, modebytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_ADDR5, ((op)->addr.val >> 40) & 0xFF) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_CMD, (op)->cmd.opcode) | \ FIELD_PREP(MODE_NO_OF_BYTES, modebytes) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R3_NUM_ADDR_BYTES, (op)->addr.nbytes)) #define CDNS_XSPI_CMD_FLD_P1_INSTR_CMD_4(op, chipsel) ( \ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_ADDR_IOS, ilog2((op)->addr.buswidth)) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_CMD_IOS, ilog2((op)->cmd.buswidth)) | \ FIELD_PREP(CDNS_XSPI_CMD_P1_R4_BANK, chipsel)) #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_1 \ FIELD_PREP(CDNS_XSPI_CMD_INSTR_TYPE, CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ) #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_2(op) \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R2_DCNT_L, (op)->data.nbytes & 0xFFFF) #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_3(op, dummybytes) ( \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_DCNT_H, \ ((op)->data.nbytes >> 16) & 0xffff) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R3_NUM_OF_DUMMY, \ (op)->dummy.buswidth != 0 ? \ (((dummybytes) * 8) / (op)->dummy.buswidth) : \ 0)) #define CDNS_XSPI_CMD_FLD_DSEQ_CMD_4(op, chipsel) ( \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_BANK, chipsel) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DATA_IOS, \ ilog2((op)->data.buswidth)) | \ FIELD_PREP(CDNS_XSPI_CMD_DSEQ_R4_DIR, \ ((op)->data.dir == SPI_MEM_DATA_IN) ? \ CDNS_XSPI_STIG_CMD_DIR_READ : CDNS_XSPI_STIG_CMD_DIR_WRITE)) enum cdns_xspi_stig_instr_type { CDNS_XSPI_STIG_INSTR_TYPE_0, CDNS_XSPI_STIG_INSTR_TYPE_1, CDNS_XSPI_STIG_INSTR_TYPE_DATA_SEQ = 127, }; enum cdns_xspi_sdma_dir { CDNS_XSPI_SDMA_DIR_READ, CDNS_XSPI_SDMA_DIR_WRITE, }; enum cdns_xspi_stig_cmd_dir { CDNS_XSPI_STIG_CMD_DIR_READ, CDNS_XSPI_STIG_CMD_DIR_WRITE, }; struct cdns_xspi_plat { struct device *dev; struct reset_ctl_bulk *resets; void __iomem *iobase; void __iomem *auxbase; void __iomem *sdmabase; int cur_cs; unsigned int sdmasize; bool sdma_error; void *in_buffer; const void *out_buffer; u8 hw_num_banks; void (*sdma_handler)(struct cdns_xspi_plat *cdns_xspi); void (*set_interrupts_handler)(struct cdns_xspi_plat *cdns_xspi, bool enabled); }; #endif /* __CADENCE_XSPI_H__ */