MIPI DSI

Overview

The 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) framework, 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 OS system 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.

Figure 1 Service-free mode

Available APIs

MipiDsiCntlrMethod

struct MipiDsiCntlrMethod {// Member functions of the core layer structure
    int32_t (*setCntlrCfg)(struct MipiDsiCntlr *cntlr);
    int32_t (*setCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd);
    int32_t (*getCmd)(struct MipiDsiCntlr *cntlr, struct DsiCmdDesc *cmd, uint32_t readLen, uint8_t *out);
    void (*toHs)(struct MipiDsiCntlr *cntlr);
    void (*toLp)(struct MipiDsiCntlr *cntlr);
    void (*enterUlps)(struct MipiDsiCntlr *cntlr);//(Optional) Enter the ultra-low power consumption mode.
    void (*exitUlps)(struct MipiDsiCntlr *cntlr); // (Optional) Exit the ultra-low power consumption mode.
    int32_t (*powerControl)(struct MipiDsiCntlr *cntlr, uint8_t enable);// (Optional) Enable or disable power control.
    int32_t (*attach)(struct MipiDsiCntlr *cntlr);// (Optional) Connect a DSI device to the host.
};

Table 1 Callbacks for the members in the MipiDsiCntlrMethod structure

Callback

Input Parameter

Output Parameter

Return Value

Description

setCntlrCfg

cntlr: structure pointer to the MIPI DSI controller.

HDF_STATUS

Sets controller parameters.

setCmd

cntlr: structure pointer to the MIPI DSI controller.

cmd: structure pointer to the input instruction.

HDF_STATUS

Sends instructions to a display device.

getCmd

cntlr: structure pointer to the MIPI DSI controller.

cmd: structure pointer to the instruction to output.

HDF_STATUS

Reads instructions from the display device.

toHs

cntlr: structure pointer to the MIPI DSI controller.

HDF_STATUS

Sets the high-speed mode.

toLp

cntlr: structure pointer to the MIPI DSI controller.

HDF_STATUS

Sets the low-power mode.

How to Develop

The MIPI DSI module adaptation involves the following steps:

  1. Instantiate the driver entry.

    • Instantiate the HdfDriverEntry structure.
    • Call HDF_INIT to register the HdfDriverEntry instance with the HDF framework.
  2. Configure attribute files.

    • Add the deviceNode information to the device_info.hcs file.
    • (Optional) Add the mipidsi_config.hcs file.
  3. Instantiate the MIPI DSI controller object.

    • Initialize MipiDsiCntlr.

    • Instantiate MipiDsiCntlrMethod in the MipiDsiCntlr object.

      NOTE

      For details, see Available APIs.

  4. Debug the driver.

    • (Optional) For new drivers, verify basic functions, for example, verify the information returned after the connect operation and whether data is successfully transmitted.

Development Example

