mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-12-19 08:21:27 +01:00
Add i3c command file to support select, get i3c device target list, read and write operation. Signed-off-by: Dinesh Maniyam <dinesh.maniyam@altera.com>
253 lines
7.6 KiB
C
253 lines
7.6 KiB
C
/* 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_*/
|