K230_DRM_API_Reference#
1. Introduction to DRM#
DRM is the management architecture responsible for interacting with the graphics card in the Linux kernel, and user programs can easily use the API provided by DRM to achieve display control, 3D rendering, video encoding and decoding, GPU computing and other work
1.1 DRM architecture features#
DRM is the mainstream graphics display framework in the current Linux kernel, compared with the traditional FB architecture, it has the following characteristics:
DRM architecture natively supports multi-layer synthesis, FB schema natively does not support multi-layer synthesis
The DRM architecture natively supports VSYNC, DMA_BUF, and Fence mechanisms
The DRM architecture manages rendering and display drivers in a unified manner, making software development and maintenance simpler
1.2 DRM architecture composition#
From the overall architecture, DRM is mainly divided into three parts:
libdrm
libdrm encapsulates the underlying interface and provides a common API interface to user patterns
libdrm also provides a modetest program internally for querying the details of DRM devices, as well as basic display testing
KMS
KMS stands for Kernel Mode Settings, which mainly sets display resolution, color space, refresh rate, and display buffer switching and multilayer compositing
GEM
Memory management, responsible for memory allocation and release
2. ModeTest instructions#
modetest is a test program provided by libdrm that can query the details of DRM devices while also performing basic display tests
2.1 Query K230 DRM details#
The specific instructions are as follows:
[root@canaan ~ ]#modetest -M canaan-drm
Encoders:
id crtc type possible crtcs possible clones
37 36 DSI 0x00000001 0x00000001
Connectors:
id encoder status name size (mm) modes encoders
38 37 connected DSI-1 68x120 1 37
modes:
index name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot
#0 1080x1920 30.00 1080 1310 1330 1350 1920 1925 1931 1939 78529 flags: ; type: preferred, driver
props:
1 EDID:
flags: immutable blob
blobs:
value:
2 DPMS:
flags: enum
enums: On=0 Standby=1 Suspend=2 Off=3
value: 0
5 link-status:
flags: enum
enums: Good=0 Bad=1
value: 0
6 non-desktop:
flags: immutable range
values: 0 1
value: 0
4 TILE:
flags: immutable blob
blobs:
value:
CRTCs:
id fb pos size
36 0 (0,0) (1080x1920)
#0 1080x1920 30.00 1080 1310 1330 1350 1920 1925 1931 1939 78529 flags: ; type: preferred, driver
props:
24 VRR_ENABLED:
flags: range
values: 0 1
value: 0
28 GAMMA_LUT:
flags: blob
blobs:
value:
29 GAMMA_LUT_SIZE:
flags: immutable range
values: 0 4294967295
value: 256
Planes:
id crtc fb CRTC x,y x,y gamma size possible crtcs
31 0 0 0,0 0,0 0 0x00000001
formats: NV12 NV21 NV16 NV61
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
32 0 0 0,0 0,0 0 0x00000001
formats: AR24 AR12 AR15 RG24 RG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 1
33 0 0 0,0 0,0 0 0x00000001
formats: AR24 AR12 AR15 RG24 RG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 2
34 0 0 0,0 0,0 0 0x00000001
formats: AR24 AR12 AR15 RG24 RG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
35 0 0 0,0 0,0 0 0x00000001
formats: AR24 AR12 AR15 RG24 RG16
props:
8 type:
flags: immutable enum
enums: Overlay=0 Primary=1 Cursor=2
value: 0
Frame buffers:
id size pitch
[root@canaan ~ ]#
The above information is the K230 DRM details, here is a brief description:
Module ID |
Module name |
Module description |
---|---|---|
37 |
Encoder |
none |
38 |
Connector |
none |
36 |
CRTC |
Resolution support: 1080x1920 |
31 |
Video layer |
Color space support: NV12, NV21, NV16, NV61 |
32 |
OSD layer |
Color space support: AR24, AR12, AR15, RG24, RG16 |
33 |
OSD layer |
Color space support: AR24, AR12, AR15, RG24, RG16 |
34 |
OSD layer |
Color space support: AR24, AR12, AR15, RG24, RG16 |
35 |
OSD layer |
Color space support: AR24, AR12, AR15, RG24, RG16 |
AR24 Display ARGB8888
AR12 Display ARGB4444
AR15 Display ARGB1555
RG24 means RGB888
RG16 stands for RGB565
The 2.2 video layer outputs smpte color bars with NV12 color space#
The specific instructions are as follows:
modetest -M canaan-drm -D 0 -a -s 38@36:1080x1920-30 -P 31@36:1080x1920@NV12 -v -F smpte
The following figure shows the LCD display:
2.3 The OSD layer outputs tiles color bars, and the color space is AR24(ARGB8888)#
The specific instructions are as follows
modetest -M canaan-drm -D 0 -a -s 38@36:1080x1920-30 -P 32@36:1080x1920@AR24 -v -F tiles
The following figure shows the LCD display:
2.4 OSD layer outputs tiles color bars with a color space of RG16(RGB565)#
The specific instructions are as follows:
modetest -M canaan-drm -D 0 -a -s 38@36:1080x1920-30 -P 32@36:1080x1920@RG16 -v -F tiles
The following figure shows the LCD display:
3. Introduction to DRM API#
3.1 Turn on the DRM device#
fd = open("/dev/dri/card0", O_RDWR | O_CLOEXEC);
if (fd < 0) {
fprintf(stderr, "open card0 error \n");
return -1;
}
3.2 Retrieving DRM resources#
drmModeResPtr drmModeGetResources(int fd);
typedef struct _drmModeRes {
int count_fbs;
uint32_t *fbs;
int count_crtcs;
uint32_t *crtcs;
int count_connectors;
uint32_t *connectors;
int count_encoders;
uint32_t *encoders;
uint32_t min_width, max_width;
uint32_t min_height, max_height;
} drmModeRes, *drmModeResPtr;
An example of a code call is as follows:
res = drmModeGetResources(fd);
if (res == NULL) {
fprintf(stderr, "drmModeGetResources error \n");
return -1;
}
conn_id = res->connectors[0];
crtc_id = res->crtcs[0];
3.4 Retrieving layer resources#
drmModePlaneResPtr drmModeGetPlaneResources(int fd);
typedef struct _drmModePlaneRes {
uint32_t count_planes;
uint32_t *planes;
} drmModePlaneRes, *drmModePlaneResPtr;
An example of a code call is as follows:
plane_res = drmModeGetPlaneResources(fd);
if (plane_res == NULL) {
fprintf(stderr, "drmModeGetPlaneResources error \n");
return -1;
}
plane_id = plane_res->planes[1];
In K230 DRM, the layer correspondence is as follows:
plane_res->plans[0] stand for Video layer
plane_res->plans[1] to plane_res->plans[4] stand for OSD layer
3.5 Obtaining Connectors#
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id);
typedef struct _drmModeConnector {
uint32_t connector_id;
uint32_t encoder_id; /**< Encoder currently connected to */
uint32_t connector_type;
uint32_t connector_type_id;
drmModeConnection connection;
uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
drmModeSubPixel subpixel;
int count_modes;
drmModeModeInfoPtr modes;
int count_props;
uint32_t *props; /**< List of property ids */
uint64_t *prop_values; /**< List of property values */
int count_encoders;
uint32_t *encoders; /**< List of encoder ids */
} drmModeConnector, *drmModeConnectorPtr;
An example of a code call is as follows:
conn = drmModeGetConnector(fd, conn_id);
if (conn == NULL) {
fprintf(stderr, "drmModeGetConnector error \n");
return -1;
}
3.6 Apply for DRM DUMB buffer#
An example of a code call is as follows:
creq.width = 1080;
creq.height = 1920;
creq.bpp = 32;
creq.fourcc = DRM_FORMAT_ARGB8888;
ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &creq);
if (ret < 0) {
fprintf(stderr, "cannot create dumb buffer (%d): %m\n",
errno);
return -errno;
}
3.7 Submit DRM Requests#
An example of a code call is as follows:
int drmModeAtomicCommit(int fd,
drmModeAtomicReqPtr req,
uint32_t flags,
void *user_data);
4. Precautions#
K230 DRM development and testing rely on LCD screens
K230 DRM internal module ID is not static, we should according to the actual ID of each module