The 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.

  1. Generally, you need to configure the device attributes in xx_config.hcs and add the deviceNode information to the device_info.hcs file. 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.

    In this example, no additional attribute needs to be configured for the MIPI DSI controller. If required, you need to add the deviceMatchAttr information to deviceNode in the device_info file and add the mipidsi_config file.

    • device_info.hcs configuration reference

      root {
      device_info {
          match_attr = "hdf_manager";
          platform :: host {
          hostName = "platform_host";
          priority = 50;
          device_mipi_dsi:: device {
              device0 :: deviceNode {
              policy = 0;
              priority = 150;
              permission = 0644;
               moduleName = "HDF_MIPI_TX"; // (Mandatory) Driver name, which must be the same as the moduleName in the driver entry.
                serviceName = "HDF_MIPI_TX";// (Mandatory) Unique name of the service published by the driver
              }
          }
          }
      }
      }
      
  2. Instantiate the driver entry. 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 of the HdfDriverEntry structure are filled by the vendors' operation functions. In the HDF framework, 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.

    Generally, HDF calls the Bind function and then the Init function to load a driver. If Init fails to be called, HDF calls Release to release driver resources and exits.

    • MIPI DSI driver entry reference

      struct HdfDriverEntry g_mipiTxDriverEntry = {
          .moduleVersion = 1,             
           .Init = Hi35xxMipiTxInit, // See the Init function.
          .Release = Hi35xxMipiTxRelease, //See the Release function.
          .moduleName = "HDF_MIPI_TX", // (Mandatory) The value must be the same as that in the device_info.hcs file.
      };
      HDF_INIT(g_mipiTxDriverEntry);  // Call HDF_INIT to register the driver entry with the HDF framework.
      
  3. Initialize the MipiDsiCntlr object at the core layer, including initializing the vendor custom structure (transferring parameters and data), instantiating MipiDsiCntlrMethod (used to call underlying functions of the driver) in MipiDsiCntlr, and implementing the HdfDriverEntry member functions (Bind, Init, and Release).

    • Custom structure reference

      To the driver, the custom structure carries parameters and data. The values in the config file are used to initialize the structure members. In this example, the MIPI DSI has no device attribute file. Therefore, the basic member structure is similar to that of MipiDsiCntlr.

      typedef struct {
        unsigned int devno; // Device number
        short laneId[LANE_MAX_NUM]; // Lane ID
        OutPutModeTag outputMode; // Output mode, which can be CSI mode, DSI Video mode, or DSI Command mode.
        VideoModeTag videoMode; // Synchronization mode of the display device
        OutputFormatTag outputFormat; // Format of the output DSI image, which can be RGB or YUV.
        SyncInfoTag syncInfo; // Settings related to timing
        unsigned int    phyDataRate;          // mbps 
        unsigned int    pixelClk;             // KHz
      } ComboDevCfgTag;
      
      // MipiDsiCntlr is the controller structure at the core layer. Its members are assigned with values by using the Init function.
      struct MipiDsiCntlr {
        struct IDeviceIoService service;
        struct HdfDeviceObject *device;
        unsigned int devNo; // Device number
        struct MipiCfg cfg;
        struct MipiDsiCntlrMethod *ops;
        struct OsalMutex  lock;
        void *priv;
      };
      
    • Instantiate the callback function structure MipiDsiCntlrMethod in MipiDsiCntlr. Other members are initialized by using the Init function.

      static struct MipiDsiCntlrMethod g_method = {
          .setCntlrCfg = Hi35xxSetCntlrCfg,
          .setCmd = Hi35xxSetCmd,
          .getCmd = Hi35xxGetCmd,
          .toHs = Hi35xxToHs,
          .toLp = Hi35xxToLp,
      };
      
    • Init function

      Input parameters:

      HdfDeviceObject, an interface parameter exposed by the driver, contains the .hcs configuration file information.

      Return values:

      HDF_STATUS (The following table lists some status. For details about other status, see HDF_STATUS in the //drivers/framework/include/utils/hdf_base.h file.)

      Status (Value)

      Description

      HDF_ERR_INVALID_OBJECT

      Invalid object

      HDF_ERR_MALLOC_FAIL

      Failed to allocate memory

      HDF_ERR_INVALID_PARAM

      Invalid parameter

      HDF_ERR_IO

      I/O error

      HDF_SUCCESS

      Operation successful

      HDF_FAILURE

      Operation failed

      Function description:

      Connects to the MipiDsiCntlrMethod instance, calls MipiDsiRegisterCntlr, and performs other vendor-defined initialization operations.

      static int32_t Hi35xxMipiTxInit(struct HdfDeviceObject *device)
      {
      int32_t ret;
      g_mipiTx.priv = NULL; // g_mipiTx is a global variable.
                              //static struct MipiDsiCntlr g_mipiTx { 
                              //     .devNo=0
                              //};
      g_mipiTx.ops = &g_method;// Connect to the MipiDsiCntlrMethod instance.
      ret = MipiDsiRegisterCntlr(&g_mipiTx, device);// (Mandatory) Call the function at the core layer and g_mipiTx to initialize global variables at the core layer.
      ...
      return MipiTxDrvInit(0); // (Mandatory) Device initialization customized by the vendor.
      }
      
      // mipi_dsi_core.c, core layer file. 
      int32_t MipiDsiRegisterCntlr(struct MipiDsiCntlr *cntlr, struct HdfDeviceObject *device)
      {
      ...
      // Define the global variable static struct MipiDsiHandle g_mipiDsihandle[MAX_CNTLR_CNT].
      if (g_mipiDsihandle[cntlr->devNo].cntlr == NULL) {
          (void)OsalMutexInit(&g_mipiDsihandle[cntlr->devNo].lock);
          (void)OsalMutexInit(&(cntlr->lock));
      
          g_mipiDsihandle[cntlr->devNo].cntlr = cntlr;// Initialize MipiDsiHandle.
          g_mipiDsihandle[cntlr->devNo].priv = NULL;  
          cntlr->device = device; // Enable conversion between HdfDeviceObject and MipiDsiHandle.
           device->service = &(cntlr->service);  // Enable conversion between HdfDeviceObject and MipiDsiHandle.
          cntlr->priv = NULL;    
          ...
          return HDF_SUCCESS;
      }
      ...
      return HDF_FAILURE;
      }
      
    • Release function

      Input parameters:

      HdfDeviceObject, an interface parameter exposed by the driver, contains the .hcs configuration file information.

      Return values:

      Function description:

      Releases the memory and deletes the controller. This function assigns a value to the Release API in the driver entry structure. When the HDF framework fails to call the Init function to initialize the driver, the Release function can be called to release driver resources. All forced conversion operations for obtaining the corresponding object can be successful only when the Init function has the corresponding value assignment operations.

      static void Hi35xxMipiTxRelease(struct HdfDeviceObject *device)
      {
      struct MipiDsiCntlr *cntlr = NULL;
      ...
      cntlr = MipiDsiCntlrFromDevice(device);// A forced conversion from HdfDeviceObject to MipiDsiCntlr is involved.
                                              //return (device == NULL) ? NULL : (struct MipiDsiCntlr *)device->service;
      ...
      MipiTxDrvExit(); // (Mandatory) Release the resources occupied by the vendor's devices.
      MipiDsiUnregisterCntlr(&g_mipiTx); // Empty function
      g_mipiTx.priv = NULL;
      HDF_LOGI("%s: unload mipi_tx driver 1212!", __func__);
      }