---
tags: Aspeed, I3C, HCI, I2C, SMBUS
---
[TOC]
# I3C HCI (Host Controller Interface)
## Overview
- I3C HCI is a standard interface that allows for easy integration of I3C Master Device (I3C Host Controller)to subsystem.

## Purpose
- Allows a single OS Driver (aka ‘in-box Driver’) to support I3C Hardware from several vendors.
- Allows for vendor-specific extensions or other improvements, which are treated as additional capabilities claimed by the Host Controller.
## Interface Architecture

- I3C Bus Controller Logic:
- managing the I/O block
- driving the enqueued transactions (Command Descriptors)
- managing the transfer of data to/from the FIFOs
- returning status via Response Descriptors
- For support the mode below the following capabilities, attributes, and logic must be implemented:
- PIO mode:
- The PIO Mode Registers section
- A valid (non-zero) value in the SECTION_OFFSET field of register PIO_SECTION_OFFSET, pointing to the starting offset of the PIO Mode Registers section
- Support for PIO Interrupt logic that allows PIO-specific interrupts to be routed to the Host via the system bus.
- DMA mode:
- Ring Controller logic:
- including one or more Ring Bundles (1~8) each exposing its own set of Ring Header registers.
- Ring Headers Specific Registers:
- from 1 to 8 Ring Header offsets, one per supported Ring Header (i.e., Ring Bundle) within the Ring Controller logic
- Memory Access Interface that uses DMA engines to access Host System memory
- A valid (non-zero) value in the SECTION_OFFSET field of register RING_HEADERS_SECTION_OFFSET pointing to the starting offset of the Ring Headers Specific Registers section.
- Support for Ring Bundle Interrupt logic that allows Ring-specific interrupts to be routed to the Host via the system bus
- PIO Mode and DMA Mode are mutually exclusive operating modes.
- v1.0: (Mode selection is made by enabling at least one Ring Header)
- Software would switch operating modes by either all Ring Headers were disabled, or only one Ring Header were enabled.
- v1.1
- The new MODE_SELECTOR field replaces that mechanism, providing direct control instead.
- Field MODE_SELECTOR shall be a read-only field while the Host Controller is in the ENABLED state
- The transaction interface to the Host software differs significantly between PIO Mode and DMA Mode:
- PIO mode:
- exposes Queue Port register:
- Command
- Reponse
- Rx Data
- Tx Data
- IBI
- Directly writes to registers to drive transactions, and maintains transaction status in order to avoid overflow/underflow.
- The Host Controller’s PIO Queues have fixed sizes.
- Software may set the thresholds for queue notifications
- DMA mode:
- exposes one or more (1~8) Ring Headers
- Command/Response Ring Pair
- Data provide two transfer mode:
- single Data Buffer (physically contiguous memory)
- Scatter-Gather transfers (Buffer List Pointer)
- 
- Transfer Descriptor is composed of:
- Command Descriptor (2 DWORDS)
- Data Buffer Descriptor(3 DWORDS)
- 
- Response Descriptor:
```c=
#define RESP_STATUS(resp) FIELD_GET(GENMASK(31, 28), resp)
#define RESP_TID(resp) FIELD_GET(GENMASK(27, 24), resp)
#define RESP_DATA_LENGTH(resp) FIELD_GET(GENMASK(21, 0), resp)
#define RESP_ERR_FIELD GENMASK(31, 28)
enum hci_resp_err {
RESP_SUCCESS = 0x0,
RESP_ERR_CRC = 0x1,
RESP_ERR_PARITY = 0x2,
RESP_ERR_FRAME = 0x3,
RESP_ERR_ADDR_HEADER = 0x4,
RESP_ERR_BCAST_NACK_7E = 0x4,
RESP_ERR_NACK = 0x5,
RESP_ERR_OVL = 0x6,
RESP_ERR_I3C_SHORT_READ = 0x7,
RESP_ERR_HC_TERMINATED = 0x8,
RESP_ERR_I2C_WR_DATA_NACK = 0x9,
RESP_ERR_BUS_XFER_ABORTED = 0x9,
RESP_ERR_NOT_SUPPORTED = 0xa,
RESP_ERR_ABORTED_WITH_CRC = 0xb,
/* 0xc to 0xf are reserved for transfer specific errors */
};
```
- IBI Ring Pair (Status/Data) (option)
- At least one Ring Bundle must have its IBI Ring Pair configured for use
- In order to receive any Target-initiated interrupt requests
- multiple Ring Bundles are supported, and have their IBI Ring Pairs enabled:
- using the RING_ID field in the DAT entry for a Device’s Dynamic Address
- Steered to Ring Bundle 0
- Hot-Join requests
- Any IBI Requests from other I3C Target Devices that do not have a dedicated DAT entry.
- If the IBI Data Ring does not have enough space to accept all of the payload Data
- terminate reception of the IBI Data
- clock Stalling
- 
- The software shall allocate and provide Driver-allocated memory for Rings.
-
- Extended Capabilities
- Each Extended Capability structure starts with a header containing two fields:
- a Capability ID, and a Length. The next Extended Capability structure starts after the end of the previous structure.
## Theory of Operation
### I3C HCI driver:
- main structure
```
struct i3c_hci {
struct i3c_master_controller master;
void __iomem *base_regs;
void __iomem *DAT_regs;
void __iomem *DCT_regs;
void __iomem *RHS_regs;
void __iomem *PIO_regs;
void __iomem *EXTCAPS_regs;
void __iomem *AUTOCMD_regs;
void __iomem *DEBUG_regs;
const struct hci_io_ops *io;
void *io_data;
const struct hci_cmd_ops *cmd;
atomic_t next_cmd_tid;
u32 caps;
unsigned int quirks;
unsigned int DAT_entries;
unsigned int DAT_entry_size;
void *DAT_data;
unsigned int DCT_entries;
unsigned int DCT_entry_size;
u8 version_major;
u8 version_minor;
u8 revision;
u32 vendor_mipi_id;
u32 vendor_version_id;
u32 vendor_product_id;
void *vendor_data;
};
```
### Host Controller Management
- Host Controller Initialization
- The Driver should perform the following steps to initialize and start the Host Controller:
- Evaluate Host Controller Register Map version:
- HCI_VERSION
- Evaluate base offsets for the DAT and the DCT:
- DAT_SECTION_OFFSET/DCT_SECTION_OFFSET
- Evaluate base offsets for PIO and/or the Ring Headers Descriptor Section Offset:
- PIO_SECTION_OFFSET/RING_HEADERS_SECTION_OFFSET
- Evaluate Host Controller capabilities:
- HC_CAPABILITIES
- (Option)evaluate list of Extended Capability structures:
- EXT_CAPS_SECTION_OFFSET/EXTCAP_HEADER
- In DMA mode:
- Read field MAX_HEADER_COUNT_CAPABILITY in register RHS_CONTROL
- Allocate memory for Rings
- Evaluate the sizes of Transfer Descriptor, Response Descriptor, and IBI Status Descriptor
- CR_SETUP’s fields XFER_STRUCT_SIZE and RESP_STRUCT_SIZE
- IBI_SETUP’s field IBI_STATUS_STRUCT_SIZE
- Allocate Driver memory according to these structures’ sizes, and program the Base Address registers for all enabled Rings in each specific Ring Header:
- fields BASE_LO and BASE_HI
- set up the number of enabled Ring Bundles:
- In register RHS_CONTROL, set field MAX_HEADER_COUNT to a value lower than, or equal to, the value of field MAX_HEADER_COUNT_CAPABILITY.
- set up Ring Sizes for each Ring
- CR_SETUP, program the RING_SIZE field
- IBI_SETUP, set fields IBI_STATUS_RING_SIZE, CHUNK_SIZE, and CHUNK_COUNT
- Allocate memory regions for the Rings, and then update all Ring base pointers
- enable and start the Ring Headers:
- RH_CONTROL **enable** the Ring Header by setting the corresponding **ENABLE** bit.
- The Driver shall not modify the Ring Header settings upon enabling the Ring Bundle.
- Enable interrupt:
- RH_INTR_STATUS_ENABLE/RH_INTR_SIGNAL_ENABLE
- RH_CONTROL, **start** the Ring Header by setting bit field **RS**
- In PIO mode
- Set up the thresholds for the queues
- Read QUEUE_SIZE
- Set the queue thresholds by programming values in register QUEUE_THLD_CTRL and register DATA_BUFFER_THLD_CTRL
- Enable interrupt:
- PIO_INTR_STATUS_ENABLE/PIO_INTR_SIGNAL_ENABLE
- Enable the Host controller:
- MODE_SELECTOR in register HC_CONTROL to set the desired operating mode (PIO/DMA)
- HC_CONTROL, set bit field BUS_ENABLE
- Enable Host Controller interrupts
- INTR_STATUS_ENABLE/INTR_SIGNAL_ENABLE
- Host Controller de-initialization
- Disable the Controller bus operation
- Clear BUS_ENABLE bit field in HC_CONTROL.
- In DMA mode:
- Stop and disable the Controller Rings
1. Clear RS bit field in RH_CONTROL.
2. Clear Enable bit field in RH_CONTROL.
- de-allocate memory allocated for Rings, for all Ring Bundles.
- Host Controller Reset
- Disable the Controller bus operation
- Clear BUS_ENABLE bit field in HC_CONTROL.
- In DMA mode:
- Stop/Disable all running/enabled Ring Bundles
1. Clear RS bit field in RH_CONTROL. Wait interrupt(?)
2. Clear Enable bit field in RH_CONTROL. Wait interrupt(?)
- Reset HC
- set the SOFT_RST bit field in RESET_CONTROL(0x10)
- Poll until SOFT_RST bit field is cleared or until an HC_INTERNAL_ERR_STAT interrupt is flagged.
### Host System Memory Access
- Device Context: DEV_CTX_BASE_LO / DEV_CTX_BASE_HI
- Command Ring: RH_CMD_RING_BASE_LO / RH_CMD_RING_BASE_HI
- Response Ring: RH_RESP_RING_BASE_LO / RH_RESP_RING_BASE_HI
- IBI Status Ring: RH_IBI_STATUS_RING_BASE_LO / RH_IBI_STATUS_RING_BASE_HI
- IBI Data Ring: RH_IBI_DATA_RING_BASE_LO / RH_IBI_DATA_RING_BASE_HI
> Each register pair shall be concatenated to hold a full 64-bit address pointer for the Host system.
> The Host Controller shall support up to 64-bit addressing for the Host system’s memory address space.
### Scatter-Gather for Host System Memory Access
- Check Capability

