• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# MIPI DSI
2
3
4## Overview
5
6The Display Serial Interface (DSI) is a specification developed by the Mobile Industry Processor Interface (MIPI) Alliance to reduce the cost of display controllers in mobile devices. In the Hardware Driver Foundation (HDF), the MIPI DSI module uses the service-free mode for API adaptation. The service-free mode applies to the devices that do not provide user-mode APIs or the operating system (OS) that does not distinguish the user mode and the kernel mode. In the service-free mode, **DevHandle** (a void pointer) directly points to the kernel-mode address of the device object.
7
8  **Figure 1** Service-free mode
9
10  ![](figures/service-free-mode.png "service-free-mode")
11
12
13## Available APIs
14
15**MipiDsiCntlrMethod**:
16
17
18```
19struct MipiDsiCntlrMethod { // Member functions of the core layer structure
20    int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr);
21    int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd);
22    int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
23    void (*toHs)(struct MipiDsiCntlr *cntlr);
24    void (*toLp)(struct MipiDsiCntlr *cntlr);
25    void (*enterUlps)(struct MipiDsiCntlr *cntlr);                      // (Optional) Enter the Ultra-Low Power State (ULPS).
26    void (*exitUlps)(struct MipiDsiCntlr *cntlr);                       // (Optional) Exit the ULPS.
27    int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
28    int32_t (*attach)(struct MipiDsiCntlr *cntlr);                      // (Optional) Attach a DSI device to the host.
29};
30```
31
32  **Table 1** Description of the callback functions in MipiDsiCntlrMethod
33
34| Function| Input Parameter| Output Parameter| Return Value| Description|
35| -------- | -------- | -------- | -------- | -------- |
36| setCntlrCfg | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets controller parameters.|
37| setCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: structure pointer to the commands to send. | –| HDF_STATUS| Sends commands to a display device.|
38| getCmd | **cntlr**: structure pointer to the MIPI DSI controller.<br>**cmd**: pointer to the command description structure.<br>**readLen**: length of the data to read.| **out**: structure pointer to the data obtained.| HDF_STATUS| Reads data by sending commands.|
39| toHs | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the high speed (HS) mode.|
40| toLp | **cntlr**: structure pointer to the MIPI DSI controller.| –| HDF_STATUS| Sets the low power (LP) mode.|
41
42
43## How to Develop
44
45The MIPI DSI module adaptation involves the following steps:
46
471. Configure attribute files.
48   - Add the **deviceNode** description to the **device_info.hcs** file.
49   - (Optional) Add the **mipidsi_config.hcs** file.
50
512. Instantiate the driver entry.
52   - Instantiate the **HdfDriverEntry** structure.
53   - Call **HDF_INIT** to register the **HdfDriverEntry** instance with the HDF.
54
553. Instantiate the MIPI DSI controller object.
56   - Initialize **MipiDsiCntlr**.
57   - Instantiate **MipiDsiCntlrMethod** in the **MipiDsiCntlr** object.
58      > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
59      > For details about the functions in **MipiDsiCntlrMethod**, see [Available APIs](#available-apis).
60
614. Debug the driver.
62
63   (Optional) For new drivers, verify basic functions, for example, check the information returned after the driver is attached and whether data is successfully transmitted.
64
65
66## Development Example
67
68The following uses **mipi_tx_hi35xx.c** as an example to present the contents that need to be provided by the vendor to implement device functions.
69
701. Configure the device attributes in **xx_config.hcs** and add the **deviceNode** information to the **device_info.hcs** file.
71
72   The device attribute values are closely related to the default values or value range of the **MipiDsiCntlr** members at the core layer. The **deviceNode** information is related to the driver entry registration.
73
74   In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, add the **deviceMatchAttr** information to **deviceNode** in the **device_info** file and add the **mipidsi_config** file.
75
76     **device_info.hcs** configuration example:
77
78   ```
79   root {
80   device_info {
81       match_attr = "hdf_manager";
82       platform :: host {
83       hostName = "platform_host";
84       priority = 50;
85       device_mipi_dsi:: device {
86           device0 :: deviceNode {
87           policy = 0;
88           priority = 150;
89           permission = 0644;
90           moduleName = "HDF_MIPI_TX";    // (Mandatory) Driver name, which must be the same as moduleName in the driver entry.
91           serviceName = "HDF_MIPI_TX";   // (Mandatory) Unique name of the service published by the driver.
92           }
93       }
94       }
95   }
96   }
97   ```
98
992. Instantiate the driver entry.
100
101   The driver entry must be a global variable of the **HdfDriverEntry** type (defined in **hdf_device_desc.h**), and the value of **moduleName** must be the same as that in **device_info.hcs**. The function pointer members in the **HdfDriverEntry** structure are filled by the vendors' operation functions. In the HDF, the start address of each **HdfDriverEntry** object of all loaded drivers is collected to form a segment address space similar to an array for the upper layer to invoke.
102
103   Generally, the HDF calls the **Bind** function and then the **Init** function to load a driver. If **Init** fails to be called, the HDF calls **Release** to release driver resources and exit.
104
105   MIPI DSI driver entry example:
106
107      ```
108      struct HdfDriverEntry g_mipiTxDriverEntry = {
109          .moduleVersion = 1,
110          .Init = Hi35xxMipiTxInit,       // See the Init function.
111          .Release = Hi35xxMipiTxRelease, // See the Release function.
112          .moduleName = "HDF_MIPI_TX",    // (Mandatory) The value must be the same as that in the device_info.hcs file.
113      };
114      HDF_INIT(g_mipiTxDriverEntry);      // Call HDF_INIT to register the driver entry with the HDF.
115      ```
116
1173. Initialize the **MipiDsiCntlr** object at the core layer, including defining a custom structure (to pass parameters and data) and implementing the **HdfDriverEntry** member functions (**Bind**, **Init** and **Release**) to instantiate **MipiDsiCntlrMethod** in **MipiDsiCntlr** (so that the underlying driver functions can be called).
118
119   - Defining a custom structure
120
121     To the driver, the custom structure holds parameters and data. Generally, the values in the **config** file are used to initialize the structure members. However, in this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of **MipiDsiCntlr**.
122
123     ```
124     typedef struct {
125       unsigned int devno;                   // Device number
126       short           laneId[LANE_MAX_NUM]; // Lane ID
127       OutPutModeTag   outputMode;           // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode.
128       VideoModeTag    videoMode;            // Synchronization mode of the display device
129       OutputFormatTag outputFormat;         // Format of the output DSI image, which can be RGB or YUV.
130       SyncInfoTag syncInfo;                 // Settings related to timing
131       unsigned int phyDataRate;             // Data rate, in Mbit/s
132       unsigned int    pixelClk;             // Clock, in kHz
133     } ComboDevCfgTag;
134
135     // MipiDsiCntlr is the controller structure at the core layer. The Init function assigns values to the members of MipiDsiCntlr.
136     struct MipiDsiCntlr {
137       struct IDeviceIoService service;
138       struct HdfDeviceObject *device;
139       unsigned int devNo;         // Device number
140       struct MipiCfg cfg;
141       struct MipiDsiCntlrMethod *ops;
142       struct OsalMutex  lock;
143       void *priv;
144     };
145     ```
146
147   - Instantiating **MipiDsiCntlrMethod** in **MipiDsiCntlr** (other members are initialized by **Init**)
148
149     ```
150     static struct MipiDsiCntlrMethod g_method = {
151         .setCntlrCfg = Hi35xxSetCntlrCfg,
152         .setCmd = Hi35xxSetCmd,
153         .getCmd = Hi35xxGetCmd,
154         .toHs = Hi35xxToHs,
155         .toLp = Hi35xxToLp,
156     };
157     ```
158
159   - **Init** function
160
161     **Input parameter**:
162
163     **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
164
165     **Return value**:
166
167     **HDF_STATUS**
168
169     The table below describes some status. For more information, see **HDF_STATUS** in the **/drivers/framework/include/utils/hdf_base.h** file.
170
171     | Status                 | Description                |
172     | ---------------------- | -------------------------- |
173     | HDF_ERR_INVALID_OBJECT | Invalid object.            |
174     | HDF_ERR_MALLOC_FAIL    | Failed to allocate memory. |
175     | HDF_ERR_INVALID_PARAM  | Invalid parameter.         |
176     | HDF_ERR_IO             | I/O error.                 |
177     | HDF_SUCCESS            | Operation successful.      |
178     | HDF_FAILURE            | Operation failed.          |
179
180     **Function description**:
181
182     Attaches the **MipiDsiCntlrMethod** instance, calls **MipiDsiRegisterCntlr**, and performs other vendor-defined initialization operations.
183
184     ```
185      static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
186      {
187      int32_t ret;
188      g_mipiTx.priv = NULL;                         // g_mipiTx is a global variable defined.
189                                                     // static struct MipiDsiCntlr g_mipiTx {
190                                                     //     .devNo=0
191                                                     //};
192      g_mipiTx.ops = &g_method;                     // Attach the MipiDsiCntlrMethod instance.
193      ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
194      ...
195      return MipiTxDrvInit(0);                      // (Mandatory) Device initialization customized by the vendor.
196      }
197
198      // mipi_dsi_core.c file
199      int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
200      {
201      ...
202      // Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT].
203      if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
204          (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
205          (void)OsalMutexInit(&(cntlr->lock));
206
207          g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle.
208          g_mipiDsihandle[cntlr->devNo].priv = NULL;
209          cntlr->device = device;                     // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
210          device->service = &(cntlr->service);       // Prerequisites for conversion between HdfDeviceObject and MipiDsiHandle.
211          cntlr->priv = NULL;
212          ...
213          return HDF_SUCCESS;
214      }
215      ...
216      return HDF_FAILURE;
217      }
218     ```
219
220   - **Release** function
221
222     **Input parameter**:
223
224     **HdfDeviceObject**, an interface parameter exposed by the driver, contains the .hcs information.
225
226     **Return value**:
227
228     No value is returned.
229
230     **Function description**:
231
232     Releases the memory and deletes the controller. This function assigns values to the **Release** API in the driver entry structure. When the HDF fails to call the **Init** function to initialize the driver, the **Release** function can be called to release driver resources.
233
234        > ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
235		>
236        > All forced conversion operations for obtaining the corresponding object can be successful only when the **Init** function has the corresponding value assignment operations.
237
238     ```
239      static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
240      {
241      struct MipiDsiCntlr *cntlr = NULL;
242      ...
243      cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved.
244                                               // return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
245      ...
246      MipiTxDrvExit(;                        // (Mandatory) Release the resources occupied by the vendor's devices.
247      MipiDsiUnregisterCntlr(&g_mipiTx);     // Empty function
248      g_mipiTx.priv = NULL;
249      HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
250      }
251     ```
252