Display Protocol

Overview

The Display protocol provides an abstract interface for controlling one additional real-time display device streaming video data using Mobility DisplayPort (MyDP).

The Display protocol interface concerns itself with the 'control' path of a display device.  The actual video data-stream, or 'data' path, is out-of-band and not included in this interface.  

  • The interface provides a number of functions:
  • Query and choose the configuration
  • Register for and receive display events
  • Query and set the current display state (e.g. on or off)

For DisplayPort devices, the implementation simply advertises the EDID configuration and sends display notification events.  The DisplayPort interface itself handles the rest.  The DisplayPort display interface should be used for DRM protected content and can support up to 4k30 resolution.


Files

nuttx/include/nuttx/device_display.h
This file defines the device_display_type_ops structure and provides a number of wrapper functions to safely call the operations in the structure.

nuttx/nuttx/drivers/hdmi_display.c
This file is a 'skeleton' implementation of a DisplayPort driver that can be used to start your own DisplayPort device implementation.​​​​​​

Generic Example Files

nuttx/nuttx/drivers/null_display.c
The file is a blank 'skeleton' driver that can be used to start your own implementation.

nuttx/nuttx/configs/hdk/muc/src/stm32_boot.c
This file provides an example Display class registration including the necessary device resources. This file provides the starting point for your development. It should be copied into nuttx/configs/<NEW_PROJECT>/src for your specific Project and modified.


Details

display-2


Display Notification Events

The Greybus display class driver is the client of the Display device driver. It automatically registers and unregisters a callback function for display notification events. Your implementation must support exactly one registration. It must also send the appropriate display notification events when appropriate.

Below are the definitions for display notification events, the callback function, and the register and unregister functions.


Host Ready

This operation is used by the client to notify implementations that it is ready to receive display notification events. This operation must be received before the your implementation can send any display notification events.

int (*host_ready)(struct device *dev);


Display Notification Events

enum display_notification_event {
  DISPLAY_NOTIFICATION_EVENT_INVALID = 0x00,
  DISPLAY_NOTIFICATION_EVENT_FAILURE = 0x01,
  DISPLAY_NOTIFICATION_EVENT_AVAILABLE = 0x02,
  DISPLAY_NOTIFICATION_EVENT_UNAVAILABLE = 0x03,
  DISPLAY_NOTIFICATION_EVENT_CONNECT = 0x04,
  DISPLAY_NOTIFICATION_EVENT_DISCONNECT = 0x05,
};

The display notification events are defined as follows:

  • DISPLAY_NOTIFICATION_EVENT_INVALID: A reserved value, do not use.
  • DISPLAY_NOTIFICATION_EVENT_FAILURE: Send this event if the display device has encountered a catastrophic failure that it cannot recover from.
  • DISPLAY_NOTIFICATION_EVENT_AVAILABLE: Send this event when the display device software is available for operations from the phone. This is typically sent in response to the host_ready() call. The phone will not send operations before this event is received.
  • DISPLAY_NOTIFICATION_EVENT_UNAVAILABLE: Send this event if the display device software is no longer available to receive operations from the phone. The phone will not send operations after this event is received.
  • DISPLAY_NOTIFICATION_EVENT_CONNECT: Send this event when the display device hardware is ready to be used (e.g. turned on). For devices that are always connected, this event can be sent immediately after the AVAILABLE event. For devices that are intermittently connected (e.g. an HDMI port), this event can be sent after an external device is plugged in.
  • DISPLAY_NOTIFICATION_EVENT_DISCONNECT: Send this event when the display device hardware is no longer ready to be used. For devices that are intermittently connected (e.g. an HDMI port), this event can be sent after an external device is unplugged. For other devices, this event is not typically used.

Display Notification Callback

typedef int (*display_notification_cb)(struct device *dev,
  enum display_notification_event event);

The callback function receives a pointer to the device and the display notification event. Clients handle these events as they see fit and return an errno. Your implementation should ignore the errno.


Register Callback

int (*register_callback)(struct device *dev, display_notification_cb cb);

This operation is used by clients to register a callback handler for display notification events. Your implementation must support at exactly one callback.
Callers pass a pointer to the device and a pointer to the callback function.
If a callback is not already registered, your implementation saves the callback function and returns success. If a callback is already registered, then return an errno.


Unregister Callback

int (*unregister_callback)(struct device *dev);

This operation is used by clients to unregister a previously registered callback handler for display notification events. It is an error to unregister a callback function if one was not previously registered.
Callers pass a pointer to the device.
If a callback is not already registered, your implementation clears the callback function and returns success. If a callback was not already registered, then return an errno.


Configuration

