xref: /linux/drivers/gpu/drm/verisilicon/vs_plane.c (revision 0fc8f6200d2313278fbf4539bbab74677c685531)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2025 Icenowy Zheng <uwu@icenowy.me>
4  */
5 
6 #include <linux/errno.h>
7 #include <linux/printk.h>
8 
9 #include <drm/drm_fb_dma_helper.h>
10 #include <drm/drm_fourcc.h>
11 #include <drm/drm_gem_dma_helper.h>
12 
13 #include "vs_plane.h"
14 
15 void drm_format_to_vs_format(u32 drm_format, struct vs_format *vs_format)
16 {
17 	switch (drm_format) {
18 	case DRM_FORMAT_XRGB4444:
19 	case DRM_FORMAT_RGBX4444:
20 	case DRM_FORMAT_XBGR4444:
21 	case DRM_FORMAT_BGRX4444:
22 		vs_format->color = VSDC_COLOR_FORMAT_X4R4G4B4;
23 		break;
24 	case DRM_FORMAT_ARGB4444:
25 	case DRM_FORMAT_RGBA4444:
26 	case DRM_FORMAT_ABGR4444:
27 	case DRM_FORMAT_BGRA4444:
28 		vs_format->color = VSDC_COLOR_FORMAT_A4R4G4B4;
29 		break;
30 	case DRM_FORMAT_XRGB1555:
31 	case DRM_FORMAT_RGBX5551:
32 	case DRM_FORMAT_XBGR1555:
33 	case DRM_FORMAT_BGRX5551:
34 		vs_format->color = VSDC_COLOR_FORMAT_X1R5G5B5;
35 		break;
36 	case DRM_FORMAT_ARGB1555:
37 	case DRM_FORMAT_RGBA5551:
38 	case DRM_FORMAT_ABGR1555:
39 	case DRM_FORMAT_BGRA5551:
40 		vs_format->color = VSDC_COLOR_FORMAT_A1R5G5B5;
41 		break;
42 	case DRM_FORMAT_RGB565:
43 	case DRM_FORMAT_BGR565:
44 		vs_format->color = VSDC_COLOR_FORMAT_R5G6B5;
45 		break;
46 	case DRM_FORMAT_XRGB8888:
47 	case DRM_FORMAT_RGBX8888:
48 	case DRM_FORMAT_XBGR8888:
49 	case DRM_FORMAT_BGRX8888:
50 		vs_format->color = VSDC_COLOR_FORMAT_X8R8G8B8;
51 		break;
52 	case DRM_FORMAT_ARGB8888:
53 	case DRM_FORMAT_RGBA8888:
54 	case DRM_FORMAT_ABGR8888:
55 	case DRM_FORMAT_BGRA8888:
56 		vs_format->color = VSDC_COLOR_FORMAT_A8R8G8B8;
57 		break;
58 	case DRM_FORMAT_ARGB2101010:
59 	case DRM_FORMAT_RGBA1010102:
60 	case DRM_FORMAT_ABGR2101010:
61 	case DRM_FORMAT_BGRA1010102:
62 		vs_format->color = VSDC_COLOR_FORMAT_A2R10G10B10;
63 		break;
64 	default:
65 		pr_warn("Unexpected drm format!\n");
66 	}
67 
68 	switch (drm_format) {
69 	case DRM_FORMAT_RGBX4444:
70 	case DRM_FORMAT_RGBA4444:
71 	case DRM_FORMAT_RGBX5551:
72 	case DRM_FORMAT_RGBA5551:
73 	case DRM_FORMAT_RGBX8888:
74 	case DRM_FORMAT_RGBA8888:
75 	case DRM_FORMAT_RGBA1010102:
76 		vs_format->swizzle = VSDC_SWIZZLE_RGBA;
77 		break;
78 	case DRM_FORMAT_XBGR4444:
79 	case DRM_FORMAT_ABGR4444:
80 	case DRM_FORMAT_XBGR1555:
81 	case DRM_FORMAT_ABGR1555:
82 	case DRM_FORMAT_BGR565:
83 	case DRM_FORMAT_XBGR8888:
84 	case DRM_FORMAT_ABGR8888:
85 	case DRM_FORMAT_ABGR2101010:
86 		vs_format->swizzle = VSDC_SWIZZLE_ABGR;
87 		break;
88 	case DRM_FORMAT_BGRX4444:
89 	case DRM_FORMAT_BGRA4444:
90 	case DRM_FORMAT_BGRX5551:
91 	case DRM_FORMAT_BGRA5551:
92 	case DRM_FORMAT_BGRX8888:
93 	case DRM_FORMAT_BGRA8888:
94 	case DRM_FORMAT_BGRA1010102:
95 		vs_format->swizzle = VSDC_SWIZZLE_BGRA;
96 		break;
97 	default:
98 		/* N/A for YUV formats */
99 		vs_format->swizzle = VSDC_SWIZZLE_ARGB;
100 	}
101 
102 	/* N/A for non-YUV formats */
103 	vs_format->uv_swizzle = false;
104 }
105 
106 dma_addr_t vs_fb_get_dma_addr(struct drm_framebuffer *fb,
107 			      const struct drm_rect *src_rect)
108 {
109 	struct drm_gem_dma_object *gem;
110 	dma_addr_t dma_addr;
111 
112 	/* Get the physical address of the buffer in memory */
113 	gem = drm_fb_dma_get_gem_obj(fb, 0);
114 
115 	/* Compute the start of the displayed memory */
116 	dma_addr = gem->dma_addr + fb->offsets[0];
117 
118 	/* Fixup framebuffer address for src coordinates */
119 	dma_addr += drm_format_info_min_pitch(fb->format, 0,
120 					      src_rect->x1 >> 16);
121 	dma_addr += (src_rect->y1 >> 16) * fb->pitches[0];
122 
123 	return dma_addr;
124 }
125