- SG setup register: BLP(Buffer vs. List Pointer) fields
- DEV_CTX_SG
- RH_CMD_RING_SG
- RH_RESP_RING_SG
- RH_IBI_STATUS_RING_SG
- RH_IBI_DATA_RING_SG
### Device Managment
#### Device Attach, Enumeration, and Initialization
- For every Device on the Bus that participates in Dynamic Address Assignment, a single DAT entry must be assigned.
- Within each DAT entry, field STATIC_ADDRESS is programmed by the Driver, based on a priori knowledge of the connected Devices on the Bus.
- For every Dynamic Addressing capable Device, field DYNAMIC_ADDRESS shall be set for each valid DAT entry, as part of the Dynamic Address Assignment process.
- Flow for Initial Bus Enumeration:
- 
- SETDASA: Assign Dynamic Address from Static Address
- SETAASA: Assign all dynamic address as Static Address
- SW need to get DCT manually.
- ENTDAA: Enter Dynamic Address Assign
- the first Device that wins Arbitration is assigned the Dynamic Address contained in the first index.
- Hw will auto updates DCT
> the SETAASA CCC is sent as a Broadcast CCC, using a standard Transfer Command (i.e., not an Address Assignment Command)
- Some dedicated Devices might not have been assigned the intended Dynamic Addresses: the Dynamic Address intended for a Device with a specific PID was instead assigned to another Device
- change the Dynamic Address for another Device: SETNEWDA
- reset all Dynamic Addresses : RSTDAA Broadcast CCC
- Use the Target Reset Pattern to reset some or all I3C Target Devices on the I3C Bus.
- Hot-join:
- Hardware:
- Hot-Join Requests shall be automatically handled
- IBI Status Descriptor shall indicate the Hot-Join ID (7'h02) in fields IBI_ID
- Software:
- populate a single new entry in the DAT table
- Issue an Address Assignment Command pointing to this entry
#### Device Detach, Reset, and Power Management
- The Controller-capable Device is not aware of a Device detaching from the Bus
- The Controller may determine this condition by repeated attempts to contact the Target using a safe Command Code (i.e. GETSTATUS).
- Upon a Device detach event (i.e., an unexpected removal of a Device from the Bus) the DAT shall not be altered
- The assigned Address is reserved.
- The Driver can re-use the specific entry by executing an Address Assignment command using the specific index of the DAT.
- If the Device is gracefully removed, then the software shall clear the DAT table entry.
#### Device Context
- DAT entries:
- could be the target of a command or transfer
- control the Host Controller’s automatic response to certain types of Interrupt Requests.
- supports automatic disabling of Controller-role Request (CRR) or In-Band Interrupt (IBI) from specific Devices, using the CRR_REJECT or IBI_REJECT fields.
- 
- DCT:
- transient table of entries
- populated by the Host Controller during ENTDAA CCC.
- DCT entries can be reused for new Devices, the Driver shall copy the contents of a DCT entry to the internal Driver context.
- A DAT table entry is associated with a given DCT table entry by DYNAMIC_ADDRESS field
### Device Addressing
- initiate Dynamic address
- ENTDAA
- Using Static address:
- SETDASA
- SETAASA:
- has no method for determining the status of any individual I3C Target Device that is asked to assign its own Static Address as a Dynamic Address.
- Change the assigned Dynamic address:
- SETNEWDA
- Reset the Dynamic address:
- RSTDAA
- supports I2C Target Devices:
- Shall not attempt to assign Dynamic Address of any I3C Target Device to conflict with any of these same Static Addresses.
- Grouped Addressing:
- I3C Group Addresses share the same address space as valid I3C Dynamic Addresses
- CCCs about group address:
- To assign an I3C Device to a Group Address:
- issue a Direct SETGRPA CCC addressed to a Dynamic Address
- To remove I3C Devices from a Group Address
- issue a Direct RSTGRPA CCC addressed to either a Dynamic Address or the Group Address
- To disband all Groups
- issue a Broadcast CCC for the RSTGRPA CCC
- Software shall only enqueue any Write-Type transfer commands.
### PIO Queue Management
- The Command Queue may support up to 255 Commands and Responses entries.
- The maximum size of the Transfer Data Queue is 256 DWORDs in each direction
- IBI Quese size: 2-255 DWORDS
- TX_BUF_THLD: 當Empty的TX Buffer DWORD entries >= TX_BUF_THLD 時發出interrupt
- prevent underflow conditions.
- RX_BUF_THLD: 當收到的RX Buffer DWORD entries >= RX_BUF_THLD 時發出interrupt
- prevent overflow conditions
#### PIO section initialization
- Get QUEUE_SIZE:
- CR_QUEUE_SIZE/RX_DATA_BUFFER_SIZE/TX_DATA_BUFFER_SIZE
- IBI_STATUS_SIZE
- Set the thresholds:
- QUEUE_THLD_CTRL
- CMD_EMPTY_BUF_THLD(Empty還剩多少)/RESP_BUF_THLD(被使用了多少)
- DATA_BUFFER_THLD_CTRL:
- TX_BUF_THLD/RX_BUF_THLD
- Set the starting thresholds of the Data FIFOs:
- DATA_BUFFER_THLD_CTRL:
- TX_START_THLD/RX_START_THLD
- Set the thresholds of the IBI Queue:
- QUEUE_THLD_CTRL
- IBI_STATUS_THLD/IBI_DATA_THLD
- Select PIO mode:
- HC_CONTROL:
- set MODE_SELECTOR to 1’b1 (‘PIO’)
- Ensure Host controller in running state:
- HC_CONTROL:
- BUS_ENABLE == 1 && RESUME == 0 && ABORT == 0
#### Command Queue Operation
1. check for available entries on the Command Queue
- for a write transfer
2. check available space on Tx Data Queue
3. Populate the Tx Data Queue with data until TX_BUF_THLD condition is not met
4. Populate the Command Queue with a Command Descriptor
- if not all Tx Data for the transfer was posted:
4a. wait interrupt and load the next batch of data
- if No write data => Clock stall
- if ROC=1, the Response Queue shall be populated with a Response Descriptor.
5. The interrupt indicating successful transfer, and/or transfer errors, shall be flagged in the PIO Interrupt Status register
6. Read Response Queue and clear the interrupt
- for read requests: Response Status 可能會比 Rx Data 來得慢
- if insufficient space is available on the Rx Data Queue
2. Service the interrupt by reading a threshold-size batch of data from the Rx Data Buffer and clearing the interrupt.
3. Transation end (all data received or error) => Post response descriptor
- if No Read buffer => Clock stall
#### Response Queue Operation
- populate a Response Descriptor structure on the Response Queue as required:
- For successful transfers:
- field ROC in the corresponding Command Descriptor
- For transfers that generate an error:
- always populate a Response Descriptor
- flag an interrupt to the Driver:
- IOC bit
- Response or Data thresholds for the queue
- RESP_READY_STAT/RESP_BUF_THLD: The Driver to process more than a batch of Response Descriptors, based on the threshold configuration; in this manner, the Driver may optionally process a batch in one run
#### IBI Queue Operation
- The IBI Queue supports up to 255 bytes of data. It stores IBI Status Descriptor structures, each describing how much data follows.
- The data is padded with ‘0’s to fill the DWORD entries as appropriate.
- an IBI event with 256 Bytes of data will require at least two IBI Status Descriptor structures.
- LAST_STATUS bit
- 
#### PIO Thresholds
- TX_THLD_STAT interrupt : when the number of available entries in the Tx Data Queue >= TX_BUF_THLD
- prevent an underflow condition, which would cause early transaction termination
- As software writes data DWORDs into the Tx Data Queue, this interrupt shall be automatically de-asserted once the Tx Data Queue is filled (available entries < TX_BUF_THLD)
- RX_THLD_STAT interrupt: when the number of entries in the Rx Data Queue >= RX_BUF_THLD
- prevent an overflow condition, which would cause early transaction termination
- As software reads data DWORDs from the Rx Data Queue, this interrupt shall be automatically de-asserted once the Rx Data Queue is drained (the number of populated entries < RX_BUF_THLD)
- Postpone transfer command:
- TX_START_THLD: the Host Controller shall wait until the Driver has written at least the indicated number of entries into the Transmit Buffer
- If the number of data DWORDs that have been written into the Tx Data Queue is not sufficient to satisfy the number of bytes indicated by the next enqueued Command Descriptor, so the transfer command shall be postponed until software writes more data DWORDs into the Tx Data Queue.
- writes additional data DWORDs to meet this threshold condition
- changes the Transfer Start Threshold to a lower value
- RX_START_THLD: the Host Controller shall wait until the Receive Buffer has at least the indicated number of DWORD entries available to receive the data bytes
- If the number of available DWORD entries in the Rx Data Queue is not sufficient to satisfy the number of bytes indicated by the next enqueued Command Descriptor, so the transfer command shall be postponed until software reads data DWORDs from the Rx Data Queue.
- reads these data DWORDs (i.e., from prior Read-Type transfers) from the Rx Data Queue and causes it to drain.
- changes the Receive Start Threshold to a lower value
- The Host Controller’s ability to notify software of data DWORDs in the Rx Data Queue from prior Read-Type transfers shall depend on the current value of RX_BUF_THLD.
> TX_START_THLD minimum value = 2DWORDs, but Write-Type transfer might only use 1 DWORD entry.
> The Host Controller shall compare the length of the transfer in the Command Descriptor (i.e., field DATA_LENGTH in bytes) to handle this exception.
### Ring Management
- A Host Controller may support up to 8 Ring Bundles
- Each Ring Bundle is described by its own Ring Header
- Each Ring Header:
- supports up to 255 (a static number) valid Ring entries for Command, Response, and IBI Status Rings.
- A Run/Stop bit: The Driver may use this bit to dynamically pause operation of a given Ring Bundle.
- An Enable/Disable bit: A transition of this bit to 1’b1 (Enable) shall reset all hardware internal pointers
- Mulitple Rings:
- Support for multiple Rings allows the software to direct separate pipes to different Device groups, which may be useful for some Device classes. For example, each individual pipe may feature different behavior in terms of processing latency.
#### Ring Bundle initialization
- Evaluatethe size of the descriptor
- CR_SETUP: XFER_STRUCT_SIZE and RESP_STRUCT_SIZE
- IBI_SETUP: IBI_STATUS_STRUCT_SIZE
- CR_SETUP: set the RING_SIZE field
- IBI_SETUP: set fields IBI_STATUS_RING_SIZE, CHUNK_SIZE, and CHUNK_COUNT
- Allocate memory for RINGs:
- Command Ring size is XFER_STRUCT_SIZE * RING_SIZE
- Response Ring size is RESP_STRUCT_SIZE * RING_SIZE
- IBI Status Ring size is IBI_STATUS_STRUCT_SIZE * IBI_STATUS_RING_SIZE
- IBI Data Ring size is (2^(CHUNK_SIZE+2) * CHUNK_COUNT)
- Enable the RIng Header:
- set the ENABLE bit in register RH_CONTROL
- Upon Ring Header being enabled, the Host Controller shall zero the Host-Controller-managed fields in the following registers:
- RH_OPERATION1/RH_OPERATION2/CHUNK_CONTROL
- Set up the memory pointer registers for each Ring
- Zero the Host Controller Driver-managed fields (R/W) in the following registers:
- RH_OPERATION1/RH_OPERATION2/CHUNK_CONTROL
- Start the Ring Header:
- To enable interrupts, set registers RH_INTR_STATUS_ENABLE and RH_INTR_SIGNAL_ENABLE
- To start the Ring Header, set the RS bit in register RH_CONTROL
#### Command/Response Ring Pairs
- Within a Command/Response Ring Pair, the Command and Response Rings always have the same length
- Pointers for Command/Response Ring pairs:
- 
- The Dequeue Pointer serves two purposes:
- enqueued Transfer Descriptors (from the Command Ring)
- populate Response Descriptors (into the Response Ring)
- Stop execution:
- detects a transfer error:
- asserting the TRANSFER_ERR_STAT interrupt
- software changes the Ring Bundle into Running or Stopped status:
- asserting the RING_OP_STAT interrupt
- Ring Abort operation for a Ring Bundle by setting the ABORT bit to 1’b1
##### Command Ring Operation:
- Putting Transfer Descriptor(s) onto the Command Ring
- Update the Enqueue Pointer (EnqPtr), which shall serve as a Doorbell to the Host Controller
- the Host Controller shall check the Enqueue Pointer and shall process, in order, until reaching the Enqueue Pointer.
- Transfers shall be split according to the width of the DATA_LENGTH field (65535 bytes)
##### Reqponse Ring Operation
- A write to SwDequeuePointer notifies the Host Controller that the software event handler has exited.
#### IBI Ring Pairs
- Pointers for IBI Ring Pair:
- 
- They are used for the IBI Status Ring
- CHUNK_COUNTER:
- Provide the position for the first Data Chunk for this IBI Status Descriptor’s Data Chunk allocation
- The Driver shall also write to this register to notify the Host Controller that the Driver has consumed the oldest Data Chunk allocation, and intends to free the allocation
- This operation shall not use circular (i.e., “modulo”) arithmetic (不斷往上加: HW會根據差值去知道多出多少空間可以使用)
- The Host Controller shall clear this field (i.e., reset to zero) when the Ring Bundle is transitioned to the Enabled state.
##### IBI status Ring operation:
- 
##### IBI data operation:
- 
- If the IBI Data Ring becomes completely full during an IBI event
- Trigger the IBI_RING_FULL_STAT interrupt
- Terminate reception of the IBI payload or stall the Bus (if possible) until the Driver can resolve the situation by freeing existing Data Chunks
- If a new IBI event occurs and the IBI Data Ring does not have any free Data Chunks.
- Trigger the IBI_RING_FULL_STAT interrupt
- NACK
#### Ring Header registers:
- 
#### Ring Bundle servicing: (We don't need it)
#### Ring Abort Operation
- setting the ABORT bit to 1’b1 in register RH_CONTROL
- If the Ring Bundle is valid and is currently the active Command/Response Ring for processing:
- Host Controller shall abort any in-progress transfers at the earliest opportunity
- ERR_STATUS having a value of 0x8 (HC_ABORTED)
- Trigger the TRANSFER_ABORT_STAT interrupt
- asserting the RING_OP_STAT interrupt (Status changed to ABORTED)
- If the Ring Bundle is valid but is not currently active for processing; or if the Ring Bundle was enabled but not currently running:
- asserting the RING_OP_STAT interrupt (Status changed to ABORTED)
- The Ring Bundle shall immediately be removed from the list of valid Ring Bundles that may be selected by the Ring Controller’s arbitration logic for servicing
- Resume operation:
- Clear RING_OP_STAT interrrupt
- Clear TRANSFER_ABORT_STAT interrupt
- Clear ABORT bit to 1’b0 in register RH_CONTROL
- Write to the Enqueue Pointer: RH_OPERATION1
- This automatically resumes the Ring operation, and any remaining Transfer Descriptors that are enqueued will be processed
### Command Handling
- Transfers may be either Read-Type or Write-Type:
- Read-type: may address any I3C Target Device that has been assigned a valid Dynamic Address
- This might take the form of a Private Read (in SDR Mode), or an HDR Generic Read.
- This might take the form of a Direct Read or Direct GET CCC (in SDR Mode).
- may not be sent to a Group Address
- Write-type: may address any I3C Target Device that has been assigned a valid Dynamic Address, or a valid Group Address
- This might take the form of a Private Write (in SDR Mode), or an HDR Generic Write.
- This might take the form of a Direct Write or Direct SET CCC (in SDR Mode).
- This might take the form of a Broadcast CCC, which addresses all I3C Devices on the Bus
- Address I3C Target Device(s) that have not yet been assigned a Dynamic Address:
- The Address Assignment Command: SETDASA/ENTDAA
- The Immediate Data Transfer Command: SETAASA.
- For all transfer commands, the Command Descriptor includes a 5-bit DEV_INDEX field containing an index into the DAT table:
- For private transfers and Direct CCCs:
- The Host Controller shall fetch the Dynamic Address from the DAT entry indicated by the DEV_INDEX field
- For Broadcast CCCs:
- The Host Controller shall not use the DEV_INDEX field. Software should set DEV_INDEX to 5’h00.
### Transfers
- PIO mode:
```
ibi_val = FIELD_GET(IBI_STATUS_SIZE, size_val);
/* 將the maximum size of IBI Data segments,設為最大值的一半,並設定上下限*/
pio->max_ibi_thresh = clamp_val(ibi_val/2, 1, 63);
val = FIELD_PREP(QUEUE_IBI_STATUS_THLD, 1) |
FIELD_PREP(QUEUE_IBI_DATA_THLD, pio->max_ibi_thresh) |
FIELD_PREP(QUEUE_RESP_BUF_THLD, 1) |
FIELD_PREP(QUEUE_CMD_EMPTY_BUF_THLD, 1);
```
- Tx:
- CMD_EMPTY_BUF_THLD/CMD_QUEUE_READY_STAT:
- Command queue 不夠一次放,設定來透過interrupt通知Driver有空間可以放command了,always set 1
- TX_BUF_THLD/TX_THLD_STAT:
- TX Data queue 不夠一次放,設定來透過interrupt通知Driver要再補Data進來了,避免underflow
- 透過將queue填超過Threshlod來清interrupt,最後一筆會有清不掉的狀況
- 目前driver會透過disable singanl的方式來解決
- Rx:
- RESP_BUF_THLD/RESP_READY_STAT:
- 有幾個Response進來的時候要通知Driver去處理,always set 1
- RX_BUF_THLD/RX_THLD_STAT:
- 設定來透過interrupt通知Driver要把Data讀掉避免overflow
- 透過讀queue來降到threshlod以下來清interrupt,最後一筆會有不知道要讀多少的狀況
- 要去看Response descriptor的data length來讀
- IBI:
- IBI_STATUS_THLD/IBI_STATUS_THLD_STAT:
- 有IBI來了而且同時表示IBI complete or a segment of payload也到了,always set 1.
- first read out an IBI Status Descriptor structure from the IBI Port
- the Driver shall read consecutive data DWORDs from the IBI Port, using the DATA_LENGTH field provided via the IBI Status Descriptor
- IBI_DATA_SEGMENT_SIZE:
- allows the incoming IBI Data to be sliced into multiple segments generating status individually.
- 避免IBI queue overflow, bit last_status不會受這個影響
- DMA mode:
- 
- CR_ENQ_PTR: Sw write去通知hardware 有幾筆Transfer Descriptor準備好了
- CR_DEQ_PTR: Hardware write 去通知有幾筆傳輸完成了,同時也有幾筆Response讀回寫入了
- CR_SW_DEQ_PTR: Software 去通知hardware response的內容已經讀取完了
- CR_ENQ_PTR == CR_DEQ_PTR == CR_SW_DEQ_PTR: Ring才會回到Idle
#### Data byte ordering:
- Field DATA_BYTE_ORDER_MODE in register HC_CONTROL
#### Host Controller Abort Operation
- Motivation:
- Detecting an incorrect result or other status received for a Read-Type transfer.
- Software拿到非預期的結果,但又不到會NACK或I3C bus error的狀況
- Setting the ABORT bit to 1
- The Host Controller shall abort any in-progress transfers that the I3C Bus Controller Logic is currently driving or receiving, at the earliest opportunity.
- Abort request cannot be cancelled by the Driver
- The Host Controller shall enter the Aborted state
- Action and States for ABORT
- 
#### Support for I3C 'Short' Read-type transfers
- The I3C Target Device returns fewer bytes than expected, does not necessarily indicate an I3C Bus error.
- Default: The Host Controller shall always treat a ‘short’ Read-Type transfer as though it were permitted
### IBI handling
#### PIO mode:
- Status和Data都會放在IBI queue中,Driver需要讀DATA_LENGTH fields in Status Descriptor去知道有多少Data緊隨其後.
- If the incoming data is not aligned to a 4-byte boundary, then there will be extra (unused) bytes at the end of the transferred IBI data.
- 看LAST_STATUE去決定這個IBI event的Data是不是傳完了
- an IBI event needing 256 Data Chunks of storage will require at least two consecutive IBI Status Descriptor structures;and so on.
- 避免IBI overflow的register fields IBI_STATUS_THLD/IBI_DATA_SEGMENT_SIZE:
- 收到IBI_STATUS_THLD(always 1)個Status Descriptor而且每個收到的Payload要 > 4 * IBI_DATA_SEGMENT_SIZE時發interrupt
#### DMA mode:
- The IBI shall be put to the Ring Bundle indicated with Ring ID in relevant DAT table entry. (Default put to Ring Bundle 0)
- Enqueue pointer: Hardware已經將IBI descriptor放到哪個位置了
- Dequeue pointer: Software通知Hardware已經處理哪些IBI descriptor了
- CHUNK_COUNTER: Software通知Hardware已經有多少Data chunk已經空閑可以使用
- IBI_READY_STAT interrupt: indicate the availability of an IBI Status Descriptor and any related Data Chunk(s) for the Driver to consume from this IBI Ring Pair.
#### Timestamping:
- If we want to support CCC: SETXTIME/GETXTIME
### Managed CCC Transfer Framing Model:
- Direct CCC framing model:
- 
- If the indicated Device ACKs:
- Write/SET CCCs send data from:
- Command descriptor (immediate data tranfet command)
- Tx data buffer
- Read/GET CCCs read data to:
- RX data buffer
- If the indicated Device NACKs:
- The Host Controller shall attempt to retry the Direct CCC at least once following the first NACK.
- If DEV_NACK_RETRY_CNT == 0, then the Host Controller shall always attempt one retry for a NACKed Direct CCC,
- else, retry according to that field’s setting.
- Broadcat CCC framing model:

#### Direct CCC Framing with Multiple Segments in a Transfer
- Software shall enqueue multiple consecutive Command Descriptor entries in the Command Queue/Ring
- The TOC field shall be set to 1’b1, only for the last Command Descriptor
- The logical for host controller to resend CCC and Defining Byte:
- 
- 只要下一個command desciptor有不同的CCC or Defining Byte就要重送:Broadcast Address, the CCC and optional Defining Byte.
#### Mixing Direct and Broadcast CCCs
- 在Direct CCCs command中直接穿插下面的descriptor:
- Broadcat Command descriptor field:
- DEV_INDEX = 0
- CCCs value = Broadcast CCC (0x00~0x7f)
#### Error Handling for CCC flows
- NACK error: the Direct CCC has been retried according to the NACK retry count
- ADDR_HEADER error: Broadcast CCC messages, if no Targets ACK the Broadcast Address, then this is a CCC framing error
- If any one Command Descriptor in the middle of such a sequence of multiple consecutive Command Descriptors results in an error
- stop processing the sequence early
- drive a STOP condition
- allow the Host to run an error recovery procedure
#### Mixing CCCs and Private Read/Write Transfers
- Transition from Private Read/Write to CCC:
- Repeated START condition, followed by the Broadcast Address (i.e., 7’h7E), then the Command Code in the next Command Descriptor
- Transition from CCC to Private Read/Write:
- The Host Controller shall end the CCC framing automatically, in an appropriate manner for the End of CCC Command.
### Auto-Command
- automatically generate a Read transfer after receiving a specified IBI event on a per-Device (per-Target) basis.
- Data received from this Auto-Command is coalesced together with the IBI Data Payload
- For all Devices for which Auto-Command behavior is desired, follow the DAT entry and:
- Set field IBI_PAYLOAD to 1’b1 to allow reception of IBI Mandatory Byte
- Set field AUTOCMD_MASK to the desired value
- Set field AUTOCMD_VALUE to the desired value
- Set field AUTOCMD_MODE to the desired value
- Set field AUTOCMD_HDR_CMD to the desired value
- 
### Request Handling
- 沒重點
### Error Handling
- The Host Controller shall halt processing to allow the Driver to handle the error
- Error code will be returned in field ERR_STATUS of the Response Director
- In PIO mode: RESUME field in register HC_CONTROL
- In DMA mode: RS field in register RH_CONTROL
- For Write requests, the Driver should issue a transfer command with the GETSTATUS Direct CCC to determine the Device’s overall error status.
- Any errors in IBI reception are flagged in the IBI Status Descriptor structure.
- Any non-recoverable internal error, the Host Controller shall stop, interrupt the software, and indicate an internal error via field HC_INTERNAL_ERR_STAT in register INTR_STATUS.
#### Error Status Codes in Response Descriptor:
- 0x0: SUCCESS: Transfer successful, no error.
- 0x1: CRC: CRC Error
- 0x2: PARITY: Parity Error
- 0x3: FRAME: Frame Error
- 0x4: ADDR_HEADER: Address Header Error
- 0x5: NACK: Address NACK’ed or Dynamic Address Assignment NACK’ed
- 0x6: OVL: Receive Overflow or Transfer Underflow Error
- 0x7: I3C_SHORT_READ_ERR: Target returned fewer data bytes than requested in field DATA_LENGTH of a Transfer Command that did not permit a ‘short’ read
- 0x8: HC_ABORTED: Aborted (i.e., terminated) by Host Controller due to internal error
- 0x9: Transfer terminated due to Bus action:
- For I2C: I2C_WR_DATA_NACK:
- Aborted due to NACK received during an I2C Write Data transfer
- For I3C: BUS_ABORTED:
- Aborted due to Early Termination, or Target not completing read or write of data phase of transfer
- 0xA: NOT_SUPPORTED: Command with specific parameters not supported by the Host Controller implementation (e.g., specific Internal Control codes may not be supported)
- 0xB: RESERVED
- 0xC–0xF: Transfer Type Specific Errors, defined for specific transfer types
#### Errors Due to Command Sequence Stall or Timeout
- SCL stall timeout interrupt:
- 
- 當I3C在傳輸一個Frame的過程中(TOC = 0),在最後一個Command descriptor(TOC=1)出現之前Enqueue的command descriptor就不夠了,此時HC就會Stall clock,如果Stall的時間Timeout了,HC就會強制中斷傳輸(SDR: STOP, HDR: Exit Pattern)
- Stall clock: HC_WARN_CMD_SEQ_STALL_STAT interrupt
- Timeout: HC_ERR_CMD_SEQ_TIMEOUT_STAT interrupt
- 當發Timeout事件之後,HC會試圖繼續傳輸接下來valid Command Descriptors 除非發生下列狀況:
- The last one processed before the stall turned into a timeout indicated a transfer error in field ERR_STATUS
- The Host Controller was processing transfer commands in an Atomic Target Reset transaction that had a timeout and would reject any subsequent transfer commands after a timeout, until software sends a special Internal Control Command to end this transaction mod
- HALT_CMD_SEQ_TIMEOUT in register HC_CONTROL was set to 1’b1
- Any other transfer error, operating mode-specific error or Host Controller interrupt was asserted
- HALT_ON_CMD_SEQ_TIMEOUT:
- 1: For a particular I3C content protocol that does not tolerate a disruption
- 0: the Host Controller may generally resume processing without waiting for software to resolve the condition
### Interrupts

- Interrupt Status Enable Mask: 用來決定是否要將interrupt 的狀態latch 到status register
- Status register: 紀錄曾經發生過的事件,需要透過Software行為來清除
- W1C or Consuming the results of the specific Queue or FIFO that caused the underlying interrupt condition.
- Interrupt Signal Enable Mask: 決定interrupt 是否可以傳送到host (Edge-trigger? Or level trigger?)

> 從driver中來看會是level trigger
### Target Reset and Bus Recovery
- The Host Controller using Command Descriptors of type Internal Control Command with value 0x4(Target Reset Pattern) in the MIPI_CMD field.
#### Target Reset Pattern
- Begins with fourteen SDA transitions while SCL is kept Low, and ends with a Repeated START followed by a STOP which triggers the actual Reset action
- 
#### Reset I3C Peripheral or Reset Whole Chip
- Target Reset Command Descriptor with a value of 0x0 in field RESET_OP_TYPE.
- Software may issue a single Target Reset Pattern to initiate the Reset I3C Peripheral action.
- Software may also issue two Target Reset Patterns to initiate the Reset Whole Chip action.
#### Configure Target for Target Reset Action
- RSTACT CCC
##### Software shall send a sequence of Command Descriptors to the Host Controller as an Atomic Target Reset transaction:
- Enqueue a Target Reset Command Descriptor with field RESET_OP_TYPE set to a value of 0x2
- This operation instructs the Host Controller to enter a Critical Section
- Software shall then send one or more subsequent Command Descriptors in SDR Mode
- The last of these Command Descriptors shall contain the value 1’b1 in the TOC field, to indicate the end of the Atomic transaction.
- Enqueue a Target Reset Command Descriptor with field RESET_OP_TYPE set to a value of 0x3:
- This operation instructs the Host Controller to leave a Critical Section
##### The Host Controller shall observe the following requirements while operating in the Critical Section:
- All transfer commands shall be in SDR Mode, at any supported data rate
- The Host Controller shall reject any other Internal Control Commands other than leave the Critical Section.
- 在收到leave the Critical Section後,HC has not yet received a valid transfer command for a RSTACT CCC with TOC=0
- If this is intentional from software (i.e., is not due to a stall that turns into a timeout) then the Host Controller shall cancel the Critical Section, and the I3C Bus Controller Logic shall not drive the Target Reset Pattern.
- The Host Controller shall resume processing any subsequent Command Descriptors as normal, and then generate a Response Descriptor with error code 0xD(SEQ_CANCELLED) in field ERR_STATUS to signal that the Target Reset was cancelled
- 在Critical Section中合法的command 組成如下:
- Begin/Start with a single Broadcast RSTACT CCC (with Defining Byte of 0x0)
- one or more Direct SET RSTACT CCCs (with non-zero Defining Byte values)
- 進到Critical Section 之後HC需要去檢查每一個收到的Transfer command:
- Broadcast CCC is received as the first transfer command:
- Defining Byte == 0: Set "partial success" flag
- Defining Byte is not 0x0: not allow a “partial success”
- No Broadcast CCC is received: not allow a “partial success”
- A subsequent Broadcast CCC is received with a non-zero Defining Byte:
- “partial success” flag is cleared and shall not be set again during this Critical Section.
- Transfer command fails during the sequence, then:
- For failures due to NACK: Retries
- For failures due to other reason: STOP and the Target Reset Action shall be cancelled.
- Error: The Host Controller shall not drive the Target Reset Pattern, and shall leave the Critical Section
- Software should subsequently run an error recovery procedure.
- Command Descriptors 填入太慢導致HC將從 stall轉變成Timeout:
- If the “partial success” flag was set earlier:
- 在Stall 轉變成Timeout前:
- Drive the Target Reset Pattern followed by a Repeated START and then a STOP.
- The Host Controller shall report the warning via field HC_WARN_CMD_SEQ_STALL_STAT of register INTR_STATUS
- Prevented the command sequence stall condition from becoming a timeout by driving the Target Reset Pattern before the end of the sequence.
- If the “partial success” flag was not set earlier(HC沒有執行Target Reset Pattern 而且允許發生Timeout):
- The I3C Bus Controller Logic shall drive a STOP condition
- The Host Controller shall assert an interrupt via the HC_SEQ_CANCEL_STAT
- The Host Controller shall report the error via field HC_ERR_CMD_SEQ_TIMEOUT_STAT
- The Host Controller shall set a flag indicating that all subsequent Command Descriptors in the sequence would be rejected
- Any Command Descriptor that is rejected shall cause a Response Descriptor to be generated, with error code 0x8 (HC_ABORTED) in field ERR_STATUS.
- When the Host Controller receives the final Target Reset Command Descriptor to leave the Critical Section:
- Resume processing any subsequent Command Descriptors as normal
- Generate a Response Descriptor with error code
- If the “partial success” flag was set: 0xC (Transfer Type Specific: CMD_UNDERFLOW)
- If the “partial success” flag was not set earlier: 0x6(OVL)
- HC 處理完所有的 Command Descriptors 而且沒有任何狀況:
- Once the HC receives the last transfer command for the RSTACT Direct SET CCC with TOC=1:
- Drive the Target Reset Pattern followed by a Repeated START and then a STOP.
- When the HC receives the final Target Reset Command Descriptor to leave the Critical Section:
- generate a Response Descriptor with error code 0x0 (Success)
##### Software should follow these requirements and recommendations:
- All transfer commands for the Atomic transaction should be a sequence comprised of Broadcast CCCs and Direct SET CCCs, for the RSTACT CCC, in continuous framing.
- SDR mode only
- the last such Command Descriptor must set field TOC to 1’b1
- All such transfer commands in the sequence should be Immediate Data Transfer Commands
- The first transfer command should generally be a Broadcast CCC with a Defining Byte value of 0x00
- Subsequent transfer commands should be Direct SET CCCs, to address individual Target Devices
#### Controller SDA Recovery or Bus Reset Procedures
- The Host Controller supports these flows using Command Descriptors of type Internal Control Command with the value of 0x5 in field MIPI_CMD
##### Recovery from stuck SDA Lane:
- Recovery Reset Command Descriptor with the appropriate options
- REC_RESET_PROC:
- 0x0: If reading from an I2C Device
- 0x1: If reading from an I3C Device with SDR Mode
- 0x2: If reading from an I3C Device with HDR-DDR Mode
- The Recovery Reset Command Descriptor should also use an appropriate SCL speed value in field SCL_SPEED
##### Forcing a STOP Condition
- Recovery Reset Command Descriptor with:
- 0x4 in the REC_RESET_PROC field
- an appropriate value in the SCL_SPEED field
- This procedure will cause the I3C Bus Controller Logic to force a STOP after the previous command transfer.
- if both the SDA and SCL Lanes are already High, then the I3C Bus Controller Logic will drive a START, followed by the Broadcast Address (i.e., 7’h7E) and a STOP.
##### CE2 Error Handling for a Non-Responsive I3C Target
- Recovery Reset Command Descriptor with:
- 0x5 in the REC_RESET_PROC field
- an appropriate value in the SCL_SPEED
- issue the HDR Exit Pattern
##### Controller Recovery After Crash or Unexpected Reset
- Recovery Reset Command Descriptor with:
- 0x7 in the REC_RESET_PROC field
- an appropriate value in the SCL_SPEED
- issue the Bus Reset procedure
## Register Map

- Capability and Operational Registers:
- Define software-discoverable Host Controller capabilities
- Allow software to limit these capabilities
- Control Host Controller behavior and current state
- Define pointers to all other sections in register map.
- the only registers in Register Map that have static offset from Base Address
- 
- HC_CAPABILITIES
- Bits | Field Name | HCI Spec. not define | Ast2700
|--|--|--|--|
|30 | SG_DC_EN | |X
|29 | SG_IBI_EN | |X
|28 | SG_CR_EN | |X
|27:25 | Reserved | |
|24:22 | MAX_DATA_LENGTH |O |
|21:20 | CMD_SIZE | | 0: 2DWORDS, 1: 4DWORDS(?)
|19 | Reserved |
|18 | DIRECT_COMMANDS_EN|O |
|17:16 | Reserved |
|15 | MULTI_LANE_EN |O |
|14:11 | Reserved |
|10 | CMD_CCC_DEFBYTE | |0x1
|9 | Reserved |
|8 | HDR_BT_EN |O |X
|7 | HDR_TS_EN | |X
|6 | HDR_DDR_EN | |0x1
|5 | STANDBY_CR_CAP | |0x1
|4 | DATA_BYTE_CFG_EN |O |
|3 | AUTO_COMMAND | |0x1
|2 | COMBO_COMMAND | |X
|1:0 | Reserved | |
> HC_CAP_DATA_BYTE_CFG_EN BIT(4) /* endian selection possible */
- RESET control
- Bits | Field Name | HCI Spec. not define | Ast2700
|--|--|--|--|
|31 | BUS_RESET |O |
|30:29 | BUS_RESET_TYPE |O |
|5 | IBI_QUEUE_RST | |
|4 | RX_FIFO_RST | |
|3 | TX_FIFO_RST | |
|2 | RESP_QUEUE_RST | |
|1 | CMD_QUEUE_RST | |
|0 | SOFT_RST | |
- Device Address Table (DAT): DAT_SECTION_OFFSET(0x30)
- stores static and dynamic addresses and configuration information
- The DAT table is populated by software.
- Device Characteristic Table (DCT): DCT_SECTION_OFFSET(0x34)
- A transient table that provides temporary storage
- Captures the PID, DCR, BCR, and assigned dynamic address during the Dynamic Address Allocation procedure
> DAT and DCT should be implemented as a set of registers
> The Host Controller may optionally request the Software to provide DAT-related and DCT-related memory as Driver-allocated memory, referred to as the Device Context.
- Ring Headers Descriptor: RING_HEADERS_SECTION_OFFSET(0x38)
- Rings are used to hold descriptors for DMA transfers for Commands, Transfers, and Events.
- 
- PIO (Programmable I/O): PIO_SECTION_OFFSET(0x3C)
- Defines registers to allow Command, Transfer, and Event transmission using registers rather than Rings.
- 
- Extended Capabilities: EXT_CAPS_SECTION_OFFSET(0x40)
- Define a linked list of capabilities, including vendor-specific capabilities.
- 
- 
```c=
static const struct hci_ext_caps ext_capabilities[] = {
EXT_CAP(0x01, 0x0c, hci_extcap_hardware_id),
EXT_CAP(0x02, 0x04, hci_extcap_master_config),
EXT_CAP(0x03, 0x04, hci_extcap_multi_bus),
EXT_CAP(0x04, 0x24, hci_extcap_xfer_modes),
EXT_CAP(0x05, 0x08, hci_extcap_auto_command),
EXT_CAP(0x08, 0x40, hci_extcap_xfer_rates),
EXT_CAP(0x0c, 0x10, hci_extcap_debug),
EXT_CAP(0x0d, 0x0c, hci_extcap_scheduled_cmd),
EXT_CAP(0x0e, 0x80, hci_extcap_non_curr_master), /* TODO confirm size */
EXT_CAP(0x0f, 0x04, hci_extcap_ccc_resp_conf),
EXT_CAP(0x10, 0x08, hci_extcap_global_DAT),
EXT_CAP(0x9d, 0x04, hci_extcap_multilane),
EXT_CAP(0x9e, 0x04, hci_extcap_ncm_multilane),
};
```
## Data Structures
### Device Address Table (DAT)
- Stores:
- Device Addresses of Target Devices attached to the I3C Bus
- Several control and information fields per Device
- Implemented:
- HCI Register Set:
- DAT_SECTION_OFFSET(0x30)
- Driver-allocated memory as part of Device Context
- DEV_CTX_BASE_LO (0x60), DEV_CTX_BASE_HI(0x64),
- The DAT is populated by software, and hardware uses it during the Dynamic Address Assignment procedure
- The size of each DAT entry is 2 DWORDs.
- Structure
```c=
/*
* Specifies Auto-Command Read Command Code.
* Only valid if Read is executed in HDR Mode.
*/
#define DAT_1_AUTOCMD_HDR_CODE W1_MASK(58, 51)
/*
* Indicates the Mode and speed for the Auto-Command Read.
* Only valid for the Device in I3C Mode.
*/
#define DAT_1_AUTOCMD_MODE W1_MASK(50, 48)
/*
* Value of the IBI Mandatory Byte that
* will trigger an Auto-Command Read transaction on the I3C Bus
*/
#define DAT_1_AUTOCMD_VALUE W1_MASK(47, 40)
#define DAT_1_AUTOCMD_MASK W1_MASK(39, 32)
/* DAT_0_I2C_DEVICE W0_BIT_(31) */
#define DAT_0_DEV_NACK_RETRY_CNT W0_MASK(30, 29)
/*
* Used to send an IBI from a specific Device to the appropriate Ring Bundle (0~7).
*/
#define DAT_0_RING_ID W0_MASK(28, 26)
/* Host controller may choose to either use or else ignore it */
#define DAT_0_DYNADDR_PARITY W0_BIT_(23)
#define DAT_0_DYNAMIC_ADDRESS W0_MASK(22, 16)
/* Device IBI Timestamp */
#define DAT_0_TS W0_BIT_(15)
/*
* In-Band Controller-role Request Reject
* only valid if the Host Controller declares Standby Controller Capability.
*/
#define DAT_0_MR_REJECT W0_BIT_(14)
/* Device In-Band Interrupt Request Reject */
/* DAT_0_SIR_REJECT W0_BIT_(13) */
/* DAT_0_IBI_PAYLOAD W0_BIT_(12) */
#define DAT_0_STATIC_ADDRESS W0_MASK(6, 0)
```
> DAT_1_AUTOCMD_MODE:
> 
> 0x5: I3C HDR-TSx
> 0x6: I3C HDR-DDR
- Usage:
- requires software to assign (i.e., to allocate) DAT entries for all known Target Devices that will be used for transfer commands.
### Device Characteristic Table (DCT)
- Captures the Device Characteristics (PID, BCR, and DCR)
- Assigned Dynamic Address of each Device on the I3C Bus that participates in the Dynamic Address Allocation (ENTDAA) procedure.

### Command Descriptor
- Command type:
- 
- 
- TOC: Terminate on Completion
- Controls what Bus condition to issue after the transfer command completes.
- 1: P (STOP)
- 0: Sr (START Repeated)
- ROC: Response on Completion
- Controls whether Response Status is sent after successful completion of the transfer command
- In DMA mode: shall always set to 1
### Response Descriptor
```c=
/*
* Response Descriptor Structure
*/
#define RESP_STATUS(resp) FIELD_GET(GENMASK(31, 28), resp)
#define RESP_TID(resp) FIELD_GET(GENMASK(27, 24), resp)
#define RESP_DATA_LENGTH(resp) FIELD_GET(GENMASK(21, 0), resp)
enum hci_resp_err {
RESP_SUCCESS = 0x0,
RESP_ERR_CRC = 0x1,
RESP_ERR_PARITY = 0x2,
RESP_ERR_FRAME = 0x3,
RESP_ERR_ADDR_HEADER = 0x4,
RESP_ERR_BCAST_NACK_7E = 0x4,
RESP_ERR_NACK = 0x5,
RESP_ERR_OVL = 0x6,
RESP_ERR_I3C_SHORT_READ = 0x7,
RESP_ERR_HC_TERMINATED = 0x8,
RESP_ERR_I2C_WR_DATA_NACK = 0x9,
RESP_ERR_BUS_XFER_ABORTED = 0x9,
RESP_ERR_NOT_SUPPORTED = 0xa,
RESP_ERR_ABORTED_WITH_CRC = 0xb,
/* 0xc to 0xf are reserved for transfer specific errors */
};
```
### IBI Status Descriptor
```c=
/*
* IBI Status Descriptor bits
*/
#define IBI_STS BIT(31)
#define IBI_ERROR BIT(30)
#define IBI_STATUS_TYPE BIT(29)
#define IBI_HW_CONTEXT GENMASK(28, 26)
#define IBI_TS BIT(25)
#define IBI_LAST_STATUS BIT(24)
#define IBI_CHUNKS GENMASK(23, 16)
#define IBI_ID GENMASK(15, 8)
#define IBI_TARGET_ADDR GENMASK(15, 9)
#define IBI_TARGET_RNW BIT(8)
#define IBI_DATA_LENGTH GENMASK(7, 0)
```
### HCI v2 Command descriptor
- Without Transfer COmmand CCC value (?)
- How to assign different CCC valus?
- DAA function:
```c=
xfer[0].cmd_desc[1] = CMD_A1_DATA_LENGTH(8);
xfer[0].cmd_tid = hci_get_tid();
xfer[0].cmd_desc[0] =
CMD_0_ATTR_A |
CMD_A0_TID(xfer[0].cmd_tid) |
CMD_A0_ROC;
xfer[1].cmd_tid = hci_get_tid();
xfer[1].cmd_desc[0] =
CMD_0_ATTR_A |
CMD_A0_TID(xfer[1].cmd_tid) |
CMD_A0_ASSIGN_ADDRESS(next_addr) |
CMD_A0_ROC |
CMD_A0_TOC;
hci->io->queue_xfer(hci, xfer, 2);
```
- Address Assignment Command
| Bits | Field Name | Memory Access | Dscription
|--|--|--|--|
|71:64| CMD | | Transfer Command CCC Value, Code not define
|63:52| Reserved | |
|53:32| Data Length| |
|31 | TOC | | Terminate on Completion
|30 | ROC | | Response on Completion
|29:18 | Reserved | |
|17:15 | Xfer Rate | | Master Data Transfer Rate Selector Values.
|14:8 | DEV Address | | Device I3C Dynamic Address
|7 | Reserved | |
|6:3 | TID | | Transaction ID</br>Used as a tag for this command.
|2:0 | CMD_ATTR | | 0x2: Address Assignment Command
- Unified Data Transfer Command
- CP? => Command Present: Indicates whether field CMD is valid for a CCC or HDR Transfer.
| Bits | Field Name | Memory Access | Dscription
|--|--|--|--|
|127:108| Reserved | | |
|107:104| HDR_TSP_ML_CTRL| |
|103:96 | IDB4/HDR_CMD | |
|95:88 | IDB3/HDR_BT | |
|87:80 | IDB2/BT_CMD2 | |
|79:72 | IDB1/BT_CMD1 | |
|71:64 | IDB0(DEF_BYTE)/BT_CMD0 | |
|63:62 | Err handling | |
|61:56 | ADD func | |
|55 | COMBO Xfer | |
|53:32 | DATA length | |
|31 | TOC | | Terminate on Completion
|30 | ROC | | Response on Completion
|29 | May Yield | |
|28:27 | NACK RCNT | | Device NACK Retry Count
|26:24 | IDB Count | |
|23 | Reserved | |
|22:18 | Mode index | | Master Transfer Mode Table Fixed Indexes
|17:15 | Xfer Rate | | Master Data Transfer Rate Selector Values.
|14:8 | DEV Address | | Device I3C Dynamic Address
|7 | RnW | | Data Transfer Direction. 0: Write, 1: Read
|6:3 | TID | | Transaction ID</br>Used as a tag for this command.
|2:0 | CMD_ATTR | | 0x4: Unified Data Transfer Command
```c=
/*
* Master Transfer Mode Table Fixed Indexes.
*
* Indexes 0x0 and 0x8 are mandatory. Availability for the rest must be
* obtained from the mode table in the extended capability area.
* Presence and definitions for indexes beyond these ones may vary.
*/
#define XFERMODE_IDX_I3C_SDR 0x00 /* I3C SDR Mode */
#define XFERMODE_IDX_I3C_HDR_DDR 0x01 /* I3C HDR-DDR Mode */
#define XFERMODE_IDX_I3C_HDR_T 0x02 /* I3C HDR-Ternary Mode */
#define XFERMODE_IDX_I3C_HDR_BT 0x03 /* I3C HDR-BT Mode */
#define XFERMODE_IDX_I2C 0x08 /* Legacy I2C Mode */
/*
* Master Data Transfer Rate Selector Values.
*
* These are the values to be used in the command descriptor XFER_RATE field
* and found in the RATE_ID field below.
* The I3C_SDR0, I3C_SDR1, I3C_SDR2, I3C_SDR3, I3C_SDR4 and I2C_FM rates
* are required, everything else is optional and discoverable in the
* Data Transfer Rate Table. Indicated are typical rates. The actual
* rates may vary slightly and are also specified in the Data Transfer
* Rate Table.
*/
#define XFERRATE_I3C_SDR0 0x00 /* 12.5 MHz */
#define XFERRATE_I3C_SDR1 0x01 /* 8 MHz */
#define XFERRATE_I3C_SDR2 0x02 /* 6 MHz */
#define XFERRATE_I3C_SDR3 0x03 /* 4 MHz */
#define XFERRATE_I3C_SDR4 0x04 /* 2 MHz */
#define XFERRATE_I3C_SDR_FM_FMP 0x05 /* 400 KHz / 1 MHz */
#define XFERRATE_I3C_SDR_USER6 0x06 /* User Defined */
#define XFERRATE_I3C_SDR_USER7 0x07 /* User Defined */
#define XFERRATE_I2C_FM 0x00 /* 400 KHz */
#define XFERRATE_I2C_FMP 0x01 /* 1 MHz */
#define XFERRATE_I2C_USER2 0x02 /* User Defined */
#define XFERRATE_I2C_USER3 0x03 /* User Defined */
#define XFERRATE_I2C_USER4 0x04 /* User Defined */
#define XFERRATE_I2C_USER5 0x05 /* User Defined */
#define XFERRATE_I2C_USER6 0x06 /* User Defined */
#define XFERRATE_I2C_USER7 0x07 /* User Defined */
```