Below are the configuration operations. Your driver must implement these operations and be prepared to handle them any time after sending a DISPLAY_NOTIFICATION_EVENT_AVAILALBE event and before sending a DISPLAY_NOTIFICATION_EVENT_UNAVAILALBE event.

Display Type

enum display_type {
  DISPLAY_TYPE_INVALID = 0x00,
  DISPLAY_TYPE_DSI = 0x01,
  DISPLAY_TYPE_DP = 0x02,
};

The display type describes the physical display interface:

  • DISPLAY_TYPE_INVALID: Reserved, do not use.
  • DISPLAY_TYPE_DSI: The Display device uses DSI.
  • DISPLAY_TYPE_DP: The Display device uses DisplayPort

Display Config Type

enum display_config_type {
  DISPLAY_CONFIG_TYPE_INVALID = 0x00,
  DISPLAY_CONFIG_TYPE_EDID_1P3 = 0x01,
  DISPLAY_CONFIG_TYPE_DSI = 0x02,
};

The display config type describes the binary format of the config data returned by get_config().

  • DISPLAY_CONFIG_TYPE_INVALID: Reserved, do not use.
  • DISPLAY_CONFIG_TYPE_EDID_1P3: An EDID binary block as defined by VESA EDID version 1.3.
  • DISPLAY_CONFIG_TYPE_DSI: A custom DSI-specific structure described in detail below.

DisplayPort implementations must use the EDID v1.3 format while DSI implementations must use the DSI format.


Get Config Size

int (*get_config_size)(struct device *dev, uint32_t *size);
This operation requests the size, in bytes, of the configuration data that would be returned by a subsequent get_configoperation.
Callers pass a pointer to the device and a pointer to a variable to hold the size.
Your implementation fills in the size and returns an appropriate errno value.


Get Config

int (*get_config)(struct device *dev, uint8_t *display_type,
  uint8_t *config_type, uint32_t *size, uint8_t **config);

This operation requests the configuration or configurations supported by the display device.
Callers pass a pointer to the device and a pointers to a variable to the display type, display config type, config size, and config data.
Your implementation fills in the display type, config type, size, and config data and returns an appropriate errno value. If a config of size 0 is returned with an errno of 0, then the client will attempt to read the display configuration from another source (e.g. directly over DisplayPort). The exact format of the configuration data is discussed in more detail below.


Set Config

int (*set_config)(struct device *dev, uint8_t index);

The EDID v1.3 format has the ability to specify more than one supported configuration. If this is the case, clients may want to select a configuration other than the default. The set_config operation allows clients to select, by zero-based index, the desired configuration.
Callers pass a pointer to the device and the zero-based index of the desired configuration.
Your implementation verifies the index and, if valid selects, the configuration. Otherwise, returns an errno. All implementations must support at least one configuration (index of 0) even if they return an zero-length config data.


State

Display State

enum display_state { DISPLAY_STATE_OFF = 0x00, DISPLAY_STATE_ON = 0x01, };
The display state describes whether the Display device is on or off.

  • DISPLAY_STATE_OFF: Off
  • DISPLAY_STATE_ON: On

Get State

int (*get_state)(struct device *dev, uint8_t *state);
This operation requests the current state of the Display device.
Callers pass a pointer to the device and a pointer to a variable to the state.
Your implementation fills in the current state and returns an appropriate errno value.


Set State

int (*set_state)(struct device *dev, uint8_t state);
This operation sets the current state of the Display device.
Callers pass a pointer to the device and a the new state.
Your implementation changes state (if appropriate) and returns an appropriate errno value.


Greybus Manifest

The Greybus Manifest requires at least two entries for a Display class:

  • The Display class
  • A Bundle

If your Display device requires additional hardware to function, include those device classes in the same bundle. If your Display device has optional hardware that is useful, but not required to function, you may want to include it in its own bundle.


Simple Display

[cport-descriptor 2]
bundle = 2 protocol = 0xee ; Display-Ext
[bundle-descriptor 2]
class = 0x0c ; Display (bundle)


Display and Backlight

[cport-descriptor 2]
bundle = 2 protocol = 0xee ; Display-Ext
[cport-descriptor 3]
bundle = 2 protocol = 0x0f ; Lights
[bundle-descriptor 2]
class = 0x0c ; Display (bundle)


Display, Backlight, and Buttons

[cport-descriptor 2]
bundle = 2 protocol = 0xee ; Display-Ext
[cport-descriptor 3]
bundle = 2 protocol = 0x0f ; Lights
[bundle-descriptor 2]
class = 0x0c ; Display (bundle)
[cport-descriptor 5]
bundle = 3 protocol = 0x05 ; HID
[bundle-descriptor 3]
class = 0x05 ; HID (bundle)