High Speed Synchronous Serial Interface (HSI)¶
Introduction¶
High Speed Synchronous Interface (HSI) is a full duplex, low latency protocol,that is optimized for die-level interconnect between an Application Processorand a Baseband chipset. It has been specified by the MIPI alliance in 2003 andimplemented by multiple vendors since then.
The HSI interface supports full duplex communication over multiple channels(typically 8) and is capable of reaching speeds up to 200 Mbit/s.
The serial protocol uses two signals, DATA and FLAG as combined data and clocksignals and an additional READY signal for flow control. An additional WAKEsignal can be used to wakeup the chips from standby modes. The signals arecommonly prefixed by AC for signals going from the application die to thecellular die and CA for signals going the other way around.
+------------+ +---------------+| Cellular | | Application || Die | | Die || | - - - - - - CAWAKE - - - - - - >| || T|------------ CADATA ------------>|R || X|------------ CAFLAG ------------>|X || |<----------- ACREADY ------------| || | | || | | || |< - - - - - ACWAKE - - - - - - -| || R|<----------- ACDATA -------------|T || X|<----------- ACFLAG -------------|X || |------------ CAREADY ----------->| || | | || | | |+------------+ +---------------+
HSI Subsystem in Linux¶
In the Linux kernel the hsi subsystem is supposed to be used for HSI devices.The hsi subsystem contains drivers for hsi controllers including support formulti-port controllers and provides a generic API for using the HSI ports.
It also contains HSI client drivers, which make use of the generic API toimplement a protocol used on the HSI interface. These client drivers canuse an arbitrary number of channels.
hsi-char Device¶
Each port automatically registers a generic client driver called hsi_char,which provides a character device for userspace representing the HSI port.It can be used to communicate via HSI from userspace. Userspace mayconfigure the hsi_char device using the following ioctl commands:
- HSC_RESET
flush the HSI port
- HSC_SET_PM
enable or disable the client.
- HSC_SEND_BREAK
send break
- HSC_SET_RX
set RX configuration
- HSC_GET_RX
get RX configuration
- HSC_SET_TX
set TX configuration
- HSC_GET_TX
get TX configuration
The kernel HSI API¶
- structhsi_channel¶
channel resource used by the hsi clients
Definition:
struct hsi_channel { unsigned int id; const char *name;};Members
idChannel number
nameChannel name
- structhsi_config¶
Configuration for RX/TX HSI modules
Definition:
struct hsi_config { unsigned int mode; struct hsi_channel *channels; unsigned int num_channels; unsigned int num_hw_channels; unsigned int speed; union { unsigned int flow; unsigned int arb_mode; };};Members
modeBit transmission mode (STREAM or FRAME)
channelsChannel resources used by the client
num_channelsNumber of channel resources
num_hw_channelsNumber of channels the transceiver is configured for [1..16]
speedMax bit transmission speed (Kbit/s)
{unnamed_union}anonymous
flowRX flow type (SYNCHRONIZED or PIPELINE)
arb_modeArbitration mode for TX frame (Round robin, priority)
- structhsi_board_info¶
HSI client board info
Definition:
struct hsi_board_info { const char *name; unsigned int hsi_id; unsigned int port; struct hsi_config tx_cfg; struct hsi_config rx_cfg; void *platform_data; struct dev_archdata *archdata;};Members
nameName for the HSI device
hsi_idHSI controller id where the client sits
portPort number in the controller where the client sits
tx_cfgHSI TX configuration
rx_cfgHSI RX configuration
platform_dataPlatform related data
archdataArchitecture-dependent device data
- structhsi_client¶
HSI client attached to an HSI port
Definition:
struct hsi_client { struct device device; struct hsi_config tx_cfg; struct hsi_config rx_cfg;};Members
deviceDriver model representation of the device
tx_cfgHSI TX configuration
rx_cfgHSI RX configuration
- structhsi_client_driver¶
Driver associated to an HSI client
Definition:
struct hsi_client_driver { struct device_driver driver;};Members
driverDriver model representation of the driver
- structhsi_msg¶
HSI message descriptor
Definition:
struct hsi_msg { struct list_head link; struct hsi_client *cl; struct sg_table sgt; void *context; void (*complete)(struct hsi_msg *msg); void (*destructor)(struct hsi_msg *msg); int status; unsigned int actual_len; unsigned int channel; unsigned int ttype:1; unsigned int break_frame:1;};Members
linkFree to use by the current descriptor owner
clHSI device client that issues the transfer
sgtHead of the scatterlist array
contextClient context data associated to the transfer
completeTransfer completion callback
destructorDestructor to free resources when flushing
statusStatus of the transfer when completed
actual_lenActual length of data transferred on completion
channelChannel were to TX/RX the message
ttypeTransfer type (TX if set, RX otherwise)
break_frameif true HSI will send/receive a break frame. Data buffers areignored in the request.
- structhsi_port¶
HSI port device
Definition:
struct hsi_port { struct device device; struct hsi_config tx_cfg; struct hsi_config rx_cfg; unsigned int num; unsigned int shared:1; int claimed; struct mutex lock; int (*async)(struct hsi_msg *msg); int (*setup)(struct hsi_client *cl); int (*flush)(struct hsi_client *cl); int (*start_tx)(struct hsi_client *cl); int (*stop_tx)(struct hsi_client *cl); int (*release)(struct hsi_client *cl); struct blocking_notifier_head n_head;};Members
deviceDriver model representation of the device
tx_cfgCurrent TX path configuration
rx_cfgCurrent RX path configuration
numPort number
sharedSet when port can be shared by different clients
claimedReference count of clients which claimed the port
lockSerialize port claim
asyncAsynchronous transfer callback
setupCallback to set the HSI client configuration
flushCallback to clean the HW state and destroy all pending transfers
start_txCallback to inform that a client wants to TX data
stop_txCallback to inform that a client no longer wishes to TX data
releaseCallback to inform that a client no longer uses the port
n_headNotifier chain for signaling port events to the clients.
- structhsi_controller¶
HSI controller device
Definition:
struct hsi_controller { struct device device; struct module *owner; unsigned int id; unsigned int num_ports; struct hsi_port **port;};Members
deviceDriver model representation of the device
ownerPointer to the module owning the controller
idHSI controller ID
num_portsNumber of ports in the HSI controller
portArray of HSI ports
- unsignedinthsi_id(structhsi_client*cl)¶
Get HSI controller ID associated to a client
Parameters
structhsi_client*clPointer to a HSI client
Description
Return the controller id where the client is attached to
- unsignedinthsi_port_id(structhsi_client*cl)¶
Gets the port number a client is attached to
Parameters
structhsi_client*clPointer to HSI client
Description
Return the port number associated to the client
- inthsi_setup(structhsi_client*cl)¶
Configure the client’s port
Parameters
structhsi_client*clPointer to the HSI client
Description
When sharing ports, clients should either relay on a singleclient setup or have the same setup for all of them.
Return -errno on failure, 0 on success
- inthsi_flush(structhsi_client*cl)¶
Flush all pending transactions on the client’s port
Parameters
structhsi_client*clPointer to the HSI client
Description
This function will destroy all pending hsi_msg in the port and resetthe HW port so it is ready to receive and transmit from a clean state.
Return -errno on failure, 0 on success
- inthsi_async_read(structhsi_client*cl,structhsi_msg*msg)¶
Submit a read transfer
Parameters
structhsi_client*clPointer to the HSI client
structhsi_msg*msgHSI message descriptor of the transfer
Description
Return -errno on failure, 0 on success
- inthsi_async_write(structhsi_client*cl,structhsi_msg*msg)¶
Submit a write transfer
Parameters
structhsi_client*clPointer to the HSI client
structhsi_msg*msgHSI message descriptor of the transfer
Description
Return -errno on failure, 0 on success
- inthsi_start_tx(structhsi_client*cl)¶
Signal the port that the client wants to start a TX
Parameters
structhsi_client*clPointer to the HSI client
Description
Return -errno on failure, 0 on success
- inthsi_stop_tx(structhsi_client*cl)¶
Signal the port that the client no longer wants to transmit
Parameters
structhsi_client*clPointer to the HSI client
Description
Return -errno on failure, 0 on success
Parameters
structhsi_port*portThe HSI port to unregister
- voidhsi_unregister_controller(structhsi_controller*hsi)¶
Unregister an HSI controller
Parameters
structhsi_controller*hsiThe HSI controller to register
- inthsi_register_controller(structhsi_controller*hsi)¶
Register an HSI controller and its ports
Parameters
structhsi_controller*hsiThe HSI controller to register
Description
Returns -errno on failure, 0 on success.
- inthsi_register_client_driver(structhsi_client_driver*drv)¶
Register an HSI client to the HSI bus
Parameters
structhsi_client_driver*drvHSI client driver to register
Description
Returns -errno on failure, 0 on success.
- voidhsi_put_controller(structhsi_controller*hsi)¶
Free an HSI controller
Parameters
structhsi_controller*hsiPointer to the HSI controller to freed
Description
HSI controller drivers should only use this function if they needto free their allocated hsi_controller structures before a successfulcall to hsi_register_controller. Other use is not allowed.
- structhsi_controller*hsi_alloc_controller(unsignedintn_ports,gfp_tflags)¶
Allocate an HSI controller and its ports
Parameters
unsignedintn_portsNumber of ports on the HSI controller
gfp_tflagsKernel allocation flags
Description
Return NULL on failure or a pointer to an hsi_controller on success.
Parameters
structhsi_msg*msgPointer to the HSI message
Description
Client is responsible to free the buffers pointed by the scatterlists.
Parameters
unsignedintnentsNumber of memory entries
gfp_tflagsKernel allocation flags
Description
nents can be 0. This mainly makes sense for read transfer.In that case, HSI drivers will call the complete callback whenthere is data to be read without consuming it.
Return NULL on failure or a pointer to an hsi_msg on success.
- inthsi_async(structhsi_client*cl,structhsi_msg*msg)¶
Submit an HSI transfer to the controller
Parameters
structhsi_client*clHSI client sending the transfer
structhsi_msg*msgThe HSI transfer passed to controller
Description
The HSI message must have the channel, ttype, complete and destructorfields set beforehand. If nents > 0 then the client has to initializealso the scatterlists to point to the buffers to write to or read from.
HSI controllers relay on pre-allocated buffers from their clients and theydo not allocate buffers on their own.
Once the HSI message transfer finishes, the HSI controller calls thecomplete callback with the status and actual_len fields of the HSI messageupdated. The complete callback can be called before returning fromhsi_async.
Returns -errno on failure or 0 on success
- inthsi_claim_port(structhsi_client*cl,unsignedintshare)¶
Claim the HSI client’s port
Parameters
structhsi_client*clHSI client that wants to claim its port
unsignedintshareFlag to indicate if the client wants to share the port or not.
Description
Returns -errno on failure, 0 on success.
- voidhsi_release_port(structhsi_client*cl)¶
Release the HSI client’s port
Parameters
structhsi_client*clHSI client which previously claimed its port
- inthsi_register_port_event(structhsi_client*cl,void(*handler)(structhsi_client*,unsignedlong))¶
Register a client to receive port events
Parameters
structhsi_client*clHSI client that wants to receive port events
void(*handler)(structhsi_client*,unsignedlong)Event handler callback
Description
Clients should register a callback to be able to receiveevents from the ports. Registration should happen afterclaiming the port.The handler can be called in interrupt context.
Returns -errno on error, or 0 on success.
- inthsi_unregister_port_event(structhsi_client*cl)¶
Stop receiving port events for a client
Parameters
structhsi_client*clHSI client that wants to stop receiving port events
Description
Clients should call this function before releasing their associatedport.
Returns -errno on error, or 0 on success.
Parameters
structhsi_port*portPort where the event occurred
unsignedlongeventThe event type
Description
Clients should not be concerned about wake line behavior. However, dueto a race condition in HSI HW protocol, clients need to be notifiedabout wake line changes, so they can implement a workaround for it.
Events:HSI_EVENT_START_RX - Incoming wake line highHSI_EVENT_STOP_RX - Incoming wake line down
Returns -errno on error, or 0 on success.
- inthsi_get_channel_id_by_name(structhsi_client*cl,char*name)¶
acquire channel id by channel name
Parameters
structhsi_client*clHSI client, which uses the channel
char*namename the channel is known under
Description
Clients can call this function to get the hsi channel ids similar torequesting IRQs or GPIOs by name. This function assumes the samechannel configuration is used for RX and TX.
Returns -errno on error or channel id on success.