1 /* 2 * ASPEED I3C Controller 3 * 4 * Copyright (C) 2021 ASPEED Technology Inc. 5 * Copyright (C) 2023 Google, LLC 6 * 7 * This code is licensed under the GPL version 2 or later. See 8 * the COPYING file in the top-level directory. 9 */ 10 11 #ifndef ASPEED_I3C_H 12 #define ASPEED_I3C_H 13 14 #include "qemu/fifo32.h" 15 #include "hw/i3c/i3c.h" 16 #include "hw/sysbus.h" 17 18 #define TYPE_ASPEED_I3C "aspeed.i3c" 19 #define TYPE_ASPEED_I3C_DEVICE "aspeed.i3c.device" 20 OBJECT_DECLARE_TYPE(AspeedI3CState, AspeedI3CClass, ASPEED_I3C) 21 22 #define ASPEED_I3C_NR_REGS (0x70 >> 2) 23 #define ASPEED_I3C_DEVICE_NR_REGS (0x300 >> 2) 24 #define ASPEED_I3C_NR_DEVICES 6 25 26 #define ASPEED_I3C_CMD_QUEUE_CAPACITY 0x10 27 #define ASPEED_I3C_RESP_QUEUE_CAPACITY 0x10 28 #define ASPEED_I3C_TX_QUEUE_CAPACITY 0x40 29 #define ASPEED_I3C_RX_QUEUE_CAPACITY 0x40 30 31 /* From datasheet. */ 32 #define ASPEED_I3C_CMD_ATTR_TRANSFER_CMD 0 33 #define ASPEED_I3C_CMD_ATTR_TRANSFER_ARG 1 34 #define ASPEED_I3C_CMD_ATTR_SHORT_DATA_ARG 2 35 #define ASPEED_I3C_CMD_ATTR_ADDR_ASSIGN_CMD 3 36 37 /* Enum values from datasheet. */ 38 typedef enum AspeedI3CRespQueueErr { 39 ASPEED_I3C_RESP_QUEUE_ERR_NONE = 0, 40 ASPEED_I3C_RESP_QUEUE_ERR_CRC = 1, 41 ASPEED_I3C_RESP_QUEUE_ERR_PARITY = 2, 42 ASPEED_I3C_RESP_QUEUE_ERR_FRAME = 3, 43 ASPEED_I3C_RESP_QUEUE_ERR_BROADCAST_NACK = 4, 44 ASPEED_I3C_RESP_QUEUE_ERR_DAA_NACK = 5, 45 ASPEED_I3C_RESP_QUEUE_ERR_OVERFLOW = 6, 46 ASPEED_I3C_RESP_QUEUE_ERR_ABORTED = 8, 47 ASPEED_I3C_RESP_QUEUE_ERR_I2C_NACK = 9, 48 } AspeedI3CRespQueueErr; 49 50 typedef enum AspeedI3CTransferState { 51 ASPEED_I3C_TRANSFER_STATE_IDLE = 0x00, 52 ASPEED_I3C_TRANSFER_STATE_START = 0x01, 53 ASPEED_I3C_TRANSFER_STATE_RESTART = 0x02, 54 ASPEED_I3C_TRANSFER_STATE_STOP = 0x03, 55 ASPEED_I3C_TRANSFER_STATE_START_HOLD = 0x04, 56 ASPEED_I3C_TRANSFER_STATE_BROADCAST_W = 0x05, 57 ASPEED_I3C_TRANSFER_STATE_BROADCAST_R = 0x06, 58 ASPEED_I3C_TRANSFER_STATE_DAA = 0x07, 59 ASPEED_I3C_TRANSFER_STATE_DAA_GEN = 0x08, 60 ASPEED_I3C_TRANSFER_STATE_CCC_BYTE = 0x0b, 61 ASPEED_I3C_TRANSFER_STATE_HDR_CMD = 0x0c, 62 ASPEED_I3C_TRANSFER_STATE_WRITE = 0x0d, 63 ASPEED_I3C_TRANSFER_STATE_READ = 0x0e, 64 ASPEED_I3C_TRANSFER_STATE_IBI_READ = 0x0f, 65 ASPEED_I3C_TRANSFER_STATE_IBI_DIS = 0x10, 66 ASPEED_I3C_TRANSFER_STATE_HDR_DDR_CRC = 0x11, 67 ASPEED_I3C_TRANSFER_STATE_CLK_STRETCH = 0x12, 68 ASPEED_I3C_TRANSFER_STATE_HALT = 0x13, 69 } AspeedI3CTransferState; 70 71 typedef enum AspeedI3CTransferStatus { 72 ASPEED_I3C_TRANSFER_STATUS_IDLE = 0x00, 73 ASPEED_I3C_TRANSFER_STATUS_BROACAST_CCC = 0x01, 74 ASPEED_I3C_TRANSFER_STATUS_DIRECT_CCC_W = 0x02, 75 ASPEED_I3C_TRANSFER_STATUS_DIRECT_CCC_R = 0x03, 76 ASPEED_I3C_TRANSFER_STATUS_ENTDAA = 0x04, 77 ASPEED_I3C_TRANSFER_STATUS_SETDASA = 0x05, 78 ASPEED_I3C_TRANSFER_STATUS_I3C_SDR_W = 0x06, 79 ASPEED_I3C_TRANSFER_STATUS_I3C_SDR_R = 0x07, 80 ASPEED_I3C_TRANSFER_STATUS_I2C_SDR_W = 0x08, 81 ASPEED_I3C_TRANSFER_STATUS_I2C_SDR_R = 0x09, 82 ASPEED_I3C_TRANSFER_STATUS_HDR_TS_W = 0x0a, 83 ASPEED_I3C_TRANSFER_STATUS_HDR_TS_R = 0x0b, 84 ASPEED_I3C_TRANSFER_STATUS_HDR_DDR_W = 0x0c, 85 ASPEED_I3C_TRANSFER_STATUS_HDR_DDR_R = 0x0d, 86 ASPEED_I3C_TRANSFER_STATUS_IBI = 0x0e, 87 ASPEED_I3C_TRANSFER_STATUS_HALT = 0x0f, 88 } AspeedI3CTransferStatus; 89 90 /* 91 * Transfer commands and arguments are 32-bit wide values that the user passes 92 * into the command queue. We interpret each 32-bit word based on the cmd_attr 93 * field. 94 */ 95 typedef struct AspeedI3CTransferCmd { 96 uint8_t cmd_attr:3; 97 uint8_t tid:4; /* Transaction ID */ 98 uint16_t cmd:8; 99 uint8_t cp:1; /* Command present */ 100 uint8_t dev_index:5; 101 uint8_t speed:3; 102 uint8_t resv0:1; 103 uint8_t dbp:1; /* Defining byte present */ 104 uint8_t roc:1; /* Response on completion */ 105 uint8_t sdap:1; /* Short data argument present */ 106 uint8_t rnw:1; /* Read not write */ 107 uint8_t resv1:1; 108 uint8_t toc:1; /* Termination (I3C STOP) on completion */ 109 uint8_t pec:1; /* Parity error check enabled */ 110 } AspeedI3CTransferCmd; 111 112 typedef struct AspeedI3CTransferArg { 113 uint8_t cmd_attr:3; 114 uint8_t resv:5; 115 uint8_t db; /* Defining byte */ 116 uint16_t data_len; 117 } AspeedI3CTransferArg; 118 119 typedef struct AspeedI3CShortArg { 120 uint8_t cmd_attr:3; 121 uint8_t byte_strb:3; 122 uint8_t resv:2; 123 uint8_t byte0; 124 uint8_t byte1; 125 uint8_t byte2; 126 } AspeedI3CShortArg; 127 128 typedef struct AspeedI3CAddrAssignCmd { 129 uint8_t cmd_attr:3; 130 uint8_t tid:4; /* Transaction ID */ 131 uint16_t cmd:8; 132 uint8_t resv0:1; 133 uint8_t dev_index:5; 134 uint16_t dev_count:5; 135 uint8_t roc:1; /* Response on completion */ 136 uint8_t resv1:3; 137 uint8_t toc:1; /* Termination (I3C STOP) on completion */ 138 uint8_t resv2:1; 139 } AspeedI3CAddrAssignCmd; 140 141 typedef union AspeedI3CCmdQueueData { 142 uint32_t word; 143 AspeedI3CTransferCmd transfer_cmd; 144 AspeedI3CTransferArg transfer_arg; 145 AspeedI3CShortArg short_arg; 146 AspeedI3CAddrAssignCmd addr_assign_cmd; 147 } AspeedI3CCmdQueueData; 148 149 OBJECT_DECLARE_SIMPLE_TYPE(AspeedI3CDevice, ASPEED_I3C_DEVICE) 150 typedef struct AspeedI3CDevice { 151 /* <private> */ 152 SysBusDevice parent; 153 154 /* <public> */ 155 MemoryRegion mr; 156 qemu_irq irq; 157 I3CBus *bus; 158 159 Fifo32 cmd_queue; 160 Fifo32 resp_queue; 161 Fifo32 tx_queue; 162 Fifo32 rx_queue; 163 164 uint8_t id; 165 uint32_t regs[ASPEED_I3C_DEVICE_NR_REGS]; 166 } AspeedI3CDevice; 167 168 typedef struct AspeedI3CState { 169 /* <private> */ 170 SysBusDevice parent; 171 172 /* <public> */ 173 MemoryRegion iomem; 174 MemoryRegion iomem_container; 175 qemu_irq irq; 176 177 uint32_t regs[ASPEED_I3C_NR_REGS]; 178 AspeedI3CDevice devices[ASPEED_I3C_NR_DEVICES]; 179 } AspeedI3CState; 180 #endif /* ASPEED_I3C_H */ 181