3.2.2.3. DSS

Introduction

This page gives a basic description of DSS7 hardware, the Linux kernel drivers (tidss) and various TI boards that use DSS. The technical reference manual (TRM) for the SoC and the board documentation give more detailed descriptions.

Hardware Architecture

The Display Subsystem (DSS) is a hardware block responsible for fetching pixel data from memory and sending it to a display peripheral like an LCD panel or an EDP monitor. DSS hardware can be divided into two major parts:

  1. Display Controller (DISPC), which handles fetching the pixel data, doing color conversions, composition, and other pixel manipulation, and
  2. Peripherals, which encode the raw pixel data to standard display signals, like MIPI DPI or eDP.

In addition to the SoC’s DSS, boards often contain external encoders (for example, DPI-to-HDMI encoder) and display panels.


../../../../../_images/DSS7_HW.png

The above image gives an overview of the DSS hardware. The arrows show how pipelines are connected to overlay managers, which are further connected to video-ports, which finally create an encoded pixel stream for display on the LCD or TV.

Display Controller (DISPC)

DISPC is the block which is responsible for fetching pixel data from the memory through DMA pipelines, and then create a pixel stream for the encoder. The pixel stream comprises of a composition of one or more image layers which we finally want to present on the display. DISPC can be split into 3 major sub-blocks:

  • Pipelines
  • Overlay Managers (Compositors)
  • Video Ports (Timing generators)

The next three sections provide details on these sub-blocks.

Pipelines

Pipelines (or DMA channels) consist of the HW block which performs DMA to fetch image pixels (of different color formats) from RAM. Besides performing DMA, pipelines perform other functions like replication, ARGB expansion, scaling, color conversion, VC1 range mapping on the input pixels before it’s passed on to the overlay manager. An overlay manager receives pixel data from one or more such pipelines, and performs the task of composing them and passing it on to the video-port.

DSS7 IP version has two types of pipelines: one or more video (VID) pipelines and a number of video-lite (VIDL) pipelines. VIDL pipelines do not support scaling. They can, however, support YUV formats. These pipelines perform chroma up-sampling by using fixed-coefficient filters. VIDEO pipelines support up/down scaling and YUV color formats by employing programmable poly-phase filters for scaling as well as chroma up-sampling.

Overlay Managers (Compositors)

Overlay managers are the blocks which take pixel data from one or more pipelines, layer them to form a composition, and create a pixel stream for the video-ports to consume.

The compositor part takes pixel data from multiple pipelines, composing them on the basis of their position with respect to the complete overlay manager size. Tasks like alpha blending, color-keying and z-order are also performed by the compositor in the overlay manager.


Video Ports (Timing generators)

Video ports take a pixel stream from an overlay manager, and encode it into a standard video signal which is understood by the LCD panel/monitor or an internal peripheral (like eDP). These video standards are specified by MIPI or general video/display bodies.

The timing generator part of the video port is responsible for providing the pixel stream generated by the compositor above according to the timings desired by the peripheral. The timing generator is a state machine which provides RGB data along with control signals like pixel clock, hsync, vsync and data enable. This timing info is used by the panel / peripheral to display the composited frame on the screen.

Driver Architecture

The driver for DSS IP is tidss. tidss is a Direct Rendering Manager (DRM) driver, located in the directory drivers/gpu/drm/tidss in the kernel tree. tidss does not implement any 3D GPU features, only the Kernel Mode Setting (KMS) features, used to display pixel data on a display.

tidss

tidss is internally divided into smaller drivers for each DSS IP submodule.

The mapping of DRM entities to DSS hardware is roughly as follows:

plane     -> DSS pipeline
crtc      -> DSS overlay manager
encoder   -> DSS output, encoder, display
connector -> DSS output, encoder, display

Driver Features

Note

This is not a comprehensive list of features supported/not supported.

Supported Features

Outputs:

  • MIPI DPI
  • eDP

DRM Plane Features:

  • Scaler
  • Z-order
  • Global alpha blending
  • Alpha blending (pre-multipled & non-pre-multiplied)

DRM CRTC Features:

  • Background color
  • Transparency color keying
  • Color Phase Rotation

Unsupported Features/Limitations

  • Interlaced content is not supported.
  • Information about interlace top/bottom fields is not given to the userspace, and the userspace has no control if a buffer is shown on top/bottom.
  • CLUT (Color Look-Up Table) color formats are not supported (BITMAP1, BITMAP2, BITMAP4, BITMAP8).
  • TDM
  • BT-656/1120

Driver Configuration

Kernel Configuration Options

tidss supports building both as built-in or as a module.

tidss can be found under “Device Drivers/Graphics support” in the kernel menuconfig. You need to enable DRM (CONFIG_DRM) before you can enable tidss (CONFIG_DRM_TIDSS).

  • Enable DSS Display Subsystem support (CONFIG_DRM_TIDSS) for Jacinto 7 SoCs
  • Enable TI DSS6 support (CONFIG_DRM_TIDSS_DSS6) for K2G SoC
  • Enable TI DSS7 support (CONFIG_DRM_TIDSS_DSS7) for K3 SoCs

Display Sharing Configuration Options

tidss supports sharing the display components with other drivers running on different cores.

tidss can be initialised with sharing information by adding the appropriate resource partitioning information in the device-tree files:

dss_planes: dss-planes {
        #address-cells = <1>;
        #size-cells = <0>;

        /* vid1, Owned by us */
        plane@0 {
                reg = <0>;
                managed = <1>;
        };

        /* vidl1, Reserved for jailhouse inmate */
        plane@1 {
                reg = <1>;
                managed = <0>;
        };

        /* vid2, owned by RTOS */
        plane@2 {
                reg = <2>;
                managed = <0>;
        };

        /* vidl2, marshalled to us by RTOS */
        plane@3 {
                reg = <3>;
                managed = <0>;
        };
};

dss_vps: dss-vps {
        #address-cells = <1>;
        #size-cells = <0>;

        /* Owned by jailhouse inmate */
        vp@0 {
                reg = <0>;
                managed = <0>;
        };

        /* Owned by RTOS */
        vp@1 {
                reg = <1>;
                managed = <0>;
        };

        /* Not owned by anyone
         * so keeping here
         */
        vp@2 {
                reg = <2>;
                managed = <1>;
        };

        /* Owned by us */
        vp@3 {
                reg = <3>;
                managed = <1>;
        };
};

In the above example, one plane vid1 and one video port vp4 is owned by us to drive a MIPI DPI output. Two planes, vid2 and vidl2, are owned by TI_RTOS for driving vp2, and therefore are marked as managed = <0>. Please note that vidl2 can be used by tidss using remote-device framework, but is actually owned by TI-RTOS. One plane vidl1 and one video port vp1 is used by a Linux virtual-machine, and therefore these are also marked as managed = <0>.

tidss also supports using one of the four interrupts, and this can be partitioned as:

dss_commons: dss-commons {
        #address-cells = <1>;
        #size-cells = <0>;

        interrupt-common {
                reg = <1>;
        };

        config-common {
                status = "disabled";
                reg = <0>;
        };
};

In the above configuration, tidss is configured to use common_s1 region for interrupt handling and the common_m region is marked as “disabled”, therefore making tidss dependant on another driver for initial configuration.

In the situation described above, tidss is required to depend on an external driver for configuration and sending frames / receiving events. tidss can perform these operations by utilising remote-device framework if the following information is provided:

dss_remote: dss-remote {
        #address-cells = <0>;
        #size-cells = <0>;

        remote-name = "r5f-tidss";
};

Driver Usage

Loading tidss

If built as a module, you need to load all the drm, tidss and mhdp8546 modules before tidss will start. When tidss starts, it will prints something along these lines:

[    9.158041] tidss 4a00000.dss: dispc7_wb_find_free_ovr: found ovr vp2 (1)
[    9.165740] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
[    9.182786] [drm] No driver support for vblank timestamp query.
[    9.207746] [drm] Initialized tidss 1.0.0 20180215 for 4a00000.dss on minor 0

Using tidss

tidss is usually used by the windowing system like X server or Weston, so normally users don’t need to use tidss directly.

tidss device appears under /dev/dri/ directory, normally card0.

There are also newer DRM device nodes, controlD64 and renderD128 which point to the same tidss device. controlD64 is a “control” node, used for mode setting. renderD128 is a “render” node, which, in tidss’s case, means that only buffer allocations can be done via the render node. The render node can be given more relaxed access restrictions, as the applications can only do buffer allocations from there, and cannot affect the system (except by allocating all the memory).

Low level userspace applications can use tidss via DRM ioctls. This is made a bit easier with libdrm, which is a wrapper library around DRM ioctls.

libdrm is included in TI releases and its sources can be found from:

git://anongit.freedesktop.org/git/mesa/drm

libdrm also contains ‘modetest’ tool, which can be used to get basic information about DRM state and to show a test pattern on a display.

Another option is kms++, a C++11 library for kernel mode setting which includes a bunch of test utilities and also V4L2 classes and Python wrappers for DRM and V4L2. kms++ can be found from:

https://github.com/tomba/kmsxx

tidss properties

tidss supports configuration via DRM properties. Many of them are standard, but some are tidss specific.

Property Object Description
zpos plane Z order of a plane. The higher the number the more top the plane is, hiding other planes beneath it. This is supported on OMAP4+ DSS IPs. Earlier DSS IPs have a fixed z-order.
COLOR_ENCODING plane Selects between BT.601 and BT.709 YCbCr encoding.
COLOR_RANGE plane Selects between full range and limited range YCbCr encoding.
alpha plane Alpha blending capabilities.
CTM crtc Color Transformation Matrix blob property. Implemented trough Color phase rotation matrix in DSS IP. Applied after gamma table. Not available on OMAP4+ TV output.
GAMMA_LUT crtc Blob property to set the gamma lookup table (LUT) mapping pixel data sent to the connector.
GAMMA_LUT_SIZE crtc Number of elements in gammma lookup table.

Buffers

The buffers used for tidss can be either allocated from tidss or imported from some other driver (dmabuf import).

tidss supports generic DRM dumb buffers. Dumb buffers are allocated using the generic DRM_IOCTL_MODE_CREATE_DUMB ioctl.

fbdev emulation (/dev/fb0)

DRM framework supports “emulating” the legacy fbdev API. This feature can be enabled or disabled in the kernel config (CONFIG_DRM_FBDEV_EMULATION). The fbdev emulation offers only the basic feature set, and the fb is shown on the first display. Fbdev emulation is mainly intended for kernel console or boot splash screens.