| /* SPDX-License-Identifier: GPL-2.0+ */ | |
| /* | |
| * Copyright (C) 2025 Altera Corporation <www.altera.com> | |
| */ | |
| #ifndef _DW_I3C_H_ | |
| #define _DW_I3C_H_ | |
| #include <clk.h> | |
| #include <i3c.h> | |
| #include <reset.h> | |
| #include <dm/device.h> | |
| #include <linux/bitops.h> | |
| #include <linux/bitfield.h> | |
| #include <linker_lists.h> | |
| #include <linux/i3c/master.h> | |
| #define DEVICE_CTRL 0x0 | |
| #define DEV_CTRL_ENABLE BIT(31) | |
| #define DEV_CTRL_RESUME BIT(30) | |
| #define DEV_CTRL_HOT_JOIN_NACK BIT(8) | |
| #define DEV_CTRL_I2C_SLAVE_PRESENT BIT(7) | |
| #define DEVICE_ADDR 0x4 | |
| #define DEV_ADDR_DYNAMIC_ADDR_VALID BIT(31) | |
| #define DEV_ADDR_DYNAMIC(x) (((x) << 16) & GENMASK(22, 16)) | |
| #define HW_CAPABILITY 0x8 | |
| #define COMMAND_QUEUE_PORT 0xc | |
| #define COMMAND_PORT_TOC BIT(30) | |
| #define COMMAND_PORT_READ_TRANSFER BIT(28) | |
| #define COMMAND_PORT_SDAP BIT(27) | |
| #define COMMAND_PORT_ROC BIT(26) | |
| #define COMMAND_PORT_SPEED(x) (((x) << 21) & GENMASK(23, 21)) | |
| #define COMMAND_PORT_DEV_INDEX(x) (((x) << 16) & GENMASK(20, 16)) | |
| #define COMMAND_PORT_CP BIT(15) | |
| #define COMMAND_PORT_CMD(x) (((x) << 7) & GENMASK(14, 7)) | |
| #define COMMAND_PORT_TID(x) (((x) << 3) & GENMASK(6, 3)) | |
| #define COMMAND_PORT_ARG_DATA_LEN(x) (((x) << 16) & GENMASK(31, 16)) | |
| #define COMMAND_PORT_ARG_DATA_LEN_MAX 65536 | |
| #define COMMAND_PORT_TRANSFER_ARG 0x01 | |
| #define COMMAND_PORT_SDA_DATA_BYTE_3(x) (((x) << 24) & GENMASK(31, 24)) | |
| #define COMMAND_PORT_SDA_DATA_BYTE_2(x) (((x) << 16) & GENMASK(23, 16)) | |
| #define COMMAND_PORT_SDA_DATA_BYTE_1(x) (((x) << 8) & GENMASK(15, 8)) | |
| #define COMMAND_PORT_SDA_BYTE_STRB_3 BIT(5) | |
| #define COMMAND_PORT_SDA_BYTE_STRB_2 BIT(4) | |
| #define COMMAND_PORT_SDA_BYTE_STRB_1 BIT(3) | |
| #define COMMAND_PORT_SHORT_DATA_ARG 0x02 | |
| #define COMMAND_PORT_DEV_COUNT(x) (((x) << 21) & GENMASK(25, 21)) | |
| #define COMMAND_PORT_ADDR_ASSGN_CMD 0x03 | |
| #define RESPONSE_QUEUE_PORT 0x10 | |
| #define RESPONSE_PORT_ERR_STATUS(x) (((x) & GENMASK(31, 28)) >> 28) | |
| #define RESPONSE_NO_ERROR 0 | |
| #define RESPONSE_ERROR_CRC 1 | |
| #define RESPONSE_ERROR_PARITY 2 | |
| #define RESPONSE_ERROR_FRAME 3 | |
| #define RESPONSE_ERROR_IBA_NACK 4 | |
| #define RESPONSE_ERROR_ADDRESS_NACK 5 | |
| #define RESPONSE_ERROR_OVER_UNDER_FLOW 6 | |
| #define RESPONSE_ERROR_TRANSF_ABORT 8 | |
| #define RESPONSE_ERROR_I2C_W_NACK_ERR 9 | |
| #define RESPONSE_PORT_TID(x) (((x) & GENMASK(27, 24)) >> 24) | |
| #define RESPONSE_PORT_DATA_LEN(x) ((x) & GENMASK(15, 0)) | |
| #define RX_TX_DATA_PORT 0x14 | |
| #define IBI_QUEUE_STATUS 0x18 | |
| #define QUEUE_THLD_CTRL 0x1c | |
| #define QUEUE_THLD_CTRL_RESP_BUF_MASK GENMASK(15, 8) | |
| #define QUEUE_THLD_CTRL_RESP_BUF(x) (((x) - 1) << 8) | |
| #define DATA_BUFFER_THLD_CTRL 0x20 | |
| #define DATA_BUFFER_THLD_CTRL_RX_BUF GENMASK(11, 8) | |
| #define IBI_QUEUE_CTRL 0x24 | |
| #define IBI_MR_REQ_REJECT 0x2C | |
| #define IBI_SIR_REQ_REJECT 0x30 | |
| #define IBI_REQ_REJECT_ALL GENMASK(31, 0) | |
| #define RESET_CTRL 0x34 | |
| #define RESET_CTRL_IBI_QUEUE BIT(5) | |
| #define RESET_CTRL_RX_FIFO BIT(4) | |
| #define RESET_CTRL_TX_FIFO BIT(3) | |
| #define RESET_CTRL_RESP_QUEUE BIT(2) | |
| #define RESET_CTRL_CMD_QUEUE BIT(1) | |
| #define RESET_CTRL_SOFT BIT(0) | |
| #define SLV_EVENT_CTRL 0x38 | |
| #define INTR_STATUS 0x3c | |
| #define INTR_STATUS_EN 0x40 | |
| #define INTR_SIGNAL_EN 0x44 | |
| #define INTR_FORCE 0x48 | |
| #define INTR_BUSOWNER_UPDATE_STAT BIT(13) | |
| #define INTR_IBI_UPDATED_STAT BIT(12) | |
| #define INTR_READ_REQ_RECV_STAT BIT(11) | |
| #define INTR_DEFSLV_STAT BIT(10) | |
| #define INTR_TRANSFER_ERR_STAT BIT(9) | |
| #define INTR_DYN_ADDR_ASSGN_STAT BIT(8) | |
| #define INTR_CCC_UPDATED_STAT BIT(6) | |
| #define INTR_TRANSFER_ABORT_STAT BIT(5) | |
| #define INTR_RESP_READY_STAT BIT(4) | |
| #define INTR_CMD_QUEUE_READY_STAT BIT(3) | |
| #define INTR_IBI_THLD_STAT BIT(2) | |
| #define INTR_RX_THLD_STAT BIT(1) | |
| #define INTR_TX_THLD_STAT BIT(0) | |
| #define INTR_ALL (INTR_BUSOWNER_UPDATE_STAT | \ | |
| INTR_IBI_UPDATED_STAT | \ | |
| INTR_READ_REQ_RECV_STAT | \ | |
| INTR_DEFSLV_STAT | \ | |
| INTR_TRANSFER_ERR_STAT | \ | |
| INTR_DYN_ADDR_ASSGN_STAT | \ | |
| INTR_CCC_UPDATED_STAT | \ | |
| INTR_TRANSFER_ABORT_STAT | \ | |
| INTR_RESP_READY_STAT | \ | |
| INTR_CMD_QUEUE_READY_STAT | \ | |
| INTR_IBI_THLD_STAT | \ | |
| INTR_TX_THLD_STAT | \ | |
| INTR_RX_THLD_STAT) | |
| #define INTR_MASTER_MASK (INTR_TRANSFER_ERR_STAT | \ | |
| INTR_RESP_READY_STAT) | |
| #define QUEUE_STATUS_LEVEL 0x4c | |
| #define QUEUE_STATUS_IBI_STATUS_CNT(x) (((x) & GENMASK(28, 24)) >> 24) | |
| #define QUEUE_STATUS_IBI_BUF_BLR(x) (((x) & GENMASK(23, 16)) >> 16) | |
| #define QUEUE_STATUS_LEVEL_RESP(x) (((x) & GENMASK(15, 8)) >> 8) | |
| #define QUEUE_STATUS_LEVEL_CMD(x) ((x) & GENMASK(7, 0)) | |
| #define DATA_BUFFER_STATUS_LEVEL 0x50 | |
| #define DATA_BUFFER_STATUS_LEVEL_TX(x) ((x) & GENMASK(7, 0)) | |
| #define PRESENT_STATE 0x54 | |
| #define CCC_DEVICE_STATUS 0x58 | |
| #define DEVICE_ADDR_TABLE_POINTER 0x5c | |
| #define DEVICE_ADDR_TABLE_DEPTH(x) (((x) & GENMASK(31, 16)) >> 16) | |
| #define DEVICE_ADDR_TABLE_ADDR(x) ((x) & GENMASK(7, 0)) | |
| #define DEV_CHAR_TABLE_POINTER 0x60 | |
| #define VENDOR_SPECIFIC_REG_POINTER 0x6c | |
| #define SLV_PID_VALUE 0x74 | |
| #define SLV_CHAR_CTRL 0x78 | |
| #define SLV_MAX_LEN 0x7c | |
| #define MAX_READ_TURNAROUND 0x80 | |
| #define MAX_DATA_SPEED 0x84 | |
| #define SLV_DEBUG_STATUS 0x88 | |
| #define SLV_INTR_REQ 0x8c | |
| #define DEVICE_CTRL_EXTENDED 0xb0 | |
| #define SCL_I3C_OD_TIMING 0xb4 | |
| #define SCL_I3C_PP_TIMING 0xb8 | |
| #define SCL_I3C_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16)) | |
| #define SCL_I3C_TIMING_LCNT(x) ((x) & GENMASK(7, 0)) | |
| #define SCL_I3C_TIMING_CNT_MIN 5 | |
| #define SCL_I2C_FM_TIMING 0xbc | |
| #define SCL_I2C_FM_TIMING_HCNT(x) (((x) << 16) & GENMASK(31, 16)) | |
| #define SCL_I2C_FM_TIMING_LCNT(x) ((x) & GENMASK(15, 0)) | |
| #define SCL_I2C_FMP_TIMING 0xc0 | |
| #define SCL_I2C_FMP_TIMING_HCNT(x) (((x) << 16) & GENMASK(23, 16)) | |
| #define SCL_I2C_FMP_TIMING_LCNT(x) ((x) & GENMASK(15, 0)) | |
| #define SCL_EXT_LCNT_TIMING 0xc8 | |
| #define SCL_EXT_LCNT_4(x) (((x) << 24) & GENMASK(31, 24)) | |
| #define SCL_EXT_LCNT_3(x) (((x) << 16) & GENMASK(23, 16)) | |
| #define SCL_EXT_LCNT_2(x) (((x) << 8) & GENMASK(15, 8)) | |
| #define SCL_EXT_LCNT_1(x) ((x) & GENMASK(7, 0)) | |
| #define SCL_EXT_TERMN_LCNT_TIMING 0xcc | |
| #define BUS_FREE_TIMING 0xd4 | |
| #define BUS_I3C_MST_FREE(x) ((x) & GENMASK(15, 0)) | |
| #define BUS_IDLE_TIMING 0xd8 | |
| #define I3C_VER_ID 0xe0 | |
| #define I3C_VER_TYPE 0xe4 | |
| #define EXTENDED_CAPABILITY 0xe8 | |
| #define SLAVE_CONFIG 0xec | |
| #define DEV_ADDR_TABLE_LEGACY_I2C_DEV BIT(31) | |
| #define DEV_ADDR_TABLE_DYNAMIC_ADDR(x) (((x) << 16) & GENMASK(23, 16)) | |
| #define DEV_ADDR_TABLE_STATIC_ADDR(x) ((x) & GENMASK(6, 0)) | |
| #define DEV_ADDR_TABLE_LOC(start, idx) ((start) + ((idx) << 2)) | |
| #define MAX_DEVS 32 | |
| #define I3C_BUS_SDR1_SCL_RATE 8000000 | |
| #define I3C_BUS_SDR2_SCL_RATE 6000000 | |
| #define I3C_BUS_SDR3_SCL_RATE 4000000 | |
| #define I3C_BUS_SDR4_SCL_RATE 2000000 | |
| #define I3C_BUS_I2C_FM_TLOW_MIN_NS 1300 | |
| #define I3C_BUS_I2C_FMP_TLOW_MIN_NS 500 | |
| #define I3C_BUS_THIGH_MAX_NS 41 | |
| #define XFER_TIMEOUT (msecs_to_jiffies(1000)) | |
| #define readl_poll_timeout_atomic readl_poll_sleep_timeout | |
| #define STRUCT_SZ(struct, count) (sizeof(struct) * (count)) | |
| #define I3C_MSG_READ 1 | |
| #define I3C_MSG_WRITE 0 | |
| #define POLL_SUCCESS 0 | |
| struct dw_i3c_master_caps { | |
| u8 cmdfifodepth; | |
| u8 datafifodepth; | |
| }; | |
| struct dw_i3c_cmd { | |
| u32 cmd_lo; | |
| u32 cmd_hi; | |
| u16 tx_len; | |
| const void *tx_buf; | |
| u16 rx_len; | |
| void *rx_buf; | |
| u8 error; | |
| }; | |
| struct dw_i3c_xfer { | |
| struct list_head node; | |
| int ret; | |
| unsigned int ncmds; | |
| struct dw_i3c_cmd cmds[16]; | |
| }; | |
| struct dw_i3c_master { | |
| struct i3c_master_controller base; | |
| u16 maxdevs; | |
| u16 datstartaddr; | |
| u32 free_pos; | |
| struct { | |
| struct list_head list; | |
| struct dw_i3c_xfer *cur; | |
| spinlock_t lock; /* spinlock for i3c transfer */ | |
| } xferqueue; | |
| struct dw_i3c_master_caps caps; | |
| void __iomem *regs; | |
| struct reset_ctl_bulk resets; | |
| struct clk core_clk; | |
| char version[5]; | |
| char type[5]; | |
| u8 addrs[MAX_DEVS]; | |
| bool first_broadcast; | |
| struct i3c_dev_desc *i3cdev[I3C_BUS_MAX_DEVS]; | |
| u16 num_i3cdevs; | |
| }; | |
| struct dw_i3c_i2c_dev_data { | |
| u8 index; | |
| }; | |
| #endif /*_DW_I3C_H_*/ |